[netcdf] 01/08: New upstream version 4.6.0

Bas Couwenberg sebastic at debian.org
Thu Jan 25 18:51:21 UTC 2018


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

sebastic pushed a commit to branch master
in repository netcdf.

commit c4490089fdb1a7d461274e11784188c3688f33f4
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Thu Jan 25 19:23:00 2018 +0100

    New upstream version 4.6.0
---
 .gitignore                                         |     4 -
 .travis.yml                                        |    50 +-
 CMakeLists.txt                                     |    64 +-
 Makefile.am                                        |    94 +-
 Makefile.in                                        |    95 +-
 RELEASE_NOTES.md                                   |    10 +
 cf                                                 |    45 +-
 cf.cmake                                           |    56 +-
 config.h.cmake.in                                  |     9 +
 config.h.in                                        |    21 +-
 configure                                          |   672 +-
 configure.ac                                       |   183 +-
 dap4_test/Makefile.am                              |    14 +-
 dap4_test/Makefile.in                              |    93 +-
 dap4_test/test_data.c                              |     2 +
 dap4_test/test_data.sh                             |    18 +-
 dap4_test/test_meta.sh                             |    21 +-
 dap4_test/test_parse.sh                            |    12 +-
 dap4_test/test_raw.sh                              |     8 +-
 dap4_test/tst_raw.sh                               |     2 -
 docs/Doxyfile.developer                            |     2 +-
 docs/Doxyfile.in                                   |    17 +-
 docs/FAQ.md                                        |     6 +-
 docs/Makefile.am                                   |    14 +-
 docs/Makefile.in                                   |    19 +-
 docs/all-error-codes.md                            |     6 +-
 docs/auth.md                                       |    36 +-
 docs/cmake_faq.md                                  |    69 -
 docs/filters.md                                    |   420 +
 docs/guide.dox                                     |     1 +
 docs/images/Makefile.in                            |     5 +-
 docs/install.md                                    |    32 +-
 docs/mainpage.dox                                  |     4 +-
 docs/old/netcdf-c.texi                             |     6 +-
 docs/static-pages/software.html                    |  7354 ++--
 docs/tutorial.dox                                  |    11 +
 docs/windows-binaries.md                           |    26 +-
 examples/C/CMakeLists.txt                          |    10 +-
 examples/C/Makefile.am                             |    49 +-
 examples/C/Makefile.in                             |   367 +-
 examples/C/filter_example.c                        |   309 +
 examples/C/hdf5plugins/CMakeLists.txt              |    37 +
 examples/C/hdf5plugins/H5Zbzip2.c                  |   181 +
 examples/C/hdf5plugins/Makefile.am                 |    28 +
 {liblib => examples/C/hdf5plugins}/Makefile.in     |   168 +-
 examples/C/hdf5plugins/blocksort.c                 |  1094 +
 examples/C/hdf5plugins/bzip2.nc                    |   Bin 0 -> 11503 bytes
 examples/C/hdf5plugins/bzlib.c                     |  1572 +
 examples/C/hdf5plugins/bzlib.h                     |   282 +
 examples/C/hdf5plugins/bzlib_private.h             |   509 +
 examples/C/hdf5plugins/compress.c                  |   672 +
 examples/C/hdf5plugins/crctable.c                  |   104 +
 examples/C/hdf5plugins/decompress.c                |   646 +
 examples/C/hdf5plugins/h5bzip2.h                   |    30 +
 examples/C/hdf5plugins/huffman.c                   |   205 +
 examples/C/hdf5plugins/randtable.c                 |    84 +
 examples/C/run_examples.sh                         |    24 +
 examples/C/run_examples4.sh                        |    39 +
 examples/C/run_filter.sh                           |    29 +
 examples/CDL/CMakeLists.txt                        |    11 +-
 examples/CDL/Makefile.am                           |    16 +-
 examples/CDL/Makefile.in                           |    64 +-
 examples/CDL/create_sample_files.sh                |    18 -
 examples/CDL/do_comps.sh                           |    22 +
 examples/CMakeLists.txt                            |     5 -
 examples/Makefile.in                               |     5 +-
 h5_test/CMakeLists.txt                             |     8 +-
 h5_test/Makefile.am                                |    10 +-
 h5_test/Makefile.in                                |    64 +-
 h5_test/tst_h_atts3.c                              |     2 -
 h5_test/tst_h_atts4.c                              |     2 -
 h5_test/tst_h_dimscales.c                          |    10 +-
 h5_test/tst_h_dimscales1.c                         |    45 +-
 h5_test/tst_h_files.c                              |     3 +-
 h5_test/tst_h_filters.c                            |   107 -
 h5_test/tst_h_rd_cmp.c                             |    62 -
 h5_test/tst_h_wrt_cmp.c                            |   125 +-
 include/Makefile.am                                |     4 +-
 include/Makefile.in                                |    17 +-
 include/err_macros.h                               |    29 +-
 include/nc.h                                       |     5 +-
 include/nc4dispatch.h                              |     6 +-
 include/nc4internal.h                              |    18 +-
 include/nc_tests.h                                 |    25 +-
 include/ncauth.h                                   |    58 +
 include/ncconfigure.h                              |    12 +
 include/ncdispatch.h                               |    11 +-
 include/ncfilter.h                                 |    27 +
 include/ncrc.h                                     |    55 +-
 include/netcdf.h                                   |   681 +-
 include/netcdf_par.h                               |     5 +-
 include/rnd.h                                      |    17 +-
 lib_flags.am                                       |     7 +-
 libdap2/Makefile.in                                |    15 +-
 libdap2/dapattr.c                                  |   365 -
 libdap2/dapcvt.c                                   |    18 +-
 libdap2/dapdump.c                                  |     2 +-
 libdap2/dapodom.c                                  |     4 +-
 libdap2/daputil.c                                  |    19 +-
 libdap2/ncd2dispatch.c                             |   107 +-
 libdap2/ncd2dispatch.h                             |     9 +-
 libdap2/test_vara.c                                |     4 +-
 libdap4/CMakeLists.txt                             |     2 +-
 libdap4/Makefile.am                                |     1 -
 libdap4/Makefile.in                                |    41 +-
 libdap4/d4chunk.c                                  |     2 +-
 libdap4/d4curlfunctions.c                          |   129 +-
 libdap4/d4curlfunctions.h                          |     2 +-
 libdap4/d4data.c                                   |     1 -
 libdap4/d4dump.c                                   |     2 +-
 libdap4/d4file.c                                   |    79 +-
 libdap4/d4http.c                                   |     5 +-
 libdap4/d4includes.h                               |     2 +
 libdap4/d4meta.c                                   |    22 +-
 libdap4/d4odom.c                                   |     4 +-
 libdap4/d4parser.c                                 |    19 +-
 libdap4/d4rc.c                                     |   666 -
 libdap4/d4read.c                                   |    59 +-
 libdap4/d4swap.c                                   |     2 +-
 libdap4/d4util.c                                   |   119 +-
 libdap4/d4varx.c                                   |     2 +-
 libdap4/ncd4.h                                     |     5 +-
 libdap4/ncd4dispatch.c                             |    93 +-
 libdap4/ncd4types.h                                |    65 +-
 libdispatch/CMakeLists.txt                         |     4 +-
 libdispatch/Makefile.am                            |    12 +-
 libdispatch/Makefile.in                            |    64 +-
 libdispatch/datt.c                                 |    43 +-
 libdispatch/dattget.c                              |    85 +-
 libdispatch/dattinq.c                              |   225 +
 libdispatch/dauth.c                                |   383 +
 libdispatch/dcopy.c                                |   148 +-
 libdispatch/ddim.c                                 |     2 +-
 libdispatch/ddispatch.c                            |    95 +-
 libdispatch/derror.c                               |    27 +-
 libdispatch/dfile.c                                |  1106 +-
 libdispatch/dfilter.c                              |   237 +
 libdispatch/dinternal.c                            |     6 +-
 libdispatch/dparallel.c                            |   279 +-
 libdispatch/drc.c                                  |   611 +-
 libdispatch/dstring.c                              |    58 +-
 libdispatch/dtype.c                                |    17 +-
 libdispatch/dutil.c                                |   254 +
 libdispatch/dv2i.c                                 |   613 +-
 libdispatch/dvar.c                                 |   491 +-
 libdispatch/dvarget.c                              |   126 +-
 libdispatch/dvarinq.c                              |   369 +-
 libdispatch/dvarput.c                              |    29 +-
 libdispatch/dwinpath.c                             |     2 -
 libdispatch/nc.c                                   |     3 +-
 libdispatch/ncuri.c                                |     5 +-
 libdispatch/test_pathcvt.c                         |     1 -
 libdispatch/utf8proc.c                             |     3 +-
 libdispatch/utf8proc.h                             |    24 +-
 liblib/CMakeLists.txt                              |     8 +
 liblib/Makefile.am                                 |     8 +-
 liblib/Makefile.in                                 |    57 +-
 libnetcdf.settings.in                              |     1 +
 libsrc/Makefile.am                                 |     9 +-
 libsrc/Makefile.in                                 |    44 +-
 libsrc/attr.c                                      |     2 -
 libsrc/attr.m4                                     |     2 -
 libsrc/dim.c                                       |     5 -
 libsrc/nc3dispatch.c                               |    19 +-
 libsrc/nc3internal.c                               |   174 +-
 libsrc/nc_hashmap.c                                |    23 +
 libsrc/ncx.c                                       | 37001 ++++++++++---------
 libsrc/ncx.h                                       |    21 +-
 libsrc/ncx.m4                                      |    13 +-
 libsrc/posixio.c                                   |     3 -
 libsrc/v1hpg.c                                     |    28 +-
 libsrc/var.c                                       |     7 +-
 libsrc4/Makefile.am                                |    12 +-
 libsrc4/Makefile.in                                |    22 +-
 libsrc4/nc3stub.c                                  |   997 -
 libsrc4/nc4attr.c                                  |   736 +-
 libsrc4/nc4dim.c                                   |   176 +-
 libsrc4/nc4dispatch.c                              |    13 +
 libsrc4/nc4file.c                                  |  3566 +-
 libsrc4/nc4grp.c                                   |   319 +-
 libsrc4/nc4hdf.c                                   |  6398 ++--
 libsrc4/nc4info.c                                  |    78 +-
 libsrc4/nc4internal.c                              |  1216 +-
 libsrc4/nc4type.c                                  |   403 +-
 libsrc4/nc4var.c                                   |  1301 +-
 libsrc4/ncfunc.c                                   |    90 +-
 libsrcp/Makefile.am                                |     5 -
 libsrcp/Makefile.in                                |    23 +-
 libsrcp/ncpdispatch.c                              |    13 +-
 nc_test/CMakeLists.txt                             |     1 +
 nc_test/Make0                                      |    11 +-
 nc_test/Makefile.am                                |    63 +-
 nc_test/Makefile.in                                |   236 +-
 nc_test/large_files.c                              |    20 +-
 nc_test/nc_enddef.c                                |    61 -
 nc_test/nc_sync.c                                  |   557 -
 nc_test/nc_sync.h                                  |     6 -
 nc_test/nc_sync_child.c                            |   100 -
 nc_test/nc_test.c                                  |    10 +-
 nc_test/quick_large_files.c                        |  1082 +-
 nc_test/run_diskless.sh                            |     2 +-
 nc_test/run_diskless2.sh                           |     3 +
 nc_test/test_put.c                                 |     3 +-
 nc_test/test_put.m4                                |     3 +-
 nc_test/test_read.c                                |     6 +-
 nc_test/test_read.m4                               |     6 +-
 nc_test/test_write.c                               |     2 +-
 nc_test/test_write.m4                              |     2 +-
 nc_test/tst_atts3.c                                |     8 -
 nc_test/tst_big_rvar.c                             |     7 +-
 nc_test/tst_big_var2.c                             |     7 +-
 nc_test/tst_big_var6.c                             |     6 +-
 nc_test/tst_cdf5format.c                           |   354 +-
 nc_test/tst_diskless.c                             |     3 +-
 nc_test/tst_elatefill.c                            |     3 +-
 nc_test/tst_formats.c                              |   159 +
 nc_test/tst_global_fillval.c                       |    77 +-
 nc_test/tst_inq_type.c                             |   266 +-
 nc_test/tst_max_var_dims.c                         |    34 +
 nc_test/tst_misc.c                                 |    22 +
 nc_test/tst_parallel2.c                            |    44 +-
 nc_test/tst_utf8_phrases.c                         |     8 +-
 nc_test/tst_utf8_validate.c                        |   Bin 15275 -> 15268 bytes
 nc_test/util.c                                     |    13 +-
 nc_test4/CMakeLists.txt                            |    51 +-
 nc_test4/Make0                                     |    33 +-
 nc_test4/Makefile.am                               |   149 +-
 nc_test4/Makefile.in                               |   816 +-
 nc_test4/bzip2.cdl                                 |    83 +
 nc_test4/filter_test/CMakeLists.txt                |    34 +
 nc_test4/filter_test/H5Zbzip2.c                    |   171 +
 nc_test4/filter_test/H5Ztemplate.c                 |   104 +
 nc_test4/filter_test/H5Ztest.c                     |   207 +
 nc_test4/filter_test/Make0                         |    38 +
 nc_test4/filter_test/Makefile.am                   |    77 +
 nc_test4/filter_test/blocksort.c                   |  1094 +
 nc_test4/filter_test/bzlib.c                       |  1572 +
 nc_test4/filter_test/bzlib.h                       |   282 +
 nc_test4/filter_test/bzlib_private.h               |   509 +
 nc_test4/filter_test/compress.c                    |   672 +
 nc_test4/filter_test/crctable.c                    |   104 +
 nc_test4/filter_test/decompress.c                  |   646 +
 nc_test4/filter_test/fake.c                        |     5 +
 nc_test4/filter_test/h5bzip2.h                     |    12 +
 nc_test4/filter_test/h5test.h                      |    18 +
 nc_test4/filter_test/huffman.c                     |   205 +
 nc_test4/filter_test/randtable.c                   |    84 +
 nc_test4/filter_test/test_filter.c                 |   493 +
 nc_test4/filter_test/test_misc.c                   |   414 +
 nc_test4/filter_test/tst_filter.sh                 |   128 +
 nc_test4/filtered.cdl                              |    88 +
 nc_test4/findplugin.in                             |    99 +
 nc_test4/h5testszip.c                              |   182 +
 nc_test4/hdf5plugins/CMakeLists.txt                |    37 +
 nc_test4/hdf5plugins/H5Zbzip2.c                    |   181 +
 nc_test4/hdf5plugins/H5Zmisc.c                     |   252 +
 nc_test4/hdf5plugins/H5Ztemplate.c                 |   104 +
 nc_test4/hdf5plugins/Makefile.am                   |    26 +
 {liblib => nc_test4/hdf5plugins}/Makefile.in       |   170 +-
 nc_test4/hdf5plugins/blocksort.c                   |  1094 +
 nc_test4/hdf5plugins/bzip2.nc                      |   Bin 0 -> 11503 bytes
 nc_test4/hdf5plugins/bzlib.c                       |  1572 +
 nc_test4/hdf5plugins/bzlib.h                       |   282 +
 nc_test4/hdf5plugins/bzlib_private.h               |   509 +
 nc_test4/hdf5plugins/compress.c                    |   672 +
 nc_test4/hdf5plugins/crctable.c                    |   104 +
 nc_test4/hdf5plugins/decompress.c                  |   646 +
 nc_test4/hdf5plugins/h5bzip2.h                     |    30 +
 nc_test4/hdf5plugins/h5misc.h                      |    34 +
 nc_test4/hdf5plugins/huffman.c                     |   205 +
 nc_test4/hdf5plugins/randtable.c                   |    84 +
 nc_test4/ref_bzip2.c                               |    98 +
 nc_test4/ref_szip.cdl                              |    85 +
 nc_test4/ref_szip.h5                               |   Bin 0 -> 5588 bytes
 nc_test4/renamegroup.c                             |     2 +-
 nc_test4/run_get_hdf4_files.sh                     |    16 +-
 nc_test4/run_par_test.sh                           |     1 +
 nc_test4/test_filter.c                             |   306 +
 nc_test4/test_filter_misc.c                        |   452 +
 nc_test4/test_szip.c                               |   155 +
 nc_test4/test_wrapper.in                           |    35 +
 nc_test4/tst_atts1.c                               |     4 +-
 {ncdump => nc_test4}/tst_bug324.c                  |     2 +-
 nc_test4/tst_camrun.c                              |    12 -
 nc_test4/tst_chunk_hdf4.c                          |    34 +-
 nc_test4/tst_chunks.c                              |    41 +
 nc_test4/tst_compounds.c                           |     8 +-
 nc_test4/tst_converts.c                            |    67 +-
 nc_test4/tst_create_files.c                        |     2 -
 nc_test4/tst_dims3.c                               |     8 +-
 nc_test4/tst_empty_vlen_unlim.c                    |    30 +-
 nc_test4/tst_enums.c                               |     5 +
 nc_test4/tst_files.c                               |    79 +-
 nc_test4/tst_files4.c                              |     2 -
 nc_test4/tst_files5.c                              |     2 +-
 nc_test4/tst_fill_attr_vanish.c                    |     9 -
 nc_test4/tst_fills2.c                              |     2 +-
 nc_test4/tst_filter.sh                             |   146 +
 nc_test4/tst_filterparser.c                        |   194 +
 nc_test4/tst_formatx_hdf4.sh                       |    15 +-
 nc_test4/tst_grps.c                                |   145 +-
 nc_test4/tst_grps2.c                               |     4 +-
 nc_test4/tst_h5_endians.c                          |    91 +-
 nc_test4/tst_h_atts2.c                             |   127 -
 nc_test4/tst_h_files3.c                            |   223 -
 nc_test4/tst_h_scalar.c                            |     2 -
 nc_test4/tst_h_strbug.c                            |     8 +-
 nc_test4/tst_h_vl2.c                               |     4 +-
 nc_test4/tst_hdf5_file_compat.c                    |     1 -
 nc_test4/tst_interops.c                            |     4 -
 nc_test4/tst_interops2.c                           |    11 +
 nc_test4/tst_interops3.c                           |    55 +-
 nc_test4/tst_interops5.c                           |    16 +-
 nc_test4/tst_large.c                               |    28 +-
 nc_test4/tst_large2.c                              |     6 +-
 nc_test4/tst_large3.c                              |     6 +-
 nc_test4/tst_large5.c                              |     2 -
 nc_test4/tst_rehash.c                              |    14 +-
 nc_test4/tst_rename.c                              |   539 +-
 nc_test4/tst_simplerw_coll_r.c                     |   641 +-
 nc_test4/tst_szip.sh                               |    29 +
 nc_test4/tst_types.c                               |   666 +-
 nc_test4/tst_vars.c                                |    37 +-
 nc_test4/tst_vars2.c                               |   578 +-
 nc_test4/tst_vars3.c                               |    27 +-
 nc_test4/tst_xplatform2.c                          |   168 +-
 nc_test4/unfiltered.cdl                            |    87 +
 ncdap_test/Makefile.am                             |    16 +-
 ncdap_test/Makefile.in                             |   121 +-
 ncdap_test/expected3/Makefile.in                   |     5 +-
 ncdap_test/expectremote3/Makefile.in               |     5 +-
 ncdap_test/t_dap.c                                 |    15 +-
 ncdap_test/t_dap3a.c                               |    16 +-
 ncdap_test/t_dap3c.c                               |     6 +-
 ncdap_test/t_dap4.c                                |   466 -
 ncdap_test/t_dap4a.c                               |   937 -
 ncdap_test/t_dap4c.c                               |    51 -
 ncdap_test/test_cvt.c                              |    16 +-
 ncdap_test/test_nstride_cached.c                   |     1 -
 ncdap_test/test_partvar.c                          |     6 +-
 ncdap_test/test_partvar2.c                         |     6 +-
 ncdap_test/test_vara.c                             |     7 +-
 ncdap_test/test_varm3.c                            |     4 +-
 ncdap_test/testdata3/Makefile.in                   |     5 +-
 ncdap_test/testurl.sh                              |    14 +-
 ncdap_test/tst_ber.sh                              |     9 +-
 ncdap_test/tst_formatx.sh                          |     8 +-
 ncdap_test/tst_ncdap.sh                            |     4 +-
 ncdap_test/tst_remote.sh                           |     3 +-
 ncdap_test/tst_special.sh                          |     3 +-
 ncdap_test/tst_tds.sh                              |     3 +-
 ncdump/CMakeLists.txt                              |   108 +-
 ncdump/L512.bin                                    |     1 +
 ncdump/Makefile.am                                 |   236 +-
 ncdump/Makefile.in                                 |   741 +-
 ncdump/bom.c                                       |     4 +-
 ncdump/cdl.h                                       |     1 +
 ncdump/cdl/Makefile.in                             |     5 +-
 ncdump/ctest.c                                     |  1472 -
 ncdump/ctest64.c                                   |  1472 -
 ncdump/ctests.sh                                   |     9 +-
 ncdump/dumplib.c                                   |    56 -
 ncdump/dumplib.h                                   |     5 -
 ncdump/expected/Makefile.in                        |     5 +-
 ncdump/indent.h                                    |     6 +-
 ncdump/isnan.h                                     |     6 +-
 ncdump/nccopy.1                                    |    25 +
 ncdump/nccopy.c                                    |   260 +-
 ncdump/ncdump.c                                    |    28 +-
 ncdump/nctime0.h                                   |     7 +-
 ncdump/nctrunc.c                                   |     1 -
 ncdump/ocprint.c                                   |     3 -
 ncdump/ref_ctest.c                                 |  2603 +-
 ncdump/ref_ctest64.c                               |  2603 +-
 ncdump/ref_null_byte_padding_test.nc               |   Bin 0 -> 1036 bytes
 ...st_360_day_1900.nc => ref_test_360_day_1900.nc} |   Bin
 ...st_365_day_1900.nc => ref_test_365_day_1900.nc} |   Bin
 ...st_366_day_1900.nc => ref_test_366_day_1900.nc} |   Bin
 ncdump/ref_test_corrupt_magic.nc                   |   Bin 0 -> 6368 bytes
 ncdump/ref_tst_nc4_utf8_4.cdl                      |    24 +
 ncdump/run_ncgen_nc4_tests.sh                      |    15 +-
 ncdump/run_ncgen_tests.sh                          |    13 +-
 ncdump/run_utf8_nc4_tests.sh                       |    22 +-
 ncdump/run_utf8_tests.sh                           |    48 +-
 ncdump/test_corrupt_magic.cdl                      |    11 +
 ncdump/tst_calendars.sh                            |     2 +-
 ncdump/tst_compress.c                              |     2 +-
 ncdump/tst_dimsizes.sh                             |    14 +-
 ncdump/tst_fileinfo.sh                             |     6 +-
 ncdump/tst_fillbug.c                               |     8 +-
 ncdump/tst_fillbug.sh                              |     1 +
 ncdump/tst_formatx3.sh                             |    26 +-
 ncdump/tst_formatx4.sh                             |    18 +-
 ncdump/tst_h_rdc0.c                                |    11 +-
 ncdump/tst_h_scalar.c                              |     4 +-
 ncdump/tst_h_scalar.sh                             |     1 +
 ncdump/tst_hdf5_offset.sh                          |    45 +
 ncdump/tst_inmemory_nc3.sh                         |    16 +-
 ncdump/tst_inmemory_nc4.sh                         |    16 +-
 ncdump/tst_nccopy3.sh                              |    33 +-
 ncdump/tst_nccopy4.sh                              |     6 +-
 ncdump/tst_ncgen4.sh                               |    17 +-
 ncdump/tst_ncgen4_classic.sh                       |    11 +-
 ncdump/tst_ncgen4_cycle.sh                         |    17 +-
 ncdump/tst_ncgen4_diff.sh                          |     6 +-
 ncdump/tst_ncgen_shared.sh                         |     5 +-
 ncdump/tst_netcdf4.sh                              |   151 +-
 ncdump/tst_netcdf4_4.sh                            |    10 +-
 ncdump/tst_null_byte_padding.sh                    |    17 +
 ncdump/tst_output.sh                               |    58 +-
 ncdump/tst_string_data.c                           |     2 +-
 ncdump/utils.h                                     |     5 +
 ncdump/vardata.c                                   |     2 -
 ncdump/vardata.h                                   |     6 +-
 ncgen/Makefile.am                                  |     2 +
 ncgen/Makefile.in                                  |    14 +-
 ncgen/cvt.c                                        |    20 +-
 ncgen/genbin.c                                     |    27 +
 ncgen/genc.c                                       |    56 +
 ncgen/genlib.h                                     |     2 +-
 ncgen/includes.h                                   |     1 -
 ncgen/main.c                                       |    12 +-
 ncgen/makeparser.sh                                |     8 +
 ncgen/nc_iter.h                                    |     6 +-
 ncgen/ncgen.h                                      |    19 +-
 ncgen/ncgen.l                                      |    10 +-
 ncgen/ncgen.y                                      |    50 +-
 ncgen/ncgenl.c                                     |  2098 +-
 ncgen/ncgeny.c                                     |  1351 +-
 ncgen/ncgeny.h                                     |    86 +-
 ncgen3/Makefile.in                                 |    16 +-
 ncgen3/genlib.c                                    |    55 -
 ncgen3/genlib.h                                    |     5 -
 ncgen3/load.c                                      |     4 -
 ncgen3/main.c                                      |     1 -
 nctest/CMakeLists.txt                              |     2 +
 nctest/Makefile.am                                 |    11 +-
 nctest/Makefile.in                                 |    61 +-
 nctest/driver.c                                    |   227 +-
 oc2/CMakeLists.txt                                 |     5 +-
 oc2/Makefile.am                                    |     6 +-
 oc2/Makefile.in                                    |    38 +-
 oc2/daplex.c                                       |    22 +-
 oc2/oc.c                                           |   130 +-
 oc2/occlientparams.c                               |    29 -
 oc2/occlientparams.h                               |    11 -
 oc2/occurlfunctions.c                              |   274 +-
 oc2/occurlfunctions.h                              |     2 +-
 oc2/ocdump.c                                       |    50 +-
 oc2/ochttp.c                                       |    24 +-
 oc2/ochttp.h                                       |     2 +-
 oc2/ocinternal.c                                   |   188 +-
 oc2/ocinternal.h                                   |    62 +-
 oc2/ocnode.c                                       |    23 +-
 oc2/ocrc.c                                         |   809 -
 oc2/ocread.c                                       |    63 +-
 oc2/ocutil.c                                       |    52 +-
 oc2/xxdr.c                                         |     2 +-
 test-driver-verbose                                |    35 +-
 test_common.in                                     |    22 +-
 460 files changed, 68705 insertions(+), 49685 deletions(-)

diff --git a/.gitignore b/.gitignore
index 110c275..e961777 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,3 @@
-#####
-# End ignored generated files.
-#####
-
 ### 'Normal' gitignore files.
 autom4te.cache
 debug.txt
diff --git a/.travis.yml b/.travis.yml
index 2a08450..a40743e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,9 @@
+# blocklist
+branches:
+  except:
+  - /.*[.]dmh/
+  - /.*[.]wif/
+
 sudo: required
 language: c
 services:
@@ -5,29 +11,33 @@ services:
 
 env:
     matrix:
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x64-signed
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x64-signed
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x86-signed
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x86-signed
-
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x64-unsigned
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x64-unsigned
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x86-unsigned
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x86-unsigned
-
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x64-signed
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x64-signed
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x86-signed
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x86-signed
-
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x64-unsigned
-        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x64-unsigned
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-gcc-x86-unsigned
-        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF' CURHOST=docker-clang-x86-unsigned
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-signed
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-signed
+
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-signed
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-signed
+
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-unsigned
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-unsigned
+
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-unsigned
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-unsigned
+
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-signed
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-signed
+
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-signed
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-signed
+
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-unsigned
+        - DOCKIMG=unidata/nctests:serial   USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-unsigned
+
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc   AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-unsigned
+        - DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-unsigned
 
 before_install:
     - docker pull $DOCKIMG > /dev/null
 
 script:
 
-    - 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 DISTCHECK=$DISTCHECK -e COPTS="$COPTS" -e AC_OPTS="$AC_OPTS" -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c $DOCKIMG
+    - 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 DISTCHECK=$DISTCHECK -e COPTS="$COPTS" -e AC_OPTS="$AC_OPTS" -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c -e TESTPROC=100 $DOCKIMG
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7a64d47..8214ed5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@ set(PACKAGE "netCDF" CACHE STRING "")
 #####
 
 SET(NC_VERSION_MAJOR 4)
-SET(NC_VERSION_MINOR 5)
+SET(NC_VERSION_MINOR 6)
 SET(NC_VERSION_PATCH 0)
 SET(NC_VERSION_NOTE "")
 SET(netCDF_VERSION ${NC_VERSION_MAJOR}.${NC_VERSION_MINOR}.${NC_VERSION_PATCH}${NC_VERSION_NOTE})
@@ -93,7 +93,6 @@ INCLUDE(${CMAKE_ROOT}/Modules/CheckTypeSize.cmake)
 INCLUDE(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
 INCLUDE(${CMAKE_ROOT}/Modules/CheckCXXSourceCompiles.cmake)
 INCLUDE(${CMAKE_ROOT}/Modules/CheckCSourceCompiles.cmake)
-INCLUDE(${CMAKE_ROOT}/Modules/CheckCSourceRuns.cmake)
 INCLUDE(${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
 INCLUDE(${CMAKE_ROOT}/Modules/CheckSymbolExists.cmake)
 INCLUDE(${CMAKE_ROOT}/Modules/GetPrerequisites.cmake)
@@ -501,6 +500,14 @@ IF(ENABLE_NETCDF_4)
   SET(ENABLE_NETCDF4 ON CACHE BOOL "")
 ENDIF()
 
+# Option to allow for strict null file padding.
+# See https://github.com/Unidata/netcdf-c/issues/657 for more information
+OPTION(ENABLE_STRICT_NULL_BYTE_HEADER_PADDING "Enable strict null byte header padding." OFF)
+
+IF(ENABLE_STRICT_NULL_BYTE_HEADER_PADDING)
+  SET(USE_STRICT_NULL_BYTE_HEADER_PADDING ON CACHE BOOL "")
+ENDIF(ENABLE_STRICT_NULL_BYTE_HEADER_PADDING)
+
 # Option for building RPC
 OPTION(ENABLE_RPC "Enable RPC Client and Server." OFF)
 IF(ENABLE_RPC)
@@ -647,7 +654,7 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
   ENDIF(HDF5_C_LIBRARY AND HDF5_HL_LIBRARY AND HDF5_INCLUDE_DIR)
 
   # There is a missing case in the above code so default it
-  IF("${HDF5_C_LIBRARY_hdf5}" STREQUAL "" )
+  IF(NOT HDF5_C_LIBRARY_HDF5 OR "${HDF5_C_LIBRARY_hdf5}" STREQUAL "" )
     SET(HDF5_C_LIBRARY_hdf5 "${HDF5_C_LIBRARY}")
   ENDIF()
 
@@ -689,10 +696,11 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
   CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Pset_deflate "" HAVE_H5PSET_DEFLATE)
 
   #Check to see if H5Z_SZIP exists in HDF5_Libraries. If so, we must use szip.
-  CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5P_SZIP "" USE_SZIP)
+  CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Z_SZIP "" USE_SZIP)
   IF(USE_SZIP)
     FIND_LIBRARY(SZIP NAMES szip sz)
     IF(SZIP)
+      SET(HAVE_H5Z_SZIP 1)
       SET(SZIP_LIBRARY ${SZIP})
       SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${SZIP})
     ELSE()
@@ -825,7 +833,6 @@ ELSE()
   SET(ENABLE_DAP4 OFF)
 ENDIF()
 
-# Check to see if libtool supports
 
 # Check for the math library so it can be explicitly linked.
 IF(NOT WIN32)
@@ -888,8 +895,7 @@ IF(ENABLE_TESTS)
 
   # Options for CTest-based tests, dashboards.
   SET(NC_CTEST_PROJECT_NAME "netcdf-c" CACHE STRING "Project Name for CTest-based testing purposes.")
-  SET(NC_CTEST_DROP_SITE "129.114.104.111" CACHE STRING "Dashboard location for CTest-based testing purposes.")
-  #SET(NC_CTEST_DROP_SITE "my.cdash.org" CACHE STRING "Dashboard location for CTest-based testing purposes.")
+  SET(NC_CTEST_DROP_SITE "cdash.unidata.ucar.edu" CACHE STRING "Dashboard location for CTest-based testing purposes.")
   SET(NC_CTEST_DROP_LOC_PREFIX "" CACHE STRING "Prefix for Dashboard location on remote server when using CTest-based testing.")
 
   FIND_PROGRAM(HOSTNAME_CMD NAMES hostname)
@@ -994,7 +1000,6 @@ IF(ENABLE_PARALLEL4 AND ENABLE_NETCDF_4)
   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)
@@ -1100,6 +1105,17 @@ IF(ENABLE_PARALLEL_TESTS AND USE_PARALLEL)
   ENDIF()
 ENDIF()
 
+# Enable special filter test; experimental when using cmake.
+OPTION(ENABLE_FILTER_TESTING "Enable filter testing. Ignored if shared libraries or netCDF4 are not enabled" OFF)
+IF(NOT ENABLE_NETCDF4)
+  MESSAGE(WARNING "ENABLE_FILTER_TESTING requires netCDF-4. Disabling.")
+  SET(ENABLE_FILTER_TESTING OFF CACHE BOOL "")
+ENDIF()
+IF(NOT BUILD_SHARED_LIBS)
+  MESSAGE(WARNING "ENABLE_FILTER_TESTING requires shared libraries. Disabling.")
+  SET(ENABLE_FILTER_TESTING OFF CACHE BOOL "")
+ENDIF()
+
 # Determine whether or not to generate documentation.
 OPTION(ENABLE_DOXYGEN "Enable generation of doxygen-based documentation." OFF)
 IF(ENABLE_DOXYGEN)
@@ -1194,14 +1210,12 @@ MARK_AS_ADVANCED(ENABLE_SHARED_LIBRARY_VERSION)
 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
+    char error_if_char_is_signed[((char)-1) < 0 ? -1 : 1];\n
+    error_if_char_is_signed[0] = 0;
+    return -;\n
 }\n")
 
-CHECK_C_SOURCE_RUNS("${SIGNED_TEST_SOURCE}" __CHAR_UNSIGNED__)
+CHECK_C_SOURCE_COMPILES("${SIGNED_TEST_SOURCE}" __CHAR_UNSIGNED__)
 
 # Library include checks
 CHECK_INCLUDE_FILE("math.h"      HAVE_MATH_H)
@@ -1240,6 +1254,7 @@ CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H)
 CHECK_INCLUDE_FILE("sys/wait.h"  HAVE_SYS_WAIT_H)
 CHECK_INCLUDE_FILE("sys/mman.h"  HAVE_SYS_MMAN_H)
 CHECK_INCLUDE_FILE("sys/resource.h" HAVE_SYS_RESOURCE_H)
+CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H)
 CHECK_INCLUDE_FILE("fcntl.h"  HAVE_FCNTL_H)
 CHECK_INCLUDE_FILE("inttypes.h"  HAVE_INTTYPES_H)
 CHECK_INCLUDE_FILE("pstdint.h"  HAVE_PSTDINT_H)
@@ -1365,6 +1380,7 @@ CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL)
 CHECK_FUNCTION_EXISTS(strtoull  HAVE_STRTOULL)
 CHECK_FUNCTION_EXISTS(strstr  HAVE_STRSTR)
 CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP)
+CHECK_FUNCTION_EXISTS(mktemp HAVE_MKTEMP)
 CHECK_FUNCTION_EXISTS(rand  HAVE_RAND)
 CHECK_FUNCTION_EXISTS(random HAVE_RANDOM)
 CHECK_FUNCTION_EXISTS(gettimeofday  HAVE_GETTIMEOFDAY)
@@ -1509,7 +1525,7 @@ ENDMACRO()
 MACRO(build_bin_test_no_prefix F)
   build_bin_test(${F})
   IF(MSVC)
-    SET_PROPERTY(TEST ${F} PROPERTY FOLDER "tests/")
+    #SET_PROPERTY(TEST ${F} PROPERTY FOLDER "tests/")
     SET_TARGET_PROPERTIES(${F} PROPERTIES RUNTIME_OUTPUT_DIRECTORY
       ${CMAKE_CURRENT_BINARY_DIR})
     SET_TARGET_PROPERTIES(${F} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
@@ -1782,10 +1798,6 @@ IF(MSVC)
   DESTINATION ${CMAKE_INSTALL_BINDIR}
   COMPONENT dependencies)
 
-  #INSTALL(DIRECTORY ${CMAKE_PREFIX_PATH} DESTINATION "deps" COMPONENT dependencies)
-  #  INSTALL(FILES ${ALL_TLL_LIBS}
-  #  DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  #  COMPONENT dependencies)
 ENDIF()
 
 # Subdirectory CMakeLists.txt files should specify their own
@@ -1827,6 +1839,12 @@ ENDFOREACH()
 SET(NC_LIBS "-lnetcdf ${NC_LIBS}")
 
 STRING(REPLACE ";" " " NC_LIBS "${NC_LIBS}")
+STRING(REPLACE "-lhdf5::hdf5-shared" "-lhdf5" NC_LIBS ${NC_LIBS})
+STRING(REPLACE "-lhdf5::hdf5_hl-shared" "-lhdf5_hl" NC_LIBS ${NC_LIBS})
+STRING(REPLACE "-lhdf5::hdf5-static" "-lhdf5" NC_LIBS ${NC_LIBS})
+STRING(REPLACE "-lhdf5::hdf5_hl-static" "-lhdf5_hl" NC_LIBS ${NC_LIBS})
+
+
 STRING(REPLACE ";" " " LINKFLAGS "${LINKFLAGS}")
 
 LIST(REMOVE_DUPLICATES NC_LIBS)
@@ -1908,6 +1926,7 @@ is_enabled(USE_MMAP HAS_MMAP)
 is_enabled(JNA HAS_JNA)
 is_enabled(STATUS_RELAX_COORD_BOUND RELAX_COORD_BOUND)
 is_enabled(USE_CDF5 HAS_CDF5)
+is_enabled(ENABLE_ERANGE_FILL ENABLE_ERANGE_FILL)
 
 # Generate file from template.
 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/libnetcdf.settings.in"
@@ -1949,6 +1968,13 @@ SET(TOPSRCDIR "${CMAKE_SOURCE_DIR}")
 SET(TOPBUILDDIR "${CMAKE_BINARY_DIR}")
 configure_file(${CMAKE_SOURCE_DIR}/test_common.in ${CMAKE_BINARY_DIR}/test_common.sh @ONLY NEWLINE_STYLE LF)
 
+#####
+# Build nc_test4/findplugin.sh
+#####
+SET(ISCMAKE "1")
+configure_file(${CMAKE_SOURCE_DIR}/nc_test4/findplugin.in ${CMAKE_BINARY_DIR}/nc_test4/findplugin.sh @ONLY NEWLINE_STYLE LF)
+
+
 ####
 # Export files
 ####
diff --git a/Makefile.am b/Makefile.am
index 136a0bb..0a88c72 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,22 +4,18 @@
 # This is the main automake file for netCDF. It builds the different
 # netcdf directories. Not all directories are built, depending on the
 # options selected during configure.
+# Ed Hartnett, Ward Fisher
 
 # This directory stores libtool macros, put there by aclocal.
 ACLOCAL_AMFLAGS = -I m4
 
 # These files get added to the distribution.
-EXTRA_DIST = README.md COPYRIGHT INSTALL.md test_prog.c \
-	lib_flags.am cmake CMakeLists.txt COMPILE.cmake.txt \
-	config.h.cmake.in cmake_uninstall.cmake.in \
-	FixBundle.cmake.in \
-	nc-config.cmake.in RELEASE_NOTES.md CTestCustom.cmake \
-	CTestConfig.cmake.in libnetcdf.settings.in netCDFConfig.cmake.in \
-	CMakeInstallation.cmake test-driver-verbose test_common.in
-
-# Doxygen doesn't build nicely in vpath builds.
-# Don't do this; it wipes out any exported values
-#DISTCHECK_CONFIGURE_FLAGS = --disable-doxygen
+EXTRA_DIST = README.md COPYRIGHT INSTALL.md test_prog.c lib_flags.am	\
+cmake CMakeLists.txt COMPILE.cmake.txt config.h.cmake.in		\
+cmake_uninstall.cmake.in FixBundle.cmake.in nc-config.cmake.in		\
+RELEASE_NOTES.md CTestCustom.cmake CTestConfig.cmake.in			\
+libnetcdf.settings.in netCDFConfig.cmake.in CMakeInstallation.cmake	\
+test-driver-verbose test_common.in
 
 pkgconfigdir=$(libdir)/pkgconfig
 pkgconfig_DATA = netcdf.pc
@@ -70,16 +66,6 @@ if USE_PNETCDF
 LIBSRCP = libsrcp
 endif
 
-# Build UDUNITS?
-#if BUILD_UDUNITS
-#UDUNITS = udunits
-#endif
-
-# Build libcf?
-#if BUILD_LIBCF
-#LIBCF = libcf
-#endif
-
 # Define Test directories
 if BUILD_TESTSETS
 TESTDIRS = $(V2_TEST) nc_test $(NC_TEST4) $(NCDAP2TESTDIR) $(NCDAP4TESTDIR)
@@ -88,15 +74,13 @@ endif
 # This is the list of subdirs for which Makefiles will be constructed
 # and run. ncgen must come before ncdump, because their tests
 # depend on it.
-SUBDIRS = include $(H5_TEST_DIR) libdispatch libsrc		\
-$(LIBSRC4_DIR) $(LIBSRCP) $(OCLIB) $(DAP2) ${DAP4} liblib  \
-$(NCGEN3) $(NCGEN) $(NCDUMP) \
-$(TESTDIRS) \
-docs $(EXAMPLES) \
-$(UDUNITS) $(LIBCF)
+SUBDIRS = include $(H5_TEST_DIR) libdispatch libsrc $(LIBSRC4_DIR)	\
+$(LIBSRCP) $(OCLIB) $(DAP2) ${DAP4} liblib $(NCGEN3) $(NCGEN)		\
+$(NCDUMP) $(TESTDIRS) docs $(EXAMPLES)
 
 # Remove these generated files, for a distclean.
-DISTCLEANFILES = VERSION comps.txt test_prog libnetcdf.settings test_common.sh
+DISTCLEANFILES = VERSION comps.txt test_prog libnetcdf.settings	\
+test_common.sh
 
 # The nc-config script helps the user build programs with netCDF.
 bin_SCRIPTS = nc-config
@@ -105,34 +89,28 @@ bin_SCRIPTS = nc-config
 BINFILES = README_BINARIES.txt
 BINFILES += include/netcdf.h share/man/man3/netcdf.3 lib/libnetcdf.a
 BINFILES += libnetcdf.settings
-ZIPBINFILES = ${prefix}/include/netcdf.h ${prefix}/share/man/man3/netcdf.3 ${prefix}/lib/libnetcdf.a
+ZIPBINFILES = ${prefix}/include/netcdf.h			\
+${prefix}/share/man/man3/netcdf.3 ${prefix}/lib/libnetcdf.a
 
 if BUILD_UTILITIES
 BINFILES += bin/ncgen3$(EXEEXT) bin/ncgen$(EXEEXT) bin/ncdump$(EXEEXT)	\
 share/man/man1/ncgen.1 share/man/man1/ncdump.1
-ZIPBINFILES += ${prefix}/bin/ncgen3$(EXEEXT) ${prefix}/bin/ncgen$(EXEEXT) ${prefix}/bin/ncdump$(EXEEXT)	\
+ZIPBINFILES += ${prefix}/bin/ncgen3$(EXEEXT)				\
+${prefix}/bin/ncgen$(EXEEXT) ${prefix}/bin/ncdump$(EXEEXT)		\
 ${prefix}/share/man/man1/ncgen.1 ${prefix}/share/man/man1/ncdump.1
 endif
 
-if BUILD_DLL
-BINFILES += bin/libnetcdf-7.dll lib/libnetcdf.dll.a lib/libnetcdf.a	\
-lib/libnetcdf.la lib/netcdfdll.def
-ZIPBINFILES += ${prefix}/bin/libnetcdf-7.dll ${prefix}/lib/libnetcdf.dll.a ${prefix}/lib/libnetcdf.a	\
-${prefix}/lib/libnetcdf.la ${prefix}/lib/netcdfdll.def
-endif # BUILD_DLL
-
 # install libnetcdf.settings in lib directory.
-settingsdir=$(libdir)
-settings_DATA=libnetcdf.settings
+settingsdir = $(libdir)
+settings_DATA = libnetcdf.settings
 
 ####
 # Provide an entry to rebuild all the m4 generated files
 # List of files to create: WARNING leave off the extension
 ####
 
-MM4= ./nc_test/test_put ./nc_test/test_get \
-     ./nc_test/test_write ./nc_test/test_read \
-     ./libsrc/netcdf ./libsrc/putget ./libsrc/ncx \
+MM4= ./nc_test/test_put ./nc_test/test_get ./nc_test/test_write		\
+     ./nc_test/test_read ./libsrc/netcdf ./libsrc/putget ./libsrc/ncx	\
      ./libsrc/t_ncxx ./libsrc/attr
 
 mm4::
@@ -147,7 +125,6 @@ mm4::
 # install-netcdf-fortran.
 #####
 
-
 ###
 # build-netcdf-fortran
 ###
@@ -168,43 +145,12 @@ install-netcdf-fortran:
 
 endif
 
-# At Unidata, package up binaries.
-ftpbin: install
-	echo "Getting binaries from ${prefix}"
-	ls -l ${prefix}
-	echo "These are the binaries for netCDF @PACKAGE_VERSION at ." > ${prefix}/README_BINARIES.txt
-	echo "For this build: CC=$(CC) CXX=$(CXX)" >> ${prefix}/README_BINARIES.txt
-	echo "CFLAGS=$(CFLAGS) CXXFLAGS=$(CXXFLAGS)" >> ${prefix}/README_BINARIES.txt
-	echo "FCFLAGS=$(FCFLAGS) F77FLAGS=$(F77FLAGS) $F90FLAGS=$(F90FLAGS)" >> ${prefix}/README_BINARIES.txt
-	which tar
-	echo "PATH: $(PATH)"
-	tar cf @BINFILE_NAME@ -C ${prefix} ${BINFILES}
-	gzip -f @BINFILE_NAME@
-	zip -j netcdf_${VERSION}.zip ${ZIPBINFILES}
-
 check_nc_config:
 	$(CC) `./nc-config --cflags` test_prog.c -o test_prog `./nc-config --libs`
 	./test_prog
 
-# Build nc_test/test_common.sh
-# Complicated by need to create during distcheck
-# which uses a read-only source tree
-#all-local:
-#	rm -f ${top_builddir}/nc_test/test_common.sh
-#	cat /dev/null > ${top_builddir}/nc_test/test_common.sh
-#	chmod a+x ${top_builddir}/nc_test/test_common.sh
-#	sed -e "s|@TOPSRCDIR@|${abs_top_srcdir}|" -e "s|@TOPBUILDDIR@|${abs_top_builddir}|" <${top_srcdir}/test_common.in >>${top_builddir}/test_common.sh
-
 install-data-hook:
 
-# if BUILD_FORTRAN
-#	chmod u+x $(abs_top_builddir)/postinstall.sh
-#	sh -c "$(abs_top_builddir)/postinstall.sh -t autotools"
-#endif
-
-if BUILD_DLL
-	cp liblib/netcdfdll.def $(DESTDIR)${prefix}/bin
-endif # BUILD_DLL
 	@echo ''
 	@echo '+-------------------------------------------------------------+'
 	@echo '| Congratulations! You have successfully installed netCDF!    |'
diff --git a/Makefile.in b/Makefile.in
index 4b5a6ad..8681604 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -19,6 +19,7 @@
 # This is the main automake file for netCDF. It builds the different
 # netcdf directories. Not all directories are built, depending on the
 # options selected during configure.
+# Ed Hartnett, Ward Fisher
 
 
 VPATH = @srcdir@
@@ -99,15 +100,10 @@ target_triplet = @target@
 @BUILD_UTILITIES_TRUE at am__append_1 = bin/ncgen3$(EXEEXT) bin/ncgen$(EXEEXT) bin/ncdump$(EXEEXT)	\
 @BUILD_UTILITIES_TRUE at share/man/man1/ncgen.1 share/man/man1/ncdump.1
 
- at BUILD_UTILITIES_TRUE@am__append_2 = ${prefix}/bin/ncgen3$(EXEEXT) ${prefix}/bin/ncgen$(EXEEXT) ${prefix}/bin/ncdump$(EXEEXT)	\
+ at BUILD_UTILITIES_TRUE@am__append_2 = ${prefix}/bin/ncgen3$(EXEEXT)				\
+ at BUILD_UTILITIES_TRUE@${prefix}/bin/ncgen$(EXEEXT) ${prefix}/bin/ncdump$(EXEEXT)		\
 @BUILD_UTILITIES_TRUE@${prefix}/share/man/man1/ncgen.1 ${prefix}/share/man/man1/ncdump.1
 
- at BUILD_DLL_TRUE@am__append_3 = bin/libnetcdf-7.dll lib/libnetcdf.dll.a lib/libnetcdf.a	\
- at BUILD_DLL_TRUE@lib/libnetcdf.la lib/netcdfdll.def
-
- at BUILD_DLL_TRUE@am__append_4 = ${prefix}/bin/libnetcdf-7.dll ${prefix}/lib/libnetcdf.dll.a ${prefix}/lib/libnetcdf.a	\
- at BUILD_DLL_TRUE@${prefix}/lib/libnetcdf.la ${prefix}/lib/netcdfdll.def
-
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -270,7 +266,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -293,12 +288,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -324,6 +321,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -338,6 +336,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -446,18 +445,13 @@ top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
 
 # These files get added to the distribution.
-EXTRA_DIST = README.md COPYRIGHT INSTALL.md test_prog.c \
-	lib_flags.am cmake CMakeLists.txt COMPILE.cmake.txt \
-	config.h.cmake.in cmake_uninstall.cmake.in \
-	FixBundle.cmake.in \
-	nc-config.cmake.in RELEASE_NOTES.md CTestCustom.cmake \
-	CTestConfig.cmake.in libnetcdf.settings.in netCDFConfig.cmake.in \
-	CMakeInstallation.cmake test-driver-verbose test_common.in
-
-
-# Doxygen doesn't build nicely in vpath builds.
-# Don't do this; it wipes out any exported values
-#DISTCHECK_CONFIGURE_FLAGS = --disable-doxygen
+EXTRA_DIST = README.md COPYRIGHT INSTALL.md test_prog.c lib_flags.am	\
+cmake CMakeLists.txt COMPILE.cmake.txt config.h.cmake.in		\
+cmake_uninstall.cmake.in FixBundle.cmake.in nc-config.cmake.in		\
+RELEASE_NOTES.md CTestCustom.cmake CTestConfig.cmake.in			\
+libnetcdf.settings.in netCDFConfig.cmake.in CMakeInstallation.cmake	\
+test-driver-verbose test_common.in
+
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = netcdf.pc
 
@@ -492,32 +486,21 @@ pkgconfig_DATA = netcdf.pc
 # Build pnetcdf
 @USE_PNETCDF_TRUE at LIBSRCP = libsrcp
 
-# Build UDUNITS?
-#if BUILD_UDUNITS
-#UDUNITS = udunits
-#endif
-
-# Build libcf?
-#if BUILD_LIBCF
-#LIBCF = libcf
-#endif
-
 # Define Test directories
 @BUILD_TESTSETS_TRUE at TESTDIRS = $(V2_TEST) nc_test $(NC_TEST4) $(NCDAP2TESTDIR) $(NCDAP4TESTDIR)
 
 # This is the list of subdirs for which Makefiles will be constructed
 # and run. ncgen must come before ncdump, because their tests
 # depend on it.
-SUBDIRS = include $(H5_TEST_DIR) libdispatch libsrc		\
-$(LIBSRC4_DIR) $(LIBSRCP) $(OCLIB) $(DAP2) ${DAP4} liblib  \
-$(NCGEN3) $(NCGEN) $(NCDUMP) \
-$(TESTDIRS) \
-docs $(EXAMPLES) \
-$(UDUNITS) $(LIBCF)
+SUBDIRS = include $(H5_TEST_DIR) libdispatch libsrc $(LIBSRC4_DIR)	\
+$(LIBSRCP) $(OCLIB) $(DAP2) ${DAP4} liblib $(NCGEN3) $(NCGEN)		\
+$(NCDUMP) $(TESTDIRS) docs $(EXAMPLES)
 
 
 # Remove these generated files, for a distclean.
-DISTCLEANFILES = VERSION comps.txt test_prog libnetcdf.settings test_common.sh
+DISTCLEANFILES = VERSION comps.txt test_prog libnetcdf.settings	\
+test_common.sh
+
 
 # The nc-config script helps the user build programs with netCDF.
 bin_SCRIPTS = nc-config
@@ -525,10 +508,10 @@ bin_SCRIPTS = nc-config
 # What needs to go in the binrary dist?
 BINFILES = README_BINARIES.txt include/netcdf.h \
 	share/man/man3/netcdf.3 lib/libnetcdf.a libnetcdf.settings \
-	$(am__append_1) $(am__append_3)
+	$(am__append_1)
 ZIPBINFILES = ${prefix}/include/netcdf.h \
 	${prefix}/share/man/man3/netcdf.3 ${prefix}/lib/libnetcdf.a \
-	$(am__append_2) $(am__append_4)
+	$(am__append_2)
 
 # install libnetcdf.settings in lib directory.
 settingsdir = $(libdir)
@@ -538,9 +521,8 @@ settings_DATA = libnetcdf.settings
 # Provide an entry to rebuild all the m4 generated files
 # List of files to create: WARNING leave off the extension
 ####
-MM4 = ./nc_test/test_put ./nc_test/test_get \
-     ./nc_test/test_write ./nc_test/test_read \
-     ./libsrc/netcdf ./libsrc/putget ./libsrc/ncx \
+MM4 = ./nc_test/test_put ./nc_test/test_get ./nc_test/test_write		\
+     ./nc_test/test_read ./libsrc/netcdf ./libsrc/putget ./libsrc/ncx	\
      ./libsrc/t_ncxx ./libsrc/attr
 
 all: config.h
@@ -1149,41 +1131,12 @@ mm4::
 @BUILD_FORTRAN_TRUE@	chmod u+x $(abs_top_builddir)/postinstall.sh
 @BUILD_FORTRAN_TRUE@	sh -c "$(abs_top_builddir)/postinstall.sh -t autotools -a install"
 
-# At Unidata, package up binaries.
-ftpbin: install
-	echo "Getting binaries from ${prefix}"
-	ls -l ${prefix}
-	echo "These are the binaries for netCDF @PACKAGE_VERSION at ." > ${prefix}/README_BINARIES.txt
-	echo "For this build: CC=$(CC) CXX=$(CXX)" >> ${prefix}/README_BINARIES.txt
-	echo "CFLAGS=$(CFLAGS) CXXFLAGS=$(CXXFLAGS)" >> ${prefix}/README_BINARIES.txt
-	echo "FCFLAGS=$(FCFLAGS) F77FLAGS=$(F77FLAGS) $F90FLAGS=$(F90FLAGS)" >> ${prefix}/README_BINARIES.txt
-	which tar
-	echo "PATH: $(PATH)"
-	tar cf @BINFILE_NAME@ -C ${prefix} ${BINFILES}
-	gzip -f @BINFILE_NAME@
-	zip -j netcdf_${VERSION}.zip ${ZIPBINFILES}
-
 check_nc_config:
 	$(CC) `./nc-config --cflags` test_prog.c -o test_prog `./nc-config --libs`
 	./test_prog
 
-# Build nc_test/test_common.sh
-# Complicated by need to create during distcheck
-# which uses a read-only source tree
-#all-local:
-#	rm -f ${top_builddir}/nc_test/test_common.sh
-#	cat /dev/null > ${top_builddir}/nc_test/test_common.sh
-#	chmod a+x ${top_builddir}/nc_test/test_common.sh
-#	sed -e "s|@TOPSRCDIR@|${abs_top_srcdir}|" -e "s|@TOPBUILDDIR@|${abs_top_builddir}|" <${top_srcdir}/test_common.in >>${top_builddir}/test_common.sh
-
 install-data-hook:
 
-# if BUILD_FORTRAN
-#	chmod u+x $(abs_top_builddir)/postinstall.sh
-#	sh -c "$(abs_top_builddir)/postinstall.sh -t autotools"
-#endif
-
- at BUILD_DLL_TRUE@	cp liblib/netcdfdll.def $(DESTDIR)${prefix}/bin
 	@echo ''
 	@echo '+-------------------------------------------------------------+'
 	@echo '| Congratulations! You have successfully installed netCDF!    |'
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 1a9caad..be5741e 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -5,6 +5,16 @@ 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.6.1 - TBD
+
+## 4.6.0 - January 24, 2018
+* [Enhancement] Full support for using HDF5 dynamic filters, both for reading and writing. See the file docs/filters.md.
+* [Enhancement] Added an option to enable strict null-byte padding for headers; this padding was specified in the spec but was not enforced.  Enabling this option will allow you to check your files, as it will return an E_NULLPAD error.  It is possible for these files to have been written by older versions of libnetcdf.  There is no effective problem caused by this lack of null padding, so enabling these options is informational only.  The options for `configure` and `cmake` are `--enabl [...]
+* [Enhancement] Reverted behavior/handling of out-of-range attribute values to pre-4.5.0 default. See [Github #512](https://github.com/Unidata/netcdf-c/issues/512) for more information.
+* [Bug] Fixed error in tst_parallel2.c. See [Github #545](https://github.com/Unidata/netcdf-c/issues/545) for more information.
+* [Bug] Fixed handling of corrupt files + proper offset handling for hdf5 files. See [Github #552](https://github.com/Unidata/netcdf-c/issues/552) for more information.
+* [Bug] Corrected a memory overflow in `tst_h_dimscales`, see [Github #511](https://github.com/Unidata/netcdf-c/issues/511), [Github #505](https://github.com/Unidata/netcdf-c/issues/505), [Github #363](https://github.com/Unidata/netcdf-c/issues/363) and [Github #244](https://github.com/Unidata/netcdf-c/issues/244) for more information.
+
 ## 4.5.0 - October 20, 2017
 
 * Corrected an issue which could potential result in a hang while using parallel file I/O. See [Github #449](https://github.com/Unidata/netcdf-c/pull/449) for more information.
diff --git a/cf b/cf
index 40ab555..5e74acd 100644
--- a/cf
+++ b/cf
@@ -1,11 +1,12 @@
 #!/bin/bash
 #NB=1
-DB=1
+#DB=1
 #X=-x
 FAST=1
 
 HDF5=1
 DAP=1
+#SZIP=1
 #HDF4=1
 #PNETCDF=1
 #PAR4=1
@@ -18,14 +19,10 @@ if test "x$PNETCDF" = x1 -o "x$PAR4" = x1 ; then
 MPIO=1
 fi
 
-#RPC=1
-
-#M32=1
-#M64=1
-
 CFLAGS=""
 #CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wconversion ${CFLAGS}"
-CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wno-char-subscripts -Wno-pointer-sign -Wno-format ${CFLAGS}"
+#CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wno-char-subscripts -Wno-pointer-sign -Wno-format ${CFLAGS}"
+CFLAGS="-Wall -Wno-unused-parameter -Wno-char-subscripts -Wno-pointer-sign ${CFLAGS}"
 #CFLAGS="-Wall ${CFLAGS}"
 #CFLAGS="-Wconversion"
 
@@ -47,6 +44,11 @@ if test "x$HDF4" = x1 ; then
 HDF5=1
 fi
 
+# !HDF5=>!SZIP
+if test "x$HDF5" != x1 ; then
+SZIP=0
+fi
+
 CC=gcc
 
 MALLOC_CHECK=""
@@ -69,6 +71,10 @@ if test "x$HDF4" = "x1" ; then
 LDFLAGS="$LDFLAGS -ljpeg"
 fi
 
+if test "x$SZIP" = "x1" ; then
+LDFLAGS="$LDFLAGS -lsz -laec"
+fi
+
 export PKG_CONFIG_PATH=/usr/lib/pkgconfig
 if test "x$DAP" = "x1" ; then
 if curl-config --version >/dev/null ; then
@@ -88,19 +94,18 @@ CXXFLAGS="$CPPFLAGS $CXXFLAGS"
 FLAGS="--prefix ${PREFIX}"
 #FLAGS="$FLAGS --disable-f77 --disable-f90"
 #FLAGS="$FLAGS --disable-cxx"
-FLAGS="$FLAGS --disable-examples"
+#FLAGS="$FLAGS --disable-examples"
 #FLAGS="$FLAGS --disable-utilities"
 #FLAGS="$FLAGS --enable-cxx-4"
 #FLAGS="$FLAGS --enable-dap-long-tests"
 #FLAGS="$FLAGS --enable-ffio"
 #FLAGS="$FLAGS --enable-benchmarks"
 FLAGS="$FLAGS --enable-extreme-numbers"
-FLAGS="$FLAGS --enable-extra-tests"
 #FLAGS="$FLAGS --enable-large-file-tests"
 #FLAGS="$FLAGS --disable-testsets"
 #FLAGS="$FLAGS --disable-dap-remote-tests"
 #FLAGS="$FLAGS --enable-dap-auth-tests" -- requires a new remotetest server
-#FLAGS="$FLAGS --enable-doxygen"
+#FLAGS="$FLAGS --enable-doxygen --enable-internal-docs"
 FLAGS="$FLAGS --enable-logging"
 #FLAGS="$FLAGS --disable-diskless"
 #FLAGS="$FLAGS --enable-mmap"
@@ -112,6 +117,7 @@ FLAGS="$FLAGS --enable-logging"
 #FLAGS="$FLAGS --disable-properties-attribute"
 #FLAGS="$FLAGS --disable-silent-rules"
 #FLAGS="$FLAGS --with-testservers=remotestserver.localhost:8083"
+#FLAGS="$FLAGS --disable-filter-testing"
 
 if test "x$PAR4" != x1 ; then
 FLAGS="$FLAGS --disable-parallel4"
@@ -152,19 +158,11 @@ FLAGS="$FLAGS --disable-dap"
 fi
 
 if test "x$MPIO" = x1 ; then
-  if test -f /machine/local_mpich2 ; then
-    MPI1=/machine/local_mpich2
-    MPI2=/machine/local_par7
-    MPI3=/machine/local_par
-  else
-    MPI1=/usr/local
-    MPI2=${MPI1}
-    MPI3=${MPI1}
-  fi
-  PATH=${PATH}:${MPI1}/bin
-  CC="${MPI1}/bin/mpicc"
-  CPPFLAGS="-I${MPI2}/include -I${MPI1}/include -I${MPI3}/include"
-  LDFLAGS="-L${MPI2}/lib -L${MPI1}/lib -L${MPI3}/lib"
+  MPIDIR=/usr/lib64/mpich
+  PATH="${PATH}:${MPIDIR}/bin"
+  CC="${MPIDIR}/bin/mpicc"
+  CPPFLAGS="-I${MPIDIR}/include"
+  LDFLAGS="$LDFLAGS -L${MPIDIR}"
   LDLIBS="-lmpich"
   FLAGS="$FLAGS --enable-pnetcdf"
   FLAGS="$FLAGS --enable-parallel-tests"
@@ -194,6 +192,7 @@ fi
 if test -z "$FAST" ; then
   if test -f Makefile ; then ${MAKE} distclean >/dev/null 2>&1 ; fi
 fi
+
 sh $X ./configure ${FLAGS}
 for c in $cmds; do
 printenv LD_LIBRARY_PATH
diff --git a/cf.cmake b/cf.cmake
index f0625b5..af71c3e 100644
--- a/cf.cmake
+++ b/cf.cmake
@@ -1,6 +1,24 @@
 # Visual Studio
-VS=1
-#VSSETUP=1
+
+# Is netcdf-4 and/or DAP enabled?
+NC4=1
+#DAP=1
+#CDF5=1
+#HDF4=1
+
+case "$1" in
+vs|VS) VS=1 ;;
+linux|nix|l|x) unset VS ;;
+*) echo "Must specify env: vs|linux"; exit 1; ;;
+esac
+
+if test "x$VS" = x1 ; then
+  if test "x$2" = xsetup ; then
+    VSSETUP=1
+  else
+    unset VSSETUP
+  fi
+fi
 
 #export NCPATHDEBUG=1
 
@@ -10,29 +28,22 @@ else
 CFG="Release"
 fi
 
-# Is netcdf-4 and/or DAP enabled?
-NC4=1
-DAP=1
-
-if test "x$VS" != x ; then
+if test "x$VS" != x -a "x$INSTALL" != x ; then
 FLAGS="-DCMAKE_PREFIX_PATH=c:/tools/nccmake"
 fi
-FLAGS="$FLAGS -DCMAKE_INSTALL_PREFIX=d:/ignore"
+FLAGS="$FLAGS -DCMAKE_INSTALL_PREFIX=/tmp/netcdf"
 
-if test "x$DAP" = x ; then
-FLAGS="$FLAGS -DENABLE_DAP=false"
-else
-FLAGS="$FLAGS -DENABLE_DAP=true"
-fi
-if test "x$NC4" = x ; then
-FLAGS="$FLAGS -DENABLE_NETCDF_4=false"
-fi
+if test "x$DAP" = x ; then FLAGS="$FLAGS -DENABLE_DAP=false"; fi
+if test "x$NC4" = x ; then FLAGS="$FLAGS -DENABLE_NETCDF_4=false"; fi
+if test "x$CDF5" != x ; then FLAGS="$FLAGS -DENABLE_CDF5=true"; fi
+if test "x$HDF4" != x ; then FLAGS="$FLAGS -DENABLE_HDF4=true"; fi
 FLAGS="$FLAGS -DENABLE_CONVERSION_WARNINGS=false"
 FLAGS="$FLAGS -DENABLE_DAP_REMOTE_TESTS=true"
 FLAGS="$FLAGS -DENABLE_TESTS=true"
 FLAGS="$FLAGS -DENABLE_EXAMPLES=false"
-#FLAGS="$FLAGS -DENABLE_HDF4=true"
 FLAGS="$FLAGS -DENABLE_DYNAMIC_LOADING=false"
+FLAGS="$FLAGS -DENABLE_WINSOCK2=false"
+#FLAGS="$FLAGS -DENABLE_LARGE_FILE_TESTS=true"
 
 rm -fr build
 mkdir build
@@ -42,17 +53,18 @@ NCLIB=`pwd`
 
 if test "x$VS" != x ; then
 # Visual Studio
-NCLIB="${NCLIB}/build/liblib/$CFG"
+CFG="Release"
+NCLIB="${NCLIB}/liblib"
 export PATH="${NCLIB}:${PATH}"
-cmake $FLAGS ..
-if test "x$VSSETUP" = x ; then
+#G=
+cmake "$G" -DCMAKE_BUILD_TYPE=${CFG} $FLAGS ..
 cmake --build . --config ${CFG}
 cmake --build . --config ${CFG} --target RUN_TESTS
-fi
 else
 # GCC
 NCLIB="${NCLIB}/build/liblib"
-G="-GUnix Makefiles"
+#G="-GUnix Makefiles"
+#T="--trace-expand"
 cmake "${G}" $FLAGS ..
 make all
 make test
diff --git a/config.h.cmake.in b/config.h.cmake.in
index 1fffe0a..80c07b7 100644
--- a/config.h.cmake.in
+++ b/config.h.cmake.in
@@ -111,6 +111,9 @@ are set when opening a binary file on Windows. */
 #cmakedefine ENABLE_CDF5 1
 #cmakedefine USE_CDF5 1
 
+/* if true, enable strict null byte header padding. */
+#cmakedefine USE_STRICT_NULL_BYTE_HEADER_PADDING 1
+
 /* if true, build DAP2 and DAP4 Client */
 #cmakedefine ENABLE_DAP 1
 
@@ -295,6 +298,9 @@ are set when opening a binary file on Windows. */
 /* Define to 1 if you have the `mkstemp' function. */
 #cmakedefine HAVE_MKSTEMP 1
 
+/* Define to 1 if you have the `mktemp' function. */
+#cmakedefine HAVE_MKTEMP 1
+
 /* Define to 1 if you have a working `mmap' system call. */
 #cmakedefine HAVE_MMAP 1
 
@@ -404,6 +410,9 @@ are set when opening a binary file on Windows. */
 /* Define to 1 if you have the `sysconf' function. */
 #cmakedefine HAVE_SYSCONF 1
 
+/* Define to 1 if you have the <sys/cdefs.h> header file. */
+#cmakedefine HAVE_SYS_CDEFS_H 1
+
 /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
    */
 #cmakedefine HAVE_SYS_DIR_H 1
diff --git a/config.h.in b/config.h.in
index b5694f4..652efd3 100644
--- a/config.h.in
+++ b/config.h.in
@@ -29,12 +29,6 @@
 /* default chunk size in bytes */
 #undef DEFAULT_CHUNK_SIZE
 
-/* set this only when building a DLL under MinGW */
-#undef DLL_EXPORT
-
-/* set this only when building a DLL under MinGW */
-#undef DLL_NETCDF
-
 /* if true, enable CDF5 Support */
 #undef ENABLE_CDF5
 
@@ -53,9 +47,6 @@
 /* if true, use _FillValue for NC_ERANGE data elements */
 #undef ERANGE_FILL
 
-/* if true, run extra tests which may not work yet */
-#undef EXTRA_TESTS
-
 /* use HDF5 1.6 API */
 #undef H5_USE_16_API
 
@@ -209,6 +200,9 @@
 /* Define to 1 if you have the `mkstemp' function. */
 #undef HAVE_MKSTEMP
 
+/* Define to 1 if you have the `mktemp' function. */
+#undef HAVE_MKTEMP
+
 /* Define to 1 if you have a working `mmap' system call. */
 #undef HAVE_MMAP
 
@@ -230,6 +224,9 @@
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
+/* Define to 1 if the system has the type `schar'. */
+#undef HAVE_SCHAR
+
 /* Define to 1 if the system has the type `size_t'. */
 #undef HAVE_SIZE_T
 
@@ -306,6 +303,9 @@
 /* Define to 1 if you have the `sysconf' function. */
 #undef HAVE_SYSCONF
 
+/* Define to 1 if you have the <sys/cdefs.h> header file. */
+#undef HAVE_SYS_CDEFS_H
+
 /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
    */
 #undef HAVE_SYS_DIR_H
@@ -552,6 +552,9 @@
 /* if true, use stdio instead of posixio */
 #undef USE_STDIO
 
+/* if true, enable strict null byte header padding */
+#undef USE_STRICT_NULL_BYTE_HEADER_PADDING
+
 /* if true, compile in szip compression in netCDF-4 variables */
 #undef USE_SZIP
 
diff --git a/configure b/configure
index 482ab78..8214c57 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.5.0.
+# Generated by GNU Autoconf 2.69 for netCDF 4.6.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.5.0'
-PACKAGE_STRING='netCDF 4.5.0'
+PACKAGE_VERSION='4.6.0'
+PACKAGE_STRING='netCDF 4.6.0'
 PACKAGE_BUGREPORT='support-netcdf at unidata.ucar.edu'
 PACKAGE_URL=''
 
@@ -638,6 +638,8 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+MSVC
+ISCMAKE
 NC_HAS_CDF5
 NC_HAS_PARALLEL4
 NC_HAS_PARALLEL
@@ -659,6 +661,7 @@ AM_CPPFLAGS
 AM_CFLAGS
 enable_static
 enable_shared
+ENABLE_ERANGE_FILL
 RELAX_COORD_BOUND
 HAS_JNA
 HAS_MMAP
@@ -677,6 +680,8 @@ HAS_DAP4
 HAS_DAP2
 HAS_DAP
 NC_LIBS
+ENABLE_FILTER_TESTING_FALSE
+ENABLE_FILTER_TESTING_TRUE
 BINFILE_NAME
 BUILD_MMAP_FALSE
 BUILD_MMAP_TRUE
@@ -747,6 +752,8 @@ MANIFEST_TOOL
 RANLIB
 ac_ct_AR
 AR
+DLLTOOL
+OBJDUMP
 LN_S
 NM
 ac_ct_DUMPBIN
@@ -757,9 +764,6 @@ EGREP
 GREP
 SED
 LIBTOOL
-OBJDUMP
-DLLTOOL
-AS
 CC_VERSION
 BUILD_BENCHMARKS_FALSE
 BUILD_BENCHMARKS_TRUE
@@ -777,12 +781,12 @@ USE_STDIO_FALSE
 USE_STDIO_TRUE
 USE_FFIO_FALSE
 USE_FFIO_TRUE
-EXTRA_TESTS_FALSE
-EXTRA_TESTS_TRUE
 ENABLE_CDF5_FALSE
 ENABLE_CDF5_TRUE
 USE_CDF5_FALSE
 USE_CDF5_TRUE
+USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE
+USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE
 INTERNAL_OCLIB_FALSE
 INTERNAL_OCLIB_TRUE
 am__fastdepCC_FALSE
@@ -806,6 +810,7 @@ BUILD_INTERNAL_DOCS
 NC_ENABLE_DOXYGEN_PDF_OUTPUT
 NC_ENABLE_DOXYGEN_PDF_OUTPUT_FALSE
 NC_ENABLE_DOXYGEN_PDF_OUTPUT_TRUE
+DOXYGEN_SERVER_BASED_SEARCH
 DOXYGEN_SEARCHENGINE
 DOXYGEN_HEADER_FILE
 DOXYGEN_CSS_FILE
@@ -816,8 +821,6 @@ SHOW_DOXYGEN_TAG_LIST_FALSE
 SHOW_DOXYGEN_TAG_LIST_TRUE
 BUILD_DOCS_FALSE
 BUILD_DOCS_TRUE
-BUILD_DLL_FALSE
-BUILD_DLL_TRUE
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
@@ -908,7 +911,6 @@ ac_user_opts='
 enable_option_checking
 enable_silent_rules
 enable_maintainer_mode
-enable_dll
 with_minblocksize
 enable_doxygen
 enable_doxygen_tasks
@@ -941,8 +943,8 @@ enable_dap_auth_tests
 enable_dap_groups
 with_testservers
 enable_dap_long_tests
+enable_strict_null_byte_header_padding
 enable_cdf5
-enable_extra_tests
 enable_ffio
 enable_stdio
 enable_examples
@@ -968,6 +970,7 @@ enable_parallel4
 enable_pnetcdf
 enable_erange_fill
 enable_zero_length_coord_bound
+enable_filter_testing
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1519,7 +1522,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.5.0 to adapt to many kinds of systems.
+\`configure' configures netCDF 4.6.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1590,7 +1593,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of netCDF 4.5.0:";;
+     short | recursive ) echo "Configuration of netCDF 4.6.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1603,7 +1606,6 @@ Optional Features:
   --enable-maintainer-mode
                           enable make rules and dependencies not useful (and
                           sometimes confusing) to the casual installer
-  --enable-dll            build a win32 DLL (only works on mingw)
   --enable-doxygen        Enable generation of documentation.
   --enable-doxygen-tasks  Enable Doxygen-generated test, todo and bug list
                           documentation. Developers only.
@@ -1655,9 +1657,10 @@ Optional Features:
   --enable-dap-auth-tests enable dap remote authorization tests
   --disable-dap-groups    disable [netcdf4] DAP2 group names
   --enable-dap-long-tests enable dap long tests
+  --enable-strict-null-byte-header-padding
+                          enable strict null-byte header padding when reading
+                          netCDF3 files.
   --enable-cdf5           build with CDF5 support.
-  --enable-extra-tests    enable some extra tests that may not pass because of
-                          known issues
   --enable-ffio           use ffio instead of posixio (ex. on the Cray)
   --enable-stdio          use stdio instead of posixio (ex. on the Cray)
   --disable-examples      don't build the netCDF examples during make check
@@ -1699,6 +1702,9 @@ Optional Features:
                           equal to dimension size when argument count is zero.
                           [default: disabled]
   --enable-jna            enable jna bug fix
+  --disable-filter-testing
+                          Do not run filter test and example; requires shared
+                          libraries and netCDF-4
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1818,7 +1824,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-netCDF configure 4.5.0
+netCDF configure 4.6.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2527,7 +2533,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.5.0, which was
+It was created by netCDF $as_me 4.6.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2887,7 +2893,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 : ${CFLAGS=""}
 
  NC_VERSION_MAJOR=4
- NC_VERSION_MINOR=5
+ NC_VERSION_MINOR=6
  NC_VERSION_PATCH=0
  NC_VERSION_NOTE=""
 
@@ -2898,11 +2904,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 # Create the VERSION file, which contains the package version from
 # AC_INIT.
-echo 4.5.0>VERSION
+echo 4.6.0>VERSION
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: netCDF 4.5.0" >&5
-$as_echo "$as_me: netCDF 4.5.0" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: netCDF 4.6.0" >&5
+$as_echo "$as_me: netCDF 4.6.0" >&6;}
 
 # Keep libtool macros in an m4 directory.
 
@@ -3080,7 +3086,6 @@ ac_config_links="$ac_config_links nc_test4/ref_chunked.hdf4:nc_test4/ref_chunked
 ac_config_links="$ac_config_links nc_test4/ref_contiguous.hdf4:nc_test4/ref_contiguous.hdf4"
 
 
-# This call is required by automake.
 am__api_version='1.15'
 
 # Find a good install program.  We prefer a C program (faster),
@@ -3567,7 +3572,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='netcdf'
- VERSION='4.5.0'
+ VERSION='4.6.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3690,35 +3695,6 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking user options" >&5
 $as_echo "$as_me: checking user options" >&6;}
 
-# If --enable-dll is specified the DLL will be built. This only works
-# on mingw.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a win32 DLL is desired" >&5
-$as_echo_n "checking whether a win32 DLL is desired... " >&6; }
-# Check whether --enable-dll was given.
-if test "${enable_dll+set}" = set; then :
-  enableval=$enable_dll;
-fi
-
-test "x$enable_dll" = xyes || enable_dll=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dll" >&5
-$as_echo "$enable_dll" >&6; }
-if test "x$enable_dll" = xyes; then
-
-$as_echo "#define DLL_NETCDF 1" >>confdefs.h
-
-
-$as_echo "#define DLL_EXPORT 1" >>confdefs.h
-
-fi
- if test x$enable_dll = xyes; then
-  BUILD_DLL_TRUE=
-  BUILD_DLL_FALSE='#'
-else
-  BUILD_DLL_TRUE='#'
-  BUILD_DLL_FALSE=
-fi
-
-
 # Did the user specify a default minimum blocksize (NCIO_MINBLOCKSIZE) for posixio?
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a NCIO_MINBLOCKSIZE was specified" >&5
 $as_echo_n "checking whether a NCIO_MINBLOCKSIZE was specified... " >&6; }
@@ -3805,6 +3781,8 @@ else
    DOXYGEN_SEARCHENGINE="YES"
 
 fi
+DOXYGEN_SERVER_BASED_SEARCH="NO"
+
 
 # Check whether --enable-doxygen-pdf-output was given.
 if test "${enable_doxygen_pdf_output+set}" = set; then :
@@ -5224,13 +5202,8 @@ else
   found_curl=no
 fi
 
-#AC_CHECK_LIB([curl.dll],[curl_easy_setopt])
 # If curl is required but there is no curl, then complain
 if test $require_curl = yes ; then
-  # Removed. Why assume no curl if we are building DLL?
-  #if test $enable_dll = yes ; then
-  #  AC_MSG_NOTICE([libcurl not found; continuing])
-  #elif test $found_curl = no ; then
   if test $found_curl = no ; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: libcurl not found; disabling remote protocol(s) support" >&5
 $as_echo "$as_me: libcurl not found; disabling remote protocol(s) support" >&6;}
@@ -5417,6 +5390,34 @@ else
 fi
 
 
+# Check whether we want to enable strict null byte header padding.
+# See https://github.com/Unidata/netcdf-c/issues/657 for more information.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable strict null-byte header padding when reading (default off)" >&5
+$as_echo_n "checking whether to enable strict null-byte header padding when reading (default off)... " >&6; }
+# Check whether --enable-strict-null-byte-header-padding was given.
+if test "${enable_strict_null_byte_header_padding+set}" = set; then :
+  enableval=$enable_strict_null_byte_header_padding;
+fi
+
+test "x$enable_strict_null_byte_header_padding" = xyes || enable_strict_null_byte_header_padding=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_strict_null_byte_header_padding" >&5
+$as_echo "$enable_strict_null_byte_header_padding" >&6; }
+
+if test "x$enable_strict_null_byte_header_padding" = xyes; then
+
+$as_echo "#define USE_STRICT_NULL_BYTE_HEADER_PADDING 1" >>confdefs.h
+
+fi
+
+ if test x$enable_strict_null_byte_header_padding = xyes ; then
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE=
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE='#'
+else
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE='#'
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE=
+fi
+
+
 # Check whether we want to enable CDF5 support.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CDF5 support should be enabled (default off)" >&5
 $as_echo_n "checking whether CDF5 support should be enabled (default off)... " >&6; }
@@ -5455,31 +5456,6 @@ else
 fi
 
 
-# Does the user want to do some extra tests?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether netCDF extra tests should be run (developers only)" >&5
-$as_echo_n "checking whether netCDF extra tests should be run (developers only)... " >&6; }
-# Check whether --enable-extra-tests was given.
-if test "${enable_extra_tests+set}" = set; then :
-  enableval=$enable_extra_tests;
-fi
-
-test "x$enable_extra_tests" = xno || enable_extra_tests=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_extra_tests" >&5
-$as_echo "$enable_extra_tests" >&6; }
-if test "x$enable_extra_tests" = xyes; then
-
-$as_echo "#define EXTRA_TESTS 1" >>confdefs.h
-
-fi
- if test x$enable_extra_tests = xyes; then
-  EXTRA_TESTS_TRUE=
-  EXTRA_TESTS_FALSE='#'
-else
-  EXTRA_TESTS_TRUE='#'
-  EXTRA_TESTS_FALSE=
-fi
-
-
 # Does the user want to use the ffio module?
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether FFIO will be used" >&5
 $as_echo_n "checking whether FFIO will be used... " >&6; }
@@ -5530,9 +5506,6 @@ else
 fi
 
 
-# Does the user want to enable the user-provided NEC-SX vectorization
-# patch.
-
 nc_build_c=yes
 nc_build_v2=yes
 nc_build_utilities=yes
@@ -7829,6 +7802,9 @@ test -z "$OBJDUMP" && OBJDUMP=objdump
 
 
 
+
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
 $as_echo_n "checking how to recognize dependent libraries... " >&6; }
 if ${lt_cv_deplibs_check_method+:} false; then :
@@ -8171,6 +8147,9 @@ test -z "$DLLTOOL" && DLLTOOL=dlltool
 
 
 
+
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
 $as_echo_n "checking how to associate runtime and link libraries... " >&6; }
 if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
@@ -10412,312 +10391,14 @@ done
 
 
 # Set options
-enable_win32_dll=yes
-
-case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
-set dummy ${ac_tool_prefix}as; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$AS"; then
-  ac_cv_prog_AS="$AS" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_AS="${ac_tool_prefix}as"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-AS=$ac_cv_prog_AS
-if test -n "$AS"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
-$as_echo "$AS" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_AS"; then
-  ac_ct_AS=$AS
-  # Extract the first word of "as", so it can be a program name with args.
-set dummy as; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_AS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_AS"; then
-  ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_AS="as"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AS=$ac_cv_prog_ac_ct_AS
-if test -n "$ac_ct_AS"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
-$as_echo "$ac_ct_AS" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_AS" = x; then
-    AS="false"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    AS=$ac_ct_AS
-  fi
-else
-  AS="$ac_cv_prog_AS"
-fi
-
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
-set dummy ${ac_tool_prefix}dlltool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_DLLTOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$DLLTOOL"; then
-  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-DLLTOOL=$ac_cv_prog_DLLTOOL
-if test -n "$DLLTOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
-$as_echo "$DLLTOOL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_DLLTOOL"; then
-  ac_ct_DLLTOOL=$DLLTOOL
-  # Extract the first word of "dlltool", so it can be a program name with args.
-set dummy dlltool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_DLLTOOL"; then
-  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
-if test -n "$ac_ct_DLLTOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
-$as_echo "$ac_ct_DLLTOOL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_DLLTOOL" = x; then
-    DLLTOOL="false"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    DLLTOOL=$ac_ct_DLLTOOL
-  fi
-else
-  DLLTOOL="$ac_cv_prog_DLLTOOL"
-fi
-
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
-set dummy ${ac_tool_prefix}objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OBJDUMP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$OBJDUMP"; then
-  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-OBJDUMP=$ac_cv_prog_OBJDUMP
-if test -n "$OBJDUMP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
-$as_echo "$OBJDUMP" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OBJDUMP"; then
-  ac_ct_OBJDUMP=$OBJDUMP
-  # Extract the first word of "objdump", so it can be a program name with args.
-set dummy objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_OBJDUMP"; then
-  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_OBJDUMP="objdump"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
-if test -n "$ac_ct_OBJDUMP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
-$as_echo "$ac_ct_OBJDUMP" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_OBJDUMP" = x; then
-    OBJDUMP="false"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    OBJDUMP=$ac_ct_OBJDUMP
-  fi
-else
-  OBJDUMP="$ac_cv_prog_OBJDUMP"
-fi
-
-  ;;
-esac
-
-test -z "$AS" && AS=as
-
-
-
-
-
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-
-
-
-
-
-test -z "$OBJDUMP" && OBJDUMP=objdump
-
-
-
-
 
 
 
         enable_dlopen=no
 
 
+  enable_win32_dll=no
+
 
             # Check whether --enable-shared was given.
 if test "${enable_shared+set}" = set; then :
@@ -15946,6 +15627,19 @@ done
 
 #fi
 
+for ac_header in sys/cdefs.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/cdefs.h" "ac_cv_header_sys_cdefs_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_cdefs_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_CDEFS_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # Check for <stdbool.h> that conforms to C99 requirements
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
@@ -16058,7 +15752,7 @@ done
 # Check for these functions...
 for ac_func in strlcat strerror snprintf strchr strrchr strcat strcpy \
                 strdup strcasecmp strtod strtoll strtoull strstr \
-		mkstemp rand random memcmp \
+		mkstemp mktemp rand random memcmp \
 		getrlimit gettimeofday fsync MPI_Comm_f2c
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -16700,6 +16394,15 @@ _ACEOF
 
 
 fi
+ac_fn_c_check_type "$LINENO" "schar" "ac_cv_type_schar" "$ac_includes_default"
+if test "x$ac_cv_type_schar" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SCHAR 1
+_ACEOF
+
+
+fi
 ac_fn_c_check_type "$LINENO" "uchar" "ac_cv_type_uchar" "$ac_includes_default"
 if test "x$ac_cv_type_uchar" = xyes; then :
 
@@ -18483,26 +18186,34 @@ fi
 #    a. do not want to use it for netcdf4
 #    b. do want to use it for netcdf4
 
-# Should we suppress parallel io for netcdf-4?
+# Should we provide 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;
+  enableval=$enable_parallel4; user_set_parallel4=${enableval}
 fi
 
-  test "x$enable_parallel4" = xno || enable_parallel4=yes
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_parallel4" >&5
+   test "x$enable_parallel4" = xno || enable_parallel4=yes
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_parallel4" >&5
 $as_echo "$enable_parallel4" >&6; }
-else
-  enable_parallel4=no
-fi
-if test "x$hdf5_parallel" = xno; then
-  # hdf5 does not support parallel io, so disable parallel4
-  enable_parallel4=no
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Parallel io disabled for netcdf-4 because hdf5 does not support" >&5
+
+   # If user wants parallel IO for netCDF-4, make sure HDF5 can provide it.
+   if test "x$enable_parallel4" = xyes; then
+      if test "x$hdf5_parallel" = xno; then
+      	 # If user specifically asked for parallel4, then error out.
+	 if test "x$user_set_parallel4" = xyes; then
+	    as_fn_error $? "Paralllel IO in netCDF-4 requested, but HDF5 does not provide parallel IO." "$LINENO" 5
+	 fi
+         # User didn't specify, so disable parallel4
+	 enable_parallel4=no
+	 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Parallel io disabled for netcdf-4 because hdf5 does not support" >&5
 $as_echo "$as_me: WARNING: Parallel io disabled for netcdf-4 because hdf5 does not support" >&2;}
+      fi
+   fi
+else
+   enable_parallel4=no
 fi
 
 # We have already tested for parallel io in netcdf4
@@ -18521,7 +18232,6 @@ $as_echo "$enable_pnetcdf" >&6; }
 
 # See if the pnetcdf lib is available and of the
 # right version (1.6.0 or later)
-
 if test "x$enable_pnetcdf" = xyes; then
   pnetcdf_conflict=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ncmpi_create in -lpnetcdf" >&5
@@ -18572,6 +18282,10 @@ else
 fi
 
 
+  if test "x$pnetcdf_conflict" = xyes ; then
+     as_fn_error $? "Cannot link to pnetcdf library." "$LINENO" 5
+  fi
+
   # Pnetcdf did not support utf-8 until 1.6.0
 
   # Save/restore CFLAGS
@@ -18615,18 +18329,10 @@ $as_echo_n "checking Is libpnetcdf version 1.6.0 or later?... " >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pnetcdf16" >&5
 $as_echo "$pnetcdf16" >&6; }
   if test x$pnetcdf16 = xno; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-pnetcdf requires version 1.6.0 or later; disabling" >&5
-$as_echo "$as_me: WARNING: --enable-pnetcdf requires version 1.6.0 or later; disabling" >&2;}
-    pnetcdf_conflict=yes
+    as_fn_error $? "--enable-pnetcdf requires version 1.6.0 or later" "$LINENO" 5
   fi
 fi
 
-if test "x$pnetcdf_conflict" = xyes ; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot link to pnetcdf library, --enable-pnetcdf disabled." >&5
-$as_echo "$as_me: WARNING: Cannot link to pnetcdf library, --enable-pnetcdf disabled." >&2;}
-  enable_pnetcdf=no
-fi
-
 # Now, set enable_parallel if either pnetcdf or parallel4 is set
 if test "x$enable_pnetcdf" = xyes -o "x$enable_parallel4" = xyes; then
 enable_parallel=yes
@@ -18731,14 +18437,14 @@ $as_echo_n "checking if erange-fill is enabled in PnetCDF... " >&6; }
       erange_fill_pnetcdf=no
    else
       erange_fill_pnetcdf=`echo ${erange_fill_pnetcdf} | cut -d' ' -f3`
-      if test "x$coord_bound_pnetcdf" = x0; then
+      if test "x$erange_fill_pnetcdf" = x0; then
           enable_erange_fill_pnetcdf=no
       else
           enable_erange_fill_pnetcdf=yes
       fi
    fi
-   { $as_echo "$as_me:${as_lineno-$LINENO}: $enable_erange_fill_pnetcdf" >&5
-$as_echo "$as_me: $enable_erange_fill_pnetcdf" >&6;}
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_erange_fill_pnetcdf" >&5
+$as_echo "$enable_erange_fill_pnetcdf" >&6; }
    if test "$enable_erange_fill" != "$enable_erange_fill_pnetcdf"; then
       if test "$enable_erange_fill_pnetcdf" = yes; then
          { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Enable erange-fill to conform with PnetCDF setting" >&5
@@ -18763,8 +18469,8 @@ $as_echo_n "checking if relax-coord-bound is enabled in PnetCDF... " >&6; }
           relax_coord_bound_pnetcdf=yes
       fi
    fi
-   { $as_echo "$as_me:${as_lineno-$LINENO}: $relax_coord_bound_pnetcdf" >&5
-$as_echo "$as_me: $relax_coord_bound_pnetcdf" >&6;}
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $relax_coord_bound_pnetcdf" >&5
+$as_echo "$relax_coord_bound_pnetcdf" >&6; }
    if test "$enable_zero_length_coord_bound" != "$relax_coord_bound_pnetcdf"; then
       if test "$relax_coord_bound_pnetcdf" = yes; then
          { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Enable relax-coord-bound to conform with PnetCDF setting" >&5
@@ -18812,33 +18518,6 @@ $as_echo "#define LOGGING 1" >>confdefs.h
 
 fi
 
-
-# Like other libraries, udunits and libcf
-# are no long part of the netcdf distribution.
-
-#AC_MSG_CHECKING([whether udunits is to be built])
-#AC_ARG_WITH([udunits],
-#              [AS_HELP_STRING([--with-udunits],
-#                              [Build udunits2 package.])])
-#test "x$with_udunits" = xyes || with_udunits=no
-#AC_MSG_RESULT($with_udunits)
-#AM_CONDITIONAL(BUILD_UDUNITS, [test "x$with_udunits" = xyes])
-
-
-# Does the user want to also build the libcf library?
-#AC_MSG_CHECKING([whether libcf is to be built])
-#AC_ARG_WITH([libcf],
-#              [AS_HELP_STRING([--with-libcf],
-#                              [build and install libcf library, a library for \
-#	      handling data in conformance with the Climate and \
-#	      Forecast conventions. (Requires netCDF-4 and HDF5)])])
-#test "x$with_libcf" = xyes || with_libcf=no
-#AC_MSG_RESULT($with_libcf)
-#AM_CONDITIONAL(BUILD_LIBCF, [test "x$with_libcf" = xyes])
-
-#AC_CONFIG_SUBDIRS([udunits libcf])
-
-
 # Automake conditionals need to be called, whether the answer is yes
 # or no.
  if test x$enable_parallel = xyes; then
@@ -18890,6 +18569,14 @@ else
   ENABLE_DAP4_FALSE=
 fi
 
+ if test x$enable_strict_null_byte_header_padding = xyes; then
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE=
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE='#'
+else
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE='#'
+  USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE=
+fi
+
  if test "x$enable_cdf5" = xyes; then
   ENABLE_CDF5_TRUE=
   ENABLE_CDF5_FALSE='#'
@@ -19327,6 +19014,38 @@ $as_echo "#define JNA 1" >>confdefs.h
 
 fi
 
+# Control filter test/example
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether filter testing should be run" >&5
+$as_echo_n "checking whether filter testing should be run... " >&6; }
+# Check whether --enable-filter-testing was given.
+if test "${enable_filter_testing+set}" = set; then :
+  enableval=$enable_filter_testing;
+fi
+
+test "x$enable_filter_testing" = xno || enable_filter_testing=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_filter_testing" >&5
+$as_echo "$enable_filter_testing" >&6; }
+
+if test "x$enable_netcdf_4" = xno ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: netCDF-4 disabled => --disable-filter-testing" >&5
+$as_echo "$as_me: WARNING: netCDF-4 disabled => --disable-filter-testing" >&2;}
+enable_filter_testing = no
+fi
+
+if test "x$enable_shared" = xno ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Shared libraries are disabled => --disable-filter-testing" >&5
+$as_echo "$as_me: WARNING: Shared libraries are disabled => --disable-filter-testing" >&2;}
+enable_filter_testing = no
+fi
+ if test x$enable_filter_testing = xyes; then
+  ENABLE_FILTER_TESTING_TRUE=
+  ENABLE_FILTER_TESTING_FALSE='#'
+else
+  ENABLE_FILTER_TESTING_TRUE='#'
+  ENABLE_FILTER_TESTING_FALSE=
+fi
+
+
 NC_LIBS=$NC_LIBS
 
 HAS_DAP=$enable_dap
@@ -19363,6 +19082,8 @@ HAS_JNA=$enable_jna
 
 RELAX_COORD_BOUND=$enable_relax_coord_bound
 
+ENABLE_ERANGE_FILL=$enable_erange_fill
+
 
 # Include some specifics for netcdf on windows.
 #AH_VERBATIM([_WIN32_STRICMP],
@@ -19510,18 +19231,25 @@ cd $srcdir
 abs_top_srcdir=`pwd`
 cd $abs_top_builddir
 
+# test_common.sh setup
 ac_config_files="$ac_config_files test_common.sh:test_common.in"
 
 #rm -f ${abs_top_builddir}/test_common.sh
 #sed -e "s|@TOPSRCDIR@|${abs_top_srcdir}|" -e "s|@TOPBUILDDIR@|${abs_top_builddir}|" <${abs_top_srcdir}/test_common.in >${abs_top_builddir}/test_common.sh
 
+# nc_test4/findplugin.sh setup
+
+
+ac_config_files="$ac_config_files nc_test4/findplugin.sh:nc_test4/findplugin.in"
+
+
 #####
 # End netcdf_meta.h definitions.
 #####
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: generating header files and makefiles" >&5
 $as_echo "$as_me: generating header files and makefiles" >&6;}
-ac_config_files="$ac_config_files Makefile nc-config netcdf.pc libnetcdf.settings postinstall.sh include/netcdf_meta.h include/Makefile h5_test/Makefile libsrc/Makefile libsrc4/Makefile libsrcp/Makefile ncdump/Makefile ncgen3/Makefile ncgen/Makefile examples/Makefile examples/C/Makefile examples/CDL/Makefile oc2/Makefile libdap2/Makefile libdap4/Makefile libdispatch/Makefile liblib/Makefile ncdump/cdl/Makefile ncdump/expected/Makefile docs/Makefile docs/images/Makefile nctest/Makefile nc [...]
+ac_config_files="$ac_config_files Makefile nc-config netcdf.pc libnetcdf.settings postinstall.sh include/netcdf_meta.h include/Makefile h5_test/Makefile libsrc/Makefile libsrc4/Makefile libsrcp/Makefile ncdump/Makefile ncgen3/Makefile ncgen/Makefile examples/Makefile examples/C/Makefile examples/C/hdf5plugins/Makefile examples/CDL/Makefile oc2/Makefile libdap2/Makefile libdap4/Makefile libdispatch/Makefile liblib/Makefile ncdump/cdl/Makefile ncdump/expected/Makefile docs/Makefile docs/im [...]
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -19652,10 +19380,6 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
   as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${BUILD_DLL_TRUE}" && test -z "${BUILD_DLL_FALSE}"; then
-  as_fn_error $? "conditional \"BUILD_DLL\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${BUILD_DOCS_TRUE}" && test -z "${BUILD_DOCS_FALSE}"; then
   as_fn_error $? "conditional \"BUILD_DOCS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -19684,6 +19408,10 @@ if test -z "${INTERNAL_OCLIB_TRUE}" && test -z "${INTERNAL_OCLIB_FALSE}"; then
   as_fn_error $? "conditional \"INTERNAL_OCLIB\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE}" && test -z "${USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE}"; then
+  as_fn_error $? "conditional \"USE_STRICT_NULL_BYTE_HEADER_PADDING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_CDF5_TRUE}" && test -z "${USE_CDF5_FALSE}"; then
   as_fn_error $? "conditional \"USE_CDF5\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -19692,10 +19420,6 @@ if test -z "${ENABLE_CDF5_TRUE}" && test -z "${ENABLE_CDF5_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_CDF5\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${EXTRA_TESTS_TRUE}" && test -z "${EXTRA_TESTS_FALSE}"; then
-  as_fn_error $? "conditional \"EXTRA_TESTS\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${USE_FFIO_TRUE}" && test -z "${USE_FFIO_FALSE}"; then
   as_fn_error $? "conditional \"USE_FFIO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -19765,6 +19489,10 @@ if test -z "${ENABLE_DAP4_TRUE}" && test -z "${ENABLE_DAP4_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_DAP4\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE}" && test -z "${USE_STRICT_NULL_BYTE_HEADER_PADDING_FALSE}"; then
+  as_fn_error $? "conditional \"USE_STRICT_NULL_BYTE_HEADER_PADDING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${ENABLE_CDF5_TRUE}" && test -z "${ENABLE_CDF5_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_CDF5\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -19849,6 +19577,10 @@ if test -z "${SHOW_DOXYGEN_TAG_LIST_TRUE}" && test -z "${SHOW_DOXYGEN_TAG_LIST_F
   as_fn_error $? "conditional \"SHOW_DOXYGEN_TAG_LIST\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${ENABLE_FILTER_TESTING_TRUE}" && test -z "${ENABLE_FILTER_TESTING_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_FILTER_TESTING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -20246,7 +19978,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.5.0, which was
+This file was extended by netCDF $as_me 4.6.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -20316,7 +20048,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.5.0
+netCDF config.status 4.6.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -20447,9 +20179,6 @@ double_quote_subst='$double_quote_subst'
 delay_variable_subst='$delay_variable_subst'
 macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
 macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
 enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
 enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
 pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
@@ -20482,10 +20211,12 @@ lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_q
 lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
 reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
 reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
 deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
 file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
 file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
 want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
 sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
 AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
 AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
@@ -20595,10 +20326,7 @@ _LTECHO_EOF'
 }
 
 # Quote evaled strings.
-for var in AS \
-DLLTOOL \
-OBJDUMP \
-SHELL \
+for var in SHELL \
 ECHO \
 PATH_SEPARATOR \
 SED \
@@ -20611,10 +20339,12 @@ LN_S \
 lt_SP2NL \
 lt_NL2SP \
 reload_flag \
+OBJDUMP \
 deplibs_check_method \
 file_magic_cmd \
 file_magic_glob \
 want_nocaseglob \
+DLLTOOL \
 sharedlib_from_linklib_cmd \
 AR \
 AR_FLAGS \
@@ -20740,6 +20470,7 @@ do
     "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
     "docs/Doxyfile") CONFIG_FILES="$CONFIG_FILES docs/Doxyfile" ;;
     "test_common.sh") CONFIG_FILES="$CONFIG_FILES test_common.sh:test_common.in" ;;
+    "nc_test4/findplugin.sh") CONFIG_FILES="$CONFIG_FILES nc_test4/findplugin.sh:nc_test4/findplugin.in" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "nc-config") CONFIG_FILES="$CONFIG_FILES nc-config" ;;
     "netcdf.pc") CONFIG_FILES="$CONFIG_FILES netcdf.pc" ;;
@@ -20756,6 +20487,7 @@ do
     "ncgen/Makefile") CONFIG_FILES="$CONFIG_FILES ncgen/Makefile" ;;
     "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
     "examples/C/Makefile") CONFIG_FILES="$CONFIG_FILES examples/C/Makefile" ;;
+    "examples/C/hdf5plugins/Makefile") CONFIG_FILES="$CONFIG_FILES examples/C/hdf5plugins/Makefile" ;;
     "examples/CDL/Makefile") CONFIG_FILES="$CONFIG_FILES examples/CDL/Makefile" ;;
     "oc2/Makefile") CONFIG_FILES="$CONFIG_FILES oc2/Makefile" ;;
     "libdap2/Makefile") CONFIG_FILES="$CONFIG_FILES libdap2/Makefile" ;;
@@ -20768,6 +20500,7 @@ do
     "docs/images/Makefile") CONFIG_FILES="$CONFIG_FILES docs/images/Makefile" ;;
     "nctest/Makefile") CONFIG_FILES="$CONFIG_FILES nctest/Makefile" ;;
     "nc_test4/Makefile") CONFIG_FILES="$CONFIG_FILES nc_test4/Makefile" ;;
+    "nc_test4/hdf5plugins/Makefile") CONFIG_FILES="$CONFIG_FILES nc_test4/hdf5plugins/Makefile" ;;
     "nc_test/Makefile") CONFIG_FILES="$CONFIG_FILES nc_test/Makefile" ;;
     "ncdap_test/Makefile") CONFIG_FILES="$CONFIG_FILES ncdap_test/Makefile" ;;
     "ncdap_test/testdata3/Makefile") CONFIG_FILES="$CONFIG_FILES ncdap_test/testdata3/Makefile" ;;
@@ -21550,15 +21283,6 @@ available_tags=''
 macro_version=$macro_version
 macro_revision=$macro_revision
 
-# Assembler program.
-AS=$lt_AS
-
-# DLL creation program.
-DLLTOOL=$lt_DLLTOOL
-
-# Object dumper program.
-OBJDUMP=$lt_OBJDUMP
-
 # Whether or not to build shared libraries.
 build_libtool_libs=$enable_shared
 
@@ -21638,6 +21362,9 @@ to_host_file_cmd=$lt_cv_to_host_file_cmd
 # convert \$build files to toolchain format.
 to_tool_file_cmd=$lt_cv_to_tool_file_cmd
 
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
 
@@ -21650,6 +21377,9 @@ file_magic_glob=$lt_file_magic_glob
 # Find potential files using nocaseglob when deplibs_check_method = "file_magic".
 want_nocaseglob=$lt_want_nocaseglob
 
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
 # Command to associate shared and link libraries.
 sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
 
@@ -22056,6 +21786,7 @@ ltmain=$ac_aux_dir/ltmain.sh
     "ncgen/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "examples/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "examples/C/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
+    "examples/C/hdf5plugins/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "examples/CDL/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "oc2/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "libdap2/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
@@ -22068,6 +21799,7 @@ ltmain=$ac_aux_dir/ltmain.sh
     "docs/images/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "nctest/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "nc_test4/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
+    "nc_test4/hdf5plugins/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "nc_test/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "ncdap_test/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
     "ncdap_test/testdata3/Makefile":F) test -f  nc-config && chmod 755 nc-config ;;
diff --git a/configure.ac b/configure.ac
index 55f2142..4f2787e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,6 +3,7 @@
 
 # This is part of Unidata's netCDF package. Copyright 2005-2012, see
 # the COPYRIGHT file for more information.
+# Ed Hartnett, Ward Fisher, Dennis Heimbigner
 
 # Recall that ${VAR-exp} expands to $VAR if var is set (even to null),
 # and to exp otherwise.
@@ -15,7 +16,7 @@ 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.5.0], [support-netcdf at unidata.ucar.edu])
+AC_INIT([netCDF], [4.6.0], [support-netcdf at unidata.ucar.edu])
 
 ##
 # Prefer an empty CFLAGS variable instead of the default -g -O2.
@@ -25,7 +26,7 @@ AC_INIT([netCDF], [4.5.0], [support-netcdf at unidata.ucar.edu])
 : ${CFLAGS=""}
 
 AC_SUBST([NC_VERSION_MAJOR]) NC_VERSION_MAJOR=4
-AC_SUBST([NC_VERSION_MINOR]) NC_VERSION_MINOR=5
+AC_SUBST([NC_VERSION_MINOR]) NC_VERSION_MINOR=6
 AC_SUBST([NC_VERSION_PATCH]) NC_VERSION_PATCH=0
 AC_SUBST([NC_VERSION_NOTE]) NC_VERSION_NOTE=""
 
@@ -74,7 +75,6 @@ AC_CONFIG_LINKS([nc_test4/ref_hdf5_compat3.nc:nc_test4/ref_hdf5_compat3.nc])
 AC_CONFIG_LINKS([nc_test4/ref_chunked.hdf4:nc_test4/ref_chunked.hdf4])
 AC_CONFIG_LINKS([nc_test4/ref_contiguous.hdf4:nc_test4/ref_contiguous.hdf4])
 
-# This call is required by automake.
 AM_INIT_AUTOMAKE([foreign dist-zip subdir-objects])
 AM_MAINTAINER_MODE()
 
@@ -83,20 +83,6 @@ AC_CONFIG_SRCDIR([include/netcdf.h])
 
 AC_MSG_NOTICE([checking user options])
 
-# If --enable-dll is specified the DLL will be built. This only works
-# on mingw.
-AC_MSG_CHECKING([whether a win32 DLL is desired])
-AC_ARG_ENABLE([dll],
-              [AS_HELP_STRING([--enable-dll],
-                              [build a win32 DLL (only works on mingw)])])
-test "x$enable_dll" = xyes || enable_dll=no
-AC_MSG_RESULT([$enable_dll])
-if test "x$enable_dll" = xyes; then
-   AC_DEFINE(DLL_NETCDF, 1, [set this only when building a DLL under MinGW])
-   AC_DEFINE(DLL_EXPORT, 1, [set this only when building a DLL under MinGW])
-fi
-AM_CONDITIONAL(BUILD_DLL, [test x$enable_dll = xyes])
-
 # Did the user specify a default minimum blocksize (NCIO_MINBLOCKSIZE) for posixio?
 AC_MSG_CHECKING([whether a NCIO_MINBLOCKSIZE was specified])
 AC_ARG_WITH([minblocksize],
@@ -141,6 +127,7 @@ else
    AC_SUBST([DOXYGEN_HEADER_FILE], [])
    AC_SUBST([DOXYGEN_SEARCHENGINE], ["YES"])
 fi
+AC_SUBST([DOXYGEN_SERVER_BASED_SEARCH], ["NO"])
 
 AC_ARG_ENABLE([doxygen-pdf-output],
     [AS_HELP_STRING([--enable-doxygen-pdf-output],
@@ -347,13 +334,8 @@ fi
 # See if the user provided us with a curl library
 # Do an initial lib test for curl, but suppress the default action
 AC_CHECK_LIB([curl],[curl_easy_setopt],[found_curl=yes],[found_curl=no])
-#AC_CHECK_LIB([curl.dll],[curl_easy_setopt])
 # If curl is required but there is no curl, then complain
 if test $require_curl = yes ; then
-  # Removed. Why assume no curl if we are building DLL?
-  #if test $enable_dll = yes ; then
-  #  AC_MSG_NOTICE([libcurl not found; continuing])
-  #elif test $found_curl = no ; then
   if test $found_curl = no ; then
     AC_MSG_NOTICE([libcurl not found; disabling remote protocol(s) support])
     enable_dap=no
@@ -442,6 +424,21 @@ AC_MSG_RESULT([$enable_dap_long_tests])
 
 AM_CONDITIONAL(INTERNAL_OCLIB,[test "x" = "x"])
 
+# Check whether we want to enable strict null byte header padding.
+# See https://github.com/Unidata/netcdf-c/issues/657 for more information.
+AC_MSG_CHECKING([whether to enable strict null-byte header padding when reading (default off)])
+AC_ARG_ENABLE([strict-null-byte-header-padding],
+    [AS_HELP_STRING([--enable-strict-null-byte-header-padding],
+                    [enable strict null-byte header padding when reading netCDF3 files.])])
+test "x$enable_strict_null_byte_header_padding" = xyes || enable_strict_null_byte_header_padding=no
+AC_MSG_RESULT($enable_strict_null_byte_header_padding)
+
+if test "x$enable_strict_null_byte_header_padding" = xyes; then
+   AC_DEFINE([USE_STRICT_NULL_BYTE_HEADER_PADDING], [1], [if true, enable strict null byte header padding])
+fi
+
+AM_CONDITIONAL(USE_STRICT_NULL_BYTE_HEADER_PADDING, [test x$enable_strict_null_byte_header_padding = xyes ])
+
 # Check whether we want to enable CDF5 support.
 AC_MSG_CHECKING([whether CDF5 support should be enabled (default off)])
 AC_ARG_ENABLE([cdf5],
@@ -458,18 +455,6 @@ fi
 AM_CONDITIONAL(USE_CDF5, [test x$enable_cdf5 = xyes ])
 AM_CONDITIONAL(ENABLE_CDF5, [test x$enable_cdf5 = xyes ])
 
-# Does the user want to do some extra tests?
-AC_MSG_CHECKING([whether netCDF extra tests should be run (developers only)])
-AC_ARG_ENABLE([extra-tests],
-              [AS_HELP_STRING([--enable-extra-tests],
-                              [enable some extra tests that may not pass because of known issues])])
-test "x$enable_extra_tests" = xno || enable_extra_tests=yes
-AC_MSG_RESULT($enable_extra_tests)
-if test "x$enable_extra_tests" = xyes; then
-   AC_DEFINE([EXTRA_TESTS], [1], [if true, run extra tests which may not work yet])
-fi
-AM_CONDITIONAL(EXTRA_TESTS, [test x$enable_extra_tests = xyes])
-
 # Does the user want to use the ffio module?
 AC_MSG_CHECKING([whether FFIO will be used])
 AC_ARG_ENABLE([ffio],
@@ -494,19 +479,6 @@ if test "x$enable_stdio" = xyes; then
 fi
 AM_CONDITIONAL(USE_STDIO, [test x$enable_stdio = xyes])
 
-# Does the user want to enable the user-provided NEC-SX vectorization
-# patch.
-dnl AC_MSG_CHECKING([whether netCDF NEC-SX vectorization patch is enabled])
-dnl AC_ARG_ENABLE([sx-vectorization],
-dnl               [AS_HELP_STRING([--enable-sx-vectorization],
-dnl                               [enable a user-provided performance patch to allow \
-dnl 			      vectorization of type conversions on NEC SX machines.])])
-dnl test "x$enable_sx_vectorization" = xyes || enable_sx_vectorization=no
-dnl AC_MSG_RESULT([$enable_sx_vectorization])
-dnl if test "x$enable_sx_vectorization" = xyes; then
-dnl    AC_DEFINE([SX_VECTORIZATION], 1, [if true, turn on vectorization patch for NEC SX])
-dnl fi
-
 nc_build_c=yes
 nc_build_v2=yes
 nc_build_utilities=yes
@@ -721,7 +693,7 @@ CFLAGS="$SAVECFLAGS"
 # Set up libtool.
 AC_MSG_NOTICE([setting up libtool])
 LT_PREREQ([2.2])
-LT_INIT(win32-dll)
+LT_INIT()
 
 # Valgrind tests don't work with shared builds because of some libtool
 # weirdness.
@@ -804,6 +776,8 @@ AC_FUNC_VPRINTF
 AC_CHECK_HEADERS([sys/resource.h])
 #fi
 
+AC_CHECK_HEADERS([sys/cdefs.h])
+
 # Check for <stdbool.h> that conforms to C99 requirements
 AC_HEADER_STDBOOL
 
@@ -813,7 +787,7 @@ AC_CHECK_HEADERS([ftw.h])
 # Check for these functions...
 AC_CHECK_FUNCS([strlcat strerror snprintf strchr strrchr strcat strcpy \
                 strdup strcasecmp strtod strtoll strtoull strstr \
-		mkstemp rand random memcmp \
+		mkstemp mktemp rand random memcmp \
 		getrlimit gettimeofday fsync MPI_Comm_f2c])
 
 # Does the user want to use NC_DISKLESS?
@@ -872,7 +846,7 @@ AC_FUNC_ALLOCA
 AC_CHECK_DECLS([isnan, isinf, isfinite, signbit],,,[#include <math.h>])
 AC_STRUCT_ST_BLKSIZE
 UD_CHECK_IEEE
-AC_CHECK_TYPES([size_t, ssize_t, ptrdiff_t, uchar, longlong, ushort, uint, int64, uint64 off_t])
+AC_CHECK_TYPES([size_t, ssize_t, ptrdiff_t, schar, uchar, longlong, ushort, uint, int64, uint64 off_t])
 AC_TYPE_SIZE_T
 AC_TYPE_OFF_T
 AC_C_CHAR_UNSIGNED
@@ -1055,20 +1029,30 @@ fi
 #    a. do not want to use it for netcdf4
 #    b. do want to use it for netcdf4
 
-# Should we suppress parallel io for netcdf-4?
+# Should we provide 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]  )])
-  test "x$enable_parallel4" = xno || enable_parallel4=yes
-  AC_MSG_RESULT($enable_parallel4)
+   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])],
+			[user_set_parallel4=${enableval}])
+   test "x$enable_parallel4" = xno || enable_parallel4=yes
+   AC_MSG_RESULT($enable_parallel4)
+
+   # If user wants parallel IO for netCDF-4, make sure HDF5 can provide it.
+   if test "x$enable_parallel4" = xyes; then
+      if test "x$hdf5_parallel" = xno; then
+      	 # If user specifically asked for parallel4, then error out.
+	 if test "x$user_set_parallel4" = xyes; then
+	    AC_MSG_ERROR([Paralllel IO in netCDF-4 requested, but HDF5 does not provide parallel IO.])
+	 fi
+         # User didn't specify, so disable parallel4
+	 enable_parallel4=no
+	 AC_MSG_WARN([Parallel io disabled for netcdf-4 because hdf5 does not support])
+      fi
+   fi
 else
-  enable_parallel4=no
-fi
-if test "x$hdf5_parallel" = xno; then
-  # hdf5 does not support parallel io, so disable parallel4
-  enable_parallel4=no
-  AC_MSG_WARN([Parallel io disabled for netcdf-4 because hdf5 does not support])
+   enable_parallel4=no
 fi
 
 # We have already tested for parallel io in netcdf4
@@ -1082,11 +1066,14 @@ AC_MSG_RESULT($enable_pnetcdf)
 
 # See if the pnetcdf lib is available and of the
 # right version (1.6.0 or later)
-
 if test "x$enable_pnetcdf" = xyes; then
   pnetcdf_conflict=no
   AC_CHECK_LIB([pnetcdf], [ncmpi_create], [],[pnetcdf_conflict=yes])
 
+  if test "x$pnetcdf_conflict" = xyes ; then
+     AC_MSG_ERROR([Cannot link to pnetcdf library.])
+  fi
+
   # Pnetcdf did not support utf-8 until 1.6.0
 
   # Save/restore CFLAGS
@@ -1106,16 +1093,10 @@ if test "x$enable_pnetcdf" = xyes; then
   AC_MSG_CHECKING([Is libpnetcdf version 1.6.0 or later?])
   AC_MSG_RESULT([$pnetcdf16])
   if test x$pnetcdf16 = xno; then
-    AC_MSG_WARN([--enable-pnetcdf requires version 1.6.0 or later; disabling])
-    pnetcdf_conflict=yes
+    AC_MSG_ERROR([--enable-pnetcdf requires version 1.6.0 or later])
   fi
 fi
 
-if test "x$pnetcdf_conflict" = xyes ; then
-  AC_MSG_WARN([Cannot link to pnetcdf library, --enable-pnetcdf disabled.])
-  enable_pnetcdf=no
-fi
-
 # Now, set enable_parallel if either pnetcdf or parallel4 is set
 if test "x$enable_pnetcdf" = xyes -o "x$enable_parallel4" = xyes; then
 enable_parallel=yes
@@ -1170,13 +1151,13 @@ if test "x$enable_pnetcdf" = xyes; then
       erange_fill_pnetcdf=no
    else
       erange_fill_pnetcdf=`echo ${erange_fill_pnetcdf} | cut -d' ' -f3`
-      if test "x$coord_bound_pnetcdf" = x0; then
+      if test "x$erange_fill_pnetcdf" = x0; then
           enable_erange_fill_pnetcdf=no
       else
           enable_erange_fill_pnetcdf=yes
       fi
    fi
-   AC_MSG_NOTICE([$enable_erange_fill_pnetcdf])
+   AC_MSG_RESULT([$enable_erange_fill_pnetcdf])
    if test "$enable_erange_fill" != "$enable_erange_fill_pnetcdf"; then
       if test "$enable_erange_fill_pnetcdf" = yes; then
          AC_MSG_WARN([Enable erange-fill to conform with PnetCDF setting])
@@ -1198,7 +1179,7 @@ if test "x$enable_pnetcdf" = xyes; then
           relax_coord_bound_pnetcdf=yes
       fi
    fi
-   AC_MSG_NOTICE([$relax_coord_bound_pnetcdf])
+   AC_MSG_RESULT([$relax_coord_bound_pnetcdf])
    if test "$enable_zero_length_coord_bound" != "$relax_coord_bound_pnetcdf"; then
       if test "$relax_coord_bound_pnetcdf" = yes; then
          AC_MSG_WARN([Enable relax-coord-bound to conform with PnetCDF setting])
@@ -1236,33 +1217,6 @@ if test "x$enable_logging" = xyes; then
    AC_DEFINE([LOGGING], 1, [If true, turn on logging.])
 fi
 
-
-# Like other libraries, udunits and libcf
-# are no long part of the netcdf distribution.
-
-#AC_MSG_CHECKING([whether udunits is to be built])
-#AC_ARG_WITH([udunits],
-#              [AS_HELP_STRING([--with-udunits],
-#                              [Build udunits2 package.])])
-#test "x$with_udunits" = xyes || with_udunits=no
-#AC_MSG_RESULT($with_udunits)
-#AM_CONDITIONAL(BUILD_UDUNITS, [test "x$with_udunits" = xyes])
-
-
-# Does the user want to also build the libcf library?
-#AC_MSG_CHECKING([whether libcf is to be built])
-#AC_ARG_WITH([libcf],
-#              [AS_HELP_STRING([--with-libcf],
-#                              [build and install libcf library, a library for \
-#	      handling data in conformance with the Climate and \
-#	      Forecast conventions. (Requires netCDF-4 and HDF5)])])
-#test "x$with_libcf" = xyes || with_libcf=no
-#AC_MSG_RESULT($with_libcf)
-#AM_CONDITIONAL(BUILD_LIBCF, [test "x$with_libcf" = xyes])
-
-#AC_CONFIG_SUBDIRS([udunits libcf])
-
-
 # Automake conditionals need to be called, whether the answer is yes
 # or no.
 AM_CONDITIONAL(BUILD_PARALLEL, [test x$enable_parallel = xyes])
@@ -1272,6 +1226,7 @@ AM_CONDITIONAL(USE_DAP, [test "x$enable_dap" = xyes]) # Alias
 # Provide protocol specific flags
 AM_CONDITIONAL(ENABLE_DAP, [test "x$enable_dap" = xyes])
 AM_CONDITIONAL(ENABLE_DAP4, [test "x$enable_dap4" = xyes])
+AM_CONDITIONAL(USE_STRICT_NULL_BYTE_HEADER_PADDING, [test x$enable_strict_null_byte_header_padding = xyes])
 AM_CONDITIONAL(ENABLE_CDF5, [test "x$enable_cdf5" = xyes])
 AM_CONDITIONAL(ENABLE_DAP_REMOTE_TESTS, [test "x$enable_dap_remote_tests" = xyes])
 AM_CONDITIONAL(ENABLE_DAP_AUTH_TESTS, [test "x$enable_dap_auth_tests" = xyes])
@@ -1380,6 +1335,25 @@ if test "x$enable_jna" = xyes ; then
 AC_DEFINE([JNA], [1], [if true, include JNA bug fix])
 fi
 
+# Control filter test/example
+AC_MSG_CHECKING([whether filter testing should be run])
+AC_ARG_ENABLE([filter-testing],
+              [AS_HELP_STRING([--disable-filter-testing],
+                              [Do not run filter test and example; requires shared libraries and netCDF-4])])
+test "x$enable_filter_testing" = xno || enable_filter_testing=yes
+AC_MSG_RESULT($enable_filter_testing)
+
+if test "x$enable_netcdf_4" = xno ; then
+AC_MSG_WARN([netCDF-4 disabled => --disable-filter-testing])
+enable_filter_testing = no
+fi
+
+if test "x$enable_shared" = xno ; then
+AC_MSG_WARN([Shared libraries are disabled => --disable-filter-testing])
+enable_filter_testing = no
+fi
+AM_CONDITIONAL(ENABLE_FILTER_TESTING, [test x$enable_filter_testing = xyes])
+
 AC_SUBST(NC_LIBS,[$NC_LIBS])
 AC_SUBST(HAS_DAP,[$enable_dap])
 AC_SUBST(HAS_DAP2,[$enable_dap])
@@ -1398,6 +1372,7 @@ AC_SUBST(HAS_DISKLESS,[$enable_diskless])
 AC_SUBST(HAS_MMAP,[$enable_mmap])
 AC_SUBST(HAS_JNA,[$enable_jna])
 AC_SUBST(RELAX_COORD_BOUND,[$enable_relax_coord_bound])
+AC_SUBST(ENABLE_ERANGE_FILL,[$enable_erange_fill])
 
 # Include some specifics for netcdf on windows.
 #AH_VERBATIM([_WIN32_STRICMP],
@@ -1472,10 +1447,16 @@ cd $srcdir
 abs_top_srcdir=`pwd`
 cd $abs_top_builddir
 
+# test_common.sh setup
 AC_CONFIG_FILES(test_common.sh:test_common.in)
 #rm -f ${abs_top_builddir}/test_common.sh
 #sed -e "s|@TOPSRCDIR@|${abs_top_srcdir}|" -e "s|@TOPBUILDDIR@|${abs_top_builddir}|" <${abs_top_srcdir}/test_common.in >${abs_top_builddir}/test_common.sh
 
+# nc_test4/findplugin.sh setup
+AC_SUBST([ISCMAKE], [])
+AC_SUBST([MSVC], [])
+AC_CONFIG_FILES(nc_test4/findplugin.sh:nc_test4/findplugin.in)
+
 #####
 # End netcdf_meta.h definitions.
 #####
@@ -1497,6 +1478,7 @@ AC_CONFIG_FILES([Makefile
                  ncgen/Makefile
                  examples/Makefile
                  examples/C/Makefile
+                 examples/C/hdf5plugins/Makefile
                  examples/CDL/Makefile
                  oc2/Makefile
                  libdap2/Makefile
@@ -1509,6 +1491,7 @@ AC_CONFIG_FILES([Makefile
                  docs/images/Makefile
                  nctest/Makefile
                  nc_test4/Makefile
+                 nc_test4/hdf5plugins/Makefile
                  nc_test/Makefile
                  ncdap_test/Makefile
                  ncdap_test/testdata3/Makefile
diff --git a/dap4_test/Makefile.am b/dap4_test/Makefile.am
index 7534768..cca89e4 100644
--- a/dap4_test/Makefile.am
+++ b/dap4_test/Makefile.am
@@ -6,8 +6,7 @@
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 include $(top_srcdir)/lib_flags.am
 
-#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
-#TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+TEST_EXTENSIONS = .sh
 
 LDADD = ${top_builddir}/liblib/libnetcdf.la
 AM_CPPFLAGS += -I$(top_srcdir)/libdap4
@@ -25,14 +24,19 @@ test_parse_SOURCES = test_parse.c test_common.h
 test_meta_SOURCES = test_meta.c test_common.h
 test_data_SOURCES = test_data.c test_common.h
 TESTS += test_parse.sh
-TESTS += test_meta.sh
-TESTS += test_data.sh
 
 if BUILD_UTILITIES
 # These rely on ncdump
 TESTS += test_raw.sh
+TESTS += test_meta.sh
+TESTS += test_data.sh
 endif
 
+# Note which tests depend on other tests. Necessary for make -j check.
+test_raw.log: test_parse.log
+test_meta.log: test_raw.log
+test_data.log: test_meta.log
+
 if ENABLE_DAP_REMOTE_TESTS
 # Note: This program name was changed to findtestserver4
 # to avoid cmake complaint about duplicate targets.
@@ -54,6 +58,8 @@ EXTRA_DIST = test_parse.sh test_meta.sh test_data.sh \
 	     baseline baselineraw baselineremote CMakeLists.txt
 
 CLEANFILES = *.exe
+# This should only be left behind if using parallel io
+CLEANFILES += tmp_*
 
 # One last thing
 BUILT_SOURCES = .daprc
diff --git a/dap4_test/Makefile.in b/dap4_test/Makefile.in
index 59f1782..1ebc836 100644
--- a/dap4_test/Makefile.in
+++ b/dap4_test/Makefile.in
@@ -101,23 +101,21 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
 check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
 
 # WARNING: these are unit tests, so they will not
 # appear in CMakeLists.txt
- at ENABLE_DAP4_TRUE@am__append_3 = test_parse test_meta test_data
- at ENABLE_DAP4_TRUE@am__append_4 = test_parse.sh test_meta.sh \
- at ENABLE_DAP4_TRUE@	test_data.sh
+ at ENABLE_DAP4_TRUE@am__append_2 = test_parse test_meta test_data
+ at ENABLE_DAP4_TRUE@am__append_3 = test_parse.sh
 
 # These rely on ncdump
- at BUILD_UTILITIES_TRUE@@ENABLE_DAP4_TRUE at am__append_5 = test_raw.sh
+ at BUILD_UTILITIES_TRUE@@ENABLE_DAP4_TRUE at am__append_4 = test_raw.sh \
+ at BUILD_UTILITIES_TRUE@@ENABLE_DAP4_TRUE@	test_meta.sh \
+ at BUILD_UTILITIES_TRUE@@ENABLE_DAP4_TRUE@	test_data.sh
 
 # Note: This program name was changed to findtestserver4
 # to avoid cmake complaint about duplicate targets.
- at ENABLE_DAP4_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE at am__append_6 = findtestserver4
+ at ENABLE_DAP4_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE at am__append_5 = findtestserver4
 subdir = dap4_test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -406,9 +404,11 @@ am__set_TESTS_bases = \
 RECHECK_LOGS = $(TEST_LOGS)
 AM_RECURSIVE_TARGETS = check recheck
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
-LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
 am__set_b = \
   case '$@' in \
     */*) \
@@ -419,12 +419,6 @@ am__set_b = \
     *) \
       b='$*';; \
   esac
-am__test_logs1 = $(TESTS:=.log)
-am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
 	$(top_srcdir)/lib_flags.am $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -432,12 +426,11 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) \
 	-I$(top_srcdir)/libdap4
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -460,12 +453,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -491,6 +486,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -505,6 +501,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -608,14 +605,12 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
-
-#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
-#TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+TEST_EXTENSIONS = .sh
 LDADD = ${top_builddir}/liblib/libnetcdf.la
-TESTS = $(am__append_4) $(am__append_5)
+TESTS = $(am__append_3) $(am__append_4)
 @ENABLE_DAP4_TRUE at test_parse_SOURCES = test_parse.c test_common.h
 @ENABLE_DAP4_TRUE at test_meta_SOURCES = test_meta.c test_common.h
 @ENABLE_DAP4_TRUE at test_data_SOURCES = test_data.c test_common.h
@@ -627,7 +622,8 @@ EXTRA_DIST = test_parse.sh test_meta.sh test_data.sh \
 	     daptestfiles dmrtestfiles cdltestfiles nctestfiles \
 	     baseline baselineraw baselineremote CMakeLists.txt
 
-CLEANFILES = *.exe
+# This should only be left behind if using parallel io
+CLEANFILES = *.exe tmp_*
 
 # One last thing
 BUILT_SOURCES = .daprc
@@ -635,7 +631,7 @@ all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+.SUFFIXES: .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -926,47 +922,19 @@ recheck: all $(check_PROGRAMS)
 	        am__force_recheck=am--force-recheck \
 	        TEST_LOGS="$$log_list"; \
 	exit $$?
-test_parse.sh.log: test_parse.sh
-	@p='test_parse.sh'; \
-	b='test_parse.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)
-test_meta.sh.log: test_meta.sh
-	@p='test_meta.sh'; \
-	b='test_meta.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)
-test_data.sh.log: test_data.sh
-	@p='test_data.sh'; \
-	b='test_data.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)
-test_raw.sh.log: test_raw.sh
-	@p='test_raw.sh'; \
-	b='test_raw.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
@@ -1131,6 +1099,11 @@ uninstall-am:
 
 .PRECIOUS: Makefile
 
+
+# Note which tests depend on other tests. Necessary for make -j check.
+ at ENABLE_DAP4_TRUE@test_raw.log: test_parse.log
+ at ENABLE_DAP4_TRUE@test_meta.log: test_raw.log
+ at ENABLE_DAP4_TRUE@test_data.log: test_meta.log
 @BUILD_UTILITIES_TRUE@@ENABLE_DAP4_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE@  # relies on ncdump
 @BUILD_UTILITIES_TRUE@@ENABLE_DAP4_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE@  # Disabled until the testserver is stable
 
diff --git a/dap4_test/test_data.c b/dap4_test/test_data.c
index 10df5fa..5b4569e 100644
--- a/dap4_test/test_data.c
+++ b/dap4_test/test_data.c
@@ -47,6 +47,8 @@ main(int argc, char** argv)
     if((ret=nc_close(ncid))) goto done;
 
 done:
+#ifdef DEBUG
     fprintf(stderr,"code=%d %s\n",ret,nc_strerror(ret));
+#endif
     return (ret ? 1 : 0);
 }
diff --git a/dap4_test/test_data.sh b/dap4_test/test_data.sh
index 750a62a..07763b2 100755
--- a/dap4_test/test_data.sh
+++ b/dap4_test/test_data.sh
@@ -11,20 +11,21 @@ cd ${DAPTESTFILES}
 F=`ls -1 *.dap | sed -e 's/[.]dap//g' | tr '\r\n' '  '`
 cd $WD
 
+mkdir ./results_test_data
 if test "x${RESET}" = x1 ; then rm -fr ${BASELINE}/*.d4d ; fi
 for f in $F ; do
     echo "testing: ${f}"
-    if ! ${VG} ${execdir}/test_data ${DAPTESTFILES}/${f} ./results/${f}.nc ; then
-        failure "${execdir}/test_data ${DAPTESTFILES}/${f} ./results/${f}.nc"
+    if ! ${VG} ${execdir}/test_data ${DAPTESTFILES}/${f} ./results_test_data/${f}.nc ; then
+        failure "${execdir}/test_data ${DAPTESTFILES}/${f} ./results_test_data/${f}.nc"
     fi
-    ${NCDUMP} ./results/${f}.nc > ./results/${f}.d4d
+    ${NCDUMP} ./results_test_data/${f}.nc > ./results_test_data/${f}.d4d
     if test "x${TEST}" = x1 ; then
-	if ! diff -wBb ${BASELINE}/${f}.d4d ./results/${f}.d4d ; then
-	    failure "diff -wBb ${BASELINE}/${f}.d4d ./results/${f}.d4d"
+	if ! diff -wBb ${BASELINE}/${f}.d4d ./results_test_data/${f}.d4d ; then
+	    failure "diff -wBb ${BASELINE}/${f}.d4d ./results_test_data/${f}.d4d"
 	fi
     elif test "x${RESET}" = x1 ; then
 	echo "${f}:" 
-	cp ./results/${f}.d4d ${BASELINE}/${f}.d4d
+	cp ./results_test_data/${f}.d4d ${BASELINE}/${f}.d4d
     fi
 done
 
@@ -75,10 +76,10 @@ if test "x${CDLDIFF}" = x1 ; then
       echo "Not found: ${CDLTESTFILES}/${STEM}.cdl"
       continue
     fi
-    echo "diff -wBb ${CDLTESTFILES}/${STEM}.cdl ./results/${f}.d4d"
+    echo "diff -wBb ${CDLTESTFILES}/${STEM}.cdl ./results_test_data/${f}.d4d"
     rm -f ./b1 ./b2 ./r1 ./r2
     trim ${CDLTESTFILES}/${STEM}.cdl ./b1
-    trim ./results/${f}.d4d ./r1
+    trim ./results_test_data/${f}.d4d ./r1
     baseclean b1 b2
     resultclean r1 r2  
     if ! diff -wBb ./b2 ./r2 ; then
@@ -86,6 +87,7 @@ if test "x${CDLDIFF}" = x1 ; then
     fi
   done
 fi
+rm -rf ./results_test_data
 
 finish
 
diff --git a/dap4_test/test_meta.sh b/dap4_test/test_meta.sh
index 86b2b09..7ab6a8e 100755
--- a/dap4_test/test_meta.sh
+++ b/dap4_test/test_meta.sh
@@ -23,35 +23,36 @@ done
 
 if test "x${RESET}" = x1 ; then rm -fr ${BASELINE}/*.d4m ; fi
 
+mkdir ./results_test_meta
 for f in ${F} ; do
     echo "checking: $f"
-    if ! ${VG} ${execdir}/test_meta ${DMRTESTFILES}/${f}.dmr ./results/${f} ; then
-        failure "${execdir}/test_meta ${DMRTESTFILES}/${f}.dmr ./results/${f}"
+    if ! ${VG} ${execdir}/test_meta ${DMRTESTFILES}/${f}.dmr ./results_test_meta/${f} ; then
+        failure "${execdir}/test_meta ${DMRTESTFILES}/${f}.dmr ./results_test_meta/${f}"
     fi
-    ${NCDUMP} -h ./results/${f} > ./results/${f}.d4m
+    ${NCDUMP} -h ./results_test_meta/${f} > ./results_test_meta/${f}.d4m
     if test "x${TEST}" = x1 ; then
-	if ! diff -wBb ${BASELINE}/${f}.d4m ./results/${f}.d4m ; then
-	    failure "diff -wBb ${BASELINE}/${f}.ncdump ./results/${f}.d4m"
+	if ! diff -wBb ${BASELINE}/${f}.d4m ./results_test_meta/${f}.d4m ; then
+	    failure "diff -wBb ${BASELINE}/${f}.ncdump ./results_test_meta/${f}.d4m"
 	fi
     elif test "x${RESET}" = x1 ; then
 	echo "${f}:" 
-	cp ./results/${f}.d4m ${BASELINE}/${f}.d4m
+	cp ./results_test_meta/${f}.d4m ${BASELINE}/${f}.d4m
     fi
 done
 
 if test "x${CDLDIFF}" = x1 ; then
   for f in $CDL ; do
-    echo "diff -wBb ${CDLTESTFILES}/${f}.cdl ./results/${f}.d4m"
+    echo "diff -wBb ${CDLTESTFILES}/${f}.cdl ./results_test_meta/${f}.d4m"
     rm -f ./tmp
     cat ${CDLTESTFILES}/${f}.cdl \
     cat >./tmp
-    echo diff -wBbu ./tmp ./results/${f}.d4m
-    if ! diff -wBbu ./tmp ./results/${f}.d4m ; then
+    echo diff -wBbu ./tmp ./results_test_meta/${f}.d4m
+    if ! diff -wBbu ./tmp ./results_test_meta/${f}.d4m ; then
 	failure "${f}" 
     fi
   done
 fi
-
+rm -rf ./results_test_meta
 finish
 
 
diff --git a/dap4_test/test_parse.sh b/dap4_test/test_parse.sh
index 2b75fc1..a4680fa 100755
--- a/dap4_test/test_parse.sh
+++ b/dap4_test/test_parse.sh
@@ -11,20 +11,21 @@ cd ${DMRTESTFILES}
 F=`ls -1 *.dmr | sed -e 's/[.]dmr//' |tr '\r\n' '  '`
 cd $WD
 
+mkdir ./results_test_parse
 if test "x${RESET}" = x1 ; then rm -fr ${BASELINE}/*.d4p ; fi
 for f in $F ; do
     echo "testing: $f"
-    if ! ${VG} ${execdir}/test_parse ${DMRTESTFILES}/${f}.dmr > ./results/${f}.d4p ; then
+    if ! ${VG} ${execdir}/test_parse ${DMRTESTFILES}/${f}.dmr > ./results_test_parse/${f}.d4p ; then
 	failure "${f}"
     fi
     if test "x${TEST}" = x1 ; then
-	if ! diff -wBb ${BASELINE}/${f}.d4p ./results/${f}.d4p ; then
+	if ! diff -wBb ${BASELINE}/${f}.d4p ./results_test_parse/${f}.d4p ; then
 	    failure "${f}"
 	fi
     elif test "x${DIFF}" = x1 ; then
-	echo "diff -wBb ${DMRTESTFILES}/${f}.dmr ./results/${f}.d4p"
+	echo "diff -wBb ${DMRTESTFILES}/${f}.dmr ./results_test_parse/${f}.d4p"
 	rm -f ./tmp
-	cat ./results/${f}.d4p \
+	cat ./results_test_parse/${f}.d4p \
 	| sed -e '/<Dimensions>/d' -e '/<Types>'/d -e '/<Variables>'/d -e '/<Groups>'/d \
 	| sed -e '/<\/Dimensions>/d' -e '/<\/Types>'/d -e '/<\/Variables>'/d -e '/<\/Groups>'/d  \
 	| sed -e '/_edu.ucar.opaque.size/,+2d' \
@@ -34,9 +35,10 @@ for f in $F ; do
 	fi
     elif test "x${RESET}" = x1 ; then
 	echo "${f}:" 
-	cp ./results/${f}.d4p ${BASELINE}/${f}.d4p	
+	cp ./results_test_parse/${f}.d4p ${BASELINE}/${f}.d4p	
     fi
 done
+rm -rf ./results_test_parse
 
 finish
 
diff --git a/dap4_test/test_raw.sh b/dap4_test/test_raw.sh
index 38df2e4..fc42f02 100755
--- a/dap4_test/test_raw.sh
+++ b/dap4_test/test_raw.sh
@@ -40,20 +40,21 @@ resultclean() {
   fi
 }
 
+mkdir ./results_test_raw
 if test "x${RESET}" = x1 ; then rm -fr ${BASELINERAW}/*.dmp ; fi
 for f in $F ; do
     echo "testing: $f"
     URL="[dap4]file://${DAPTESTFILES}/${f}"
-    if ! ${VG} ${NCDUMP} "${URL}" > ./results/${f}.dmp; then
+    if ! ${VG} ${NCDUMP} "${URL}" > ./results_test_raw/${f}.dmp; then
         failure "${URL}"
     fi
     if test "x${TEST}" = x1 ; then
-	if ! diff -wBb ${BASELINERAW}/${f}.dmp ./results/${f}.dmp ; then
+	if ! diff -wBb ${BASELINERAW}/${f}.dmp ./results_test_raw/${f}.dmp ; then
 	    failure "diff ${f}.dmp"
 	fi
     elif test "x${RESET}" = x1 ; then
 	echo "${f}:" 
-	cp ./results/${f}.dmp ${BASELINERAW}/${f}.dmp
+	cp ./results_test_raw/${f}.dmp ${BASELINERAW}/${f}.dmp
     elif test "x${DIFF}" = x1 ; then
 	echo "hdrtest: ${f}"
 	rm -f ./tr1 ./tr2 ./tb1 ./tb2
@@ -63,6 +64,7 @@ for f in $F ; do
 	fi
     fi
 done
+rm -rf ./results_test_raw
 
 finish
 
diff --git a/dap4_test/tst_raw.sh b/dap4_test/tst_raw.sh
index c2e2a94..ad24edb 100755
--- a/dap4_test/tst_raw.sh
+++ b/dap4_test/tst_raw.sh
@@ -5,8 +5,6 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 
 . ${srcdir}/d4test_common.sh
 
-set -x
-
 # Compute the set of testfiles
 PUSHD ${srcdir}/daptestfiles
 F=`ls -1d *.dap`
diff --git a/docs/Doxyfile.developer b/docs/Doxyfile.developer
index 8bc97fb..cc93ec2 100644
--- 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.5.0
+PROJECT_NUMBER         = 4.6.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/Doxyfile.in b/docs/Doxyfile.in
index 5712b56..81ab12f 100644
--- a/docs/Doxyfile.in
+++ b/docs/Doxyfile.in
@@ -759,6 +759,7 @@ INPUT = \
     @abs_top_srcdir@/docs/tutorial.dox \
     @abs_top_srcdir@/docs/notes.md \
     @abs_top_srcdir@/docs/auth.md \
+    @abs_top_srcdir@/docs/filters.md \
     @abs_top_srcdir@/docs/all-error-codes.md \
     @abs_top_srcdir@/docs/FAQ.md \
     @abs_top_srcdir@/docs/known_problems.md \
@@ -787,7 +788,18 @@ INPUT = \
     @abs_top_srcdir@/libdispatch/dparallel.c \
     @abs_top_srcdir@/libdispatch/derror.c \
     @abs_top_srcdir@/libdispatch/dv2i.c \
+    @abs_top_srcdir@/libdispatch/dcopy.c \
     @abs_top_srcdir@/libsrc4/nc4file.c \
+    @abs_top_srcdir@/libsrc4/nc4var.c \
+    @abs_top_srcdir@/libsrc4/nc4hdf.c \
+    @abs_top_srcdir@/libsrc4/nc4internal.c \
+    @abs_top_srcdir@/libsrc4/nc4type.c \
+    @abs_top_srcdir@/libsrc4/nc4grp.c \
+    @abs_top_srcdir@/libsrc4/ncfunc.c \
+    @abs_top_srcdir@/libsrc4/nc4dim.c \
+    @abs_top_srcdir@/libsrc4/nc4attr.c \
+    @abs_top_srcdir@/libsrc4/nc4info.c \
+    @abs_top_srcdir@/libsrc4/nc4dispatch.c \
     @abs_top_srcdir@/examples/C/simple_xy_wr.c \
     @abs_top_srcdir@/examples/C/simple_xy_rd.c \
     @abs_top_srcdir@/examples/C/sfc_pres_temp_wr.c \
@@ -797,7 +809,8 @@ INPUT = \
     @abs_top_srcdir@/examples/C/simple_nc4_wr.c \
     @abs_top_srcdir@/examples/C/simple_nc4_rd.c \
     @abs_top_srcdir@/examples/C/simple_xy_nc4_wr.c \
-    @abs_top_srcdir@/examples/C/simple_xy_nc4_rd.c
+    @abs_top_srcdir@/examples/C/simple_xy_nc4_rd.c \
+    @abs_top_srcdir@/examples/C/filter_example.c
 
 
 # This tag can be used to specify the character encoding of the source files
@@ -873,7 +886,7 @@ EXAMPLE_PATH           = @abs_top_srcdir@/examples/C
 # *.h) to filter out the source-files in the directories. If left blank all
 # files are included.
 
-EXAMPLE_PATTERNS       =
+EXAMPLE_PATTERNS       = 
 
 # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
 # searched for input files to be used with the \include or \dontinclude commands
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 9f94508..98d3091 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -864,7 +864,7 @@ model format file foo4c.nc, you could use:
   nccopy -k netCDF-4-classic foo3.nc foo4c.nc
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If you have installed [NCO](http://www.unidata.ucar.edu/software/netcdf/docs/software.html#NCO), the NCO
+If you have installed [NCO](http://www.unidata.ucar.edu/software/netcdf/software.html#NCO), the NCO
 utility "ncks" can be used to accomplish the same task, as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~ {.boldcode}
@@ -1866,8 +1866,8 @@ checking be used for all netCDF function calls.
 ----------
 
 
-CMake {#cmake_faq}
-==============================================
+CMake-Related Frequently Asked Questions {#cmake_faq}
+========================================
 
 Below are a list of commonly-asked questions regarding NetCDF and CMake.
 
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 6de6829..45a387a 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -4,14 +4,12 @@
 
 
 # These files will be included with the dist.
-EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html \
-    mainpage.dox tutorial.dox \
-    guide.dox types.dox cdl.dox \
-    architecture.dox internal.dox windows-binaries.md \
-    building-with-cmake.md CMakeLists.txt \
-    groups.dox install.md notes.md install-fortran.md \
-    all-error-codes.md cmake_faq.md credits.md \
-    auth.md obsolete/fan_utils.html bestpractices.md
+EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html	\
+mainpage.dox tutorial.dox guide.dox types.dox cdl.dox			\
+architecture.dox internal.dox windows-binaries.md			\
+building-with-cmake.md CMakeLists.txt groups.dox install.md notes.md	\
+install-fortran.md all-error-codes.md credits.md auth.md		\
+obsolete/fan_utils.html bestpractices.md filters.md
 
 # Turn off parallel builds in this directory.
 .NOTPARALLEL:
diff --git a/docs/Makefile.in b/docs/Makefile.in
index 1336470..cf4e9d6 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -194,7 +194,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -217,12 +216,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -248,6 +249,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -262,6 +264,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -367,14 +370,12 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
 # These files will be included with the dist.
-EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html \
-    mainpage.dox tutorial.dox \
-    guide.dox types.dox cdl.dox \
-    architecture.dox internal.dox windows-binaries.md \
-    building-with-cmake.md CMakeLists.txt \
-    groups.dox install.md notes.md install-fortran.md \
-    all-error-codes.md cmake_faq.md credits.md \
-    auth.md obsolete/fan_utils.html bestpractices.md
+EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html	\
+mainpage.dox tutorial.dox guide.dox types.dox cdl.dox			\
+architecture.dox internal.dox windows-binaries.md			\
+building-with-cmake.md CMakeLists.txt groups.dox install.md notes.md	\
+install-fortran.md all-error-codes.md credits.md auth.md		\
+obsolete/fan_utils.html bestpractices.md filters.md
 
 
 # To build documentation you must have M4 in their path.
diff --git a/docs/all-error-codes.md b/docs/all-error-codes.md
index ff2c35d..3405fc4 100644
--- a/docs/all-error-codes.md
+++ b/docs/all-error-codes.md
@@ -15,14 +15,14 @@ NetCDF Error Code Listing {#nc-error-codes}
 #define NC_ENOTINDEFINE (-38)   // Operation not allowed in data mode
 #define NC_EINDEFINE    (-39)   // Operation not allowed in define mode
 #define NC_EINVALCOORDS (-40)   // Index exceeds dimension bound
-#define NC_EMAXDIMS     (-41)   // NC_MAX_DIMS exceeded
+#define NC_EMAXDIMS     (-41)   // NC_MAX_DIMS exceeded  [not enforced after 4.5.0]
 #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
+#define NC_EMAXATTS     (-44)   // NC_MAX_ATTRS exceeded  [not enforced after 4.5.0]
 #define NC_EBADTYPE     (-45)   // Not a netcdf data type
 #define NC_EBADDIM      (-46)   // Invalid dimension id or name
 #define NC_EUNLIMPOS    (-47)   // NC_UNLIMITED in the wrong index
-#define NC_EMAXVARS     (-48)   // NC_MAX_VARS exceeded
+#define NC_EMAXVARS     (-48)   // NC_MAX_VARS exceeded  [not enforced after 4.5.0]
 #define NC_ENOTVAR      (-49)   // Variable not found
 #define NC_EGLOBAL      (-50)   // Action prohibited on NC_GLOBAL varid
 #define NC_ENOTNC       (-51)   // Not a netcdf file
diff --git a/docs/auth.md b/docs/auth.md
index 93d836b..1b98c75 100644
--- a/docs/auth.md
+++ b/docs/auth.md
@@ -125,12 +125,14 @@ will have HTTP.VERBOSE set to 0 because its host+port matches the example above.
 ## Authorization-Related Keys {#AUTHKEYS}
 
 The currently defined set of authorization-related keys are as follows.
-The second column is the affected curl_easy_setopt option(s), if any.
+The second column is the affected curl_easy_setopt option(s), if any
+(see reference #1).
 <table>
 <tr><th>Key</th><th>Affected curl_easy_setopt Options</th><th>Notes</th>
 <tr><td>HTTP.COOKIEJAR</td><td>CURLOPT_COOKIEJAR</td>
 <tr><td>HTTP.COOKIEFILE</td><td>CURLOPT_COOKIEJAR</td><td>Alias for CURLOPT_COOKIEJAR</td>
-<tr><td>HTTP.PROXY_SERVER</td><td>CURLOPT_PROXY, CURLOPT_PROXYPORT, CURLOPT_PROXYUSERPWD</td>
+<tr><td>HTTP.PROXY.SERVER</td><td>CURLOPT_PROXY, CURLOPT_PROXYPORT, CURLOPT_PROXYUSERPWD</td>
+<tr><td>HTTP.PROXY_SERVER</td><td>CURLOPT_PROXY, CURLOPT_PROXYPORT, CURLOPT_PROXYUSERPWD</td><td>Decprecated: use HTTP.PROXY.SERVER</td>
 <tr><td>HTTP.SSL.CERTIFICATE</td><td>CURLOPT_SSLCERT</td>
 <tr><td>HTTP.SSL.KEY</td><td>CURLOPT_SSLKEY</td>
 <tr><td>HTTP.SSL.KEYPASSWORD</td><td>CURLOPT_KEYPASSWORD</td>
@@ -139,7 +141,9 @@ The second column is the affected curl_easy_setopt option(s), if any.
 <tr><td>HTTP.SSL.VERIFYPEER</td><td>CURLOPT_SSL_VERIFYPEER</td>
 <tr><td>HTTP.SSL.VALIDATE</td><td>CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST</td>
 <tr><td>HTTP.CREDENTIALS.USERPASSWORD</td><td>CURLOPT_USERPASSWORD</td>
-<tr><td>HTTP.NETRC</td><td>CURLOPT_NETRC,CURLOPT_NETRC_FILE</td>
+<tr><td>HTTP.CREDENTIALS.USERNAME</td><td>CURLOPT_USERNAME</td>
+<tr><td>HTTP.CREDENTIALS.PASSWORD</td><td>CURLOPT_PASSWORD</td>
+<tr><td>HTTP.NETRC</td><td>N.A.</td><td>Specify path of the .netrc file</td>
 </table>
 
 ### Password Authentication
@@ -154,6 +158,15 @@ to see how this value must escape certain characters.
 Also see <a href="#REDIR">redirection authorization</a>
 for important additional information.
 
+The pair of keys
+HTTP.CREDENTIALS.USERNAME and HTTP.CREDENTIALS.PASSWORD
+can be used as an alternative to HTTP.CREDENTIALS.USERPASSWORD
+to set the simple password authentication.
+If present, they take precedence over HTTP.CREDENTIALS.USERPASSWORD.
+The values do not need to be escaped.
+See <a href="#REDIR">redirection authorization</a>
+for important additional information.
+
 ### Cookie Jar
 
 The HTTP.COOKIEJAR key
@@ -180,15 +193,19 @@ specifies the password for accessing the HTTP.SSL.CERTIFICAT/HTTP.SSL.key file.
 HTTP.SSL.CAPATH
 specifies the path to a directory containing
 trusted certificates for validating server sertificates.
+See reference #2 for more info.
 
 HTTP.SSL.VALIDATE
 is a boolean (1/0) value that if true (1)
 specifies that the client should verify the server's presented certificate.
 
-HTTP.PROXY_SERVER
+HTTP.PROXY.SERVER
 specifies the url for accessing the proxy:
 e.g. *http://[username:password@]host[:port]*
 
+HTTP.PROXY_SERVER
+deprecated; use HTTP.PROXY.SERVER
+
 HTTP.NETRC
 specifies the absolute path of the .netrc file.
 See [redirection authorization](#REDIR)
@@ -207,7 +224,8 @@ If the user+pwd is embedded in the URL, then '@' and ':' __must__ be escaped.
 If the user+pwd is the value for 
 the HTTP.CREDENTIALS.USERPASSWORD key in the _rc_ file, then
 ':' __must__ be escaped.
-Escaping should __not__ be used in the `.netrc` file.
+Escaping should __not__ be used in the `.netrc` file nor in
+HTTP.CREDENTIALS.USERNAME or HTTPCREDENTIALS.PASSWORD.
 
 The relevant escape codes are as follows.
 <table>
@@ -284,6 +302,11 @@ This requires setting the following entries:
 
 Note that the first two are there to support re-direction based authentication.
 
+## References
+
+1. https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+2. https://curl.haxx.se/docs/ssl-compared.html
+
 ## Appendix A. All RC-File Keys {#allkeys}
 
 For completeness, this is the list of all rc-file keys.
@@ -297,6 +320,7 @@ the code is definitive.
 <tr><td>HTTP.USERAGENT</td><td>CUROPT_USERAGENT</td>
 <tr><td>HTTP.COOKIEJAR</td><td>CUROPT_COOKIEJAR</td>
 <tr><td>HTTP.COOKIE_JAR</td><td>CUROPT_COOKIEJAR</td>
+<tr valign="top"><td>HTTP.PROXY.SERVER</td><td>CURLOPT_PROXY,<br>CURLOPT_PROXYPORT,<br>CURLOPT_PROXYUSERPWD</td>
 <tr valign="top"><td>HTTP.PROXY_SERVER</td><td>CURLOPT_PROXY,<br>CURLOPT_PROXYPORT,<br>CURLOPT_PROXYUSERPWD</td>
 <tr><td>HTTP.SSL.CERTIFICATE</td><td>CUROPT_SSLCERT</td>
 <tr><td>HTTP.SSL.KEY</td><td>CUROPT_SSLKEY</td>
@@ -305,6 +329,8 @@ the code is definitive.
 <tr><td>HTTP.SSL.CAPATH</td><td>CUROPT_CAPATH</td>
 <tr><td>HTTP.SSL.VERIFYPEER</td><td>CUROPT_SSL_VERIFYPEER</td>
 <tr><td>HTTP.CREDENTIALS.USERPASSWORD</td><td>CUROPT_USERPASSWORD</td>
+<tr><td>HTTP.CREDENTIALS.USERNAME</td><td>CUROPT_USERNAME</td>
+<tr><td>HTTP.CREDENTIALS.PASSWORD</td><td>CUROPT_PASSWORD</td>
 <tr><td>HTTP.NETRC</td><td>CURLOPT_NETRC,CURLOPT_NETRC_FILE</td>
 </table>
 
diff --git a/docs/cmake_faq.md b/docs/cmake_faq.md
deleted file mode 100644
index 8bce789..0000000
--- a/docs/cmake_faq.md
+++ /dev/null
@@ -1,69 +0,0 @@
-CMake-Related Frequently-Asked-Questions (FAQ) {#cmake_faq}
-==============================================
-
-Below are a list of commonly-asked questions regarding NetCDF and CMake.
-
-## How can I see the options available to CMake? {#listoptions}
-
-        $ cmake [path to source tree] -L	- This will show the basic options.
-        $ cmake [path to source tree] -LA	- This will show the basic and advanced options.
-
-
-## How do I specify how to build a shared or static library? {#sharedstatic}
-
-    This is controlled with the internal `cmake` option, `BUILD_SHARED_LIBS`.
-
-        $ cmake [Source Directory] -DBUILD_SHARED_LIBS=[ON/OFF]
-
-
-## Can I build both shared and static libraries at the same time with cmake? {#sharedstaticboth}
-
-    Not at this time; it is required to instead build first one version, and then the other, if you need both.
-
-    ## What if I want to link against multiple libraries in a non-standard location? {#nonstdloc}
-
-        You can specify the path to search when looking for dependencies and header files using the `CMAKE_PREFIX_PATH` variable:
-
-    * Windows:
-
-            $ cmake [Source Directory] -DCMAKE_PREFIX_PATH=c:\shared\libs\
-
-
-    * Linux/Unix/OSX:
-
-            $ cmake [Source Directory] -DCMAKE_PREFIX_PATH=/usr/custom_library_locations/		
-
-
-## How can I specify linking against a particular library? {#partlib}
-
-    It depends on the library.  To specify a custom `ZLib`, for example, you would do the following:
-
-        $ cmake [Source Directory] -DZLIB_LIBRARY=/path/to/my/zlib.lib
-
-
-    `HDF5` is more complex, since it requires both the `hdf5` and `hdf5_hl` libraries. You would specify custom `HDF5` libraries as follows:
-
-        $ cmake [Source Directory] -DHDF5_LIB=/path/to/hdf5.lib \
-            -DHDF5_HL_LIB=/path/to/hdf5_hl.lib \
-            -DHDF5_INCLUDE_DIR=/path/to/hdf5/include
-
-
-    Alternatively, you may specify:
-
-        $ cmake [Source Directory] \
-            -DHDF5_LIBRARIES="/path/to/hdf5.lib;/path/to/hdf5_hl.lib" \
-            -DHDF5_INCLUDE_DIR=/path/to/hdf5/include/
-
-
-## How can I specify a Parallel Build using HDF5 {#parallelhdf}
-
-    If cmake is having problems finding the parallel `HDF5` install, you can specify the location manually:
-
-
-        $ cmake [Source Directory] -DENABLE_PARALLEL=ON \
-            -DHDF5_LIB=/usr/lib64/openmpi/lib/libhdf5.so \
-            -DHDF5_HL_LIB=/usr/lib64/openmpi/lib/libhdf5.hl.so \
-            -DHDF5_INCLUDE_DIR=/usr/include/openmpi-x86_64 \
-
-
-    You will, of course, need to use the location of the libraries specific to your development environment.
diff --git a/docs/filters.md b/docs/filters.md
new file mode 100644
index 0000000..0919206
--- /dev/null
+++ b/docs/filters.md
@@ -0,0 +1,420 @@
+Filter Support in netCDF-4 (Enhanced)
+============================
+<!-- double header is needed to workaround doxygen bug -->
+
+Filter Support in netCDF-4 (Enhanced) {#compress}
+=================================
+
+[TOC]
+
+Introduction {#compress_intro}
+==================
+
+The HDF5 library (1.8.11 and later) 
+supports a general filter mechanism to apply various
+kinds of filters to datasets before reading or writing. 
+The netCDF enhanced (aka netCDF-4) library inherits this
+capability since it depends on the HDF5 library.
+
+Filters assume that a variable has chunking
+defined and each chunk is filtered before
+writing and "unfiltered" after reading and
+before passing the data to the user.
+
+The most common kind of filter is a compression-decompression
+filter, and that is the focus of this document.
+
+HDF5 supports dynamic loading of compression filters using the following
+process for reading of compressed data.
+
+1. Assume that we have a dataset with one or more variables that
+were compressed using some algorithm. How the dataset was compressed
+will be discussed subsequently.
+
+2. Shared libraries or DLLs exist that implement the compress/decompress
+algorithm. These libraries have a specific API so that the HDF5 library
+can locate, load, and utilize the compressor.
+These libraries are expected to installed in a specific
+directory.
+
+Enabling A Compression Filter {#Enable}
+=============================
+
+In order to compress a variable, the netcdf-c library
+must be given three pieces of information:
+(1) some unique identifier for the filter to be used,
+(2) a vector of parameters for
+controlling the action of the compression filter, and
+(3) a shared library implementation of the filter.
+
+The meaning of the parameters is, of course,
+completely filter dependent and the filter
+description [3] needs to be consulted. For
+bzip2, for example, a single parameter is provided
+representing the compression level.
+It is legal to provide a zero-length set of parameters.
+Defaults are not provided, so this assumes that
+the filter can operate with zero parameters.
+
+Filter ids are assigned by the HDF group. See [4]
+for a current list of assigned filter ids.
+Note that ids above 32767 can be used for testing without
+registration.
+
+The first two pieces of  information can be provided in one of three ways:
+using __ncgen__, via an API call, or via command line parameters to __nccopy__.
+In any case, remember that filtering also requires setting chunking, so the
+variable must also be marked with chunking information.
+
+Using The API {#API}
+-------------
+The necessary API methods are included in __netcdf.h__ by default.
+One API method is for setting the filter to be used
+when writing a variable. The relevant signature is
+as follows.
+````
+int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
+````
+This must be invoked after the variable has been created and before
+__nc_enddef__ is invoked.
+
+A second API methods makes it possible to query a variable to
+obtain information about any associated filter using this signature.
+````
+int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
+
+````
+The filter id wil be returned in the __idp__ argument (if non-NULL),
+the number of parameters in __nparamsp__ and the actual parameters in
+__params__.  As is usual with the netcdf API, one is expected to call
+this function twice. The first time to get __nparams__ and the
+second to get the parameters in client-allocated memory.
+
+Using ncgen {#NCGEN}
+-------------
+
+In a CDL file, compression of a variable can be specified
+by annotating it with the following attribute:
+
+* ''_Filter'' -- a string containing a comma separated list of
+constants specifying (1) the filter id to apply, and (2)
+a vector of constants representing the
+parameters for controlling the operation of the specified filter.
+See the section on the <a href="#Syntax">parameter encoding syntax</a>
+for the details on the allowable kinds of constants.
+
+This is a "special" attribute, which means that
+it will normally be invisible when using
+__ncdump__ unless the -s flag is specified.
+
+Example CDL File (Data elided)
+------------------------------
+````
+netcdf bzip2 {
+dimensions:
+  dim0 = 4 ; dim1 = 4 ; dim2 = 4 ; dim3 = 4 ;
+variables:
+  float var(dim0, dim1, dim2, dim3) ;
+    var:_Filter = "307,9" ;
+    var:_Storage = "chunked" ;
+    var:_ChunkSizes = 4, 4, 4, 4 ;
+data:
+...
+}
+````
+
+Using nccopy {#NCCOPY}
+-------------
+When copying a netcdf file using __nccopy__ it is possible
+to specify filter information for any output variable by
+using the "-F" option on the command line; for example:
+````
+nccopy -F "var,307,9" unfiltered.nc filtered.nc
+````
+Assume that __unfiltered.nc__ has a chunked but not bzip2 compressed
+variable named "var". This command will create that variable in
+the __filtered.nc__ output file but using filter with id 307
+(i.e. bzip2) and with parameter(s) 9 indicating the compression level.
+See the section on the <a href="#Syntax">parameter encoding syntax</a>
+for the details on the allowable kinds of constants.
+
+The "-F" option can be used repeatedly as long as the variable name
+part is different. A different filter id and parameters can be
+specified for each occurrence.
+
+Note that if the input file has compressed variables, that fact
+will be invisble to nccopy because it is handled within the
+netcdf-c/hdf5 library code. This is true for any program that calls
+the netcdf-c library.
+
+Parameter Encoding {#ParamEncode}
+==========
+
+The parameters passed to a filter are encoded internally as a vector
+of 32-bit unsigned integers. It may be that the parameters
+required by a filter can naturally be encoded as unsigned integers.
+The bzip2 compression filter, for example, expects a single
+integer value from zero thru nine. This encodes naturally as a
+single unsigned integer.
+
+Note that signed integers and single-precision (32-bit) float values
+also can easily be represented as 32 bit unsigned integers by
+proper casting to an unsigned integer so that the bit pattern
+is preserved. Simple integer values of type short or char
+(or the unsigned versions) can also be mapped to an unsigned
+integer by truncating to 16 or 8 bits respectively and then
+zero extending.
+
+Machine byte order (aka endian-ness) is an issue for passing
+some kinds of parameters. You might define the parameters when
+compressing on a little endian machine, but later do the
+decompression on a big endian machine. Byte order is not an
+issue for 32-bit values because HDF5 takes care of converting
+them between the local machine byte order and network byte
+order.
+
+Parameters whose size is larger than 32-bits present a byte order problem.
+This typically includes double precision floats and (signed or unsigned)
+64-bit integers. For these cases, the machine byte order must be
+handled by the compression code. This is because HDF5 will treat,
+for example, an unsigned long long as two 32-bit unsigned integers
+and will convert each to network order separately. This means that
+on a machine whose byte order is different than the machine in which
+the parameters were initially created, the two integers are out of order
+and must be swapped to get the correct unsigned long long value.
+Consider this example. Suppose we have this little endian unsigned long long.
+
+    1000000230000004
+
+In network byte order, it will be stored as two 32-bit integers.
+
+    20000001 40000003
+
+On a big endian machine, this will be given to the filter in that form.
+
+    2000000140000003
+
+But note that the proper big endian unsigned long long form is this.
+
+4000000320000001
+
+So, the two words need to be swapped.
+
+But consider the case when both original and final machines are big endian.
+
+1. 4000000320000001
+2. 40000003 20000001
+3. 40000003 20000001
+
+where #1 is the original number, #2 is the network order and
+#3 is the what is given to the filter. In this case we do not
+want to swap words.
+
+The solution is to forcibly encode the original number using some
+specified endianness so that the filter always assumes it is getting
+its parameters in that order and will always do swapping as needed.
+This is irritating, but one needs to be aware of it. Since most
+machines are little-endian. We choose to use that as the endianness
+for handling 64 bit entities.
+
+Filter Specification Syntax {#Syntax}
+==========
+
+Both of the utilities
+<a href="#NCGEN">__ncgen__</a>
+and
+<a href="#NCCOPY">__nccopy__</a>
+allow the specification of filter parameters.
+These specifications consist of a sequence of comma
+separated constants. The constants are converted
+within the utility to a proper set of unsigned int
+constants (see the <a href="#ParamEncode">parameter encoding section</a>).
+
+To simplify things, various kinds of constants can be specified
+rather than just simple unsigned integers. The utilities will encode
+them properly using the rules specified in 
+the <a href="#ParamEncode">parameter encoding section</a>.
+
+The currently supported constants are as follows.
+<table>
+<tr halign="center"><th>Example<th>Type<th>Format Tag<th>Notes
+<tr><td>-17b<td>signed 8-bit byte<td>b|B<td>Truncated to 8 bits and zero extended to 32 bits
+<tr><td>23ub<td>unsigned 8-bit byte<td>u|U b|B<td>Truncated to 8 bits and zero extended to 32 bits
+<tr><td>-25S<td>signed 16-bit short<td>s|S<td>Truncated to 16 bits and zero extended to 32 bits
+<tr><td>27US<td>unsigned 16-bit short<td>u|U s|S<td>Truncated to 16 bits and zero extended to 32 bits
+<tr><td>-77<td>implicit signed 32-bit integer<td>Leading minus sign and no tag<td>
+<tr><td>77<td>implicit unsigned 32-bit integer<td>No tag<td>
+<tr><td>93U<td>explicit unsigned 32-bit integer<td>u|U<td>
+<tr><td>789f<td>32-bit float<td>f|F<td>
+<tr><td>12345678.12345678d<td>64-bit double<td>d|D<td>Network byte order
+<tr><td>-9223372036854775807L<td>64-bit signed long long<td>l|L<td>Network byte order
+<tr><td>18446744073709551615UL<td>64-bit unsigned long long<td>u|U l|L<td>Network byte order
+</table>
+Some things to note.
+
+1. In all cases, except for an untagged positive integer,
+   the format tag is required and determines how the constant
+   is converted to one or two unsigned int values.
+   The positive integer case is for backward compatibility.
+2. For signed byte and short, the value is sign extended to 32 bits
+   and then treated as an unsigned int value.
+3. For double, and signed|unsigned long long, they are converted
+   to network byte order and then treated as two unsigned int values.
+   This is consistent with the <a href="#ParamEncode">parameter encoding</a>.
+
+Dynamic Loading Process {#Process}
+==========
+
+The documentation[1,2] for the HDF5 dynamic loading was (at the time
+this was written) out-of-date with respect to the actual HDF5 code
+(see HDF5PL.c). So, the following discussion is largely derived
+from looking at the actual code. This means that it is subject to change.
+
+Plugin directory {#Plugindir}
+----------------
+
+The HDF5 loader expects plugins to be in a specified plugin directory.
+The default directory is:
+   * "/usr/local/hdf5/lib/plugin” for linux/unix operating systems (including Cygwin)
+   * “%ALLUSERSPROFILE%\\hdf5\\lib\\plugin” for Windows systems, although the code
+     does not appear to explicitly use this path.
+
+The default may be overridden using the environment variable
+__HDF5_PLUGIN_PATH__.
+
+Plugin Library Naming {#Pluginlib}
+---------------------
+
+Given a plugin directory, HDF5 examines every file in that
+directory that conforms to a specified name pattern
+as determined by the platform on which the library is being executed.
+<table>
+<tr halign="center"><th>Platform<th>Basename<th>Extension
+<tr halign="left"><td>Linux<td>lib*<td>.so*
+<tr halign="left"><td>OSX<td>lib*<td>.so*
+<tr halign="left"><td>Cygwin<td>cyg*<td>.dll*
+<tr halign="left"><td>Windows<td>*<td>.dll
+</table>
+
+Plugin Verification {#Pluginverify}
+-------------------
+For each dynamic library located using the previous patterns,
+HDF5 attempts to load the library and attempts to obtain information
+from it. Specifically, It looks for two functions with the following
+signatures.
+
+1. __H5PL_type_t H5PLget_plugin_type(void)__ --
+This function is expected to return the constant value
+__H5PL_TYPE_FILTER__ to indicate that this is a filter library.
+2. __const void* H5PLget_plugin_info(void)__ --
+This function returns a pointer to a table of type __H5Z_class2_t__.
+This table contains the necessary information needed to utilize the
+filter both for reading and for writing. In particular, it specifies
+the filter id implemented by the library and if must match that id
+specified for the variable in __nc_def_var_filter__ in order to be used.
+
+If plugin verification fails, then that plugin is ignored and
+the search continues for another, matching plugin.
+
+Debugging {#Debug}
+-------
+Debugging plugins can be very difficult. You will probably
+need to use the old printf approach for debugging the filter itself.
+
+One case worth mentioning is when you have a dataset that is
+using an unknown filter. For this situation, you need to
+identify what filter(s) are used in the dataset. This can
+be accomplished using this command.
+````
+ncdump -s -h <dataset filename>
+````
+Since ncdump is not being asked to access the data (the -h flag), it
+can obtain the filter information without failures. Then it can print
+out the filter id and the parameters (the -s flag).
+
+Test Case {#TestCase}
+-------
+Within the netcdf-c source tree, the directory
+__netcdf-c/nc_test4__ contains a test case (__test_filter.c__) for
+testing dynamic filter writing and reading using
+bzip2. Another test (__test_filter_misc.c__) validates
+parameter passing.  These tests are disabled if __--enable-shared__
+is not set or if __--enable-netcdf-4__ is not set.
+
+Example {#Example}
+-------
+A slightly simplified version of the filter test case is also
+available as an example within the netcdf-c source tree
+directory __netcdf-c/examples/C. The test is called __filter_example.c__
+and it is executed as part of the __run_examples4.sh__ shell script.
+The test case demonstrates dynamic filter writing and reading.
+
+The files __example/C/hdf5plugins/Makefile.am__
+and  __example/C/hdf5plugins/CMakeLists.txt__
+demonstrate how to build the hdf5 plugin for bzip2.
+
+Notes
+==========
+
+Supported Systems
+-----------------
+The current matrix of OS X build systems known to work is as follows.
+<table>
+<tr><th>Build System<th>Supported OS
+<tr><td>Automake<td>Linux, Cygwin
+<tr><td>Cmake<td>Linux, Cygwin, Visual Studio
+</table>
+
+Generic Plugin Build
+--------------------
+If you do not want to use Automake or Cmake, the following
+has been known to work.
+````
+gcc -g -O0 -shared -o libbzip2.so <plugin source files>  -L${HDF5LIBDIR} -lhdf5_hl -lhdf5 -L${ZLIBDIR} -lz
+````
+
+Appendix A. Byte Swap Code {#AppendixA}
+==========
+Since in some cases, it is necessary for a filter to
+byte swap from little-endian to big-endian, This appendix
+provides sample code for doing this. It also provides
+a code snippet for testing if the machine the
+endianness of a machine.
+
+Byte swap an 8-byte chunk of memory
+-------
+````
+static void
+byteswap8(unsigned char* mem)
+{
+    register unsigned char c;
+    c = mem[0];
+    mem[0] = mem[7];
+    mem[7] = c;
+    c = mem[1];
+    mem[1] = mem[6];
+    mem[6] = c;
+    c = mem[2];
+    mem[2] = mem[5];
+    mem[5] = c;
+    c = mem[3];
+    mem[3] = mem[4];
+    mem[4] = c;
+}
+
+````
+
+Test for Machine Endianness
+-------
+````
+static const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
+int endianness = (1 == *(unsigned int*)b); /* 1=>big 0=>little endian
+````
+
+References {#References}
+==========
+
+1. https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters/HDF5DynamicallyLoadedFilters.pdf
+2. https://support.hdfgroup.org/HDF5/doc/TechNotes/TechNote-HDF5-CompressionTroubleshooting.pdf
+3. https://support.hdfgroup.org/services/filters.html
+4. https://support.hdfgroup.org/services/contributions.html#filters
diff --git a/docs/guide.dox b/docs/guide.dox
index 7f57f19..613055a 100644
--- a/docs/guide.dox
+++ b/docs/guide.dox
@@ -10,6 +10,7 @@
 - \subpage netcdf_utilities_guide
 - \subpage dap2
 - \subpage dap4
+- \subpage compress
 - \subpage BestPractices
 - \subpage users_guide_appendices
 
diff --git a/docs/images/Makefile.in b/docs/images/Makefile.in
index 3910a09..37c2b95 100644
--- a/docs/images/Makefile.in
+++ b/docs/images/Makefile.in
@@ -131,7 +131,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -154,12 +153,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -185,6 +186,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -199,6 +201,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/docs/install.md b/docs/install.md
index ad1299a..69ea848 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -73,7 +73,9 @@ full functionality. (See \ref architecture).
 Requirements {#netcdf_requirements}
 ----------------------------------
 
-* HDF5 1.8.9 or later (for netCDF-4 support)
+* For netCDF-4 support
+  * HDF5 1.8.9 or later.
+  * HDF5 1.10.1 or later.
 * zlib 1.2.5 or later (for netCDF-4 compression)
 * curl 7.18.0 or later (for DAP remote access client support)
 
@@ -95,7 +97,15 @@ HDF5 and zlib packages are available from the <a href="http://www.hdfgroup.org/d
 
 ### Optional: szip support {#op_szip_support}
 
-*Optionally*, you can also build netCDF-4 with the szip library (a.k.a. szlib). If building with szlib, get szip 2.0 or later. NetCDF cannot create szipped data files, but can read HDF5 data files that have used szip. To determine whether license restrictions on the use of szip apply to your situation, see the <a href="http://www.hdfgroup.org/doc_resource/SZIP/">web page on szip compression in HDF products</a>.
+*Optionally*, you can also build netCDF-4 with the szip library (a.k.a. szlib). If building with szlib, get szip 2.0 or later. Technically, we mean that
+the HDF5 library is built with szip support. The netcdf build will then
+inherit szip support from the HDF5 library.
+If you intend to write files with szip compression, then we suggest that you
+use [libaec](https://gitlab.dkrz.de/k202009/libaec.git)
+to avoid patent problems. That library can be used as a 
+drop-in replacement for the standard szip library.
+If you plan to use the standard szip library, 
+then determine whether license restrictions on the use of szip apply to your situation. See the <a href="http://www.hdfgroup.org/doc_resource/SZIP/">web page on szip compression in HDF products</a>.
 
 If `make check` fails for either `zlib` or `HDF5`, the problem must be resolved before the netCDF-4 installation can continue. For HDF5 problems, see the <a href="http://www.hdfgroup.org/services/support.html">HDF5 help services</a>.
 
@@ -332,6 +342,7 @@ Note: `--disable` prefix indicates that the option is normally enabled.
 <tr><td>--enable-pnetcdf<td>build netcdf-4 with parallel I/O for classic and
                           64-bit offset files using parallel-netcdf
 <tr><td>--enable-extra-example-tests<td>Run extra example tests<td>--enable-netcdf-4,GNU sed
+<tr><td>--disable-filter-testing<td>Run filter example<td>--enable-shared --enable-netcdf-4
 <tr><td>--enable-parallel-tests <td>run extra parallel IO tests<td>--enable-netcdf-4, parallel IO support
 <tr><td>--enable-logging<td>enable logging capability<td>--enable-netcdf-4
 <tr><td>--disable-dap<td>build without DAP client support.<td>libcurl
@@ -407,13 +418,13 @@ The output of the configuration step is a project file based on the appropriate
 
 | **Option** | **Autotools** | **CMake** |
 | :------- | :---- | :----- |
-Specify Install Location | --prefix=PREFIX | -D"CMAKE\_INSTALL\_PREFIX=PREFIX"
-Enable/Disable netCDF-4 | --enable-netcdf-4<br>--disable-netcdf-4 | -D"ENABLE\_NETCDF\_4=ON" <br> -D"ENABLE\_NETCDF\_4=OFF"
-Enable/Disable DAP | --enable-dap <br> --disable-dap | -D"ENABLE\_DAP=ON" <br> -D"ENABLE\_DAP=OFF"
-Enable/Disable Utilities | --enable-utilities <br> --disable-utilities | -D"BUILD\_UTILITIES=ON" <br> -D"BUILD\_UTILITIES=OFF"
-Specify shared/Static Libraries | --enable-shared <br> --enable-static | -D"BUILD\_SHARED\_LIBS=ON" <br> -D"BUILD\_SHARED\_LIBS=OFF"
-Enable/Disable Tests | --enable-testsets <br> --disable-testsets | -D"ENABLE\_TESTS=ON" <br> -D"ENABLE\_TESTS=OFF"
-Specify a custom library location | Use *CFLAGS* and *LDFLAGS* | -D"CMAKE\_PREFIX\_PATH=/usr/custom_libs/"
+Specify Install Location | --prefix=PREFIX | -D"CMAKE_INSTALL_PREFIX=PREFIX"
+Enable/Disable netCDF-4 | --enable-netcdf-4<br>--disable-netcdf-4 | -D"ENABLE_NETCDF_4=ON" <br> -D"ENABLE_NETCDF_4=OFF"
+Enable/Disable DAP | --enable-dap <br> --disable-dap | -D"ENABLE_DAP=ON" <br> -D"ENABLE_DAP=OFF"
+Enable/Disable Utilities | --enable-utilities <br> --disable-utilities | -D"BUILD_UTILITIES=ON" <br> -D"BUILD_UTILITIES=OFF"
+Specify shared/Static Libraries | --enable-shared <br> --enable-static | -D"BUILD_SHARED_LIBS=ON" <br> -D"BUILD_SHARED_LIBS=OFF"
+Enable/Disable Tests | --enable-testsets <br> --disable-testsets | -D"ENABLE_TESTS=ON" <br> -D"ENABLE_TESTS=OFF"
+Specify a custom library location | Use *CFLAGS* and *LDFLAGS* | -D"CMAKE_PREFIX_PATH=/usr/custom_libs/"
 
 A full list of *basic* options can be found by invoking `cmake [Source Directory] -L`. To enable a list of *basic* and *advanced* options, one would invoke `cmake [Source Directory] -LA`.
 
@@ -463,4 +474,5 @@ or
 
 ## See Also {#cmake_see_also}
 
-For further information regarding netCDF and CMake, see \ref cmake_faq
+For further information regarding netCDF and CMake, see \ref cmake_faq.
+
diff --git a/docs/mainpage.dox b/docs/mainpage.dox
index 1a04765..ccd1366 100644
--- a/docs/mainpage.dox
+++ b/docs/mainpage.dox
@@ -18,12 +18,12 @@ The NetCDF homepage may be found at <a href="http://www.unidata.ucar.edu/softwar
 
 \subsubsection NetCDF-C
 
-- <A href="http://my.cdash.org/index.php?project=netcdf-c">The netCDF-C Nightly and Continuous Integration Dashboard</A>
+- <A href="http://cdash.unidata.ucar.edu/index.php?project=netcdf-c">The netCDF-C Nightly and Continuous Integration Dashboard</A>
 - <A href="https://travis-ci.org/Unidata/netcdf-c">NetCDF-C at Travis-CI</A>
 
 \subsubsection NetCDF-Fortran
 
-- <A href="http://my.cdash.org/index.php?project=netcdf-fortran">The netCDF-Fortran Nightly and Continuous Integration Dashboard</A>
+- <A href="http://cdash.unidata.ucar.edu/index.php?project=netcdf-fortran">The netCDF-Fortran Nightly and Continuous Integration Dashboard</A>
 - <A href="https://travis-ci.org/Unidata/netcdf-c">NetCDF-Fortran at Travis-CI</A>
 
 \section learn-more Learn more about using NetCDF-C
diff --git a/docs/old/netcdf-c.texi b/docs/old/netcdf-c.texi
index f8e42c5..b09c11b 100644
--- a/docs/old/netcdf-c.texi
+++ b/docs/old/netcdf-c.texi
@@ -12249,14 +12249,14 @@ nc_strerror
 #define NC_ENOTINDEFINE (-38)   /* Operation not allowed in data mode */
 #define NC_EINDEFINE    (-39)   /* Operation not allowed in define mode */
 #define NC_EINVALCOORDS (-40)   /* Index exceeds dimension bound */
-#define NC_EMAXDIMS     (-41)   /* NC_MAX_DIMS exceeded */
+#define NC_EMAXDIMS     (-41)   /* NC_MAX_DIMS exceeded */ /* not enforced after 4.5.0 */
 #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 */
+#define NC_EMAXATTS     (-44)   /* NC_MAX_ATTRS exceeded */ /* not enforced after 4.5.0 */
 #define NC_EBADTYPE     (-45)   /* Not a netcdf data type */
 #define NC_EBADDIM      (-46)   /* Invalid dimension id or name */
 #define NC_EUNLIMPOS    (-47)   /* NC_UNLIMITED in the wrong index */
-#define NC_EMAXVARS     (-48)   /* NC_MAX_VARS exceeded */
+#define NC_EMAXVARS     (-48)   /* NC_MAX_VARS exceeded */ /* not enforced after 4.5.0 */
 #define NC_ENOTVAR      (-49)   /* Variable not found */
 #define NC_EGLOBAL      (-50)   /* Action prohibited on NC_GLOBAL varid */
 #define NC_ENOTNC       (-51)   /* Not a netcdf file */
diff --git a/docs/static-pages/software.html b/docs/static-pages/software.html
index 2190b7e..d4615f4 100644
--- a/docs/static-pages/software.html
+++ b/docs/static-pages/software.html
@@ -1,2831 +1,2831 @@
-<html>
-
-  <head>
-
-    <title>Software for Manipulating or Displaying NetCDF Data</title>
-    <meta name="UIINDEX" content="0">
-    <meta name="BOOKMARK" content="NetCDF Utilities">
-    <meta name="AUTHOR" content="russ">
-    <meta name="KEYWORDS" content="netcdf, utilities, software, use">
-    <meta name="DESCRIPTION" content="This document provides references to software packages that may be used for manipulating or displaying netCDF data. We include information about both freely-available and licensed (commercial) software that can be used with netCDF data. ">
-
-  </head>
-
-  <body>
-
-    <h1>Software for Manipulating or Displaying NetCDF Data</h1>
-    <p>
-      This document provides references to software packages that may be used for manipulating
-      or displaying <a
-      href="/software/netcdf/">netCDF</a> data. We include information about
-      both freely-available and licensed (commercial) software that can be used with
-      netCDF data. We rely on developers to help keep this list up-to-date. If you know
-      of corrections or additions, please <a href="mailto:support at unidata.ucar.edu">send
-      them to us</a>. Where practical, we would like to include WWW links to information
-      about these packages in the HTML version of this document.
-    </p>
-
-    <p>
-      Other useful guides to utilities that can handle netCDF data include ARM's list of
-      <a href="http://science.arm.gov/%7ecflynn/ARM_Tested_Tools/"
-      >ARM-tested netCDF data tools</a>, which includes some downloadable
-      binaries and the NOAA Geophysical
-      Fluid Dynamics Laboratory
-      <a href=
-      "http://nomads.gfdl.noaa.gov/sandbox/products/vis/data/netcdf/GFDL_VG_NetCDF_Utils.html"> guide to netCDF utilities</a>.
-    </p>
-
-    <hr />
-    <h2><a href="#freely">Freely Available Software</a></h2>
-    <ul>
-      <li>
-        <a href="#ANDX">ANDX (ARM NetCDF Data eXtract) and ANAX (ARM NetCDF ASCII eXtract)</a>
-      </li>
-      <li>
-        <a href="#ANTS" >ANTS (ARM NetCDF Tool Suite)</a>
-      </li>
-      <li>
-        <a href="#ARGOS">ARGOS (interActive thRee-dimensional Graphics ObServatory)</a>
-      </li>
-      <li>
-        <a href="#CDAT">CDAT (Climate Data Analysis Tool)</a>
-      </li>
-      <li>
-        <a href="#CDFconvert" >CDFconvert (Convert netCDF to RPN and GEMPAK Grids)</a>
-      </li>
-      <li>
-        <a href="#cdfsync">cdfsync (network synchronization of netCDF files)</a>
-      </li>
-      <li>
-        <a href="#CDO" >CDO (Climate Data Operators)</a>
-      </li>
-      <li>
-        <a href="#CIDS Tools">CIDS Tools</a>
-      </li>
-      <li>
-        <a href="#CSIRO-MATLAB">CSIRO MATLAB/netCDF interface</a>
-      </li>
-      <li>
-        <a href="#EPIC">EPIC</a>
-      </li>
-      <li>
-        <a href="#ExcelUse" >Excel Use</a>
-      </li>
-      <li>
-        <a href="#EzGet">EzGet</a>
-      </li>
-      <li>
-        <a href="#FAN">FAN (File Array Notation)</a>
-      </li>
-      <li>
-        <a href="#FERRET">FERRET</a>
-      </li>
-      <li>
-        <a href="#fimex" >FIMEX (File Interpolation, Manipulation, and EXtraction)</a>
-      </li>
-      <li>
-        <a href="#fwtools" >FWTools (GIS Binary Kit for Windows and Linux)</a>
-      </li>
-      <li>
-        <a href="#GDAL" >GDAL (Geospatial Data Abstraction Library)</a>
-      </li>
-      <li>
-        <a href="#GDL" >GDL (GNU Data Language)</a>
-      </li>
-      <li>
-        <a href="#Gfdnavi" >Gfdnavi (Geophysical fluid data navigator)</a>
-      </li>
-      <li>
-        <a href="#GMT">GMT (Generic Mapping Tools)</a>
-      </li>
-      <li>
-        <a href="#Grace">Grace</a>
-      </li>
-      <li>
-        <a href="#GrADS">GrADS (Grid Analysis and Display System)</a>
-      </li>
-      <li>
-        <a href="#Gri">Gri</a>
-      </li>
-      <li>
-        <a href="#GXSM">GXSM - Gnome X Scanning Microscopy project</a>
-      </li>
-      <li>
-        <a href="#HDF interface">HDF (Hierarchical Data Format) interface</a>
-      </li>
-      <li>
-        <a href="#HDF-EOS" >HDF-EOS to netCDF converter</a>
-      </li>
-      <li>
-        <a href="#HIPHOP">HIPHOP (Handy IDL-Program for HDF-Output Plotting)</a>
-      </li>
-      <li>
-        <a href="#Hyperslab OPerator Suite (HOPS)">HOPS (Hyperslab OPerator Suite)</a>
-      </li>
-      <li>
-        <a href="#iCDF" >iCDF (imports chromatographic netCDF data into MATLAB)</a>
-      </li>
-      <li>
-        <a href="#IDV" >IDV (Integrated Data Viewer)</a>
-      </li>
-      <li>
-        <a href="#Ingrid">Ingrid</a>
-      </li>
-      <li>
-        <a href="#IntelArrayVisualizer" >Intel Array Visualizer</a>
-      </li>
-      <li>
-        <a href="#IVE">IVE (Interactive Visualization Environment)</a>
-      </li>
-      <li>
-        <a href="#JSON" >JSON format with the ncdump-json utility</a>
-      </li>
-      <li>
-        <a href="#Java interface">Java interface</a>
-      </li>
-      <li>
-        <a href="#KST">Kst (2D plotting tool)</a>
-      </li>
-      <li>
-        <a href="#Labview-API" >Labview interface</a>
-      </li>
-      <li>
-        <a href="#MBDyn">MBDyn (MultiBody Dynamics)</a>
-      </li>
-      <li>
-        <a href="#Max_diff_nc">Max_diff_nc</a>
-      </li>
-      <li>
-        <a href="#MeteoExplorer" >MeteoExplorer</a>
-      </li>
-      <li>
-        <a href="#MeteoInfo" >MeteoInfo</a>
-      </li>
-      <li>
-        <a href="#MexEPS">MexEPS (MATLAB interface)</a>
-      </li>
-      <li>
-        <a href="#MEXNC">MEXNC and SNCTOOLS (a MATLAB interface)</a>
-      </li>
-      <li>
-        <a href="#Mirone">Mirone (Windows MATLAB-based display)</a>
-      </li>
-      <li>
-        <a href="#ncBrowse">ncBrowse (netCDF File Browser)</a>
-      </li>
-      <li>
-        <a href="#nccmp" >nccmp (netCDF compare)</a>
-      </li>
-      <li>
-        <a href="#ncdx" >ncdx (netCDF for OpenDX)</a>
-      </li>
-      <li>
-        <a href="#ncensemble" >ncensemble (command line utility to do ensemble statistics)</a>
-      </li>
-      <li>
-        <a href="#NCL">NCL (NCAR Command Language)</a>
-      </li>
-      <li>
-        <a href="#NCO">NCO (NetCDF Operators)</a>
-      </li>
-      <li>
-        <a href="#ncregrid" >ncregrid</a>
-      </li>
-      <li>
-        <a href="#nctoolbox" >nctoolbox (a MATLAB common data model interface)</a>
-      </li>
-      <li>
-        <a href="#ncview">ncview</a>
-      </li>
-      <li>
-        <a href="#ncvtk" >ncvtk</a>
-      </li>
-      <li>
-        <a href="#netcdf_tools" >netcdf tools</a>
-      </li>
-      <li>
-        <a href="#netcdf4excel" >netcdf4excel (add-in for MS Excel)</a>
-      </li>
-      <li>
-        <a href="#netcdf95" >NetCDF95 alternative Fortran API</a>
-      </li>
-      <li>
-        <a href="#Objective-C" >Objective-C interface</a>
-      </li>
-      <li>
-        <a href="#NCMEX" >Octave interface</a>
-      </li>
-      <li>
-        <a href="#Octave" >Octave interface (Barth)</a>
-      </li>
-      <li>
-        <a href="#OPeNDAP">OPeNDAP (formerly DODS)</a>
-      </li>
-      <li>
-        <a href="#OpenDX">OpenDX (formerly IBM Data Explorer)</a>
-      </li>
-      <li>
-        <a href="#Panoply" >Panoply</a>
-      </li>
-      <li>
-        <a href="#Parallel-NetCDF" >Parallel-NetCDF</a>
-      </li>
-      <li>
-        <a href="#Paraview" >Paraview and vtkCSCSNetCDF</a>
-      </li>
-      <li>
-        <a href="#Perl" >Perl interfaces</a>
-      </li>
-      <li>
-        <a href="#PolyPaint+">PolyPaint+</a>
-      </li>
-      <li>
-        <a href="#pomegranate" >Pomegranate</a>
-      </li>
-      <li>
-        <a href="#pupynere" >Pupynere (PUre PYthon NEtcdf REader)</a>
-      </li>
-      <li>
-        <a href="#PyNGL" >PyNGL and PyNIO</a>
-      </li>
-      <li>
-        <a href="#Python">Python interfaces</a>
-      </li>
-      <li>
-        <a href="#QGIS" >QGIS (Quantum GIS)</a>
-      </li>
-      <li>
-        <a href="#R">R interface</a>
-      </li>
-      <li>
-        <a href="#Ruby" >Ruby interface</a>
-      </li>
-      <li>
-        <a href="#SDS" >Scientific DataSet (SDS) Library</a>
-      </li>
-      <li>
-        <a href="#SIS">Apache Spatial Information System (SIS)</a>
-      </li>
-      <li>
-        <a href="#Tcl/Tk">Tcl/Tk interfaces</a>
-      </li>
-      <li>
-        <a href="#Tcl-nap" >Tcl-nap (N-dimensional array processor)</a>
-      </li>
-      <li>
-        <a href="#VB" >Visual Basic and VB.net</a>
-      </li>
-      <li>
-        <a href="#VisAD">VisAD</a>
-      </li>
-      <li>
-        <a href="#WCT">Weather and Climate Toolkit (WCT)</a>
-      </li>
-      <li>
-        <a href="#WebWinds">WebWinds</a>
-      </li>
-      <li>
-        <a href="#xray" >xray (Python N-D labelled arrays)</a>
-      </li>
-      <li>
-        <a href="#Zebra">Zebra</a>
-      </li>
-      <li>
-        <a href="#user">User-contributed software</a>
-      </li>
-    </ul>
-    <hr />
-    <h2><a href="#commercial">Commercial or Licensed Packages</a></h2>
-    <ul>
-      <li>
-        <a href="#ArcGIS">ArcGIS Pro - Space Time Pattern Mining Toolbox
-      </li>
-      <li>
-        <a href="#Agrimetsoft"> AgriMetSoft - Netcdf-Extractor
-      </li>
-      <li>
-        <a href="#ViewNcDap" >ASA ViewNcDap</a>
-      </li>
-      <li>
-        <a href="#Avizo" >Avizo</a>
-      </li>
-      <li>
-        <a href="#AVS">AVS</a>
-      </li>
-      <li>
-        <a href="#BCS-UFI" >Barrodale UFI</a>
-      </li>
-      <li>
-        <a href="#DioVISTA/Storm" >DioVISTA/Storm</a>
-      </li>
-      <li>
-        <a href="#EnSight" >EnSight</a>
-      </li>
-      <li>
-        <a href="#Environmental WorkBench">Environmental WorkBench</a>
-      </li>
-      <li>
-        <a href="#ESRI" >ESRI</a>
-      </li>
-      <li>
-        <a href="#FME" >FME</a>
-      </li>
-      <li>
-        <a href="#HDF-Explorer" >HDF Explorer</a>
-      </li>
-      <li>
-        <a href="#IDL">IDL Interface</a>
-      </li>
-      <li>
-        <a href="#InterFormat">InterFormat</a>
-      </li>
-      <li>
-        <a href="#IRIS Explorer Module">IRIS Explorer Module</a>
-      </li>
-      <li>
-        <a href="#LeoNetCDF" >LeoNetCDF</a>
-      </li>
-      <li>
-        <a href="#Mathematica" >Mathematica</a>
-      </li>
-      <li>
-        <a href="#MATLAB">MATLAB</a>
-      </li>
-      <li>
-        <a href="#Noesys">Noesys</a>
-      </li>
-      <li>
-        <a href="#Origin" >Origin</a>
-      </li>
-      <li>
-        <a href="#PPLUS">PPLUS</a>
-      </li>
-      <li>
-        <a href="#PV-Wave">PV-Wave</a>
-      </li>
-      <li>
-        <a href="#SlicerDicer">Slicer Dicer</a>
-      </li>
-      <li>
-        <a href="#Surfer">Surfer</a>
-      </li>
-      <li>
-        <a href="#vGeo" >vGeo</a>
-      </li>
-      <li>
-        <a href="#VISAGE and Decimate">VISAGE and Decimate</a>
-      </li>
-      <li>
-        <a href="#Voyager">Voyager</a>
-      </li>
-    </ul>
-    <hr />
-    <p></p>
-    <h1 id="freely">Freely Available Software</h1>
-
-    <h2><a id="ANDX" name="ANDX">ANDX and ANAX</a></h2>
-
-    <p>
-      The ARM Program has developed
-      <a href="http://engineering.arm.gov/~sbeus/andx-web/html/" >ANDX (ARM
-      NetCDF Data eXtract)</a>,
-      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.
-    </p>
-
-    <p>
-      <a href="http://science.arm.gov/~cflynn/ARM_Tested_Tools/" >ANAX (ARM
-      NetCDF ASCII eXtract)</a> 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.
-    </p>
-
-    <h2><a id="ANTS" name="ANTS">ANTS</a></h2>
-    <p>
-      The ARM Program has developed <a
-      href="http://science.arm.gov/~cflynn/ANTS/" >ANTS (ARM NetCDF Tool
-      Suite)</a>, 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.
-    </p>
-
-    <p>
-      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.
-    </p>
-
-    <p>
-      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 <a href="http://science.arm.gov/~cflynn/ANTS/"
-      >website</a> for more information.
-    </p>
-
-    <h2><a id="ARGOS" name="ARGOS">ARGOS</a></h2>
-    <p>
-      <a href="http://www.lapeth.ethz.ch/argos/index.html">ARGOS</a> (interActive thRee-dimensional
-      Graphics ObServatory) is a new IDL-based interactive 3D visualization
-      tool, developed by <a
-      href="http://www.lapeth.ethz.ch/~david/index.html">David N. Bresch</a> and <a href="http://www.lapeth.ethz.ch/~mark/index.html">Mark
-      A. Liniger</a> at the Institute for Atmospheric Science at the Swiss Federal Institute
-      of Technology, ETH, Zürich.
-    </p>
-
-    <p>
-      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
-      <a
-      href="http://www.lapeth.ethz.ch/argos/argos_general.html">html-help</a>. 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.
-    </p>
-    <p>
-      Information about <a
-      href="http://www.lapeth.ethz.ch/argos/argos_copyright.html">copyright and licensing
-      conditions</a> are available. For further information and installation, please
-      E-mail to: bresch at atmos.umnw.ethz.ch
-    </p>
-    <p></p>
-    <h2><a id="CDAT" name="CDAT">CDAT</a></h2>
-    The <a href="http://cdat.sf.net">Climate Data Analysis Tool
-    (CDAT)</a>, developed by the <a
-    href="http://www-pcmdi.llnl.gov/">Program for Climate Model Diagnosis
-    and Intercomparison (PCMDI)</a> at Lawrence Livermore National Laboratory, provides
-    the capabilities needed to analyze model data, perform complex mathematical calculations,
-    and graphically display the results. It provides the necessary tools to diagnose,
-    validate, and intercompare large observational and global climate model data sets.
-    <p>
-      It includes the ability to ingest
-      large climate datasets in netCDF, HDF, DRS, and GrADS/GRIB format;
-      the Visualization and Computation System (VCS) module, visually displays and
-      animates ingested or created data; and the Library of AMIP Data Transmission
-      Standards (LATS) module outputs data in the machine-independent netCDF or GrADS/GRIB
-      file formats.
-    </p>
-    <p>
-      In addition, the Command Line Interface (CLI) module allows
-      CDAT to receive argument and function input via the command line, and the Graphical
-      User Interface (GUI) allows CDAT to receive argument and function input via
-      a point-and-click environment.
-    </p>
-    <p>
-      The software, which runs as a standalone process or within PCMDI's
-      Visualization and Computation System (VCS), provides climate scientists with
-      an easy and fast method to read different file formats, and to analyze and
-      graphically display climate data in an integrated fashion. CDAT includes a
-      set of pre-defined functions to allow the user to manipulate the data and
-      send the output to a file which can be viewed as an image, or as a collection
-      of images in an animation. The software has a gradual learning curve, allowing
-      the novice user to quickly obtain useful results.
-    </p>
-    <p></p>
-    <h2><a id="CDFconvert" name="CDFconvert">CDFconvert</a></h2>
-    <p>
-      The <a href="http://www.atmos.albany.edu/facstaff/rmctc/cdf_cvt/" >MRG
-      CDFconvert package</a> provided by the Mesoscale Research Group,
-      McGill University/SUNY Albany, is designed to address data conversion
-      issues for gridded datasets stored under the <a
-      href="http://ferret.wrc.noaa.gov/noaa_coop/coop_cdf_profile.html">COARDS</a>
-      convention. CDFconvert converts regular Cylindrical Equidistant
-      (Lat/Long) and Gaussian (Spherical) netCDF grids into either the
-      Canadian <a
-      href="http://www.cmc.ec.gc.ca/rpn/modcom/si/libraries/rmnlib/fstd/index.html"
-      >RPN Standard File</a> or <a href="/software/gempak/index.html"
-      >GEMPAK</a> file formats. MRG CDFconvert has the flexibility to handle
-      netCDF files generated by a number of sources, including NCEP and
-      ECMWF. User-definable conversion tables make the extension of the
-      package to different datasets possible.
-    </p>
-
-    <p></p>
-    <h2><a id="cdfsync" name="cdfsync">cdfsync</a></h2>
-    <p>
-      Joe Sirott of NOAA's Pacific Marine Environmental Laboratory has
-      developed cdfsync, a program that allows users to rapidly synchronize a
-      set of netCDF files over a network. Fast synchronization times are
-      achieved by only transmitting the differences between files. It is
-      built on the Open Source <a href="http://samba.anu.edu.au/rsync/" >rsync</a>
-      program, but contains a number of optimizations including:
-      <ul>
-        <li>
-          Special handling of netCDF files for faster synchronization
-          calculations
-        </li>
-        <li>
-          Much faster updates of large numbers of small netCDF files
-        </li>
-        <li>
-          In-place updates of large netCDF files
-        </li>
-      </ul>
-    <p>
-      The latest version should run on Linux variants and Solaris.
-    </p>
-    More information is available at the <a
-    href="http://www.epic.noaa.gov/epic/software/cdfsync/">cdfsync website</a>.
-    </p>
-    <p></p>
-    <h2><a id="CDO" name="CDO">CDO (Climate Data Operators)</a></h2>
-    <p>
-      Uwe Schulzweida at the Max Planck Institute for Meteorology has developed
-      <a href="http://code.zmaw.de/projects/cdo" >CDO</a>, a collection of
-      Operators to manipulate and analyze
-      Climate Data files. Supported file formats include netCDF and GRIB.
-      There are more than 350 operators available. The following
-      table provides a brief overview of the main categories.
-    </p>
-    <ul>
-      <li>
-        File information (info, sinfo, diff, ...)
-      </li>
-      <li>
-        File operations (copy, cat, merge, split*, ...)
-      </li>
-      <li>
-        Selection (selcode, selvar, sellevel, seltimestep, ...)
-      </li>
-      <li>
-        Missing values (setctomiss, setmisstoc, setrtomiss)
-      </li>
-      <li>
-        Arithmetic (add, sub, mul, div, ...)
-      </li>
-      <li>
-        Mathematical functions (sqrt, exp, log, sin, cos, ...)
-      </li>
-      <li>
-        Comparision (eq, ne, le, lt, ge, gt, ...)
-      </li>
-      <li>
-        Conditions (ifthen, ifnotthen, ifthenc, ifnotthenc)
-      </li>
-      <li>
-        Field statistics (fldsum, fldavg, fldstd, fldmin, fldmax, ...)
-      </li>
-      <li>
-        Vertical statistics (vertsum, vertavg, vertstd, vertmin, ...)
-      </li>
-      <li>
-        Time range statistics (timavg, yearavg, monavg, dayavg, ...)
-      </li>
-      <li>
-        Field interpolation (remapbil, remapcon, remapdis, ...)
-      </li>
-      <li>
-        Vertical interpolation (ml2pl, ml2hl)
-      </li>
-      <li>
-        Time interpolation (inttime, intyear)
-      </li>
-    </ul>
-    <p>
-      As an example of use of CDO, converting
-      from GRIB to netCDF can be as simple as
-      <pre>
-    cdo -f nc copy file.grb file.nc
-</pre>
-or with relative time axis (for usage with GrADS)
-       <pre>
-    cdo -r -f nc copy file.grb file.nc
-</pre>
-or using ECMWF reanalysis on a reduced grid
-       <pre>
-    cdo -R -f nc copy file.grb file.nc
-</pre>
-    </p>
-    <p>
-      More information is available on the <a
-      href="http://code.zmaw.de/projects/cdo" >CDO homepage</a>.
-    </p>
-    <p></p>
-    <h2><a id="CIDS Tools" name="CIDS Tools">CIDS Tools</a></h2>
-    The Center for Clouds Chemistry and Climate (<a
-    href="http://www-c4.ucsd.edu/">C4</a>) Integrated Data Systems (<a
-    href="http://www-c4.ucsd.edu/~cids/">CIDS</a>) group has developed several useful
-    netCDF utilities:
-    <ul>
-      <li>
-        cdf2idl: Writes an IDL script to read a NetCDF file.
-      </li>
-      <li>
-        cdf2c: Writes C code to read a NetCDF file.
-      </li>
-      <li>
-        cdf2fortran: Writes FORTRAN source code to read a NetCDF file.
-      </li>
-      <li>
-        cdf2asc: Dumps NetCDF data to an ASCII file.
-      </li>
-    </ul>
-    The source for these utilities can be downloaded from <a
-    href="http://www-c4.ucsd.edu/~cids/software/visual.html">CIDS NetCDF Visualization
-    Tools site</a>. <p></p>
-    <h2><a id="CSIRO-MATLAB" name="CSIRO-MATLAB">CSIRO MATLAB/netCDF interface</a></h2>
-    The <a
-    href="http://www.marine.csiro.au/sw/matlab-netcdf.html">CSIRO MATLAB/netCDF interface</a>
-    is now available from the <a
-    href="http://www.marine.csiro.au">CSIRO Marine Laboratories</a>.
-    <p>
-      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 retrieving data from,
-      and information about, existing netCDF files.
-    </p>
-    <p>
-      The basis of the interface is a machine-dependent mex-file called
-      mexcdf53. Rather than call the mex-file
-      directly users are advised to employ both <a href="#NC4ML5">Chuck Denham's
-      netCDF toolbox</a> and the CSIRO MATLAB/netCDF interface described here. For
-      read-only access to existing netCDF data, the CSIRO interface has a simpler
-      syntax than the netCDF Toolbox, but the latter may also be used to create and
-      manipulate netCDF variables and datasets.
-    </p>
-    <p></p>
-    <h2><a id="EPIC" name="EPIC">EPIC</a></h2>
-    NOAA's Pacific Marine Environmental Laboratory (<a
-    href="http://www.pmel.noaa.gov/">PMEL</a>) has developed the <a
-    href="http://www.pmel.noaa.gov/epic/">EPIC</a> software package for oceanographic
-    data. EPIC provides graphical display and data field manipulation for multi-dimensional
-    netCDF files (up to 4 dimensions). PMEL has been using this software on Unix and
-    VMS several years. At present, they have:
-    <p></p>
-    <ul>
-      <li>
-        a data file I/O library ( <a
-        href="http://www.pmel.noaa.gov/epic/eps-manual/epslib_toc.html">epslib</a>, which
-        is layered on top of the netCDF library).
-      </li>
-      <li>
-        epslib allows transparent access to multiple data file formats
-      </li>
-      <li>
-        a <a href="http://www.epic.noaa.gov/epic/software/mexeps.htm">MATLAB MexEPS
-        interface</a> for using any supported EPIC file with MATLAB
-      </li>
-      <li>
-        <a
-        href="http://www.epic.noaa.gov/epic/software/ep_programs.htm">suite of EPIC programs</a>
-        for graphics and analysis of hydrographic profile data and time series data.
-      </li>
-    </ul>
-    This software was developed on Sun/Unix and is also supported for DEC/Ultrix and
-    VAX/VMS as a system for data management, display and analysis system for observational
-    oceanographic time series and hydrographic data. The EPIC software includes over
-    50 programs for oceanographic display and analysis, as well as utilities for putting
-    in-situ or observational data on-line (with on-the-fly graphics and data download)
-    on the WWW.
-    <p>
-      The developers are interested in coordinating with others who may be developing
-      oceanographic software for use with netCDF files. The EPIC software is available
-      via anonymous FTP from ftp.noaapmel.gov in the epic/ and /eps directories. To
-      obtain the EPIC software, please see Web pages at <a
-      href="http://www.pmel.noaa.gov/epic/download/index.html">http://www.pmel.noaa.gov/epic/download/index.html</a>.
-      For information about EPIC, please see the Web pages at <a
-      href="http://www.pmel.noaa.gov/epic/index.html">http://www.pmel.noaa.gov/epic/index.html</a>.
-      Contact epic at pmel.noaa.gov, or Nancy Soreide, nns at noaapmel.gov, for more information.
-    </p>
-    <p></p>
-
-    <h2><a id="ExcelUse" name="ExcelUse">Excel Use</a></h2>
-
-    <p>
-      Several packages are available for accessing netCDF data from
-      Microsoft Excel,
-      including the <a href="#netcdf4excel" >netcdf4excel</a> add-in for Excel, and a <a
-      href="#SDS" >Scientific Dataset (SDS) Library</a> that supports a
-      DataSetEditor add-in for Excel to view and modify various
-      forms of data, including netCDF.
-    </p>
-    <p></p>
-    <h2><a id="EzGet" name="EzGet">EzGet</a></h2>
-    A FORTRAN library called <a
-    href="http://www-pcmdi.llnl.gov/ktaylor/ezget/ezget.html">EzGet</a> has been developed
-    at <a
-    href="http://www-pcmdi.llnl.gov/PCMDI.html">PCMDI</a> to facilitate retrieval
-    of modeled and observed climate data stored in popular formats including <a
-    href="http://www-pcmdi.llnl.gov/drach/DRS.html">DRS</a>, <a
-    href="/software/netcdf/">netCDF</a>, <a
-    href="http://grads.iges.org/grads">GrADS</a>, and, if a control file is supplied, <a
-    href="ftp://nic.fb4.noaa.gov/pub/nws/nmc/docs/gribed1/">GRIB</a>. You can specify
-    how the data should be structured and whether it should undergo a grid transformation
-    before you receive it, even when you know little about the original structure
-    of the stored data (e.g., its original dimension order, grid, and domain).
-    <p>
-      The EzGet library comprises a set of subroutines that can be linked to any
-      FORTRAN program. EzGet reads files through the <a
-      href="http://www-pcmdi.llnl.gov/drach/cdunif.html">cdunif</a> interface, but use
-      of EzGet does not require familiarity with cdunif. The main advantages of using
-      EzGet instead of the lower level cdunif library include:
-    </p>
-    <ul>
-      <li>
-        Substantial error trapping capabilities and detailed error messages
-      </li>
-      <li>
-        Versatile capability of conveniently selecting data from specified regions
-        (e.g., oceans, North America, all land areas north of 45 degrees latitude,
-        etc.)
-      </li>
-      <li>
-        Ability to map data to a new grid at the time it is retrieved by EzGet
-      </li>
-      <li>
-        Automatic creation of ``weights'' for use in subsequent averaging
-        or masking of data
-      </li>
-      <li>
-        Increased control in specifying the domain of the data to be retrieved.
-      </li>
-    </ul>
-    <p>
-      For more information about EzGet, including instructions for downloading the
-      documentation or software, see the EzGet home page at <a
-      href="http://www-pcmdi.llnl.gov/ktaylor/ezget/ezget.html">http://www-pcmdi.llnl.gov/ktaylor/ezget/ezget.html</a>.
-      For questions or comments on EzGet, contact Karl Taylor (taylor13 at llnl.gov).
-    </p>
-    <h2><a id="FAN" name="FAN">FAN</a></h2>
-    <a href="/software/netcdf/fan_utils.html">FAN (File Array Notation)</a>
-    is Harvey Davies' package for extracting and manipulating array data from
-    netCDF files. The package includes the three utilities nc2text, text2nc, and ncrob
-    for printing selected data from netCDF arrays, copying ASCII data into netCDF
-    arrays, and performing various operations (sum, mean, max, min, product, ...)
-    on netCDF arrays. A library (fanlib) is also included that supports the use of
-    FAN from C programs. The package is available via anonymous FTP from <a
-    href="ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/fan.tar.Z">ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/fan.tar.Z</a>.
-    Questions and comments may be sent to Harvey Davies, harvey.davies at csiro.au.
-    <p></p>
-    <h2><a id="FERRET" name="FERRET">FERRET</a></h2>
-    <a href="http://ferret.wrc.noaa.gov/Ferret/">FERRET</a> is an interactive computer
-    visualization and analysis environment designed to meet the needs of oceanographers
-    and meteorologists analyzing large and complex gridded data sets. It is available
-    by anonymous ftp from abyss.pmel.noaa.gov for a number of computer systems: SUN
-    (Solaris and SUNOS), DECstation (Ultrix and OSF/1), SGI, VAX/VMS and Macintosh
-    (limited support), and IBM RS-6000 (soon to be released).
-    <p>
-      FERRET offers a Mathematica-like approach to analysis; new variables may be
-      defined interactively as mathematical expressions involving data set variables.
-      Calculations may be applied over arbitrarily shaped regions. Fully documented
-      graphics are produced with a single command. Graphics styles included line plots,
-      scatter plots, contour plots, color-filled contour plots, vector plots, wire
-      frame plots, etc. Detailed controls over plot characteristics, page layout and
-      overlays are provided. NetCDF is supported both as an input and an output format.
-    </p>
-    <p>
-      Many excellent software packages have been developed recently for scientific
-      visualization. The features that make FERRET distinctive among these packages
-      are Mathematica-like flexibility, geophysical formatting (latitude/longitude/date),
-      "intelligent" connection to its data base, special memory management
-      for very large calculations, and symmetrical processing in 4 dimensions. Contact
-      Steve Hankin, hankin at noaapmel.gov, for more information.
-    </p>
-    <p></p>
-
-    <h2><a id="fimex" name="fimex" >Fimex</a></h2>
-    <p>
-      Heiko Klein (Norwegian Meteorological Institute) has developed
-      the <a href="https://wiki.met.no/fimex/start" >fimex</a> (File
-      Interpolation, Manipulation, and EXtraction) C++ library
-      for gridded geospatial data.  It converts between several
-      data formats (currently netCDF, NcML, GRIB1 or GRIB2, and felt). Fimex
-      also enables you
-      to change the projection and interpolation of scalar and vector grids,
-      to subset the gridded data, and to extract only parts
-      of the files.  Fimex supports a growing list of other <a
-      href="https://wiki.met.no/fimex/features" >features</a>, including
-      support for most NcML features and for netCDF-4 compression.
-    </p>
-    <p>
-      For simple usage, Fimex also comes with the command line program fimex.
-    </p>
-    <p>
-      Documentation and downloads are available
-      from the <a href="http://wiki.met.no/fimex/" >fimex web site</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="fwtools" name="fwtools">FWTools (GIS Binary Kit for Windows and Linux)</a></h2>
-
-    <p>
-      <a href="http://fwtools.maptools.org/" >FWTools</a> is Frank Warmerdam's set of Open Source GIS
-      binaries for Windows (win32) and Linux (x86 32bit) systems.
-      The kits are intended to be easy for end users to install and get going with, and include OpenEV,
-      GDAL, MapServer, PROJ.4 and OGDI as well as some supporting components.
-      FWTools aims to track the latest development versions of the packages included as opposed to
-      official releases, "to give folks a chance to use the <em>latest and greatest</em>".
-    </p>
-
-    <h2><a id="GDAL" name="GDAL">GDAL</a></h2>
-
-    <p>
-      Frank Warmerdam's <a
-      href="http://www.remotesensing.org/gdal/index.html" >GDAL</a> is a
-      translator library for raster geospatial data formats that is released
-      under an X/MIT style Open Source license.  As a library, it presents a
-      <a href="http://www.remotesensing.org/gdal/gdal_datamodel.html"> single abstract data model</a> to the calling application for all
-      supported formats. The related <a
-      href="http://www.remotesensing.org/gdal/ogr">OGR</a> library (which
-      lives within the GDAL source tree) provides a similar capability for
-      simple features vector data.
-    </p>
-
-    <p>
-      GDAL is in active use in several projects, and includes roughly 40
-      format drivers, including a translator for netCDF (read/write).  Other
-      translators include GeoTIFF (read/write), Erdas Imagine (read/write),
-      ESRI .BIL (read), .aux labeled raw (read/write), DTED (read), SDTS
-      DEM (read), CEOS (read), JPEG (read/write), PNG (read/write), Geosoft
-      GXF (read) and Arc/Info Binary Grid (read). A full list is available
-      in <a
-      href="http://www.remotesensing.org/gdal/formats_list.html">Supported
-      Formats</a>.
-    </p>
-
-    <p>
-      GDAL has recently included support for the netCDF-4 enhanced data
-      model and netCDF-4 format, as well as improved support for recent
-      additions to the CF conventions.
-    </p>
-
-    <p>
-      As an example of the use of GDAL, converting an ArcInfo ASCII grid
-      to netCDF (GMT conventions) as easy as:
-      <pre>
-   gdal_translate arc_ascii.grd -of GMT gmt_grid.nc
-</pre>
-    </p>
-
-    <p></p>
-    <h2><a id="GDL" name="GDL">GDL (GNU Data Language)</a></h2>
-    <p>
-      <a href="http://gnudatalanguage.sourceforge.net/" >GDL</a> is a free
-      implementation of most of the programming language supported by <a href="#IDL" >IDL</a>
-      (Interactive Data Language).  GDL supports the netCDF-3 API.
-    </p>
-
-    <p></p>
-
-    <h2><a id="Gfdnavi" name="Gfdnavi">Gfdnavi (Geophysical fluid data navigator)</a></h2>
-
-    <p>
-      <a
-      href="http://www.gfd-dennou.org/arch/davis/gfdnavi/index.en.htm"
-      >Gfdnavi</a> is a web-based tool to archive, share, distribute, analyze, and
-      visualize geophysical fluid data and knowledge.
-      The software is under development by members of the GFD Dennou Club,
-      including T. Horinouchi (RISH, Kyoto U.), S. Nishizawa (RIMS, Kyoto
-      U.), and colleagues.  Gfdnavi uses a metadata
-      database for managing and analyzing data and visualizations.  It also
-      permits publishing data for web access and will soon support access to
-      data on other Gfdnavi servers.  Web service APIs are now under
-      development.  A presentation <a
-      href="http://www.gfd-dennou.org/arch/davis/gfdnavi/presen/2007-03-05_GfdnaviIntro.En/pub/"
-      >Introducing Gfdnavi</a> describes the architecture and shows examples
-      of use.
-    </p>
-    <p>
-      Gfdnavi is dependent on two technologies:
-      <ul>
-        <li>
-          <a href="http://www.rubyonrails.com/" >Ruby on Rails</a>, a
-          framework for web applications, and
-        </li>
-        <li>
-          <a href="http://ruby.gfd-dennou.org/" >the Dennou Ruby
-          Project</a>,
-          a collection of tools for geophysical
-          data.   These tools include <a
-          href="http://ruby.gfd-dennou.org/products/gphys/" >GPhys</a>
-          software to handle GRIB, GrADS, and netCDF data uniformly.
-        </li>
-      </ul>
-    </p>
-    <p>
-      As an example of this technology, Takuji Kubota has established <a
-      href="http://www.gsmap.aero.osakafu-u.ac.jp/gfdnavi/" >a Gfdnavi server</a> for the
-      Global Satellite Mapping of Precipitation (<a href="http://www.radar.aero.osakafu-u.ac.jp/~gsmap/index_english.html" >GSMaP</a>) project.
-    </p>
-    <p></p>
-
-    <h2><a id="GMT" name="GMT">GMT</a></h2>
-    <p>
-      <a href="http://gmt.soest.hawaii.edu/">GMT</a> (Generic Mapping Tools) is
-      an open source collection of about 60 tools for manipulating
-      geographic and Cartesian data sets (including filtering, trend
-      fitting, gridding, projecting, etc.) and producing Encapsulated
-      PostScript File (EPS) illustrations ranging from simple x-y plots via
-      contour maps to artificially illuminated surfaces and 3-D perspective
-      views. GMT supports 30 map projections and transformations and comes
-      with support data such as coastlines, rivers, and political
-      boundaries. GMT is developed and maintained by Paul Wessel and Walter
-      H. F. Smith with help from a global set of volunteers, and is
-      supported by the National Science Foundation. It is released under
-      the GNU General Public License.
-    </p>
-    <p>
-      The package can access COARDS-compliant netCDF grids as well as ASCII,
-      native binary, or user-defined formats.  The GMT package is available
-      via anonymous ftp from several servers; see <a
-      href="http://gmt.soest.hawaii.edu" >gmt.soest.hawaii.edu</a>
-      for installation information.
-    </p>
-    <p></p>
-    <h2><a id="Grace" name="Grace">Grace</a></h2>
-    <a href="http://plasma-gate.weizmann.ac.il/Grace/">Grace</a> is a tool to make
-    two-dimensional plots of scientific data, including 1D netCDF
-    variables.
-    It runs under the X Window System and
-    OSF Motif (recent versions of LessTif are, by and large, fine, too). Grace runs
-    on practically any version of Unix. As well, it has been successfully ported to
-    VMS, OS/2 and Win9*/NT (some functionality may be missing, though). Grace is a
-    descendant of ACE/gr.
-    <p>
-      A few features of Grace are:
-    </p>
-    <ul>
-      <li>
-        User defined scaling, tick marks, labels, symbols, line styles, colors.
-      </li>
-      <li>
-        Batch mode for unattended plotting.
-      </li>
-      <li>
-        Read and write parameters used during a session.
-      </li>
-      <li>
-        Regressions, splines, running averages, DFT/FFT, cross/auto-correlation,
-        ...
-      </li>
-      <li>
-        Support for dynamic module loading.
-      </li>
-      <li>
-        Hardcopy support for PostScript, PDF, GIF, and PNM formats.
-      </li>
-      <li>
-        Device-independent Type1 font rastering.
-      </li>
-      <li>
-        Ability to read or write netCDF data.
-      </li>
-    </ul>
-    <p></p>
-    <h2><a id="GrADS" name="GrADS">GrADS</a></h2>
-    <a href="http://grads.iges.org/grads/grads.html">GrADS</a> (Grid
-    Analysis and Display System)
-    is an interactive desktop tool from <a
-    href="http://grads.iges.org/cola.html">COLA/IGES</a> that is currently in use
-    worldwide for the analysis and display of earth science data. GrADS is implemented
-    on all commonly available UNIX workstations, Apple Macintosh, and DOS or Linux
-    based PCs, and is freely available via anonymous ftp. GrADS provides an integrated
-    environment for access, manipulation, and display of earth science
-    data in several forms, including GRIB and netCDF.
-    For more information, see the <a
-    href="http://grads.iges.org/grads/gadoc/users.html" >GrADS User's
-    Guide</a>. <p></p>
-    <h2><a id="Gri" name="Gri">Gri</a></h2>
-    Gri is an extensible plotting language for producing scientific graphs, such as
-    x-y plots, contour plots, and image plots. Dan Kelley of Dalhousie University
-    is the author of Gri, which can read data from netCDF files as well as ASCII and
-    native binary data. For more information on Gri, see the URL <a
-    href="http://gri.sourceforge.net/">http://gri.sourceforge.net/</a>. <p></p>
-    <h2><a id="GXSM" name="GXSM">GXSM</a></h2> The GXSM is the Gnome X
-    Scanning Microscopy project, it is a bit more than just a piece of
-    software (the GXSM itself), there is full hardware support for DSP
-    cards including open source DSP software and a growing set of SPM
-    related electronics. For more information, see <a
-    href="http://gxsm.sourceforge.net/">http://gxsm.sourceforge.net/</a>. <p></p>
-    <h2><a id="HDF interface" name="HDF interface">HDF interface</a></h2>
-    The National Center for Supercomputing Applications (NCSA) has added the netCDF
-    interface to their <a
-    href="http://hdf.ncsa.uiuc.edu/">Hierarchical Data Format (HDF)</a> software.
-    HDF is an extensible data format for self-describing files. A substantial set
-    of applications and utilities based on HDF is available; these support raster-image
-    manipulation and display and browsing through multidimensional scientific data.
-    An implementation is now available that provides the netCDF interface to HDF.
-    With this software, it is possible to use the netCDF calling interface to place
-    data into an HDF file. The netCDF calling interface has not changed and netCDF
-    files stored in XDR format are readable, so existing programs and data will still
-    be usable (although programs will need to be relinked to the new library). There
-    is currently no support for the mixing of HDF and netCDF structures. For example,
-    a raster image can exist in the same file as a netCDF object, but you have to
-    use the Raster Image interface to read the image and the netCDF interface to read
-    the netCDF object. The other HDF interfaces are currently being modified to allow
-    multi-file access, closer integration with the netCDF interface will probably
-    be delayed until the end of that project.
-    <p>
-      Eventually, it will be possible to integrate netCDF objects with the rest of
-      the HDF tool suite. Such an integration will then allow tools written for netCDF
-      and tools written for HDF to both interact intelligently with the new data files.
-    </p>
-    <p></p>
-    <h2><a id="HDF-EOS" name="HDF-EOS">HDF-EOS to netCDF converter</a></h2>
-    <p>
-      The
-      Goddard Earth Sciences Data and Information Services Center (<a
-      href="http://disc.gsfc.nasa.gov" >GES DISC</a>)
-      has developed an on-the-fly HDF-EOS to netCDF/CF converter
-      for the following products, making them easier to use in the <a
-      href="#IDV" >Unidata IDV</a> and <a
-      href="http://www.ssec.wisc.edu/mcidas/software/v/" >McIDAS-V</a>:
-      <ul>
-        <li>
-          AIRS Level 2 (scene) profiles of moisture, air temperature and
-          trace gases
-        </li>
-        <li>
-          AIRS Level 3 (global grid) profiles of moisture, air temperature and trace gases
-        </li>
-        <li>
-          OMI UV-B at the surface
-        </li>
-        <li>
-          TOMS ozone and aerosols
-        </li>
-      </ul>
-    <p>
-      <a href="http://disc.gsfc.nasa.gov/services/NetCDFConversionforIDVandMcIDAS-V.shtml" >Instructions</a> are available for searching and converting these data.
-      More information on AIRS products is available at
-      <a href="http://disc.gsfc.nasa.gov/AIRS/index.html"
-      >http://disc.gsfc.nasa.gov/AIRS/index.html</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="HIPHOP" name="HIPHOP">HIPHOP</a></h2>
-    <a
-    href="http://www.knmi.nl/onderzk/atmosam/English/Service/hiphop/hiphop.html">HIPHOP</a>,
-    developed
-    by Dominik Brunner, is a widget based IDL application that largely facilitates
-    the visualization and analysis of 2D, 3D, and 4D atmospheric science data, in
-    particular atmospheric tracer distributions and meteorological fields.
-    <p>
-      Graphical output of (atmospheric model) data can be quickly generated in a
-      large number of different ways, including horizontal maps at selected model
-      or pressure levels, vertical north-south, east-west, or slant cross-sections
-      (including zonal averages), time slices, animations, etc. It also allows mathematical
-      operations on the existing fields to generate new fields for further analysis,
-      and it can be run as a batch application.
-    </p>
-    <p>
-      The program handles data in netCDF, HDF and GRIB format. Interfaces to other
-      data formats (e.g. ASCII and binary data) can be added easily.
-    </p>
-    <p>
-      Beginning with Version 4.0, it also supports the ability to overlay meteorological
-      fields on a number of different satellite images, and to draw air parcel trajectories.
-    </p>
-    <p></p>
-    <h2><a id="Hyperslab OPerator Suite (HOPS)"
-    name="Hyperslab OPerator Suite (HOPS)">Hyperslab OPerator Suite (HOPS)</a></h2>
-    Hyperslab OPerator Suite (<a
-    href="http://www.cgd.ucar.edu/gds/svn/hyperslab.html">HOPS</a>), developed by
-    R. Saravanan at NCAR, is a bilingual, multi-platform software package for processing
-    data in netCDF files conforming to the NCAR-CCM format or the NCAR Ocean Model
-    format. HOPS is implemented in <a href="#IDL">IDL</a>, the widely-used commercial
-    interpreted language, and also in <a
-    href="ftp://ftp-icf.llnl.gov/pub/Yorick/">Yorick</a>, a public-domain interpreted
-    language that is freely available from the Lawrence Livermore National Laboratory.
-    The IDL version of HOPS should run on any platform supported by IDL. The Yorick
-    version too runs on most common UNIX platforms, such as Sun, SGI, Cray, and LINUX
-    computers.
-    <p>
-      HOPS is not a monolithic program, but a suite of operators that act on data
-      units called "hyperslabs". The design of HOPS is object-oriented,
-      rather than procedure-oriented; the operators treat the numeric data and the
-      associated meta-data (like coordinate information) as a single object.
-    </p>
-    <p>
-      Note that HOPS is not a general purpose netCDF utility and works only for the
-      NCAR CSM netCDF formats. For more information, check the <a href="http://www.cgd.ucar.edu/gds/svn/hyperslab.html">HOPS
-      home page</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="iCDF" name="iCDF">iCDF (imports chromatographic netCDF data into MATLAB)</a></h2>
-    <p>
-      Klavs M. Sørensen, Thomas Skov and Rasmus Bro (Faculty of Life
-      Sciences, University of Copenhagen) have developed <a
-      href="http://www.models.life.ku.dk/source/iCDF/index.asp" >iCDF</a>, a
-      free and documented toolbox for importing chromatographic data in the
-      netCDF-based format that most manufacturers of chromatographic
-      software support.
-    </p>
-    <p>
-      The iCDF software is currently for XC-MS data (X: GC, LC, HPLC), but
-      soon it will be able to import data using other detectors as well.  It
-      can be used to open netCDF files from many different instruments
-      (e.g. Agilent, Bruker) and many chromatographic software packages
-      (e.g. ChemStation).
-    </p>
-    <p>
-      For more information, see the paper
-      <blockquote>
-        Skov T and Bro R. (2008) Solving fundamental problems in chromatographic analysis
-        Analytical and Bioanalytical Chemistry, 390 (1): 281-285.
-      </blockquote>
-    </p>
-    <p></p>
-
-    <h2><a id="IDV" name="IDV">IDV (Integrated Data Viewer)</a></h2>
-    <p>
-      Unidata's <a href="/software/idv/"
-      >Integrated Data Viewer (IDV)</a> is a Java application (for Java 1.4
-      or later)
-      that can be used to display a variety of netCDF files, particularly
-      well formatted, geolocated datasets.   Features include:
-      <ul>
-        <li>
-          Access to local and remote netCDF files and a variety of <a
-          href="/software/idv/docs/userguide/data/DataSources.html" >other
-          data formats</a>
-        </li>
-        <li>
-          Slicing and probing of multidimensional data
-        </li>
-        <li>
-          Support for netCDF conventions (CF, COARDS, NUWG, AWIPS)
-        </li>
-        <li>
-          InstallAnywhere installers for easy download and installation
-        </li>
-        <li>
-          Save display state to a bundle for easy recreation of views
-        </li>
-        <li>
-          Support for non-gridded data through the <a
-          href="/software/netcdf-java/CDM/" >Common Data Model (CDM)</a>
-        </li>
-      </ul>
-      The IDV uses the <a href="http://www.ssec.wisc.edu/~billh/visad.html"
-      >VisAD Java library</a> for interactive and collaborative
-      visualization and analysis
-      and the <a href="/software/netcdf-java/" >netCDF Java library</a> for reading and manipulating
-      netCDF files.
-    </p>
-    <p></p>
-
-    <h2><a id="Ingrid" name="Ingrid">Ingrid</a></h2>
-    <p>
-      <a href="http://ingrid.ldgo.columbia.edu/">Ingrid</a>, by M. Benno Blumenthal
-      <benno at ldeo.columbia.edu>, is designed to manipulate large datasets and
-      model input/output. It can read
-      data from its data catalog, a netCDF file, or a directly attached model, and output
-      the data, either by feeding it to a model, creating a netCDF file, or creating
-      plots and other representations of the data.
-    </p>
-    <p>
-      Ingrid has a number of filters which allow simple data manipulations, such
-      as adding two datasets together, smoothing, averaging, and regridding to a new
-      coordinate.  In addition to netCDF, it also reads HDF, CDF, VOGL,
-      and SGI GL.
-    </p>
-    <p>
-      Ingrid is currently running as a WWW daemon that can be accessed through <a
-      href="http://rainbow.ldgo.columbia.edu/datacatalog.html">http://rainbow.ldgo.columbia.edu/datacatalog.html</a>
-      to see some of its capabilities on a climate data catalog maintained by the
-      <a
-      href="http://rainbow.ldeo.columbia.edu/">Climate Group</a> of the <a href="http://www.ldeo.columbia.edu/">Lamont-Doherty
-      Earth Observatory</a> of Columbia University. To quote the introduction:
-    </p>
-    <blockquote>
-      The Data Catalog is both a catalog and a library of datasets, i.e.
-      it both helps you figure out which data you want, and helps you work with the
-      data. The interface allows you to make plots, tables, and files from any dataset,
-      its subsets, or processed versions thereof.
-      <p>
-        This data server is designed to make data accessible to people using WWW
-        clients (viewers) and to serve as a data resource for WWW documents. Since
-        most documents cannot use raw data, the server is able to deliver the data
-        in a variety of ways: as data files (netCDF and HDF), as tables (html), and
-        in a variety of plots (line, contour, color, vector) and plot formats (PostScript
-        and gif). Processing of the data, particularly averaging, can be requested
-        as well.
-      </p>
-      <p>
-        The Data Viewer in particular demonstrates the power of the Ingrid daemon.
-      </p>
-    </blockquote>
-    <p>
-      Ingrid currently runs on Linux, for which binaries are available.
-      CVS access to the current source can be arranged.
-    </p>
-    <p></p>
-
-    <h2><a id="IntelArrayVisualizer" name="IntelArrayVisualizer"> Intel Array Visualizer</a></h2>
-
-    <p>
-      The <a
-      href="http://www.intel.com/cd/software/products/asmo-na/eng/compilers/226277.htm"
-      >Intel® Array Visualizer</a> and Intel® Array Viewer are available as <a
-      href="http://www.intel.com/cd/software/products/asmo-na/eng/compilers/226277.htm"
-      >free downloads</a> for
-      Windows platforms.  They offer an application and a set
-      of software tools and components, which include C, Fortran, and .Net libraries, for
-      developing scientific visualization applications and for creating interactive graphs of
-      array data in various formats, including HDF and netCDF.
-    </p>
-
-    <p></p>
-    <h2><a id="IVE" name="IVE">IVE</a></h2>
-    <p>
-      <a href="http://www.atmos.washington.edu/ive/">IVE (Interactive Visualization
-      Environment)</a> is a software package designed to interactively display and analyze
-      gridded data. IVE assumes the data to be displayed are contained in one- two-,
-      three- or four-dimensional arrays. By default, the numbers within these arrays
-      are assumed to represent grid point values of some field variable (such as pressure)
-      on a rectangular evenly spaced grid. IVE is, nevertheless, capable of displaying
-      data on arbitrary curvilinear grids.
-    </p>
-    <p>
-      If the data points are not evenly spaced on a rectangular grid, IVE must be
-      informed of the grid structure, either by specifying "attributes"
-      in the data input or by specifying the coordinate transform in a user supplied
-      subroutine. Stretched rectangular grids (which occur when the stretching along
-      a given coordinate is a function only of the value of that coordinate) can be
-      accommodated by specifying one-dimensional arrays containing the grid-point
-      locations along the stretched coordinate as part of the IVE input data. Staggered
-      meshes can also be accommodated by setting "attributes" in the input
-      data. The structure of more complicated curvilinear grids must be communicated
-      to IVE via user supplied "transforms," which define the mapping between
-      physical space and the array indices.
-    </p>
-    <p>
-      Since four-dimensional data cannot be directly displayed on a flat computer
-      screen, it is necessary to reduced the dimensionality of the data before it
-      is displayed. One of IVE's primary capabilities involves dimension reduction
-      or "data slicing." IVE allows the user to display lower-dimensional
-      subsets of the data by fixing a coordinate or by averaging over the coordinate.
-    </p>
-    <p>
-      IVE currently has the capability to display
-    </p>
-    <ul>
-      <li>
-        scalar fields as
-        <ul>
-          <li>
-            2D scalar plots
-          </li>
-          <li>
-            1D scalar plots
-          </li>
-          <li>
-            vertical soundings
-          </li>
-          <li>
-            a single point value
-          </li>
-        </ul>
-      </li>
-      <li>
-        vector fields as 2D vector plots
-      </li>
-    </ul>
-    <p>
-      IVE lets you overlay plots, loop plots, and control a wide variety of display
-      parameters.
-    </p>
-    <p>
-      IVE also can perform algebraic computations on the gridded data and can calculate
-      derivatives. More complicated computations can be performed in user supplied
-      subroutines.
-    </p>
-    <p>
-      IVE uses NetCDF for the data input format, and uses the <a
-      href="http://ngwww.ucar.edu/ng/">NCAR Graphics Library</a> to produce graphical
-      output. IVE is <a
-      href="http://www.atmos.washington.edu/ive/getting.html">available</a> as source
-      via anonymous ftp; and as binary on request for licensees of NCAR graphics.
-    </p>
-    <p></p>
-    <h2><a id="JSON" name="JSON">JSON format with the ncdump-json utility</a></h2>
-    <p>
-      Josep Llodrà has developed a program to output the contents
-      of a netCDF-3 or netCDF-4 file in
-      JSON (JavaScript Object Notation).
-      It is based on Unidata's NCDUMP utility,
-      and it keeps the original ncdump functionality, unless the "-j" option
-      is used to specify JSON output.
-    </p>
-    <p>
-      The program and source are available from <a
-      href="https://github.com/jllodra/ncdump-json"
-      >https://github.com/jllodra/ncdump-json</a>
-      .
-    </p>
-    <p></p>
-
-    <h2><a id="Java interface" name="Java interface">Java interface</a></h2>
-    <p>
-      The <a href="/software/netcdf-java/"
-      >NetCDF-Java 4.2 Library</a> is a Java interface to netCDF files,
-      as well as to many other types of scientific data formats. It
-      is freely available and the source code is released under the
-      (MIT-style) netCDF C library license. Previous versions use the GNU
-      Lesser General Public License (LGPL).
-    </p>
-    <p>
-      The library implements a Common Data Model (<a
-      href="/software/netcdf-java/CDM/" >CDM</a>), a generalization
-      of the netCDF, OpenDAP and HDF5 data models. The library is a
-      prototype for the netCDF-4 project, which provides a C language API
-      for the "data access layer" of the CDM, on top of the HDF5 file
-      format. The NetCDF-Java library is a 100% Java framework for <em>reading</em> netCDF
-      and other file formats into the CDM, as well as <em>writing</em> to the
-      netCDF-3 file format.
-      The library also implements <a
-      href="http://www.unidata.ucar.edu/software/netcdf/ncml/">NcML</a>,
-      which allows you to add metadata to CDM datasets, as well as to create
-      virtual datasets through aggregation.
-    </p>
-
-    <h2><a id="KST" >Kst (2D plotting tool)</a></h2>
-
-    <p>
-      <a href="http://kst-plot.kde.org" >Kst</a> is an open-source, cross-platform 2D plotting tool focused on
-      performance and ease of use. Packages for Windows, various Linux
-      distributions and Mac OS X are <a
-      href="http://sourceforge.net/projects/kst/files/"
-      >available</a>,
-      as well as the complete
-      source code and CMake-based build files.  A more detailed presentation
-      of Kst can be found on the web page at <a href="http://kst-plot.kde.org" >http://kst-plot.kde.org</a>,
-      including numerous screenshots and all the useful download links.
-    </p>
-    <p>
-      Kst is characterized by the following features:
-    </p>
-    <ul>
-      <li>
-        Outstanding performance: curves with millions of points are no problem
-      </li>
-      <li>
-        Plotting of live streams
-      </li>
-      <li>
-        Out-of-the box support for a variety of formats (currently ASCII, netCDF, dirfile, Qimage-supported types, fits images)
-      </li>
-      <li>
-        User-friendly with a modern and consistent user interface
-      </li>
-      <li>
-        A set of unique tools to boost efficiency, including a data import wizard, capacity to edit multiple objects at once or the "Change Data File" tool to compare multiple experiments easily
-      </li>
-      <li>
-        An active community
-      </li>
-      <li>
-        Easily expandable for new data formats or data analysis algorithms thanks to a plugin-based architecture
-      </li>
-      <li>
-        Available on Windows, Linux, and Mac OSX
-      </li>
-    </ul>
-
-    <h2><a id="Labview-API" >Labview interface</a></h2>
-
-    <p>
-      A netCDF Labview interface, implemented in the Labview programming
-      language is available.  The software includes A graphical user
-      interface for editing netCDF data and
-      conversion to other data formats.  The package was developed and is
-      maintained by L. F. Hwang of Sun Yat-sen University in China.
-      For more information
-      and to download the source code, see the <a
-      href="https://sourceforge.net/projects/netcdflabview/" >NetCDFLabview
-      web site</a>.
-    </p>
-
-    <h2><a id="MBDyn" name="MBDyn">MBDyn (MultiBody Dynamics)</a></h2>
-    <p>
-      <a href="http://www.aero.polimi.it/~mbdyn/" >MBDyn</a> is an open-source
-      MultiBody Dynamics analysis system
-      developed at the Dipartimento di Ingegneria Aerospaziale of the
-      University "Politecnico di Milano", Italy.  It uses netCDF as its
-      primary output format.
-    </p>
-    <p>
-      MBDyn features the
-      integrated multidisciplinary analysis of multibody, multiphysics
-      systems, including nonlinear mechanics of rigid and flexible
-      constrained bodies, smart materials, electric networks, active
-      control, hydraulic networks, essential fixed-wing and rotorcraft
-      aerodynamics.  It allows users to simulate the behavior of heterogeneous
-      mechanical, aero-servo-elastic systems based on first principles
-      equations.  It is being actively developed and used in the aerospace
-      and automotive fields for dynamics analysis and simulation of complex
-      systems.  Dynamic linking of
-      user-defined modules is heavily exploited to let users extend the
-      feature library.
-    </p>
-    <p></p>
-
-    <h2><a id="Max_diff_nc" name="Max_diff_nc">Max_diff_nc</a></h2>
-
-    <p>
-      This is a program which compares two NetCDF files. Variables with the
-      same ID in the two files are assumed to be of the same type and have
-      the same shape.  For each such couple of variables, the program
-      computes the maximum of the absolute value of the difference, and the
-      maximum of the absolute value of the relative difference. The program
-      also tells you at what location (the subscript list of the array) the
-      maximum difference is reached.
-
-    <p>
-      The web page for this program is: <a href="http://web.lmd.jussieu.fr/~lglmd/Max_diff_nc">http://web.lmd.jussieu.fr/~lglmd/Max_diff_nc</a>
-
-    <p>
-      This is a freely available tool.
-    </p>
-    <p></p>
-
-    <h2><a id="MeteoExplorer" name="MeteoExplorer"></a>MeteoExplorer</h2>
-
-    <p>
-      <a href="http://www.eastmodelsoft.com/index_en.htm"
-      >MeteoExplorer</a>, developed by Lianqing Yu at China Meteorological
-      Administration, is a cross-platform software application for analyzing
-      and rendering atmospheric science and geoscience data. It supports
-      popular data formats including WMO GRIB1/GRIB2, NetCDF, and MICAPS,
-      and provides basic GIS functionalities. Developed with C++, Meteo
-      Explorer targets multiple computing platforms including Microsoft
-      Windows, GNU Linux, and SGI IRIX operating systems.
-    </p>
-
-    <p>
-      The primary features include:
-    </p>
-    <ul>
-      <li>
-        Graphics layer management (navigation and animation)
-      </li>
-      <li>
-        Objective analysis of physical elements in surface or upperair soundings data
-      </li>
-      <li>
-        Isoline analysis and shading of grid field
-      </li>
-      <li>
-        Streamline analysis of wind field
-      </li>
-      <li>
-        Computation of physics elements
-      </li>
-      <li>
-        NetCDF data process and display
-      </li>
-      <li>
-        GRIB1/GRIB2 data process and display
-      </li>
-      <li>
-        MICAPS data process and display
-      </li>
-      <li>
-        Satellite nephogram data display and animation, support AWX, GPF and HDF format
-      </li>
-      <li>
-        Interactive composition of synoptic chart (command undo/redo, automatic save)
-      </li>
-      <li>
-        Map zoom, pan, projection and clipping
-      </li>
-      <li>
-        Full screen display and zoom to area
-      </li>
-      <li>
-        Quick navigation via thumbnail view of graphics layers
-      </li>
-      <li>
-        Save screen shot as image file (support formats: BMP, JPG, PNG)
-      </li>
-      <li>
-        Vector graphics exported to clipboard or saved as EMF file (Windows version only)
-      </li>
-      <li>
-        Remote desktop connection support
-      </li>
-      <li>
-        System configuration (dynamic menu)
-      </li>
-      <li>
-        Fast switch of user interface language on the fly
-      </li>
-    </ul>
-    <p>
-      For more information, please visit <a
-      href="http://www.eastmodelsoft.com/software/mexplorer.htm"
-      >MeteoExplorer's home page</a> or contact the support staff via
-      meteoexplorer at hotmail.com .
-    </p>
-
-    <p></p>
-    <h2><a id="MeteoInfo" name="MeteoInfo"></a>MeteoInfo</h2>
-
-    <p>
-      For better cross-platform support, <a
-      href="http://www.meteothinker.com" >MeteoInfo</a> has recently been re-developed
-      using Unidata's NetCDF Java library.  MeteoInfo is GIS software for
-      visualization and analysis of spatial and meteorological data.
-      The Java edition can be run in Windows, Mac OS, Linux, and
-      Unix systems.  The Groovy script engine was coupled
-      in the software, so users can write Groovy script to run the software
-      automatically for analysis with complex steps.
-    </p>
-
-    <p>
-      Download: <a href="http://www.meteothinker.com/" >http://www.meteothinker.com/</a>
-    </p>
-
-    <p>
-      Java 6 is needed to run the software.
-    </p>
-
-    <p></p>
-    <h2><a id="MexEPS" name="MexEPS">MexEPS</a></h2>
-    <a href="http://www.pmel.noaa.gov/">PMEL</a> has developed a MATLAB interface, <a
-    href="http://www.epic.noaa.gov/epic/software/mexeps.htm">MexEPS</a>, which supports
-    several netCDF file conventions, including <a
-    href="ftp://ftp.unidata.ucar.edu/pub/netcdf/Conventions/PMEL-EPIC/"> those adopted
-    by PMEL</a>. Many styles of time axes are supported and time manipulation routines
-    ease the use of the time axis in MATLAB. The MexEPS package supports the following
-    data formats:
-    <ul>
-      <li>
-        reading, writing and editing netCDF files;
-      </li>
-      <li>
-        reading and writing Classic EPIC files
-      </li>
-      <li>
-        reading formatted ASCII files
-      </li>
-    </ul>
-    It includes:
-    <ul>
-      <li>
-        VARIABLE, AXIS, ATTRIBUTE manipulation routines
-      </li>
-      <li>
-        TIME manipulation
-        <ul>
-          <li>
-            TIME enters MATLAB as YYMMDDhhmmss.fff
-          </li>
-          <li>
-            Can be converted to netCDF udunits time convention (e.g. days <i>since</i>
-            1990-01-01 00:00:00)
-          </li>
-        </ul>
-      </li>
-      <li>
-        <a href="ftp://ftp.pmel.noaa.gov/eps/mexeps/help-m/">MATLAB help</a> and <a
-        href="ftp://ftp.pmel.noaa.gov/eps/mexeps/examples/">example scripts</a> using
-        MexEPS
-      </li>
-      <li>
-        <b>ASCII2MAT</b> mexFunction, which reads a formatted file into MATLAB as
-        a matrix
-      </li>
-    </ul>
-    <p>
-      The MexEPS package is freely available in PMEL's anonymous ftp directory <a
-      href="ftp://ftp.pmel.noaa.gov/eps/mexeps/">ftp://ftp.pmel.noaa.gov/eps/mexeps/</a>
-    </p>
-    <p>
-      If you have any questions or comments, please contact the author, Willa Zhu <a
-      href="mailto:willa at pmel.noaa.gov">(willa at pmel.noaa.gov)</a> or Nancy Soreide (nns at pmel.noaa.gov).
-    </p>
-    <p></p>
-    <h2><a id="MEXNC" name="MEXNC">MEXNC and SNCTOOLS</a></h2>
-    <p>
-      John Evans of Rutgers University maintains MEXNC and developed SNCTOOLS.
-      <a href="http://mexcdf.sourceforge.net/" >MEXNC</a> is a mexfile
-      interface to NetCDF files for MATLAB that has roughly a one-to-one
-      equivalence with the C API for netCDF. <a
-      href="http://mexcdf.sourceforge.net/tutorial/index.html"
-      >SNCTOOLS</a> is a set of
-      higher-level m-files that sit atop MEXNC, shielding the user from
-      such low level netCDF details as file IDs, variable IDs, and dimension
-      IDs.  The general philosophy behind SNCTOOLS is providing the ability
-      to read and write data without trying to invent a new syntax.
-    </p>
-
-    <p></p>
-    <h2><a id="Mirone" name="Mirone">Mirone (Windows MATLAB-based display)</a></h2>
-
-    <p>
-      Joaquim Luis of Universidade do Algarve has developed <a href="http://w3.ualg.pt/~jluis/mirone/">Mirone</a>,
-      a Windows MATLAB-based framework tool that
-      allows the display and manipulation of a large number of grid/images
-      formats through its interface with the <a
-      href="http://remotesensing.org/gdal/" >GDAL</a> library. Its main
-      purpose is to provide users with an easy-to-use graphical interface to
-      manipulate <a href="http://gmt.soest.hawaii.edu/" >GMT</a> grids. In
-      addition it offers a wide range of tools
-      dedicated to topics in the earth sciences, including tools for
-      multibeam mission planning, elastic deformation studies, tsunami
-      propagation modeling, earth magnetic field computations and magnetic
-      Parker inversions, Euler rotations and poles computations, plate
-      tectonic reconstructions, and seismicity and focal mechanism
-      plotting. The high quality mapping and cartographic capabilities for
-      which GMT is renowned is guaranteed through Mirone's ability to
-      automatically generate GMT cshell scripts and dos batch files.
-    </p>
-    <p>
-      Although Mirone is written in MATLAB, a stand-alone version to run
-      under Windows is also provided. Regrettably this version is not as
-      efficient as the native MATLAB code but provides a solution for users
-      that don't have MATLAB.
-    </p>
-    <p>
-      Also see
-      <br>
-      J. F. Luis. Mirone: A multi-purpose tool for exploring grid
-      data. Computers & Geosciences, 33, 31-41, 2007.
-    </p>
-    <p></p>
-    <h2><a id="ncBrowse" name="ncBrowse">ncBrowse</a></h2>
-    <p>
-      Donald Denbo of NOAA's Pacific Marine Environmental Laboratory has developed
-      and made available <a
-      href="http://www.epic.noaa.gov/java/ncBrowse">ncBrowse</a>, a Java application
-      (JDK1.2) that provides flexible, interactive graphical displays of data and attributes
-      from a wide range of netCDF data file conventions. Features include:
-    </p>
-    <ul>
-      <li>
-        Designed to work with arbitrary netCDF files.
-      </li>
-      <li>
-        Browses file using the EPIC and COARDS conventions.
-      </li>
-      <li>
-        Provides a "tree" view of the netCDF file.
-      </li>
-      <li>
-        Handles character variables.
-      </li>
-      <li>
-        Handles dimensions without an associated variable.
-      </li>
-      <li>
-        Uses sgt graphics to perform 1 and 2 dimensional cuts through data.
-      </li>
-      <li>
-        Save to file single variable as a "cdl" text file.
-      </li>
-      <li>
-        InstallAnywhere scripts for UNIX, Win32, and MacOS.
-      </li>
-      <li>
-        Currently uses Java 2 and Swing.
-      </li>
-    </ul>
-    <p>
-      ncBrowse will run on any UNIX or Windows machine with a Java 2 (JDK1.2) virtual
-      machine installed. Automated installation scripts are available for Windows and
-      UNIX. Additional information on ncBrowse and download instructions are available
-      at <a
-      href="http://www.epic.noaa.gov/java/ncBrowse">http://www.epic.noaa.gov/java/ncBrowse</a>.
-    </p>
-    <p>
-      Questions and suggestions should be directed to <<a
-      href="mailto:dwd at pmel.noaa.gov">dwd at pmel.noaa.gov></a>. If you have problems
-      reading a netCDF file with ncBrowse, please send him a copy of the file and
-      he'll get ncBrowse to read it!
-    </p>
-    <p></p>
-    <h2><a id="nccmp" name="nccmp">nccmp</a></h2>
-    <p>
-      Remik Ziemlinski of the NOAA Geophysical Fluid Dynamics Laboratory has
-      developed <a href="http://nccmp.sourceforge.net/" >nccmp</a>,
-      a tool to compare two netCDF files.
-      It can use MPI, include/exclude specific
-      variables or metadata and operates quickly.
-      Highly recommended for regression testing with large datasets.
-      See the Web site
-      <a href="http://nccmp.sourceforge.net/"
-      >http://nccmp.sourceforge.net/</a> for more information.
-    <p></p>
-    <h2><a id="NCL" name="NCL">NCL</a></h2>
-    <p>
-      The <a href="http://www.ncl.ucar.edu/" >NCAR Command Language
-      (NCL)</a> is an intepreted programming
-      language for scientific data analysis and visualization developed and
-      maintained in
-      NCAR's <a href="http://www.cisl.ucar.edu/">Computational and Information Systems
-      Laboratory</a>.
-    </p>
-    <p>
-      NCL has many features common to modern programming languages,
-      including types, variables, operators, expressions, conditional
-      statements, loops, and functions and procedures.  NCL also has
-      features that are not found in other programming languages, including
-      those that handle the manipulation of metadata, the configuration of
-      visualizations, the import of data from a variety of data formats, and
-      an algebra that supports array operations.
-    </p>
-    <p>
-      NCL has robust file input and output capabilities. It allows different
-      datasets of different formats (netCDF, netCDF-4 classic, HDF4, HDF4-EOS,
-      GRIB-1, and GRIB-2) to
-      be imported into one uniform and consistent data manipulation
-      environment, which internally is the netCDF data format.  NCL doesn't
-      place any restrictions or conventions on the organization of input
-      netCDF files.
-    </p>
-    <p>
-      NCL comes with many useful built-in functions and procedures for
-      processing and manipulating data. There are over 600 functions and
-      procedures that include routines for use specifically with climate and
-      model data, empirical orthogonal functions, Fourier
-      coefficients, wavelets, singular value decomposition, 1-, 2-, and
-      3-dimensional interpolation, approximation, and regridding, and
-      computer analysis of scalar and vector global geophysical quantities.
-    </p>
-    <p>
-      The visualizations are publication-quality and highly customizable,
-      with hundreds of options available for tweaking the looks of your
-      graphics. NCL can generate contours, XY plots, vectors, streamlines,
-      and can overlay these plots on many different map projections.  There
-      are also specialized functions for generating histograms, wind roses,
-      meteograms, skew-T plots, weather maps.
-    </p>
-    <p>
-      Included with the software are two command line tools:
-      "ncl_convert2nc" for converting GRIB-1/2 or HDF files to netCDF
-      files, and "ncl_filedump" which will dump the contents of a file
-      format that NCL recognizes (netCDF, GRIB-1/2, HDF, etc).
-    </p>
-    <p>
-      NCL is available under an open source license or in binary form for
-      several popular UNIX platforms, including (but not limited to) Linux,
-      MacOSX, and Windows/Cygwin.
-    </p>
-    <p>
-      Documentation and additional information on NCL are available from the
-      <a href="http://www.ncl.ucar.edu/">NCL website</a>, which contains
-      hundreds of <a
-      href="http://www.ncl.ucar.edu/Applications/">application examples</a>
-      for one to download. You can also contact Mary Haley, at <a
-      href="mailto:haley at ucar.edu">haley at ucar.edu</a> for more information.
-
-    <p></p>
-    <h2><a id="NCO" name="NCO">NCO</a></h2>
-    <a href="http://nco.sourceforge.net">NCO</a> (netCDF operators) is a package of
-    command line operators that work on generic netCDF or HDF4 files:
-    <ul>
-      <li>
-        ncap2 - arithmetic processor
-      </li>
-      <li>
-        ncatted - attribute editor
-      </li>
-      <li>
-        ncbo - binary operator
-      </li>
-      <li>
-        ncdiff - differencer
-      </li>
-      <li>
-        ncea - ensemble averager
-      </li>
-      <li>
-        ncecat - ensemble concatenator
-      </li>
-      <li>
-        ncflint - file interpolator
-      </li>
-      <li>
-        ncks - kitchen sink (extract, cut, paste, print data)
-      </li>
-      <li>
-        ncpdq - permute dimensions quickly
-      </li>
-      <li>
-        ncra - running averager
-      </li>
-      <li>
-        ncrcat - record concatenator
-      </li>
-      <li>
-        ncrename - renamer
-      </li>
-      <li>
-        ncwa - weighted averager
-      </li>
-    </ul>
-
-    <p>
-      All operators may now be <a href="http://www.opendap.org">OPeNDAP</a> clients. OPeNDAP enables
-      network transparent data access to any OPeNDAP server. Thus OPeNDAP-enabled NCO can
-      operate on remote files accessible through any OPeNDAP server without transferring
-      the files. Only the required data (e.g., the variable or hyperslab specified)
-      are transferred.
-    </p>
-    <p>
-      The source code is freely available from the <a
-      href="http://nco.sourceforge.net/">NCO home page</a>, as is the NCO User's
-      Guide.
-    </p>
-    <p>
-      For more information, contact the author, Charlie Zender.
-    </p>
-    <p></p>
-    <h2><a id="ncregrid" name="ncregrid">ncregrid</a></h2>
-    <p>
-      Patrick Jöckel of the Max Planck Institute for Chemistry has developed <strong>ncregrid</strong>,
-      a tool (written in FORTRAN-90) for data transfer of gridded 2- and 3-dimensional
-      (spatial) geophysical/geochemical scalar fields between grids of different resolutions.
-      The algorithm handles data on rectangular latitude/longitude grids (not necessarily
-      evenly spaced) and vertical pressure hybrid grids of arbitrary resolution. The
-      input/output data format is netCDF. ncregrid is freely available without any
-      warranty under the GNU public license (GPL). ncregrid can be used as a "stand-alone"
-      program, and/or linked as an interface to a model, in order to re-grid automatically
-      the input from an arbitrary grid space onto the required grid resolution.
-    </p>
-    <p>
-      More information is available on the web-page: <a href="http://www.mpch-mainz.mpg.de/~joeckel/ncregrid/index.html" > http://www.mpch-mainz.mpg.de/~joeckel/ncregrid/index.html</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="nctoolbox" name="nctoolbox">nctoolbox (a MATLAB common data model interface)</a></h2>
-
-    <p>
-      <a
-      href="http://nctoolbox.github.io/nctoolbox/" >nctoolbox</a> is a MATLAB
-      interface that provides read-only access to <a
-      href="/software/netcdf-java/CDM/index.html" >Common Data Model</a>
-      datasets.
-      Under the hood, nctoolbox uses Unidata's NetCDF-Java as the data access layer.
-      This allows nctoolbox to access to netCDF, OPeNDAP, HDF5, GRIB, GRIB2, HDF4,
-      and many (15+) other file formats and services using the same API.
-      It works with MATLAB 2008a and later.  The nctoolbox software was
-      developed by Brian Schlining (MBARI), Rich Signell
-      (USGS), Sachin Kumar Bhate (freelance), and Alex Crosby (RPS/ASA).
-    </p>
-
-    <p></p>
-
-    <h2><a id="ncdx" name="ncdx">ncdx</a></h2>
-    <p>
-      Patrick Jöckel of the Max Planck Institute for Chemistry has developed <strong>ncdx</strong>,
-      a tool (written in FORTRAN-90) that scans a netCDF file and makes it <a href="#OpenDX" >OpenDX</a>
-      compliant. ncdx is freely available without any warranty under the GNU public
-      license (GPL). More information is available on the web-page: <a href="http://www.mpch-mainz.mpg.de/~joeckel/ncdx/index.html" > http://www.mpch-mainz.mpg.de/~joeckel/ncdx/index.html</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="ncensemble" name="ncensemble">ncensemble</a></h2>
-    <p>
-      Alan Iwi, of Rutherford Appleton Laboratory, offers this command
-      line ensemble statistics utility. More information is available on
-      the web-page: <a href="http://home.badc.rl.ac.uk/iwi/ncensemble/" > http://home.badc.rl.ac.uk/iwi/ncensemble/</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="ncview" name="ncview">ncview</a></h2>
-    <a
-    href="http://meteora.ucsd.edu/~pierce/ncview_home_page.html">Ncview</a> is a visual
-    browser for netCDF files. Typically you would use ncview to get a quick and easy,
-    push-button look at your netCDF files. You can view simple movies of the data,
-    view along various dimensions, take a look at the actual data values, change color
-    maps, invert the data, etc. It runs on UNIX platforms under X11, R4 or higher.
-    For more information, check out the <a
-    href="http://meteora.ucsd.edu/~pierce/docs/ncview.README">README</a> file; you
-    can also see a representative <a
-    href="http://meteora.ucsd.edu/~pierce/docs/ncview.gif">screen image</a> (GIF,
-    66K) of ncview in action.
-    <p>
-      The source may be downloaded from <a
-      href="ftp://cirrus.ucsd.edu/pub/ncview/">ftp://cirrus.ucsd.edu/pub/ncview/</a>.
-      For more information, please contact the author, David W. Pierce at <a href="mailto:dpierce at ucsd.edu">dpierce at ucsd.edu</a>.
-    </p>
-
-    <h2><a id="NC4ML5" name="NC4ML5">NetCDF Toolbox for MATLAB-5</a></h2>
-    The <a
-    href="http://mexcdf.sourceforge.net/">NetCDF Toolbox for
-    MATLAB-5</a>, originally developed by Charles R. Denham, combined netCDF-3 with <a
-    href="http://www.mathworks.com/products/matlab/">MATLAB</a> to form an interface that
-    used MATLAB operator-syntax for arithmetic, logical, and subscripting operations
-    on netCDF entities.  The NetCDF Toolbox is in bug-fix-only mode, and is
-    maintained by John.G.Evans.NE at gmail.com,
-    on the <a href="http://mexcdf.sf.net" > MEXNC, SNCTOOLS, and the
-    NetCDF Toolbox</a> web page.
-    </p>
-    <p></p>
-
-    <h2><a id="ncvtk" name="ncvtk">ncvtk</a></h2>
-
-    <p>
-      <a href="http://ncvtk.sourceforge.net/" >Ncvtk</a> is a program for
-      exploring planetary data stored in a NetCDF file.
-      The NetCDF file  should loosely follow the <a
-      href="http://www.cgd.ucar.edu/cms/eaton/cf-metadata/" >CF metadata
-      conventions</a>.
-    </p>
-    <p>
-      Ncvtk was designed from the ground up with the aim of offering a high
-      degree of interactivity to scientists who have a need to explore
-      structured, three-dimensional, time-dependent climate data on the
-      sphere. A graphical user interface allows users to interact with their
-      data via color/transparency/contour/vector plots, apply vertical slices,
-      probe data, apply an external sun light, overlay hydrographic and
-      geopolitical data, rotate, zoom, etc. with minimal fuss.
-    </p>
-    <p>
-      Ncvtk is written in python and is based on the <a
-      href="http://public.kitware.com/VTK/" >Visualization Toolkit
-      (VTK)</a>. Like python and VTK, Ncvtk is
-      highly portable and known to run on Windows and Linux (i386, ia64,
-      EMT64) platforms. More information about Ncvtk is available at <a
-      href="http://ncvtk.sourceforge.net"
-      >http://ncvtk.sourceforge.net</a>.
-    </p>
-
-    <p></p>
-
-    <h2><a id="netcdf_tools" name="netcdf_tools">Ivan Shmakov's netcdf tools</a></h2>
-
-    <p>
-      The NetCDF tools is a free software package consisting of a few
-      tools operating on NetCDF and, by utilizing the compatibility API,
-      HDF4 files, which are intended to be usable from Shell scripts.
-    </p>
-    <p>
-      The currently packaged tools are:
-    </p>
-    <ul>
-      <li>
-        a couple of simple shell wrappers over the respective NetCDF
-        functions (ncattget and ncattput);
-      </li>
-      <li>
-        a more sophisticated ncget tool.
-      </li>
-    </ul>
-    <p>
-      The ncget tool implements functionalilty that is similar to hdp
-      dumpsds (for NetCDF, which lacks such a tool), or complements it in
-      the case of HDF4. It can be seen as a complement to the ncdump tool
-      (included in both the NetCDF and HDF4 distributions) as well.
-    </p>
-    <p>
-      This tool allows a selected part of a NetCDF variable or an HDF4
-      scientific data set (SDS) to be extracted in either an ASCII or
-      binary form, applying the transformation specified by the usual
-      scale_factor and add_offset attributes. It allows one to feed the
-      data contained in NetCDF variables (or HDF4 SDS) to the tools
-      designed to operate on either ASCII (text) or raw (binary) data.
-    </p>
-    <p>
-      This version of the package is the first one to be announced to the
-      public. It has some known bugs and limitations, but it's proved to
-      be quite usable.  A <a
-      href="http://freshmeat.net/projects/netcdf-tools" >project page</a> on
-      freshmeat.net.  The <a
-      href="http://waterlily.siamics.net/~ivan/src/netcdf-tools-0.1-rc1.tar.gz"
-      >source</a> is also available.
-    </p>
-
-    <h2><a id="netcdf4excel" name="netcdf4excel">netcdf4excel (add-in for MS Excel)</a></h2>
-    <p>
-      Alexander Bruhns
-      <bruhns at free.fr>
-        has developed <a
-        href="http://code.google.com/p/netcdf4excel/" >a netCDF add-in written in
-        Visual Basic for MS Excel</a>.  This add-in simplifies the use of
-        NetCDF data in Excel, providing a ready to use solution for
-        manipulating this type of data.
-    </p>
-    <p>
-      For developers, the open-source (GPL V3 license) can be downloaded
-      directly or checked out with Mercurial.
-    </p>
-    <p>
-      The add-in is written in VBA 6.0 (so it won't work with Office 2010 64 bits) and is designed for Excel 2007 running with the Microsoft Windows operating system.
-      It supports opening netCDF classic format data with Excel for read or
-      write access.
-    </p>
-    <p>
-      More details are available on the <a
-      href="http://code.google.com/p/netcdf4excel/" >netcdf4excel web
-      site</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="netcdf95" name="netcdf95">NetCDF95 alternative Fortran API</a></h2>
-
-    <p>
-      Lionel Guez has developed and made feely available <a
-      href="http://web.lmd.jussieu.fr/~lglmd/NetCDF95" >NetCDF95</a>, a new
-      alternative Fortran interface to the NetCDF library.  Compared to the
-      Unidata-provided Fortran 90 netCDF interface, the NetCDF95 interface
-      is meant to be easier to use and more secure.
-    </p>
-
-    <h2><a id="Objective-C" name="Objective-C">Objective-C API</a></h2>
-
-    <p>
-      Tom Moore has an Objective-C API, available here: <a href="http://www.paleoterra.com/software" >www.paleoterra.com/software</a>.
-
-      The netCDF Framework is an open source (Argonne Open Source License)
-      MacOSX application framework that provides an Objective-C interface
-      to the NCAR netCDF library version 3.  The framework is available
-      both as source code and universal compiles (works on both PPC and
-      Intel macs).  The source code has also been compiled by users for the
-      GNUStep environment.   Version 2 of the framework will provide
-      classes for accessing multiple netCDF files, working with in-memory
-      data slabs using standard notation, and some support for
-      multithreading.
-
-      <h3>Mark Tracy's Objective-C API</h3>
-
-    <p>
-      Mark Tracy has written <a href="http://www.mt-se.com/nc_1.html"
-      >NetcdfStep</a>, an Objective-C
-      API for netCDF that uses Objective-C Foundation Classes.
-
-    <p>
-      NetcdfStep is framework for using the netCDF library in
-      object-oriented programming with Objective-C. It now
-      supports the full functionality of netCDF 3.6.2.
-    </p>
-    <p>
-      A <a
-      href="http://www.mt-se.com/pub/NetcdfStep-1.0.2.zip" > complete Mac OS X distribution</a> including pre-built static library and <a
-      href="http://www.mt-se.com/netcdfstep_doc/" >online documentation</a>
-      are available.  Applications linked to this framework have no external
-      dependencies (other than Mac OS X itself).
-      A <a href="http://www.mt-se.com/pub/NetcdfStep-GNUstep-0.6.1.tar.gz" > source-code only distribution</a> synced up to version 0.6.1 is
-      available for GNUstep for use on
-      Linux and other Unix platforms.
-    </p>
-
-    <p></p>
-    <h2><a id="NCMEX" name="NCMEX">Octave interface</a></h2>
-
-    <p>
-      The ARM Program has contributed NCMEX for Octave, a port of Chuck
-      Denham's MATLAB NCMEX to <a href="http://www.octave.org" >Octave</a>.  The
-      calling syntax
-      is identical, so scripts using NCMEX in MATLAB should in theory be
-      portable to Octave.  In order to build NCMEX, a compiled C NetCDF
-      library must already be installed.
-    </p>
-    <p>
-      In addition to the base NetCDF library interface, this package includes a
-      simple toolbox to automate the reading and writing of NetCDf files
-      within Octave using NCMEX.  These tools as well as the source for
-      NCMEX are available from <a
-      href="http://engineering.arm.gov/~sbeus/octavex/octavex.tar" > http://engineering.arm.gov/~sbeus/octavex/octavex.tar</a>
-      (NOTE: this .tar file contains other
-      Octave extension functions besides NCMEX.)
-    </p>
-    <p>
-      Also see <a href="http://ocgmod1.marine.usf.edu/octcdf/" >Octcdf</a>,
-      a netCDF toolbox for Octave.
-    </p>
-    <p>
-      For installation instructions, see the README file inside the .tar file.
-    </p>
-
-    <p></p>
-
-    <h2><a id="Octave" name="Octave">Octave interface (Barth)</a></h2>
-
-    <p>
-      Alexander Barth has contributed the following:
-    </p>
-    <p>
-      Octcdf is a netCDF toolbox for <a
-      href="http://www.octave.org/">Octave</a> which uses the same operator
-      syntax as the <a
-      href="http://mexcdf.sourceforge.net/netcdf_toolbox.html">matlab netCDF
-      toolbox</a> of Charles R. Denham. NetCDF dimensions, attributes and
-      variables are Octave objects and can be accessed, sliced and changed
-      just as regular variables. Unlike most netCDF toolboxes for matlab, it
-      does not depend on the NCMEX wrapper around the netCDF interface. This
-      octave toolbox is written in C++ calling directly the netCDF library.
-      The octcdf toolbox can also be used to download data from an OpenDAP
-      server. The octcdf source code is available at <a
-      href="http://modb.oce.ulg.ac.be/mediawiki/index.php/NetCDF_toolbox_for_Octave"> http://modb.oce.ulg.ac.be/mediawiki/index.php/NetCDF_toolbox_for_Octave</a>.
-      It was also included in the Octave Repository <a
-      href="http://octave.sourceforge.net/">octave-forge</a>.
-    </p>
-
-    <p></p>
-
-    <h2><a id="OPeNDAP" name="OPeNDAP">OPeNDAP (formerly DODS)</a></h2>
-
-    <p>
-      The <a href="http://opendap.org/">OPeNDAP</a> (formerly known as
-      DODS) is an Open-source Project for a Network Data Access Protocol
-      that makes local data and subsets of local data accessible to remote
-      locations independent of the local storage format. OPeNDAP also
-      provides tools for transforming existing applications into OPeNDAP
-      clients, enabling them to remotely access OPeNDAP served data.
-      OPeNDAP is based on existing data access tools; rather than developing
-      a self contained system, it makes extensive use of existing data
-      access APIs.
-    </p>
-
-    <p>
-      OPeNDAP can be used to make netCDF data files available over the
-      Internet and it can also be used to adapt existing software which use
-      the netCDF API (by re-linking) to read data served by an OPeNDAP data
-      server. In principle, any program written using netCDF can be adapted
-      to read data from an OPeNDAP server - in other words any program
-      which uses netCDF can become a client in the OPeNDAP client-server
-      system. Included in the source and binary distributions are two freely
-      available programs that have already been modified (re-linked).
-    </p>
-
-    <p>
-      With a client program accessing data from a netCDF server, it is
-      possible to access a small subset of a large dataset over the Internet
-      without copying the entire dataset (as you would have to do with FTP
-      or AFS). The client can see changes to the netCDF dataset, e.g. when
-      new records are added (which would not be possible with FTP). Finally,
-      the client can also access cross-sections of variable data without
-      paging large amounts of data across the network (as you would have to
-      do with NFS, for example).
-    </p>
-
-    <p>
-      OPeNDAP software is freely available in both
-      source form or binary form for selected platforms.
-    </p>
-
-    <p></p>
-
-    <h2><a id="OpenDX" name="OpenDX">OpenDX</a></h2>
-    <a href="http://www.opendx.org/about.html">OpenDX</a> (formerly IBM Data Explorer,
-    also known as simply DX) is a general-purpose software package for data visualization
-    and analysis. It employs a data-flow driven client-server execution model and
-    provides a graphical program editor that allows the user to create a visualization
-    using a point and click interface.
-    <p>
-      DX runs on 7 major UNIX platforms as well as Windows 95/NT and is designed
-      to take full advantage of multi-processor systems from IBM, SGI and Sun.
-    </p>
-    <p>
-      DX is built upon an internal data model, which describes and provides uniform
-      access services for any data brought into, generated by, or exported from the
-      software. This data model supports a number of different classes of scientific
-      data, which can be described by their shape (size and number of dimensions),
-      rank (e.g., scalar, vector, tensor), type (float, integer, byte, etc. or real,
-      complex, quaternion), where the data are located in space (positions), how the
-      locations are related to each other (connections), aggregates or groups (e.g.,
-      hierarchies, series, composites, multizone grids, etc.). It also supports those
-      entities required for graphics and imaging operations within the context of
-      Data Explorer. Regular and irregular, deformed or curvilinear, structured and
-      unstructured data as well as "missing" or invalid data are supported.
-    </p>
-    <p>
-      The details of the data model are hidden at the user level. As a result DX
-      operations or modules are polymorphic and appear typeless. The DX Import module,
-      which reads data for use within Data Explorer directly utilizes data in netCDF
-      as well as other formats (e.g., HDF, CDF). One or more variables may be selected
-      as well as step(s) of a time series. Data in conventional netCDFs are directly
-      imported. Since the DX data model is more comprehensive than the netCDF data
-      model, a methodology to extend netCDF via attribute conventions (e.g., for unstructured
-      meshes, non-scalar data and hierarchies) for use with Data Explorer is available.
-    </p>
-    <p>
-      DX supports a number of realization techniques for generating renderable geometry
-      from data. These include color and opacity mapping (e.g., for surface and volume
-      rendering), contours and isosurfaces, histograms, two-dimensional and three-dimensional
-      plotting, surface deformation, etc. for scalar data. For vector data, arrow
-      plots, streamlines, streaklines, etc. are provided. Realizations may be annotated
-      with ribbons, tubes, axes, glyphs, text and display of data locations, meshes
-      and boundaries. Data probing, picking, arbitrary surface and volume sampling,
-      and arbitrary cutting/mapping planes are supported.
-    </p>
-    <p>
-      DX supports a number of non-graphical functions such as point-wise mathematical
-      expressions (e.g., arithmetic, transcendental, boolean, type conversion, etc.),
-      univariate statistics and image processing (e.g., transformation, filter, warp,
-      edge detection, convolution, equalization, blending, morphological operations,
-      etc.). Field/vector operations such as divergence, gradient and curl, dot and
-      cross products, etc. are provided. Non-gridded or scattered data may be interpolated
-      to an arbitrary grid or triangulated, depending on the analysis requirements.
-      The length, area or volume of various geometries may also be computed. Tools
-      for data manipulation such as removal of data points, subsetting by position,
-      sub/supersampling, grid construction, mapping, interpolation, regridding, transposition,
-      etc. are available.
-    </p>
-    <p>
-      Tools for doing cartographic projections and registration as well as earth,
-      space and environmental sciences examples are available at Cornell University
-      via info.tc.cornell.edu. Also see the <a href="#ncdx" >ncdx</a> tool for making
-      netCDF files OpenDX compliant.
-    </p>
-    <p></p>
-    <h2><a id="Panoply" name="Panoply">Panoply</a></h2>
-    <p>
-      <a href="http://www.giss.nasa.gov/tools/panoply/" >Panoply</a>
-      is an application that plots geo-gridded and other arrays from netCDF,
-      HDF, GRIB, and other datasets. Features include:
-    </p>
-    <ul>
-      <li>
-        Slice and plot geo-gridded latitude-longitude,
-        latitude-vertical, longitude-vertical, or
-        time-latitude arrays from larger multidimensional variables.
-      </li>
-      <li>
-        Two arrays may be combined in one plot by differencing, summing, or averaging.
-      </li>
-      <li>
-        Lon-lat data may be plotted as global maps (using any of over 75
-        map projections) or as zonal average plots.
-      </li>
-      <li>
-        Overlay continent outlines or masks on lon-lat plots.
-      </li>
-      <li>
-        Use your favorite CPT, GGR, PAL, or ACT color table for scale colorbar.
-      </li>
-      <li>
-        Save plots to disk in GIF, JPEG, PNG or TIFF bitmap images or as
-        PDF or PostScript graphics files.
-      </li>
-      <li>
-        Export lon-lat map plots in KMZ format.
-      </li>
-      <li>
-        Export animations as AVI or MOV video or as a collection of
-        invididual frame images.
-      </li>
-      <li>
-        Explore remote THREDDS and OpenDAP catalogs and open datasets served from them.
-      </li>
-    </ul>
-    <p>
-      Panoply requires that your computer have a Java SE 6 runtime
-      environment, or better, installed.
-    </p>
-    <p>
-      Panoply is developed at the NASA Goddard Institute for Space Studies. Questions
-      and suggestions should be directed to <a
-      href="http://www.giss.nasa.gov/staff/rschmunk.html" >Dr. Robert
-      B. Schmunk</a>.
-    </p>
-    <p></p>
-    <h2><a id="Parallel-NetCDF" name="Parallel-NetCDF">Parallel-NetCDF</a></h2>
-    <p>
-      A group of researchers at Northwestern University and Argonne National
-      Laboratory (Jianwei Li, Wei-keng Liao, Alok Choudhary, Robert Ross, Rajeev
-      Thakur, William Gropp, and Rob Latham) have designed and implemented a new
-      <a href="http://www.mcs.anl.gov/parallel-netcdf/" > parallel interface for writing and reading netCDF data</a>, tailored for use on
-      high performance platforms with parallel I/O.  The implementation builds on
-      the MPI-IO interface, providing portability to most platforms in use and
-      allowing users to leverage the many optimizations built into MPI-IO
-      implementations.  Testing so far has been on Linux platforms with ROMIO and
-      IBM SP machines using IBM's MPI.
-    </p>
-    <p>
-      Documentation and code for Parallel-NetCDF is now available for
-      testing.
-      Although a few interfaces are not implemented yet, the current implementation
-      is complete enough to provide significant I/O performance improvements on
-      parallel platforms, as described in a <a
-      href="ftp://info.mcs.anl.gov/pub/tech_reports/reports/P1048.pdf"
-      >technical report</a>.   Users are invited to test Parallel-NetCDF
-      in their applications.
-    </p>
-    <p></p>
-
-    <h2><a id="Paraview" name="Paraview">Paraview and vtkCSCSNetCDF</a></h2>
-
-    <p>
-      <a href="http://www.paraview.org/">http://www.paraview.org/</a>
-
-    <p>
-      ParaView is an application designed with the need to visualize large
-      data sets in mind. The goals of the ParaView project include the
-      following:
-
-      <ul>
-        <li>
-          Develop an open-source, multi-platform visualization application.
-        <li>
-          Support distributed computation models to process large data sets.
-        <li>
-          Create an open, flexible, and intuitive user interface.
-        <li>
-          Develop an extensible architecture based on open standards.
-      </ul>
-
-    <p>
-      ParaView runs on distributed and shared memory parallel as well as
-      single processor systems and has been successfully tested on
-      Windows, Linux and various Unix workstations and clusters. Under the
-      hood, ParaView uses the Visualization Toolkit as the data processing
-      and rendering engine and has a user interface written using a unique
-      blend of Tcl/Tk and C++.
-
-    <p>
-      A vtk/ParaView reader for netCDF files can be found
-      <a href="http://www.paraview.org/Wiki/ParaView/Users_Guide/List_of_readers#NetCDF_Reader">here</a>.
-
-      <h2><a id="Perl" name="Perl">Perl interfaces</a></h2>
-      There are two netCDF interfaces for Perl:
-      <ul>
-        <li>
-          <a
-          href="http://search.cpan.org/~dhunt/PDL-NetCDF-4.05/netcdf.pd" > PDL::NetCDF</a>,
-          Doug Hunt's perl interface which uses the PDL (perl data language) extension.
-        </li>
-        <li>
-          <a href="/software/netcdf-perl/" >NetCDFPerl</a>, Steve Emmerson's
-          extension module, based on version 2 of the netCDF package. Uses perl lists
-          for representing netCDF variables.
-        </li>
-      </ul>
-    <p></p>
-    <h2><a id="PolyPaint+" name="PolyPaint+">PolyPaint+</a></h2>
-    <a
-    href="http://lasp.colorado.edu/polypaint/home.html">PolyPaint+</a> is an interactive
-    scientific visualization tool that displays complex structures within three-dimensional
-    data fields. It provides both color shaded-surface display and simple volumetric
-    rendering in either index or true color. For shaded surface rendering, the PolyPaint+
-    routines first compute the polygon set that describes a desired surface within
-    the 3D data volume. These polygons are then rendered as continuously shaded surfaces.
-    PolyPaint+ contains a wide variety of options that control lighting, viewing,
-    and shading. Objects rendered volumetrically may be viewed along with shaded surfaces.
-    Additional data sets can be overlaid on shaded surfaces by color coding the data
-    according to a specified color ramp. 3D visualizations can be viewed in stereo
-    for added depth perspective.
-    <p>
-      Currently supported 3D visualizations are the following:
-    </p>
-    <ul>
-      <li>
-        Shaded isosurface
-      </li>
-      <li>
-        Transparent contour shells or isosurfaces at varying levels
-      </li>
-      <li>
-        Volumetric or density plot
-      </li>
-      <li>
-        Planes
-      </li>
-      <li>
-        Contour ribbons
-      </li>
-      <li>
-        Topographic surface from 2D geographic data sets
-      </li>
-    </ul>
-    <p>
-      3D data volumes may be sliced in the X, Y, or Z plane using an interactive
-      cutting plane. A cross section of the data volume can be viewed in a 2D window
-      as a 2D contour plot, a vector plot, a raster image or a combination of these
-      options superimposed. Map outlines can be used as a background for 2D cross
-      section plots of geographic data. All data is projected according to the coordinates
-      specified by the user for the cross section window.
-    </p>
-    <p>
-      The user interface provides direct manipulation tools for specifying the eye
-      position, center of view, light sources, and color ramps. Subsetting of data
-      can be done easily by selecting the data by index or geographic coordinate.
-      On-line contextual help provides easy access to more detail about the software.
-      Tutorials which range from very simple visualizations to complex combinations
-      of data sets provide the user with a quick learning tool.
-    </p>
-    <p>
-      Currently PolyPaint+ accepts only data which is in the NetCDF file format.
-      A file conversion utility which converts from raw binary data to netCDf is a
-      part of the application.
-    </p>
-    <p>
-      PolyPaint+ is a joint effort of the University of Colorado and NCAR (National
-      Center for Atmospheric Research) funded by the NASA AISRP program. A beta version
-      of PolyPaint+ is currently available free of charge using FTP or for a nominal
-      fee which would cover tape distribution. A license agreement must be signed
-      in order to use it.
-    </p>
-    <p>
-      You may order by...
-    </p>
-    <ul>
-      <li>
-        TELEPHONE : 303-492-7289 (Margi Klemp) : 303-497-8159 (Bill Boyd)
-      </li>
-      <li>
-        U.S. MAIL :         <pre>
-      Margi Klemp
-      University of Colorado / LASP
-      1234 Innovation Dr.
-      Boulder, CO 80303
-      USA
-
-      </pre>
-      </li>
-      <li>
-        E-MAIL : margi at aries.colorado.edu
-      </li>
-    </ul>
-    <p></p>
-    <h2><a id="pomegranate" name="pomegranate">Pomegranate</a></h2>
-    <p>
-      The P9E Team at
-      NASA JPL has developed <a href="http://pomegranate.jpl.nasa.gov/"
-      >Pomegranate</a>, a python application that "webifies" science data files.
-      Supported formats include netCDF, HDF4, HDF5, GRIB and FITS.
-    </p>
-    <p>
-      Pomegranate can be installed on web servers as either a WSGI or CGI application
-      to provide webification (w10n) services. To learn more about w10n of
-      science data files, please visit
-      <a href="http://webification.org/">http://webification.org/</a>.
-      A brief <a href="http://pomegranate.jpl.nasa.gov/test/help.txt"
-      >help</a> document describes how to use the <a
-      href="http://pomegranate.jpl.nasa.gov/test" >demo directory</a> to
-      browse or download metadata or data in netCDF, JSON, or other
-      formats by clicking on data folder and document icons.
-    </p>
-    <p>
-      Pomegranate can also be used as a standalone library or command line application.
-      This greatly simplifies the retrieval of metadata and data
-      from files in supported formats.
-    </p>
-    <p>
-      Pomegranate is open source software and can be downloaded from
-      <a href="http://www.openchannelsoftware.com/projects/Pomegranate/" > http://www.openchannelsoftware.com/projects/Pomegranate/</a>.
-    </p>
-
-    <h2><a id="PyNGL" name="PyNGL">PyNGL and PyNIO</a></h2>
-    <p>
-      NCAR's Computational and Information Systems Laboratory has developed
-      <a href="http://www.pyngl.ucar.edu/" >PyNGL</a>, a python package for
-      scientific visualization and data analysis and <a
-      href="http://www.pyngl.ucar.edu/Nio.shtml" >PyNIO</a>, a Python
-      package supporting access to a variety of data formats using an
-      interface modelled on netCDF.
-    </p>
-    <p></p>
-
-    <h2><a id="Python" name="Python">Python interfaces</a></h2>
-    <p>
-      Python is an interpreted, object-oriented language that is supported on a wide
-      range of hardware and operating systems. Python information and sources can be
-      obtained from <a
-      href="http://www.python.org/">http://www.python.org/</a>. There are now
-      several netCDF interfaces for Python.
-    </p>
-    <p>
-      Jeff Whitaker of the NOAA Earth System Research Lab has developed a
-      netCDF-4 module for python:
-      <a
-      href="http://code.google.com/p/netcdf4-python/"> http://code.google.com/p/netcdf4-python/</a>.  Most new features of
-      netCDF-4 are implemented, such as multiple unlimited dimensions,
-      groups and zlib data compression. All the new numeric data types (such
-      as 64-bit and unsigned integer types) are implemented. Compound and
-      variable length (vlen) data types are supported, but the enum and
-      opaque data types are not. Mixtures of compound and vlen data types
-      (compound types containing vlens, and vlens containing compound types)
-      are not supported.
-    </p>
-    <p>
-      <a href="#xray" >xray</a> is a higher-level interface that uses
-      netcdf4-python internally to implement a pandas-like package for N-D
-      labelled arrays for scientific data.
-    </p>
-    <p>
-      André Gosselin of the Institut Maurice-Lamontagne, Péches & Océans Canada,
-      has implemented pycdf, a new Python interface to the netCDF library.  It
-      is available from <a href="http://pysclint.sourceforge.net/pycdf/"
-      >http://pysclint.sourceforge.net/pycdf/</a>, where you will find the install
-      files, installation instructions, extensive documentation in text and html
-      format, and examples. pycdf requires the Numeric python package, and
-      installs through the simple "python setyp.py install" command.
-    </p>
-    <p>
-      Bill Noon (noon at snow.cit.cornell.edu) has implemented another netCDF Python
-      module that allows easy creation, access, and browsing of netCDF data. The bindings
-      also use the <a
-      href="/software/udunits/">udunits library</a> to do unit conversions.
-      More information and source for Noon's Python netCDF module are available
-      from <a
-      href="http://snow.cit.cornell.edu/noon/ncmodule.html">http://snow.cit.cornell.edu/noon/ncmodule.html</a>.
-    </p>
-
-    <p>
-      The package from Konrad Hinsen has been integrated into his <a
-      href="https://sourcesup.cru.fr/projects/scientific-py/">ScientificPython</a>
-      package.
-    </p>
-
-    <p>
-      Dave Brown of NCAR's Computational and Information Systems Laboratory has developed <a
-      href="http://www.pyngl.ucar.edu/Nio.shtml" >PyNIO</a>, a Python
-      package that allows read and/or write access to a variety of data
-      formats using an interface modelled on netCDF.  Currently supported
-      formats include netCDF, HDF4, GRIB1 and GRIB2 (read only), and HDF-EOS
-      2 Grid and Swath data (read only).
-    </p>
-
-    <p>
-      Vicente Galiano of Miguel Hernandez University has developed a Python interface to
-      PnetCDF. This Python's package called "PyPnetCDF" allows access to NetCDF files using MPI and
-      the library pnetCDF developed by http://www.mcs.anl.gov/parallel-netcdf/.
-      The tools are very similar to Konrad Hinsen's NetCDF package to Python
-      but can read and write in a parallel way. For more information, see:
-      <a
-      href="http://www.pyacts.org/pypnetcdf">http://www.pyacts.org/pypnetcdf</a>.
-    </p>
-    <p>
-      <a id="pupynere" name="pupynere">Pupynere (PUre PYthon NEtcdf
-      REader)</a>
-      Roberto De Almeida has developed <a
-      href="http://pypi.python.org/pypi/pupynere/" >pupynere</a>, a PUre
-      PYthon NEtcdf REader that allows read-access to netCDF files using the
-      same syntax as the Scientific.IO.NetCDF Python module. Even though it's
-      written in Python, the module is up to 40% faster than
-      Scientific.IO.NetCDF and pynetcdf.
-    </p>
-
-    <p></p>
-    <h2><a id="R" name="R">R interface</a></h2>
-    <p>
-      The R Project for Statistical Computing has developed <a
-      href="http://www.R-project.org/" > R</a>, a language and environment for statistical
-      computing and graphics. It provides a wide variety of statistical and graphical
-      techniques, including linear and nonlinear modelling, statistical tests, time
-      series analysis, classification, and clustering.
-    </p>
-    <p>
-      David Pierce has contributed the <a
-      href="http://cran.r-project.org/web/packages/ncdf4/index.html"
-      >ncdf4 package</a> for reading netCDF data into R and for creating new netCDF
-      dimensions, variables, and files, or manipulating existing netCDF
-      files from R.
-    </p>
-    <p>
-      Pavel Michna has contributed another package, <a href="http://cran.r-project.org/web/packages/RNetCDF/index.html" >RNetCDF</a>, that also provides access to netCDF data and to udunits
-      calendar functions from R.
-    </p>
-    <p>
-      Robert Hijmans (with additional contributors) has created the <a
-      href="http://cran.r-project.org/web/packages/raster/index.html"
-      >R raster package</a> for geographic data analysis and modeling. The
-      raster package can be used for reading, writing, manipulating,
-      analyzing and modeling gridded spatial data. The package is especially
-      useful for large datasets that don't fit into memory, because data is
-      processed in chunks. See <a
-      href="http://cran.r-project.org/web/packages/raster/vignettes/Raster.pdf"
-      >Introduction to the 'raster' package</a> for more information.
-    </p>
-
-    <p></p>
-    <h2><a id="QGIS" name="QGIS">Quantum GIS (QGIS)</a></h2>
-    <p>
-      <a href="http://www.qgis.org/" >Quantum GIS</a> (QGIS) is an Open
-      Source Geographic Information System (GIS) licensed
-      under the GNU General Public License. QGIS is an official project of
-      the Open Source Geospatial Foundation (OSGeo). It runs on Linux, Unix,
-      Mac OSX, and Windows and supports numerous vector, raster, and
-      database formats and functionalities.  QGIS supports a desktop,
-      browser, server, and client for viewing, editing, analysis,
-      serving, and accessing data.  Its server complies with the OGC WMS 1.3 standard.
-      In addition to PostGIS and SpatiaLite formats, it can access data in vector
-      formats supported by the OGR library as well as most raster formats
-      supported by the GDAL library, including netCDF.  For a more detailed list of
-      features of the QGIS desktop, browser, server, and client, see the
-      <a href="http://www.qgis.org/en/about-qgis/features.html" >QGIS features page</a>.
-    </p>
-    <p></p>
-
-    <h2><a id="Ruby" name="Ruby">Ruby interface</a></h2>
-    <p>
-      A group at the Research Institute for Sustainable Humanosphere (RISH) of Kyoto
-      University has developed a <a
-      href="http://www.gfd-dennou.org/arch/ruby/products/ruby-netcdf/" >netCDF interface
-      for Ruby</a>, an interpreted, object-oriented scripting language. This interface
-      is intended to cover all the functionality of the C library for netCDF. Also
-      available are combination functions such as iterators (which offer abstract
-      ways to scan files and variables). Numeric arrays are handled by the "NArray"
-      multi-dimensional array class, which is becoming the de facto standard multi-dimensional
-      array for Ruby.  See also the Ruby-based <a href="#Gfdnavi" >GPhys
-      software and Gfdnavi tool</a>
-      for accessing GRIB, GrADS, and netCDF data uniformly.
-    </p>
-    <p>
-      More information about Ruby is available from the <a href="http://www.ruby-lang.org/" >Ruby
-      web site</a>.
-    </p>
-    <p></p>
-    <h2><a id="SDS" name="SDS">Scientific DataSet (SDS) Library</a></h2>
-    <p>
-      The <a href="http://sds.codeplex.com" >Scientific DataSet Library and
-      Tools project</a>, developed jointly by
-      Microsoft Research Cambridge and Moscow State University,
-      is aimed at manipulation and visualization of multidimensional data
-      sets.
-    </p>
-    <p>
-      Scientific DataSet (or SDS in short) is a .NET class library for
-      manipulating scientific data  and their metadata. SDS provides a unified API
-      for convenient access to various data storages. Three types of storages are
-      supported by the first release: NetCDF files, CSV text files and volatile
-      in-memory datasets. SDS uses native NetCDF library built from version 4.0.1
-      both for 32 and 64-bit Windows platforms. New storage types can be added to
-      SDS infractructure as plugins. Support for accessing TIFF image files from
-      SDS as 2D arrays will be available soon as a separate CodePlex project.
-    </p>
-    <p>
-      Three applications are built on top of SDS:
-    </p>
-    <ul>
-      <li>
-        sds command line utility. It allows users to examine data set schema,
-        copy data sets, modify their metadata.
-      </li>
-      <li>
-        DataSetViewer application for visualization of data sets. DataSetViewer
-        is both a standalone application and Windows Presentation Foundation Control
-        that can be built into your applications. DataSetViewer has support for
-        interactive slicing of multidimensional data along any dimension.
-      </li>
-      <li>
-        DataSetEditor add-in for Microsoft Office Excel. DataSetEditor provides
-        ability to view and modify the contents of any data set as Excel
-        worksheets.
-      </li>
-    </ul>
-    <p>
-      You can read the Getting Started document at
-      <a
-      href="http://sds.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=127282"
-      > http://sds.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=127282 </a>
-      for a more detailed introduction to the Scientific DataSet
-      software. A Windows
-      Installation package for SDS binaries along with DataSet Viewer and DataSet
-      Editor are available also. You can also build core class libraries and
-      the sds utility under Mono. You may use, copy, and reproduce this
-      software for any non-commercial purpose. For further details see license at
-      <a href="http://sds.codeplex.com/license" >http://sds.codeplex.com/license</a>.
-    </p>
-    <p>
-      The SDS project is in beta phase and keeps evolving.  You are welcome to
-      join discussions or report issues at the CodePlex site:
-      <a href="http://sds.codeplex.com" >http://sds.codeplex.com</a>.
-    </p>
-    <p></p>
-    <h2><a id="SIS" name="SIS">Apache Spatial Information System (SIS)</a></h2>
-    <p>
-      <a href="https://builds.apache.org/job/sis-trunk/site/index.html"
-      >Apache Spatial Information System (SIS)</a> is a Java library for
-      developing geospatial applications. SIS enables representation of
-      coordinates for searching, data clustering, archiving, or any other
-      relevant spatial needs. The library is an implementation of GeoAPI 3.0
-      interfaces and can be used for desktop or server applications.
-    </p>
-    <p>
-      SIS provides data structures for geographic data and associated
-      metadata along with methods to manipulate those data structures. The
-      SIS metadata module forms the base of the library and enables the
-      creation of metadata objects which comply with the ISO 19115 metadata
-      model and which can be read from or written to ISO 19139 compliant XML
-      documents. The SIS referencing module will enable the construction of
-      geodetic data structures for geospatial referencing based on the ISO
-      19111 model such as axis, projection and coordinate reference system
-      definitions, along with the associated operations which enable the
-      mathematical conversion of coordinates between different systems of
-      reference. The SIS storage modules will provide a common approach to
-      the reading and writing of grid coverages applicable to simple imagery
-      and multidimensional data structures.
-    </p>
-    <p>
-      SIS supports creating ISO 19115 metadata from metadata in a netCDF
-      store from a given file, URL, stream, or NetcdfFile object.  SIS
-      netCDF storage is intended to be a bridge between NetCDF Climate and
-      Forecast (CF) conventions and ISO 19115 metadata.
-    </p>
-    <p>
-      SIS is under developement as an Apache project.  Release 0.3 is
-      currently available for download.
-    </p>
-    <p></p>
-    <h2><a id="Tcl/Tk" name="Tcl/Tk">Tcl/Tk interfaces</a></h2>
-    <p>
-      Dan Schmitt has developed <a
-      href="http://cnrit.tamu.edu/rsg/cdftcl/">cdftcl</a>, a <a
-      href="http://www.scriptics.com/">Tcl/Tk</a> interface for netCDF. It allows the
-      use of "wildcards" (*) or ranges (1-4) in the subscript notation,
-      and use of name references instead of variable IDs. Contact dan at computer.org
-      for more information.
-    </p>
-    <p></p>
-    <h2><a id="Tcl-nap" name="Tcl-nap">Tcl-nap</a></h2>
-    <p>
-      <a href="http://tcl-nap.sourceforge.net" >Tcl-nap</a> (n-dimensional array
-      processor) is a loadable extension of Tcl which provides a powerful and efficient
-      facility for processing data in the form of n-dimensional arrays. It has been
-      designed to provide an array-processing facility with much of the functionality
-      of languages such as <a href="http://www.acm.org/sigapl/" >APL</a>, Fortran-90, <a href="#IDL" >IDL</a>, <a href="http://www.jsoftware.com/" >J</a>, <a href="http://www.mathworks.com" >matlab</a>, and <a href="http://www.octave.org/" >octave</a>.
-    </p>
-    <p>
-      Support is provided for data based on n-dimensional grids, where the dimensions
-      correspond to continuous spatial coordinates. There are interfaces to the HDF
-      and netCDF file formats commonly used for such data, especially in Earth sciences
-      such as Oceanography and Meteorology.
-    </p>
-    <p>
-      The internal data structure is called a NAO (n-dimensional array object) and
-      contains similar information to that of HDF SDSs and netCDF variables.
-    </p>
-    <p>
-      Tcl-nap was developed as part of the <a
-      href="http://www.dar.csiro.au/rs/avhrr_processing_software.htm" >CSIRO CAPS project</a>,
-      but can be loaded and used without the (satellite oriented) CAPS extension.
-    </p>
-    <p></p>
-    <h2><a id="VB" name="VB">Visual Basic and VB.net interfaces</a></h2>
-    <p>
-      Carsten Wieczorrek has developed code in VB 6 to export chromatographic
-      data into the netcdf/ANDI format.
-      The application writes netCDF files that can be read by
-      CHROMELEON, for example.  For others interested in programming with
-      netcdf.dll from VB 6, see
-      Wieczorrek's web page on <a
-      href="http://www.mn-net.com/netcdf_vb6"
-      >netCDF and VB 6.0</a> and for VB.net, see <a
-      href="http://www.mn-net.com/netcdf_vbnet" >netCDF and VB.net</a>.
-    </p>
-    <p></p>
-    <h2><a id="VisAD" name="VisAD">VisAD</a></h2>
-    <a href="http://www.ssec.wisc.edu/~billh/visad.html">VisAD</a> is a Java class
-    library for interactive and collaborative visualization and analysis of numerical
-    data. It combines:
-    <ul>
-      <li>
-        The use of pure Java for platform independence and to support data sharing
-        and real-time collaboration among geographically distributed users. Support
-        for distributed computing is integrated at the lowest levels of the system
-        using Java RMI distributed objects.
-      </li>
-      <li>
-        A general mathematical data model that can be adapted to virtually any numerical
-        data, that supports data sharing among different users, different data sources
-        and different scientific disciplines, and that provides transparent access
-        to data independent of storage format and location (i.e., memory, disk or
-        remote). The data model has been adapted to netCDF, FITS, HDF-EOS, McIDAS,
-        Vis5D, GIF and JPEG file formats.
-      </li>
-      <li>
-        A general display model that supports interactive 3-D, data fusion, multiple
-        data views, direct manipulation, collaboration, and virtual reality. The display
-        model has been adapted to Java3D and Java2D and used in an ImmersaDesk virtual
-        reality display.
-      </li>
-      <li>
-        Data analysis and computation integrated with visualization to support computational
-        steering and other complex interaction modes.
-      </li>
-      <li>
-        Support for two distinct communities: developers who create domain- specific
-        systems based on VisAD, and users of those domain-specific systems. VisAD
-        is designed to support a wide variety of user interfaces, ranging from simple
-        data browser applets to complex applications that allow groups of scientists
-        to collaboratively develop data analysis algorithms.
-      </li>
-      <li>
-        Developer extensibility in as many ways as possible.
-      </li>
-    </ul>
-    VisAD was written by programmers at the <a
-    href="http://www.ssec.wisc.edu/~billh/vis.html">SSEC Visualization Project</a>
-    at the University of Wisconsin-Madison <a
-    href="http://www.ssec.wisc.edu/">Space Science and Engineering Center</a>, and
-    the <a href="/index.html">Unidata Program Center</a>. <p></p>
-    <h2><a id="WCT" name="WCT">Weather and Climate Toolkit (WCT)</a></h2>
-    <p>
+<html>
+
+  <head>
+
+    <title>Software for Manipulating or Displaying NetCDF Data</title>
+    <meta name="UIINDEX" content="0">
+    <meta name="BOOKMARK" content="NetCDF Utilities">
+    <meta name="AUTHOR" content="russ">
+    <meta name="KEYWORDS" content="netcdf, utilities, software, use">
+    <meta name="DESCRIPTION" content="This document provides references to software packages that may be used for manipulating or displaying netCDF data. We include information about both freely-available and licensed (commercial) software that can be used with netCDF data. ">
+
+  </head>
+
+  <body>
+
+    <h1>Software for Manipulating or Displaying NetCDF Data</h1>
+    <p>
+      This document provides references to software packages that may be used for manipulating
+      or displaying <a
+      href="/software/netcdf/">netCDF</a> data. We include information about
+      both freely-available and licensed (commercial) software that can be used with
+      netCDF data. We rely on developers to help keep this list up-to-date. If you know
+      of corrections or additions, please <a href="mailto:support at unidata.ucar.edu">send
+      them to us</a>. Where practical, we would like to include WWW links to information
+      about these packages in the HTML version of this document.
+    </p>
+
+    <p>
+      Other useful guides to utilities that can handle netCDF data include ARM's list of
+      <a href="http://science.arm.gov/%7ecflynn/ARM_Tested_Tools/"
+      >ARM-tested netCDF data tools</a>, which includes some downloadable
+      binaries and the NOAA Geophysical
+      Fluid Dynamics Laboratory
+      <a href=
+      "http://nomads.gfdl.noaa.gov/sandbox/products/vis/data/netcdf/GFDL_VG_NetCDF_Utils.html"> guide to netCDF utilities</a>.
+    </p>
+
+    <hr />
+    <h2><a href="#freely">Freely Available Software</a></h2>
+    <ul>
+      <li>
+        <a href="#ANDX">ANDX (ARM NetCDF Data eXtract) and ANAX (ARM NetCDF ASCII eXtract)</a>
+      </li>
+      <li>
+        <a href="#ANTS" >ANTS (ARM NetCDF Tool Suite)</a>
+      </li>
+      <li>
+        <a href="#ARGOS">ARGOS (interActive thRee-dimensional Graphics ObServatory)</a>
+      </li>
+      <li>
+        <a href="#CDAT">CDAT (Climate Data Analysis Tool)</a>
+      </li>
+      <li>
+        <a href="#CDFconvert" >CDFconvert (Convert netCDF to RPN and GEMPAK Grids)</a>
+      </li>
+      <li>
+        <a href="#cdfsync">cdfsync (network synchronization of netCDF files)</a>
+      </li>
+      <li>
+        <a href="#CDO" >CDO (Climate Data Operators)</a>
+      </li>
+      <li>
+        <a href="#CIDS Tools">CIDS Tools</a>
+      </li>
+      <li>
+        <a href="#CSIRO-MATLAB">CSIRO MATLAB/netCDF interface</a>
+      </li>
+      <li>
+        <a href="#EPIC">EPIC</a>
+      </li>
+      <li>
+        <a href="#ExcelUse" >Excel Use</a>
+      </li>
+      <li>
+        <a href="#EzGet">EzGet</a>
+      </li>
+      <li>
+        <a href="#FAN">FAN (File Array Notation)</a>
+      </li>
+      <li>
+        <a href="#FERRET">FERRET</a>
+      </li>
+      <li>
+        <a href="#fimex" >FIMEX (File Interpolation, Manipulation, and EXtraction)</a>
+      </li>
+      <li>
+        <a href="#fwtools" >FWTools (GIS Binary Kit for Windows and Linux)</a>
+      </li>
+      <li>
+        <a href="#GDAL" >GDAL (Geospatial Data Abstraction Library)</a>
+      </li>
+      <li>
+        <a href="#GDL" >GDL (GNU Data Language)</a>
+      </li>
+      <li>
+        <a href="#Gfdnavi" >Gfdnavi (Geophysical fluid data navigator)</a>
+      </li>
+      <li>
+        <a href="#GMT">GMT (Generic Mapping Tools)</a>
+      </li>
+      <li>
+        <a href="#Grace">Grace</a>
+      </li>
+      <li>
+        <a href="#GrADS">GrADS (Grid Analysis and Display System)</a>
+      </li>
+      <li>
+        <a href="#Gri">Gri</a>
+      </li>
+      <li>
+        <a href="#GXSM">GXSM - Gnome X Scanning Microscopy project</a>
+      </li>
+      <li>
+        <a href="#HDF interface">HDF (Hierarchical Data Format) interface</a>
+      </li>
+      <li>
+        <a href="#HDF-EOS" >HDF-EOS to netCDF converter</a>
+      </li>
+      <li>
+        <a href="#HIPHOP">HIPHOP (Handy IDL-Program for HDF-Output Plotting)</a>
+      </li>
+      <li>
+        <a href="#Hyperslab OPerator Suite (HOPS)">HOPS (Hyperslab OPerator Suite)</a>
+      </li>
+      <li>
+        <a href="#iCDF" >iCDF (imports chromatographic netCDF data into MATLAB)</a>
+      </li>
+      <li>
+        <a href="#IDV" >IDV (Integrated Data Viewer)</a>
+      </li>
+      <li>
+        <a href="#Ingrid">Ingrid</a>
+      </li>
+      <li>
+        <a href="#IntelArrayVisualizer" >Intel Array Visualizer</a>
+      </li>
+      <li>
+        <a href="#IVE">IVE (Interactive Visualization Environment)</a>
+      </li>
+      <li>
+        <a href="#JSON" >JSON format with the ncdump-json utility</a>
+      </li>
+      <li>
+        <a href="#Java interface">Java interface</a>
+      </li>
+      <li>
+        <a href="#KST">Kst (2D plotting tool)</a>
+      </li>
+      <li>
+        <a href="#Labview-API" >Labview interface</a>
+      </li>
+      <li>
+        <a href="#MBDyn">MBDyn (MultiBody Dynamics)</a>
+      </li>
+      <li>
+        <a href="#Max_diff_nc">Max_diff_nc</a>
+      </li>
+      <li>
+        <a href="#MeteoExplorer" >MeteoExplorer</a>
+      </li>
+      <li>
+        <a href="#MeteoInfo" >MeteoInfo</a>
+      </li>
+      <li>
+        <a href="#MexEPS">MexEPS (MATLAB interface)</a>
+      </li>
+      <li>
+        <a href="#MEXNC">MEXNC and SNCTOOLS (a MATLAB interface)</a>
+      </li>
+      <li>
+        <a href="#Mirone">Mirone (Windows MATLAB-based display)</a>
+      </li>
+      <li>
+        <a href="#ncBrowse">ncBrowse (netCDF File Browser)</a>
+      </li>
+      <li>
+        <a href="#nccmp" >nccmp (netCDF compare)</a>
+      </li>
+      <li>
+        <a href="#ncdx" >ncdx (netCDF for OpenDX)</a>
+      </li>
+      <li>
+        <a href="#ncensemble" >ncensemble (command line utility to do ensemble statistics)</a>
+      </li>
+      <li>
+        <a href="#NCL">NCL (NCAR Command Language)</a>
+      </li>
+      <li>
+        <a href="#NCO">NCO (NetCDF Operators)</a>
+      </li>
+      <li>
+        <a href="#ncregrid" >ncregrid</a>
+      </li>
+      <li>
+        <a href="#nctoolbox" >nctoolbox (a MATLAB common data model interface)</a>
+      </li>
+      <li>
+        <a href="#ncview">ncview</a>
+      </li>
+      <li>
+        <a href="#ncvtk" >ncvtk</a>
+      </li>
+      <li>
+        <a href="#netcdf_tools" >netcdf tools</a>
+      </li>
+      <li>
+        <a href="#netcdf4excel" >netcdf4excel (add-in for MS Excel)</a>
+      </li>
+      <li>
+        <a href="#netcdf95" >NetCDF95 alternative Fortran API</a>
+      </li>
+      <li>
+        <a href="#Objective-C" >Objective-C interface</a>
+      </li>
+      <li>
+        <a href="#NCMEX" >Octave interface</a>
+      </li>
+      <li>
+        <a href="#Octave" >Octave interface (Barth)</a>
+      </li>
+      <li>
+        <a href="#OPeNDAP">OPeNDAP (formerly DODS)</a>
+      </li>
+      <li>
+        <a href="#OpenDX">OpenDX (formerly IBM Data Explorer)</a>
+      </li>
+      <li>
+        <a href="#Panoply" >Panoply</a>
+      </li>
+      <li>
+        <a href="#Parallel-NetCDF" >Parallel-NetCDF</a>
+      </li>
+      <li>
+        <a href="#Paraview" >Paraview and vtkCSCSNetCDF</a>
+      </li>
+      <li>
+        <a href="#Perl" >Perl interfaces</a>
+      </li>
+      <li>
+        <a href="#PolyPaint+">PolyPaint+</a>
+      </li>
+      <li>
+        <a href="#pomegranate" >Pomegranate</a>
+      </li>
+      <li>
+        <a href="#pupynere" >Pupynere (PUre PYthon NEtcdf REader)</a>
+      </li>
+      <li>
+        <a href="#PyNGL" >PyNGL and PyNIO</a>
+      </li>
+      <li>
+        <a href="#Python">Python interfaces</a>
+      </li>
+      <li>
+        <a href="#QGIS" >QGIS (Quantum GIS)</a>
+      </li>
+      <li>
+        <a href="#R">R interface</a>
+      </li>
+      <li>
+        <a href="#Ruby" >Ruby interface</a>
+      </li>
+      <li>
+        <a href="#SDS" >Scientific DataSet (SDS) Library</a>
+      </li>
+      <li>
+        <a href="#SIS">Apache Spatial Information System (SIS)</a>
+      </li>
+      <li>
+        <a href="#Tcl/Tk">Tcl/Tk interfaces</a>
+      </li>
+      <li>
+        <a href="#Tcl-nap" >Tcl-nap (N-dimensional array processor)</a>
+      </li>
+      <li>
+        <a href="#VB" >Visual Basic and VB.net</a>
+      </li>
+      <li>
+        <a href="#VisAD">VisAD</a>
+      </li>
+      <li>
+        <a href="#WCT">Weather and Climate Toolkit (WCT)</a>
+      </li>
+      <li>
+        <a href="#WebWinds">WebWinds</a>
+      </li>
+      <li>
+        <a href="#xray" >xray (Python N-D labelled arrays)</a>
+      </li>
+      <li>
+        <a href="#Zebra">Zebra</a>
+      </li>
+      <li>
+        <a href="#user">User-contributed software</a>
+      </li>
+    </ul>
+    <hr />
+    <h2><a href="#commercial">Commercial or Licensed Packages</a></h2>
+    <ul>
+      <li>
+        <a href="#ArcGIS">ArcGIS Pro - Space Time Pattern Mining Toolbox
+      </li>
+      <li>
+        <a href="#Agrimetsoft"> AgriMetSoft - Netcdf-Extractor
+      </li>
+      <li>
+        <a href="#ViewNcDap" >ASA ViewNcDap</a>
+      </li>
+      <li>
+        <a href="#Avizo" >Avizo</a>
+      </li>
+      <li>
+        <a href="#AVS">AVS</a>
+      </li>
+      <li>
+        <a href="#BCS-UFI" >Barrodale UFI</a>
+      </li>
+      <li>
+        <a href="#DioVISTA/Storm" >DioVISTA/Storm</a>
+      </li>
+      <li>
+        <a href="#EnSight" >EnSight</a>
+      </li>
+      <li>
+        <a href="#Environmental WorkBench">Environmental WorkBench</a>
+      </li>
+      <li>
+        <a href="#ESRI" >ESRI</a>
+      </li>
+      <li>
+        <a href="#FME" >FME</a>
+      </li>
+      <li>
+        <a href="#HDF-Explorer" >HDF Explorer</a>
+      </li>
+      <li>
+        <a href="#IDL">IDL Interface</a>
+      </li>
+      <li>
+        <a href="#InterFormat">InterFormat</a>
+      </li>
+      <li>
+        <a href="#IRIS Explorer Module">IRIS Explorer Module</a>
+      </li>
+      <li>
+        <a href="#LeoNetCDF" >LeoNetCDF</a>
+      </li>
+      <li>
+        <a href="#Mathematica" >Mathematica</a>
+      </li>
+      <li>
+        <a href="#MATLAB">MATLAB</a>
+      </li>
+      <li>
+        <a href="#Noesys">Noesys</a>
+      </li>
+      <li>
+        <a href="#Origin" >Origin</a>
+      </li>
+      <li>
+        <a href="#PPLUS">PPLUS</a>
+      </li>
+      <li>
+        <a href="#PV-Wave">PV-Wave</a>
+      </li>
+      <li>
+        <a href="#SlicerDicer">Slicer Dicer</a>
+      </li>
+      <li>
+        <a href="#Surfer">Surfer</a>
+      </li>
+      <li>
+        <a href="#vGeo" >vGeo</a>
+      </li>
+      <li>
+        <a href="#VISAGE and Decimate">VISAGE and Decimate</a>
+      </li>
+      <li>
+        <a href="#Voyager">Voyager</a>
+      </li>
+    </ul>
+    <hr />
+    <p></p>
+    <h1 id="freely">Freely Available Software</h1>
+
+    <h2><a id="ANDX" name="ANDX">ANDX and ANAX</a></h2>
+
+    <p>
+      The ARM Program has developed
+      <a href="http://engineering.arm.gov/~sbeus/andx-web/html/" >ANDX (ARM
+      NetCDF Data eXtract)</a>,
+      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.
+    </p>
+
+    <p>
+      <a href="http://science.arm.gov/~cflynn/ARM_Tested_Tools/" >ANAX (ARM
+      NetCDF ASCII eXtract)</a> 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.
+    </p>
+
+    <h2><a id="ANTS" name="ANTS">ANTS</a></h2>
+    <p>
+      The ARM Program has developed <a
+      href="http://science.arm.gov/~cflynn/ANTS/" >ANTS (ARM NetCDF Tool
+      Suite)</a>, 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.
+    </p>
+
+    <p>
+      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.
+    </p>
+
+    <p>
+      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 <a href="http://science.arm.gov/~cflynn/ANTS/"
+      >website</a> for more information.
+    </p>
+
+    <h2><a id="ARGOS" name="ARGOS">ARGOS</a></h2>
+    <p>
+      <a href="http://www.lapeth.ethz.ch/argos/index.html">ARGOS</a> (interActive thRee-dimensional
+      Graphics ObServatory) is a new IDL-based interactive 3D visualization
+      tool, developed by <a
+      href="http://www.lapeth.ethz.ch/~david/index.html">David N. Bresch</a> and <a href="http://www.lapeth.ethz.ch/~mark/index.html">Mark
+      A. Liniger</a> at the Institute for Atmospheric Science at the Swiss Federal Institute
+      of Technology, ETH, Zürich.
+    </p>
+
+    <p>
+      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
+      <a
+      href="http://www.lapeth.ethz.ch/argos/argos_general.html">html-help</a>. 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.
+    </p>
+    <p>
+      Information about <a
+      href="http://www.lapeth.ethz.ch/argos/argos_copyright.html">copyright and licensing
+      conditions</a> are available. For further information and installation, please
+      E-mail to: bresch at atmos.umnw.ethz.ch
+    </p>
+    <p></p>
+    <h2><a id="CDAT" name="CDAT">CDAT</a></h2>
+    The <a href="http://cdat.sf.net">Climate Data Analysis Tool
+    (CDAT)</a>, developed by the <a
+    href="http://www-pcmdi.llnl.gov/">Program for Climate Model Diagnosis
+    and Intercomparison (PCMDI)</a> at Lawrence Livermore National Laboratory, provides
+    the capabilities needed to analyze model data, perform complex mathematical calculations,
+    and graphically display the results. It provides the necessary tools to diagnose,
+    validate, and intercompare large observational and global climate model data sets.
+    <p>
+      It includes the ability to ingest
+      large climate datasets in netCDF, HDF, DRS, and GrADS/GRIB format;
+      the Visualization and Computation System (VCS) module, visually displays and
+      animates ingested or created data; and the Library of AMIP Data Transmission
+      Standards (LATS) module outputs data in the machine-independent netCDF or GrADS/GRIB
+      file formats.
+    </p>
+    <p>
+      In addition, the Command Line Interface (CLI) module allows
+      CDAT to receive argument and function input via the command line, and the Graphical
+      User Interface (GUI) allows CDAT to receive argument and function input via
+      a point-and-click environment.
+    </p>
+    <p>
+      The software, which runs as a standalone process or within PCMDI's
+      Visualization and Computation System (VCS), provides climate scientists with
+      an easy and fast method to read different file formats, and to analyze and
+      graphically display climate data in an integrated fashion. CDAT includes a
+      set of pre-defined functions to allow the user to manipulate the data and
+      send the output to a file which can be viewed as an image, or as a collection
+      of images in an animation. The software has a gradual learning curve, allowing
+      the novice user to quickly obtain useful results.
+    </p>
+    <p></p>
+    <h2><a id="CDFconvert" name="CDFconvert">CDFconvert</a></h2>
+    <p>
+      The <a href="http://www.atmos.albany.edu/facstaff/rmctc/cdf_cvt/" >MRG
+      CDFconvert package</a> provided by the Mesoscale Research Group,
+      McGill University/SUNY Albany, is designed to address data conversion
+      issues for gridded datasets stored under the <a
+      href="http://ferret.wrc.noaa.gov/noaa_coop/coop_cdf_profile.html">COARDS</a>
+      convention. CDFconvert converts regular Cylindrical Equidistant
+      (Lat/Long) and Gaussian (Spherical) netCDF grids into either the
+      Canadian <a
+      href="http://www.cmc.ec.gc.ca/rpn/modcom/si/libraries/rmnlib/fstd/index.html"
+      >RPN Standard File</a> or <a href="/software/gempak/index.html"
+      >GEMPAK</a> file formats. MRG CDFconvert has the flexibility to handle
+      netCDF files generated by a number of sources, including NCEP and
+      ECMWF. User-definable conversion tables make the extension of the
+      package to different datasets possible.
+    </p>
+
+    <p></p>
+    <h2><a id="cdfsync" name="cdfsync">cdfsync</a></h2>
+    <p>
+      Joe Sirott of NOAA's Pacific Marine Environmental Laboratory has
+      developed cdfsync, a program that allows users to rapidly synchronize a
+      set of netCDF files over a network. Fast synchronization times are
+      achieved by only transmitting the differences between files. It is
+      built on the Open Source <a href="http://samba.anu.edu.au/rsync/" >rsync</a>
+      program, but contains a number of optimizations including:
+      <ul>
+        <li>
+          Special handling of netCDF files for faster synchronization
+          calculations
+        </li>
+        <li>
+          Much faster updates of large numbers of small netCDF files
+        </li>
+        <li>
+          In-place updates of large netCDF files
+        </li>
+      </ul>
+    <p>
+      The latest version should run on Linux variants and Solaris.
+    </p>
+    More information is available at the <a
+    href="http://www.epic.noaa.gov/epic/software/cdfsync/">cdfsync website</a>.
+    </p>
+    <p></p>
+    <h2><a id="CDO" name="CDO">CDO (Climate Data Operators)</a></h2>
+    <p>
+      Uwe Schulzweida at the Max Planck Institute for Meteorology has developed
+      <a href="http://code.zmaw.de/projects/cdo" >CDO</a>, a collection of
+      Operators to manipulate and analyze
+      Climate Data files. Supported file formats include netCDF and GRIB.
+      There are more than 350 operators available. The following
+      table provides a brief overview of the main categories.
+    </p>
+    <ul>
+      <li>
+        File information (info, sinfo, diff, ...)
+      </li>
+      <li>
+        File operations (copy, cat, merge, split*, ...)
+      </li>
+      <li>
+        Selection (selcode, selvar, sellevel, seltimestep, ...)
+      </li>
+      <li>
+        Missing values (setctomiss, setmisstoc, setrtomiss)
+      </li>
+      <li>
+        Arithmetic (add, sub, mul, div, ...)
+      </li>
+      <li>
+        Mathematical functions (sqrt, exp, log, sin, cos, ...)
+      </li>
+      <li>
+        Comparision (eq, ne, le, lt, ge, gt, ...)
+      </li>
+      <li>
+        Conditions (ifthen, ifnotthen, ifthenc, ifnotthenc)
+      </li>
+      <li>
+        Field statistics (fldsum, fldavg, fldstd, fldmin, fldmax, ...)
+      </li>
+      <li>
+        Vertical statistics (vertsum, vertavg, vertstd, vertmin, ...)
+      </li>
+      <li>
+        Time range statistics (timavg, yearavg, monavg, dayavg, ...)
+      </li>
+      <li>
+        Field interpolation (remapbil, remapcon, remapdis, ...)
+      </li>
+      <li>
+        Vertical interpolation (ml2pl, ml2hl)
+      </li>
+      <li>
+        Time interpolation (inttime, intyear)
+      </li>
+    </ul>
+    <p>
+      As an example of use of CDO, converting
+      from GRIB to netCDF can be as simple as
+      <pre>
+    cdo -f nc copy file.grb file.nc
+</pre>
+or with relative time axis (for usage with GrADS)
+       <pre>
+    cdo -r -f nc copy file.grb file.nc
+</pre>
+or using ECMWF reanalysis on a reduced grid
+       <pre>
+    cdo -R -f nc copy file.grb file.nc
+</pre>
+    </p>
+    <p>
+      More information is available on the <a
+      href="http://code.zmaw.de/projects/cdo" >CDO homepage</a>.
+    </p>
+    <p></p>
+    <h2><a id="CIDS Tools" name="CIDS Tools">CIDS Tools</a></h2>
+    The Center for Clouds Chemistry and Climate (<a
+    href="http://www-c4.ucsd.edu/">C4</a>) Integrated Data Systems (<a
+    href="http://www-c4.ucsd.edu/~cids/">CIDS</a>) group has developed several useful
+    netCDF utilities:
+    <ul>
+      <li>
+        cdf2idl: Writes an IDL script to read a NetCDF file.
+      </li>
+      <li>
+        cdf2c: Writes C code to read a NetCDF file.
+      </li>
+      <li>
+        cdf2fortran: Writes FORTRAN source code to read a NetCDF file.
+      </li>
+      <li>
+        cdf2asc: Dumps NetCDF data to an ASCII file.
+      </li>
+    </ul>
+    The source for these utilities can be downloaded from <a
+    href="http://www-c4.ucsd.edu/~cids/software/visual.html">CIDS NetCDF Visualization
+    Tools site</a>. <p></p>
+    <h2><a id="CSIRO-MATLAB" name="CSIRO-MATLAB">CSIRO MATLAB/netCDF interface</a></h2>
+    The <a
+    href="http://www.marine.csiro.au/sw/matlab-netcdf.html">CSIRO MATLAB/netCDF interface</a>
+    is now available from the <a
+    href="http://www.marine.csiro.au">CSIRO Marine Laboratories</a>.
+    <p>
+      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 retrieving data from,
+      and information about, existing netCDF files.
+    </p>
+    <p>
+      The basis of the interface is a machine-dependent mex-file called
+      mexcdf53. Rather than call the mex-file
+      directly users are advised to employ both <a href="#NC4ML5">Chuck Denham's
+      netCDF toolbox</a> and the CSIRO MATLAB/netCDF interface described here. For
+      read-only access to existing netCDF data, the CSIRO interface has a simpler
+      syntax than the netCDF Toolbox, but the latter may also be used to create and
+      manipulate netCDF variables and datasets.
+    </p>
+    <p></p>
+    <h2><a id="EPIC" name="EPIC">EPIC</a></h2>
+    NOAA's Pacific Marine Environmental Laboratory (<a
+    href="http://www.pmel.noaa.gov/">PMEL</a>) has developed the <a
+    href="http://www.pmel.noaa.gov/epic/">EPIC</a> software package for oceanographic
+    data. EPIC provides graphical display and data field manipulation for multi-dimensional
+    netCDF files (up to 4 dimensions). PMEL has been using this software on Unix and
+    VMS several years. At present, they have:
+    <p></p>
+    <ul>
+      <li>
+        a data file I/O library ( <a
+        href="http://www.pmel.noaa.gov/epic/eps-manual/epslib_toc.html">epslib</a>, which
+        is layered on top of the netCDF library).
+      </li>
+      <li>
+        epslib allows transparent access to multiple data file formats
+      </li>
+      <li>
+        a <a href="http://www.epic.noaa.gov/epic/software/mexeps.htm">MATLAB MexEPS
+        interface</a> for using any supported EPIC file with MATLAB
+      </li>
+      <li>
+        <a
+        href="http://www.epic.noaa.gov/epic/software/ep_programs.htm">suite of EPIC programs</a>
+        for graphics and analysis of hydrographic profile data and time series data.
+      </li>
+    </ul>
+    This software was developed on Sun/Unix and is also supported for DEC/Ultrix and
+    VAX/VMS as a system for data management, display and analysis system for observational
+    oceanographic time series and hydrographic data. The EPIC software includes over
+    50 programs for oceanographic display and analysis, as well as utilities for putting
+    in-situ or observational data on-line (with on-the-fly graphics and data download)
+    on the WWW.
+    <p>
+      The developers are interested in coordinating with others who may be developing
+      oceanographic software for use with netCDF files. The EPIC software is available
+      via anonymous FTP from ftp.noaapmel.gov in the epic/ and /eps directories. To
+      obtain the EPIC software, please see Web pages at <a
+      href="http://www.pmel.noaa.gov/epic/download/index.html">http://www.pmel.noaa.gov/epic/download/index.html</a>.
+      For information about EPIC, please see the Web pages at <a
+      href="http://www.pmel.noaa.gov/epic/index.html">http://www.pmel.noaa.gov/epic/index.html</a>.
+      Contact epic at pmel.noaa.gov, or Nancy Soreide, nns at noaapmel.gov, for more information.
+    </p>
+    <p></p>
+
+    <h2><a id="ExcelUse" name="ExcelUse">Excel Use</a></h2>
+
+    <p>
+      Several packages are available for accessing netCDF data from
+      Microsoft Excel,
+      including the <a href="#netcdf4excel" >netcdf4excel</a> add-in for Excel, and a <a
+      href="#SDS" >Scientific Dataset (SDS) Library</a> that supports a
+      DataSetEditor add-in for Excel to view and modify various
+      forms of data, including netCDF.
+    </p>
+    <p></p>
+    <h2><a id="EzGet" name="EzGet">EzGet</a></h2>
+    A FORTRAN library called <a
+    href="http://www-pcmdi.llnl.gov/ktaylor/ezget/ezget.html">EzGet</a> has been developed
+    at <a
+    href="http://www-pcmdi.llnl.gov/PCMDI.html">PCMDI</a> to facilitate retrieval
+    of modeled and observed climate data stored in popular formats including <a
+    href="http://www-pcmdi.llnl.gov/drach/DRS.html">DRS</a>, <a
+    href="/software/netcdf/">netCDF</a>, <a
+    href="http://grads.iges.org/grads">GrADS</a>, and, if a control file is supplied, <a
+    href="ftp://nic.fb4.noaa.gov/pub/nws/nmc/docs/gribed1/">GRIB</a>. You can specify
+    how the data should be structured and whether it should undergo a grid transformation
+    before you receive it, even when you know little about the original structure
+    of the stored data (e.g., its original dimension order, grid, and domain).
+    <p>
+      The EzGet library comprises a set of subroutines that can be linked to any
+      FORTRAN program. EzGet reads files through the <a
+      href="http://www-pcmdi.llnl.gov/drach/cdunif.html">cdunif</a> interface, but use
+      of EzGet does not require familiarity with cdunif. The main advantages of using
+      EzGet instead of the lower level cdunif library include:
+    </p>
+    <ul>
+      <li>
+        Substantial error trapping capabilities and detailed error messages
+      </li>
+      <li>
+        Versatile capability of conveniently selecting data from specified regions
+        (e.g., oceans, North America, all land areas north of 45 degrees latitude,
+        etc.)
+      </li>
+      <li>
+        Ability to map data to a new grid at the time it is retrieved by EzGet
+      </li>
+      <li>
+        Automatic creation of ``weights'' for use in subsequent averaging
+        or masking of data
+      </li>
+      <li>
+        Increased control in specifying the domain of the data to be retrieved.
+      </li>
+    </ul>
+    <p>
+      For more information about EzGet, including instructions for downloading the
+      documentation or software, see the EzGet home page at <a
+      href="http://www-pcmdi.llnl.gov/ktaylor/ezget/ezget.html">http://www-pcmdi.llnl.gov/ktaylor/ezget/ezget.html</a>.
+      For questions or comments on EzGet, contact Karl Taylor (taylor13 at llnl.gov).
+    </p>
+    <h2><a id="FAN" name="FAN">FAN</a></h2>
+    <a href="/software/netcdf/fan_utils.html">FAN (File Array Notation)</a>
+    is Harvey Davies' package for extracting and manipulating array data from
+    netCDF files. The package includes the three utilities nc2text, text2nc, and ncrob
+    for printing selected data from netCDF arrays, copying ASCII data into netCDF
+    arrays, and performing various operations (sum, mean, max, min, product, ...)
+    on netCDF arrays. A library (fanlib) is also included that supports the use of
+    FAN from C programs. The package is available via anonymous FTP from <a
+    href="ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/fan.tar.Z">ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/fan.tar.Z</a>.
+    Questions and comments may be sent to Harvey Davies, harvey.davies at csiro.au.
+    <p></p>
+    <h2><a id="FERRET" name="FERRET">FERRET</a></h2>
+    <a href="http://ferret.wrc.noaa.gov/Ferret/">FERRET</a> is an interactive computer
+    visualization and analysis environment designed to meet the needs of oceanographers
+    and meteorologists analyzing large and complex gridded data sets. It is available
+    by anonymous ftp from abyss.pmel.noaa.gov for a number of computer systems: SUN
+    (Solaris and SUNOS), DECstation (Ultrix and OSF/1), SGI, VAX/VMS and Macintosh
+    (limited support), and IBM RS-6000 (soon to be released).
+    <p>
+      FERRET offers a Mathematica-like approach to analysis; new variables may be
+      defined interactively as mathematical expressions involving data set variables.
+      Calculations may be applied over arbitrarily shaped regions. Fully documented
+      graphics are produced with a single command. Graphics styles included line plots,
+      scatter plots, contour plots, color-filled contour plots, vector plots, wire
+      frame plots, etc. Detailed controls over plot characteristics, page layout and
+      overlays are provided. NetCDF is supported both as an input and an output format.
+    </p>
+    <p>
+      Many excellent software packages have been developed recently for scientific
+      visualization. The features that make FERRET distinctive among these packages
+      are Mathematica-like flexibility, geophysical formatting (latitude/longitude/date),
+      "intelligent" connection to its data base, special memory management
+      for very large calculations, and symmetrical processing in 4 dimensions. Contact
+      Steve Hankin, hankin at noaapmel.gov, for more information.
+    </p>
+    <p></p>
+
+    <h2><a id="fimex" name="fimex" >Fimex</a></h2>
+    <p>
+      Heiko Klein (Norwegian Meteorological Institute) has developed
+      the <a href="https://wiki.met.no/fimex/start" >fimex</a> (File
+      Interpolation, Manipulation, and EXtraction) C++ library
+      for gridded geospatial data.  It converts between several
+      data formats (currently netCDF, NcML, GRIB1 or GRIB2, and felt). Fimex
+      also enables you
+      to change the projection and interpolation of scalar and vector grids,
+      to subset the gridded data, and to extract only parts
+      of the files.  Fimex supports a growing list of other <a
+      href="https://wiki.met.no/fimex/features" >features</a>, including
+      support for most NcML features and for netCDF-4 compression.
+    </p>
+    <p>
+      For simple usage, Fimex also comes with the command line program fimex.
+    </p>
+    <p>
+      Documentation and downloads are available
+      from the <a href="http://wiki.met.no/fimex/" >fimex web site</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="fwtools" name="fwtools">FWTools (GIS Binary Kit for Windows and Linux)</a></h2>
+
+    <p>
+      <a href="http://fwtools.maptools.org/" >FWTools</a> is Frank Warmerdam's set of Open Source GIS
+      binaries for Windows (win32) and Linux (x86 32bit) systems.
+      The kits are intended to be easy for end users to install and get going with, and include OpenEV,
+      GDAL, MapServer, PROJ.4 and OGDI as well as some supporting components.
+      FWTools aims to track the latest development versions of the packages included as opposed to
+      official releases, "to give folks a chance to use the <em>latest and greatest</em>".
+    </p>
+
+    <h2><a id="GDAL" name="GDAL">GDAL</a></h2>
+
+    <p>
+      Frank Warmerdam's <a
+      href="http://www.remotesensing.org/gdal/index.html" >GDAL</a> is a
+      translator library for raster geospatial data formats that is released
+      under an X/MIT style Open Source license.  As a library, it presents a
+      <a href="http://www.remotesensing.org/gdal/gdal_datamodel.html"> single abstract data model</a> to the calling application for all
+      supported formats. The related <a
+      href="http://www.remotesensing.org/gdal/ogr">OGR</a> library (which
+      lives within the GDAL source tree) provides a similar capability for
+      simple features vector data.
+    </p>
+
+    <p>
+      GDAL is in active use in several projects, and includes roughly 40
+      format drivers, including a translator for netCDF (read/write).  Other
+      translators include GeoTIFF (read/write), Erdas Imagine (read/write),
+      ESRI .BIL (read), .aux labeled raw (read/write), DTED (read), SDTS
+      DEM (read), CEOS (read), JPEG (read/write), PNG (read/write), Geosoft
+      GXF (read) and Arc/Info Binary Grid (read). A full list is available
+      in <a
+      href="http://www.remotesensing.org/gdal/formats_list.html">Supported
+      Formats</a>.
+    </p>
+
+    <p>
+      GDAL has recently included support for the netCDF-4 enhanced data
+      model and netCDF-4 format, as well as improved support for recent
+      additions to the CF conventions.
+    </p>
+
+    <p>
+      As an example of the use of GDAL, converting an ArcInfo ASCII grid
+      to netCDF (GMT conventions) as easy as:
+      <pre>
+   gdal_translate arc_ascii.grd -of GMT gmt_grid.nc
+</pre>
+    </p>
+
+    <p></p>
+    <h2><a id="GDL" name="GDL">GDL (GNU Data Language)</a></h2>
+    <p>
+      <a href="http://gnudatalanguage.sourceforge.net/" >GDL</a> is a free
+      implementation of most of the programming language supported by <a href="#IDL" >IDL</a>
+      (Interactive Data Language).  GDL supports the netCDF-3 API.
+    </p>
+
+    <p></p>
+
+    <h2><a id="Gfdnavi" name="Gfdnavi">Gfdnavi (Geophysical fluid data navigator)</a></h2>
+
+    <p>
+      <a
+      href="http://www.gfd-dennou.org/arch/davis/gfdnavi/index.en.htm"
+      >Gfdnavi</a> is a web-based tool to archive, share, distribute, analyze, and
+      visualize geophysical fluid data and knowledge.
+      The software is under development by members of the GFD Dennou Club,
+      including T. Horinouchi (RISH, Kyoto U.), S. Nishizawa (RIMS, Kyoto
+      U.), and colleagues.  Gfdnavi uses a metadata
+      database for managing and analyzing data and visualizations.  It also
+      permits publishing data for web access and will soon support access to
+      data on other Gfdnavi servers.  Web service APIs are now under
+      development.  A presentation <a
+      href="http://www.gfd-dennou.org/arch/davis/gfdnavi/presen/2007-03-05_GfdnaviIntro.En/pub/"
+      >Introducing Gfdnavi</a> describes the architecture and shows examples
+      of use.
+    </p>
+    <p>
+      Gfdnavi is dependent on two technologies:
+      <ul>
+        <li>
+          <a href="http://www.rubyonrails.com/" >Ruby on Rails</a>, a
+          framework for web applications, and
+        </li>
+        <li>
+          <a href="http://ruby.gfd-dennou.org/" >the Dennou Ruby
+          Project</a>,
+          a collection of tools for geophysical
+          data.   These tools include <a
+          href="http://ruby.gfd-dennou.org/products/gphys/" >GPhys</a>
+          software to handle GRIB, GrADS, and netCDF data uniformly.
+        </li>
+      </ul>
+    </p>
+    <p>
+      As an example of this technology, Takuji Kubota has established <a
+      href="http://www.gsmap.aero.osakafu-u.ac.jp/gfdnavi/" >a Gfdnavi server</a> for the
+      Global Satellite Mapping of Precipitation (<a href="http://www.radar.aero.osakafu-u.ac.jp/~gsmap/index_english.html" >GSMaP</a>) project.
+    </p>
+    <p></p>
+
+    <h2><a id="GMT" name="GMT">GMT</a></h2>
+    <p>
+      <a href="http://gmt.soest.hawaii.edu/">GMT</a> (Generic Mapping Tools) is
+      an open source collection of about 60 tools for manipulating
+      geographic and Cartesian data sets (including filtering, trend
+      fitting, gridding, projecting, etc.) and producing Encapsulated
+      PostScript File (EPS) illustrations ranging from simple x-y plots via
+      contour maps to artificially illuminated surfaces and 3-D perspective
+      views. GMT supports 30 map projections and transformations and comes
+      with support data such as coastlines, rivers, and political
+      boundaries. GMT is developed and maintained by Paul Wessel and Walter
+      H. F. Smith with help from a global set of volunteers, and is
+      supported by the National Science Foundation. It is released under
+      the GNU General Public License.
+    </p>
+    <p>
+      The package can access COARDS-compliant netCDF grids as well as ASCII,
+      native binary, or user-defined formats.  The GMT package is available
+      via anonymous ftp from several servers; see <a
+      href="http://gmt.soest.hawaii.edu" >gmt.soest.hawaii.edu</a>
+      for installation information.
+    </p>
+    <p></p>
+    <h2><a id="Grace" name="Grace">Grace</a></h2>
+    <a href="http://plasma-gate.weizmann.ac.il/Grace/">Grace</a> is a tool to make
+    two-dimensional plots of scientific data, including 1D netCDF
+    variables.
+    It runs under the X Window System and
+    OSF Motif (recent versions of LessTif are, by and large, fine, too). Grace runs
+    on practically any version of Unix. As well, it has been successfully ported to
+    VMS, OS/2 and Win9*/NT (some functionality may be missing, though). Grace is a
+    descendant of ACE/gr.
+    <p>
+      A few features of Grace are:
+    </p>
+    <ul>
+      <li>
+        User defined scaling, tick marks, labels, symbols, line styles, colors.
+      </li>
+      <li>
+        Batch mode for unattended plotting.
+      </li>
+      <li>
+        Read and write parameters used during a session.
+      </li>
+      <li>
+        Regressions, splines, running averages, DFT/FFT, cross/auto-correlation,
+        ...
+      </li>
+      <li>
+        Support for dynamic module loading.
+      </li>
+      <li>
+        Hardcopy support for PostScript, PDF, GIF, and PNM formats.
+      </li>
+      <li>
+        Device-independent Type1 font rastering.
+      </li>
+      <li>
+        Ability to read or write netCDF data.
+      </li>
+    </ul>
+    <p></p>
+    <h2><a id="GrADS" name="GrADS">GrADS</a></h2>
+    <a href="http://grads.iges.org/grads/grads.html">GrADS</a> (Grid
+    Analysis and Display System)
+    is an interactive desktop tool from <a
+    href="http://grads.iges.org/cola.html">COLA/IGES</a> that is currently in use
+    worldwide for the analysis and display of earth science data. GrADS is implemented
+    on all commonly available UNIX workstations, Apple Macintosh, and DOS or Linux
+    based PCs, and is freely available via anonymous ftp. GrADS provides an integrated
+    environment for access, manipulation, and display of earth science
+    data in several forms, including GRIB and netCDF.
+    For more information, see the <a
+    href="http://grads.iges.org/grads/gadoc/users.html" >GrADS User's
+    Guide</a>. <p></p>
+    <h2><a id="Gri" name="Gri">Gri</a></h2>
+    Gri is an extensible plotting language for producing scientific graphs, such as
+    x-y plots, contour plots, and image plots. Dan Kelley of Dalhousie University
+    is the author of Gri, which can read data from netCDF files as well as ASCII and
+    native binary data. For more information on Gri, see the URL <a
+    href="http://gri.sourceforge.net/">http://gri.sourceforge.net/</a>. <p></p>
+    <h2><a id="GXSM" name="GXSM">GXSM</a></h2> The GXSM is the Gnome X
+    Scanning Microscopy project, it is a bit more than just a piece of
+    software (the GXSM itself), there is full hardware support for DSP
+    cards including open source DSP software and a growing set of SPM
+    related electronics. For more information, see <a
+    href="http://gxsm.sourceforge.net/">http://gxsm.sourceforge.net/</a>. <p></p>
+    <h2><a id="HDF interface" name="HDF interface">HDF interface</a></h2>
+    The National Center for Supercomputing Applications (NCSA) has added the netCDF
+    interface to their <a
+    href="http://hdf.ncsa.uiuc.edu/">Hierarchical Data Format (HDF)</a> software.
+    HDF is an extensible data format for self-describing files. A substantial set
+    of applications and utilities based on HDF is available; these support raster-image
+    manipulation and display and browsing through multidimensional scientific data.
+    An implementation is now available that provides the netCDF interface to HDF.
+    With this software, it is possible to use the netCDF calling interface to place
+    data into an HDF file. The netCDF calling interface has not changed and netCDF
+    files stored in XDR format are readable, so existing programs and data will still
+    be usable (although programs will need to be relinked to the new library). There
+    is currently no support for the mixing of HDF and netCDF structures. For example,
+    a raster image can exist in the same file as a netCDF object, but you have to
+    use the Raster Image interface to read the image and the netCDF interface to read
+    the netCDF object. The other HDF interfaces are currently being modified to allow
+    multi-file access, closer integration with the netCDF interface will probably
+    be delayed until the end of that project.
+    <p>
+      Eventually, it will be possible to integrate netCDF objects with the rest of
+      the HDF tool suite. Such an integration will then allow tools written for netCDF
+      and tools written for HDF to both interact intelligently with the new data files.
+    </p>
+    <p></p>
+    <h2><a id="HDF-EOS" name="HDF-EOS">HDF-EOS to netCDF converter</a></h2>
+    <p>
+      The
+      Goddard Earth Sciences Data and Information Services Center (<a
+      href="http://disc.gsfc.nasa.gov" >GES DISC</a>)
+      has developed an on-the-fly HDF-EOS to netCDF/CF converter
+      for the following products, making them easier to use in the <a
+      href="#IDV" >Unidata IDV</a> and <a
+      href="http://www.ssec.wisc.edu/mcidas/software/v/" >McIDAS-V</a>:
+      <ul>
+        <li>
+          AIRS Level 2 (scene) profiles of moisture, air temperature and
+          trace gases
+        </li>
+        <li>
+          AIRS Level 3 (global grid) profiles of moisture, air temperature and trace gases
+        </li>
+        <li>
+          OMI UV-B at the surface
+        </li>
+        <li>
+          TOMS ozone and aerosols
+        </li>
+      </ul>
+    <p>
+      <a href="http://disc.gsfc.nasa.gov/services/NetCDFConversionforIDVandMcIDAS-V.shtml" >Instructions</a> are available for searching and converting these data.
+      More information on AIRS products is available at
+      <a href="http://disc.gsfc.nasa.gov/AIRS/index.html"
+      >http://disc.gsfc.nasa.gov/AIRS/index.html</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="HIPHOP" name="HIPHOP">HIPHOP</a></h2>
+    <a
+    href="http://www.knmi.nl/onderzk/atmosam/English/Service/hiphop/hiphop.html">HIPHOP</a>,
+    developed
+    by Dominik Brunner, is a widget based IDL application that largely facilitates
+    the visualization and analysis of 2D, 3D, and 4D atmospheric science data, in
+    particular atmospheric tracer distributions and meteorological fields.
+    <p>
+      Graphical output of (atmospheric model) data can be quickly generated in a
+      large number of different ways, including horizontal maps at selected model
+      or pressure levels, vertical north-south, east-west, or slant cross-sections
+      (including zonal averages), time slices, animations, etc. It also allows mathematical
+      operations on the existing fields to generate new fields for further analysis,
+      and it can be run as a batch application.
+    </p>
+    <p>
+      The program handles data in netCDF, HDF and GRIB format. Interfaces to other
+      data formats (e.g. ASCII and binary data) can be added easily.
+    </p>
+    <p>
+      Beginning with Version 4.0, it also supports the ability to overlay meteorological
+      fields on a number of different satellite images, and to draw air parcel trajectories.
+    </p>
+    <p></p>
+    <h2><a id="Hyperslab OPerator Suite (HOPS)"
+    name="Hyperslab OPerator Suite (HOPS)">Hyperslab OPerator Suite (HOPS)</a></h2>
+    Hyperslab OPerator Suite (<a
+    href="http://www.cgd.ucar.edu/gds/svn/hyperslab.html">HOPS</a>), developed by
+    R. Saravanan at NCAR, is a bilingual, multi-platform software package for processing
+    data in netCDF files conforming to the NCAR-CCM format or the NCAR Ocean Model
+    format. HOPS is implemented in <a href="#IDL">IDL</a>, the widely-used commercial
+    interpreted language, and also in <a
+    href="ftp://ftp-icf.llnl.gov/pub/Yorick/">Yorick</a>, a public-domain interpreted
+    language that is freely available from the Lawrence Livermore National Laboratory.
+    The IDL version of HOPS should run on any platform supported by IDL. The Yorick
+    version too runs on most common UNIX platforms, such as Sun, SGI, Cray, and LINUX
+    computers.
+    <p>
+      HOPS is not a monolithic program, but a suite of operators that act on data
+      units called "hyperslabs". The design of HOPS is object-oriented,
+      rather than procedure-oriented; the operators treat the numeric data and the
+      associated meta-data (like coordinate information) as a single object.
+    </p>
+    <p>
+      Note that HOPS is not a general purpose netCDF utility and works only for the
+      NCAR CSM netCDF formats. For more information, check the <a href="http://www.cgd.ucar.edu/gds/svn/hyperslab.html">HOPS
+      home page</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="iCDF" name="iCDF">iCDF (imports chromatographic netCDF data into MATLAB)</a></h2>
+    <p>
+      Klavs M. Sørensen, Thomas Skov and Rasmus Bro (Faculty of Life
+      Sciences, University of Copenhagen) have developed <a
+      href="http://www.models.life.ku.dk/source/iCDF/index.asp" >iCDF</a>, a
+      free and documented toolbox for importing chromatographic data in the
+      netCDF-based format that most manufacturers of chromatographic
+      software support.
+    </p>
+    <p>
+      The iCDF software is currently for XC-MS data (X: GC, LC, HPLC), but
+      soon it will be able to import data using other detectors as well.  It
+      can be used to open netCDF files from many different instruments
+      (e.g. Agilent, Bruker) and many chromatographic software packages
+      (e.g. ChemStation).
+    </p>
+    <p>
+      For more information, see the paper
+      <blockquote>
+        Skov T and Bro R. (2008) Solving fundamental problems in chromatographic analysis
+        Analytical and Bioanalytical Chemistry, 390 (1): 281-285.
+      </blockquote>
+    </p>
+    <p></p>
+
+    <h2><a id="IDV" name="IDV">IDV (Integrated Data Viewer)</a></h2>
+    <p>
+      Unidata's <a href="/software/idv/"
+      >Integrated Data Viewer (IDV)</a> is a Java application (for Java 1.4
+      or later)
+      that can be used to display a variety of netCDF files, particularly
+      well formatted, geolocated datasets.   Features include:
+      <ul>
+        <li>
+          Access to local and remote netCDF files and a variety of <a
+          href="/software/idv/docs/userguide/data/DataSources.html" >other
+          data formats</a>
+        </li>
+        <li>
+          Slicing and probing of multidimensional data
+        </li>
+        <li>
+          Support for netCDF conventions (CF, COARDS, NUWG, AWIPS)
+        </li>
+        <li>
+          InstallAnywhere installers for easy download and installation
+        </li>
+        <li>
+          Save display state to a bundle for easy recreation of views
+        </li>
+        <li>
+          Support for non-gridded data through the <a
+          href="/software/netcdf-java/CDM/" >Common Data Model (CDM)</a>
+        </li>
+      </ul>
+      The IDV uses the <a href="http://www.ssec.wisc.edu/~billh/visad.html"
+      >VisAD Java library</a> for interactive and collaborative
+      visualization and analysis
+      and the <a href="/software/netcdf-java/" >netCDF Java library</a> for reading and manipulating
+      netCDF files.
+    </p>
+    <p></p>
+
+    <h2><a id="Ingrid" name="Ingrid">Ingrid</a></h2>
+    <p>
+      <a href="http://ingrid.ldgo.columbia.edu/">Ingrid</a>, by M. Benno Blumenthal
+      <benno at ldeo.columbia.edu>, is designed to manipulate large datasets and
+      model input/output. It can read
+      data from its data catalog, a netCDF file, or a directly attached model, and output
+      the data, either by feeding it to a model, creating a netCDF file, or creating
+      plots and other representations of the data.
+    </p>
+    <p>
+      Ingrid has a number of filters which allow simple data manipulations, such
+      as adding two datasets together, smoothing, averaging, and regridding to a new
+      coordinate.  In addition to netCDF, it also reads HDF, CDF, VOGL,
+      and SGI GL.
+    </p>
+    <p>
+      Ingrid is currently running as a WWW daemon that can be accessed through <a
+      href="http://rainbow.ldgo.columbia.edu/datacatalog.html">http://rainbow.ldgo.columbia.edu/datacatalog.html</a>
+      to see some of its capabilities on a climate data catalog maintained by the
+      <a
+      href="http://rainbow.ldeo.columbia.edu/">Climate Group</a> of the <a href="http://www.ldeo.columbia.edu/">Lamont-Doherty
+      Earth Observatory</a> of Columbia University. To quote the introduction:
+    </p>
+    <blockquote>
+      The Data Catalog is both a catalog and a library of datasets, i.e.
+      it both helps you figure out which data you want, and helps you work with the
+      data. The interface allows you to make plots, tables, and files from any dataset,
+      its subsets, or processed versions thereof.
+      <p>
+        This data server is designed to make data accessible to people using WWW
+        clients (viewers) and to serve as a data resource for WWW documents. Since
+        most documents cannot use raw data, the server is able to deliver the data
+        in a variety of ways: as data files (netCDF and HDF), as tables (html), and
+        in a variety of plots (line, contour, color, vector) and plot formats (PostScript
+        and gif). Processing of the data, particularly averaging, can be requested
+        as well.
+      </p>
+      <p>
+        The Data Viewer in particular demonstrates the power of the Ingrid daemon.
+      </p>
+    </blockquote>
+    <p>
+      Ingrid currently runs on Linux, for which binaries are available.
+      CVS access to the current source can be arranged.
+    </p>
+    <p></p>
+
+    <h2><a id="IntelArrayVisualizer" name="IntelArrayVisualizer"> Intel Array Visualizer</a></h2>
+
+    <p>
+      The <a
+      href="http://www.intel.com/cd/software/products/asmo-na/eng/compilers/226277.htm"
+      >Intel® Array Visualizer</a> and Intel® Array Viewer are available as <a
+      href="http://www.intel.com/cd/software/products/asmo-na/eng/compilers/226277.htm"
+      >free downloads</a> for
+      Windows platforms.  They offer an application and a set
+      of software tools and components, which include C, Fortran, and .Net libraries, for
+      developing scientific visualization applications and for creating interactive graphs of
+      array data in various formats, including HDF and netCDF.
+    </p>
+
+    <p></p>
+    <h2><a id="IVE" name="IVE">IVE</a></h2>
+    <p>
+      <a href="http://www.atmos.washington.edu/ive/">IVE (Interactive Visualization
+      Environment)</a> is a software package designed to interactively display and analyze
+      gridded data. IVE assumes the data to be displayed are contained in one- two-,
+      three- or four-dimensional arrays. By default, the numbers within these arrays
+      are assumed to represent grid point values of some field variable (such as pressure)
+      on a rectangular evenly spaced grid. IVE is, nevertheless, capable of displaying
+      data on arbitrary curvilinear grids.
+    </p>
+    <p>
+      If the data points are not evenly spaced on a rectangular grid, IVE must be
+      informed of the grid structure, either by specifying "attributes"
+      in the data input or by specifying the coordinate transform in a user supplied
+      subroutine. Stretched rectangular grids (which occur when the stretching along
+      a given coordinate is a function only of the value of that coordinate) can be
+      accommodated by specifying one-dimensional arrays containing the grid-point
+      locations along the stretched coordinate as part of the IVE input data. Staggered
+      meshes can also be accommodated by setting "attributes" in the input
+      data. The structure of more complicated curvilinear grids must be communicated
+      to IVE via user supplied "transforms," which define the mapping between
+      physical space and the array indices.
+    </p>
+    <p>
+      Since four-dimensional data cannot be directly displayed on a flat computer
+      screen, it is necessary to reduced the dimensionality of the data before it
+      is displayed. One of IVE's primary capabilities involves dimension reduction
+      or "data slicing." IVE allows the user to display lower-dimensional
+      subsets of the data by fixing a coordinate or by averaging over the coordinate.
+    </p>
+    <p>
+      IVE currently has the capability to display
+    </p>
+    <ul>
+      <li>
+        scalar fields as
+        <ul>
+          <li>
+            2D scalar plots
+          </li>
+          <li>
+            1D scalar plots
+          </li>
+          <li>
+            vertical soundings
+          </li>
+          <li>
+            a single point value
+          </li>
+        </ul>
+      </li>
+      <li>
+        vector fields as 2D vector plots
+      </li>
+    </ul>
+    <p>
+      IVE lets you overlay plots, loop plots, and control a wide variety of display
+      parameters.
+    </p>
+    <p>
+      IVE also can perform algebraic computations on the gridded data and can calculate
+      derivatives. More complicated computations can be performed in user supplied
+      subroutines.
+    </p>
+    <p>
+      IVE uses NetCDF for the data input format, and uses the <a
+      href="http://ngwww.ucar.edu/ng/">NCAR Graphics Library</a> to produce graphical
+      output. IVE is <a
+      href="http://www.atmos.washington.edu/ive/getting.html">available</a> as source
+      via anonymous ftp; and as binary on request for licensees of NCAR graphics.
+    </p>
+    <p></p>
+    <h2><a id="JSON" name="JSON">JSON format with the ncdump-json utility</a></h2>
+    <p>
+      Josep Llodrà has developed a program to output the contents
+      of a netCDF-3 or netCDF-4 file in
+      JSON (JavaScript Object Notation).
+      It is based on Unidata's NCDUMP utility,
+      and it keeps the original ncdump functionality, unless the "-j" option
+      is used to specify JSON output.
+    </p>
+    <p>
+      The program and source are available from <a
+      href="https://github.com/jllodra/ncdump-json"
+      >https://github.com/jllodra/ncdump-json</a>
+      .
+    </p>
+    <p></p>
+
+    <h2><a id="Java interface" name="Java interface">Java interface</a></h2>
+    <p>
+      The <a href="/software/netcdf-java/"
+      >NetCDF-Java 4.2 Library</a> is a Java interface to netCDF files,
+      as well as to many other types of scientific data formats. It
+      is freely available and the source code is released under the
+      (MIT-style) netCDF C library license. Previous versions use the GNU
+      Lesser General Public License (LGPL).
+    </p>
+    <p>
+      The library implements a Common Data Model (<a
+      href="/software/netcdf-java/CDM/" >CDM</a>), a generalization
+      of the netCDF, OpenDAP and HDF5 data models. The library is a
+      prototype for the netCDF-4 project, which provides a C language API
+      for the "data access layer" of the CDM, on top of the HDF5 file
+      format. The NetCDF-Java library is a 100% Java framework for <em>reading</em> netCDF
+      and other file formats into the CDM, as well as <em>writing</em> to the
+      netCDF-3 file format.
+      The library also implements <a
+      href="http://www.unidata.ucar.edu/software/netcdf/ncml/">NcML</a>,
+      which allows you to add metadata to CDM datasets, as well as to create
+      virtual datasets through aggregation.
+    </p>
+
+    <h2><a id="KST" >Kst (2D plotting tool)</a></h2>
+
+    <p>
+      <a href="http://kst-plot.kde.org" >Kst</a> is an open-source, cross-platform 2D plotting tool focused on
+      performance and ease of use. Packages for Windows, various Linux
+      distributions and Mac OS X are <a
+      href="http://sourceforge.net/projects/kst/files/"
+      >available</a>,
+      as well as the complete
+      source code and CMake-based build files.  A more detailed presentation
+      of Kst can be found on the web page at <a href="http://kst-plot.kde.org" >http://kst-plot.kde.org</a>,
+      including numerous screenshots and all the useful download links.
+    </p>
+    <p>
+      Kst is characterized by the following features:
+    </p>
+    <ul>
+      <li>
+        Outstanding performance: curves with millions of points are no problem
+      </li>
+      <li>
+        Plotting of live streams
+      </li>
+      <li>
+        Out-of-the box support for a variety of formats (currently ASCII, netCDF, dirfile, Qimage-supported types, fits images)
+      </li>
+      <li>
+        User-friendly with a modern and consistent user interface
+      </li>
+      <li>
+        A set of unique tools to boost efficiency, including a data import wizard, capacity to edit multiple objects at once or the "Change Data File" tool to compare multiple experiments easily
+      </li>
+      <li>
+        An active community
+      </li>
+      <li>
+        Easily expandable for new data formats or data analysis algorithms thanks to a plugin-based architecture
+      </li>
+      <li>
+        Available on Windows, Linux, and Mac OSX
+      </li>
+    </ul>
+
+    <h2><a id="Labview-API" >Labview interface</a></h2>
+
+    <p>
+      A netCDF Labview interface, implemented in the Labview programming
+      language is available.  The software includes A graphical user
+      interface for editing netCDF data and
+      conversion to other data formats.  The package was developed and is
+      maintained by L. F. Hwang of Sun Yat-sen University in China.
+      For more information
+      and to download the source code, see the <a
+      href="https://sourceforge.net/projects/netcdflabview/" >NetCDFLabview
+      web site</a>.
+    </p>
+
+    <h2><a id="MBDyn" name="MBDyn">MBDyn (MultiBody Dynamics)</a></h2>
+    <p>
+      <a href="http://www.aero.polimi.it/~mbdyn/" >MBDyn</a> is an open-source
+      MultiBody Dynamics analysis system
+      developed at the Dipartimento di Ingegneria Aerospaziale of the
+      University "Politecnico di Milano", Italy.  It uses netCDF as its
+      primary output format.
+    </p>
+    <p>
+      MBDyn features the
+      integrated multidisciplinary analysis of multibody, multiphysics
+      systems, including nonlinear mechanics of rigid and flexible
+      constrained bodies, smart materials, electric networks, active
+      control, hydraulic networks, essential fixed-wing and rotorcraft
+      aerodynamics.  It allows users to simulate the behavior of heterogeneous
+      mechanical, aero-servo-elastic systems based on first principles
+      equations.  It is being actively developed and used in the aerospace
+      and automotive fields for dynamics analysis and simulation of complex
+      systems.  Dynamic linking of
+      user-defined modules is heavily exploited to let users extend the
+      feature library.
+    </p>
+    <p></p>
+
+    <h2><a id="Max_diff_nc" name="Max_diff_nc">Max_diff_nc</a></h2>
+
+    <p>
+      This is a program which compares two NetCDF files. Variables with the
+      same ID in the two files are assumed to be of the same type and have
+      the same shape.  For each such couple of variables, the program
+      computes the maximum of the absolute value of the difference, and the
+      maximum of the absolute value of the relative difference. The program
+      also tells you at what location (the subscript list of the array) the
+      maximum difference is reached.
+
+    <p>
+      The web page for this program is: <a href="http://web.lmd.jussieu.fr/~lglmd/Max_diff_nc">http://web.lmd.jussieu.fr/~lglmd/Max_diff_nc</a>
+
+    <p>
+      This is a freely available tool.
+    </p>
+    <p></p>
+
+    <h2><a id="MeteoExplorer" name="MeteoExplorer"></a>MeteoExplorer</h2>
+
+    <p>
+      <a href="http://www.eastmodelsoft.com/index_en.htm"
+      >MeteoExplorer</a>, developed by Lianqing Yu at China Meteorological
+      Administration, is a cross-platform software application for analyzing
+      and rendering atmospheric science and geoscience data. It supports
+      popular data formats including WMO GRIB1/GRIB2, NetCDF, and MICAPS,
+      and provides basic GIS functionalities. Developed with C++, Meteo
+      Explorer targets multiple computing platforms including Microsoft
+      Windows, GNU Linux, and SGI IRIX operating systems.
+    </p>
+
+    <p>
+      The primary features include:
+    </p>
+    <ul>
+      <li>
+        Graphics layer management (navigation and animation)
+      </li>
+      <li>
+        Objective analysis of physical elements in surface or upperair soundings data
+      </li>
+      <li>
+        Isoline analysis and shading of grid field
+      </li>
+      <li>
+        Streamline analysis of wind field
+      </li>
+      <li>
+        Computation of physics elements
+      </li>
+      <li>
+        NetCDF data process and display
+      </li>
+      <li>
+        GRIB1/GRIB2 data process and display
+      </li>
+      <li>
+        MICAPS data process and display
+      </li>
+      <li>
+        Satellite nephogram data display and animation, support AWX, GPF and HDF format
+      </li>
+      <li>
+        Interactive composition of synoptic chart (command undo/redo, automatic save)
+      </li>
+      <li>
+        Map zoom, pan, projection and clipping
+      </li>
+      <li>
+        Full screen display and zoom to area
+      </li>
+      <li>
+        Quick navigation via thumbnail view of graphics layers
+      </li>
+      <li>
+        Save screen shot as image file (support formats: BMP, JPG, PNG)
+      </li>
+      <li>
+        Vector graphics exported to clipboard or saved as EMF file (Windows version only)
+      </li>
+      <li>
+        Remote desktop connection support
+      </li>
+      <li>
+        System configuration (dynamic menu)
+      </li>
+      <li>
+        Fast switch of user interface language on the fly
+      </li>
+    </ul>
+    <p>
+      For more information, please visit <a
+      href="http://www.eastmodelsoft.com/software/mexplorer.htm"
+      >MeteoExplorer's home page</a> or contact the support staff via
+      meteoexplorer at hotmail.com .
+    </p>
+
+    <p></p>
+    <h2><a id="MeteoInfo" name="MeteoInfo"></a>MeteoInfo</h2>
+
+    <p>
+      For better cross-platform support, <a
+      href="http://www.meteothinker.com" >MeteoInfo</a> has recently been re-developed
+      using Unidata's NetCDF Java library.  MeteoInfo is GIS software for
+      visualization and analysis of spatial and meteorological data.
+      The Java edition can be run in Windows, Mac OS, Linux, and
+      Unix systems.  The Groovy script engine was coupled
+      in the software, so users can write Groovy script to run the software
+      automatically for analysis with complex steps.
+    </p>
+
+    <p>
+      Download: <a href="http://www.meteothinker.com/" >http://www.meteothinker.com/</a>
+    </p>
+
+    <p>
+      Java 6 is needed to run the software.
+    </p>
+
+    <p></p>
+    <h2><a id="MexEPS" name="MexEPS">MexEPS</a></h2>
+    <a href="http://www.pmel.noaa.gov/">PMEL</a> has developed a MATLAB interface, <a
+    href="http://www.epic.noaa.gov/epic/software/mexeps.htm">MexEPS</a>, which supports
+    several netCDF file conventions, including <a
+    href="ftp://ftp.unidata.ucar.edu/pub/netcdf/Conventions/PMEL-EPIC/"> those adopted
+    by PMEL</a>. Many styles of time axes are supported and time manipulation routines
+    ease the use of the time axis in MATLAB. The MexEPS package supports the following
+    data formats:
+    <ul>
+      <li>
+        reading, writing and editing netCDF files;
+      </li>
+      <li>
+        reading and writing Classic EPIC files
+      </li>
+      <li>
+        reading formatted ASCII files
+      </li>
+    </ul>
+    It includes:
+    <ul>
+      <li>
+        VARIABLE, AXIS, ATTRIBUTE manipulation routines
+      </li>
+      <li>
+        TIME manipulation
+        <ul>
+          <li>
+            TIME enters MATLAB as YYMMDDhhmmss.fff
+          </li>
+          <li>
+            Can be converted to netCDF udunits time convention (e.g. days <i>since</i>
+            1990-01-01 00:00:00)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <a href="ftp://ftp.pmel.noaa.gov/eps/mexeps/help-m/">MATLAB help</a> and <a
+        href="ftp://ftp.pmel.noaa.gov/eps/mexeps/examples/">example scripts</a> using
+        MexEPS
+      </li>
+      <li>
+        <b>ASCII2MAT</b> mexFunction, which reads a formatted file into MATLAB as
+        a matrix
+      </li>
+    </ul>
+    <p>
+      The MexEPS package is freely available in PMEL's anonymous ftp directory <a
+      href="ftp://ftp.pmel.noaa.gov/eps/mexeps/">ftp://ftp.pmel.noaa.gov/eps/mexeps/</a>
+    </p>
+    <p>
+      If you have any questions or comments, please contact the author, Willa Zhu <a
+      href="mailto:willa at pmel.noaa.gov">(willa at pmel.noaa.gov)</a> or Nancy Soreide (nns at pmel.noaa.gov).
+    </p>
+    <p></p>
+    <h2><a id="MEXNC" name="MEXNC">MEXNC and SNCTOOLS</a></h2>
+    <p>
+      John Evans of Rutgers University maintains MEXNC and developed SNCTOOLS.
+      <a href="http://mexcdf.sourceforge.net/" >MEXNC</a> is a mexfile
+      interface to NetCDF files for MATLAB that has roughly a one-to-one
+      equivalence with the C API for netCDF. <a
+      href="http://mexcdf.sourceforge.net/tutorial/index.html"
+      >SNCTOOLS</a> is a set of
+      higher-level m-files that sit atop MEXNC, shielding the user from
+      such low level netCDF details as file IDs, variable IDs, and dimension
+      IDs.  The general philosophy behind SNCTOOLS is providing the ability
+      to read and write data without trying to invent a new syntax.
+    </p>
+
+    <p></p>
+    <h2><a id="Mirone" name="Mirone">Mirone (Windows MATLAB-based display)</a></h2>
+
+    <p>
+      Joaquim Luis of Universidade do Algarve has developed <a href="http://w3.ualg.pt/~jluis/mirone/">Mirone</a>,
+      a Windows MATLAB-based framework tool that
+      allows the display and manipulation of a large number of grid/images
+      formats through its interface with the <a
+      href="http://remotesensing.org/gdal/" >GDAL</a> library. Its main
+      purpose is to provide users with an easy-to-use graphical interface to
+      manipulate <a href="http://gmt.soest.hawaii.edu/" >GMT</a> grids. In
+      addition it offers a wide range of tools
+      dedicated to topics in the earth sciences, including tools for
+      multibeam mission planning, elastic deformation studies, tsunami
+      propagation modeling, earth magnetic field computations and magnetic
+      Parker inversions, Euler rotations and poles computations, plate
+      tectonic reconstructions, and seismicity and focal mechanism
+      plotting. The high quality mapping and cartographic capabilities for
+      which GMT is renowned is guaranteed through Mirone's ability to
+      automatically generate GMT cshell scripts and dos batch files.
+    </p>
+    <p>
+      Although Mirone is written in MATLAB, a stand-alone version to run
+      under Windows is also provided. Regrettably this version is not as
+      efficient as the native MATLAB code but provides a solution for users
+      that don't have MATLAB.
+    </p>
+    <p>
+      Also see
+      <br>
+      J. F. Luis. Mirone: A multi-purpose tool for exploring grid
+      data. Computers & Geosciences, 33, 31-41, 2007.
+    </p>
+    <p></p>
+    <h2><a id="ncBrowse" name="ncBrowse">ncBrowse</a></h2>
+    <p>
+      Donald Denbo of NOAA's Pacific Marine Environmental Laboratory has developed
+      and made available <a
+      href="https://www.nodc.noaa.gov/woce/woce_v3/wocedata_1/utils/netcdf/ncbrowse/index.htm">ncBrowse</a>, a Java application
+      (JDK1.2) that provides flexible, interactive graphical displays of data and attributes
+      from a wide range of netCDF data file conventions. Features include:
+    </p>
+    <ul>
+      <li>
+        Designed to work with arbitrary netCDF files.
+      </li>
+      <li>
+        Browses file using the EPIC and COARDS conventions.
+      </li>
+      <li>
+        Provides a "tree" view of the netCDF file.
+      </li>
+      <li>
+        Handles character variables.
+      </li>
+      <li>
+        Handles dimensions without an associated variable.
+      </li>
+      <li>
+        Uses sgt graphics to perform 1 and 2 dimensional cuts through data.
+      </li>
+      <li>
+        Save to file single variable as a "cdl" text file.
+      </li>
+      <li>
+        InstallAnywhere scripts for UNIX, Win32, and MacOS.
+      </li>
+      <li>
+        Currently uses Java 2 and Swing.
+      </li>
+    </ul>
+    <p>
+      ncBrowse will run on any UNIX or Windows machine with a Java 2 (JDK1.2) virtual
+      machine installed. Automated installation scripts are available for Windows and
+      UNIX. Additional information on ncBrowse and download instructions are available
+      at <a
+      href="http://www.epic.noaa.gov/java/ncBrowse">http://www.epic.noaa.gov/java/ncBrowse</a>.
+    </p>
+    <p>
+      Questions and suggestions should be directed to <<a
+      href="mailto:dwd at pmel.noaa.gov">dwd at pmel.noaa.gov></a>. If you have problems
+      reading a netCDF file with ncBrowse, please send him a copy of the file and
+      he'll get ncBrowse to read it!
+    </p>
+    <p></p>
+    <h2><a id="nccmp" name="nccmp">nccmp</a></h2>
+    <p>
+      Remik Ziemlinski of the NOAA Geophysical Fluid Dynamics Laboratory has
+      developed <a href="http://nccmp.sourceforge.net/" >nccmp</a>,
+      a tool to compare two netCDF files.
+      It can use MPI, include/exclude specific
+      variables or metadata and operates quickly.
+      Highly recommended for regression testing with large datasets.
+      See the Web site
+      <a href="http://nccmp.sourceforge.net/"
+      >http://nccmp.sourceforge.net/</a> for more information.
+    <p></p>
+    <h2><a id="NCL" name="NCL">NCL</a></h2>
+    <p>
+      The <a href="http://www.ncl.ucar.edu/" >NCAR Command Language
+      (NCL)</a> is an intepreted programming
+      language for scientific data analysis and visualization developed and
+      maintained in
+      NCAR's <a href="http://www.cisl.ucar.edu/">Computational and Information Systems
+      Laboratory</a>.
+    </p>
+    <p>
+      NCL has many features common to modern programming languages,
+      including types, variables, operators, expressions, conditional
+      statements, loops, and functions and procedures.  NCL also has
+      features that are not found in other programming languages, including
+      those that handle the manipulation of metadata, the configuration of
+      visualizations, the import of data from a variety of data formats, and
+      an algebra that supports array operations.
+    </p>
+    <p>
+      NCL has robust file input and output capabilities. It allows different
+      datasets of different formats (netCDF, netCDF-4 classic, HDF4, HDF4-EOS,
+      GRIB-1, and GRIB-2) to
+      be imported into one uniform and consistent data manipulation
+      environment, which internally is the netCDF data format.  NCL doesn't
+      place any restrictions or conventions on the organization of input
+      netCDF files.
+    </p>
+    <p>
+      NCL comes with many useful built-in functions and procedures for
+      processing and manipulating data. There are over 600 functions and
+      procedures that include routines for use specifically with climate and
+      model data, empirical orthogonal functions, Fourier
+      coefficients, wavelets, singular value decomposition, 1-, 2-, and
+      3-dimensional interpolation, approximation, and regridding, and
+      computer analysis of scalar and vector global geophysical quantities.
+    </p>
+    <p>
+      The visualizations are publication-quality and highly customizable,
+      with hundreds of options available for tweaking the looks of your
+      graphics. NCL can generate contours, XY plots, vectors, streamlines,
+      and can overlay these plots on many different map projections.  There
+      are also specialized functions for generating histograms, wind roses,
+      meteograms, skew-T plots, weather maps.
+    </p>
+    <p>
+      Included with the software are two command line tools:
+      "ncl_convert2nc" for converting GRIB-1/2 or HDF files to netCDF
+      files, and "ncl_filedump" which will dump the contents of a file
+      format that NCL recognizes (netCDF, GRIB-1/2, HDF, etc).
+    </p>
+    <p>
+      NCL is available under an open source license or in binary form for
+      several popular UNIX platforms, including (but not limited to) Linux,
+      MacOSX, and Windows/Cygwin.
+    </p>
+    <p>
+      Documentation and additional information on NCL are available from the
+      <a href="http://www.ncl.ucar.edu/">NCL website</a>, which contains
+      hundreds of <a
+      href="http://www.ncl.ucar.edu/Applications/">application examples</a>
+      for one to download. You can also contact Mary Haley, at <a
+      href="mailto:haley at ucar.edu">haley at ucar.edu</a> for more information.
+
+    <p></p>
+    <h2><a id="NCO" name="NCO">NCO</a></h2>
+    <a href="http://nco.sourceforge.net">NCO</a> (netCDF operators) is a package of
+    command line operators that work on generic netCDF or HDF4 files:
+    <ul>
+      <li>
+        ncap2 - arithmetic processor
+      </li>
+      <li>
+        ncatted - attribute editor
+      </li>
+      <li>
+        ncbo - binary operator
+      </li>
+      <li>
+        ncdiff - differencer
+      </li>
+      <li>
+        ncea - ensemble averager
+      </li>
+      <li>
+        ncecat - ensemble concatenator
+      </li>
+      <li>
+        ncflint - file interpolator
+      </li>
+      <li>
+        ncks - kitchen sink (extract, cut, paste, print data)
+      </li>
+      <li>
+        ncpdq - permute dimensions quickly
+      </li>
+      <li>
+        ncra - running averager
+      </li>
+      <li>
+        ncrcat - record concatenator
+      </li>
+      <li>
+        ncrename - renamer
+      </li>
+      <li>
+        ncwa - weighted averager
+      </li>
+    </ul>
+
+    <p>
+      All operators may now be <a href="http://www.opendap.org">OPeNDAP</a> clients. OPeNDAP enables
+      network transparent data access to any OPeNDAP server. Thus OPeNDAP-enabled NCO can
+      operate on remote files accessible through any OPeNDAP server without transferring
+      the files. Only the required data (e.g., the variable or hyperslab specified)
+      are transferred.
+    </p>
+    <p>
+      The source code is freely available from the <a
+      href="http://nco.sourceforge.net/">NCO home page</a>, as is the NCO User's
+      Guide.
+    </p>
+    <p>
+      For more information, contact the author, Charlie Zender.
+    </p>
+    <p></p>
+    <h2><a id="ncregrid" name="ncregrid">ncregrid</a></h2>
+    <p>
+      Patrick Jöckel of the Max Planck Institute for Chemistry has developed <strong>ncregrid</strong>,
+      a tool (written in FORTRAN-90) for data transfer of gridded 2- and 3-dimensional
+      (spatial) geophysical/geochemical scalar fields between grids of different resolutions.
+      The algorithm handles data on rectangular latitude/longitude grids (not necessarily
+      evenly spaced) and vertical pressure hybrid grids of arbitrary resolution. The
+      input/output data format is netCDF. ncregrid is freely available without any
+      warranty under the GNU public license (GPL). ncregrid can be used as a "stand-alone"
+      program, and/or linked as an interface to a model, in order to re-grid automatically
+      the input from an arbitrary grid space onto the required grid resolution.
+    </p>
+    <p>
+      More information is available on the web-page: <a href="http://www.mpch-mainz.mpg.de/~joeckel/ncregrid/index.html" > http://www.mpch-mainz.mpg.de/~joeckel/ncregrid/index.html</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="nctoolbox" name="nctoolbox">nctoolbox (a MATLAB common data model interface)</a></h2>
+
+    <p>
+      <a
+      href="http://nctoolbox.github.io/nctoolbox/" >nctoolbox</a> is a MATLAB
+      interface that provides read-only access to <a
+      href="/software/netcdf-java/CDM/index.html" >Common Data Model</a>
+      datasets.
+      Under the hood, nctoolbox uses Unidata's NetCDF-Java as the data access layer.
+      This allows nctoolbox to access to netCDF, OPeNDAP, HDF5, GRIB, GRIB2, HDF4,
+      and many (15+) other file formats and services using the same API.
+      It works with MATLAB 2008a and later.  The nctoolbox software was
+      developed by Brian Schlining (MBARI), Rich Signell
+      (USGS), Sachin Kumar Bhate (freelance), and Alex Crosby (RPS/ASA).
+    </p>
+
+    <p></p>
+
+    <h2><a id="ncdx" name="ncdx">ncdx</a></h2>
+    <p>
+      Patrick Jöckel of the Max Planck Institute for Chemistry has developed <strong>ncdx</strong>,
+      a tool (written in FORTRAN-90) that scans a netCDF file and makes it <a href="#OpenDX" >OpenDX</a>
+      compliant. ncdx is freely available without any warranty under the GNU public
+      license (GPL). More information is available on the web-page: <a href="http://www.mpch-mainz.mpg.de/~joeckel/ncdx/index.html" > http://www.mpch-mainz.mpg.de/~joeckel/ncdx/index.html</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="ncensemble" name="ncensemble">ncensemble</a></h2>
+    <p>
+      Alan Iwi, of Rutherford Appleton Laboratory, offers this command
+      line ensemble statistics utility. More information is available on
+      the web-page: <a href="http://home.badc.rl.ac.uk/iwi/ncensemble/" > http://home.badc.rl.ac.uk/iwi/ncensemble/</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="ncview" name="ncview">ncview</a></h2>
+    <a
+    href="http://meteora.ucsd.edu/~pierce/ncview_home_page.html">Ncview</a> is a visual
+    browser for netCDF files. Typically you would use ncview to get a quick and easy,
+    push-button look at your netCDF files. You can view simple movies of the data,
+    view along various dimensions, take a look at the actual data values, change color
+    maps, invert the data, etc. It runs on UNIX platforms under X11, R4 or higher.
+    For more information, check out the <a
+    href="http://meteora.ucsd.edu/~pierce/docs/ncview.README">README</a> file; you
+    can also see a representative <a
+    href="http://meteora.ucsd.edu/~pierce/docs/ncview.gif">screen image</a> (GIF,
+    66K) of ncview in action.
+    <p>
+      The source may be downloaded from <a
+      href="ftp://cirrus.ucsd.edu/pub/ncview/">ftp://cirrus.ucsd.edu/pub/ncview/</a>.
+      For more information, please contact the author, David W. Pierce at <a href="mailto:dpierce at ucsd.edu">dpierce at ucsd.edu</a>.
+    </p>
+
+    <h2><a id="NC4ML5" name="NC4ML5">NetCDF Toolbox for MATLAB-5</a></h2>
+    The <a
+    href="http://mexcdf.sourceforge.net/">NetCDF Toolbox for
+    MATLAB-5</a>, originally developed by Charles R. Denham, combined netCDF-3 with <a
+    href="http://www.mathworks.com/products/matlab/">MATLAB</a> to form an interface that
+    used MATLAB operator-syntax for arithmetic, logical, and subscripting operations
+    on netCDF entities.  The NetCDF Toolbox is in bug-fix-only mode, and is
+    maintained by John.G.Evans.NE at gmail.com,
+    on the <a href="http://mexcdf.sf.net" > MEXNC, SNCTOOLS, and the
+    NetCDF Toolbox</a> web page.
+    </p>
+    <p></p>
+
+    <h2><a id="ncvtk" name="ncvtk">ncvtk</a></h2>
+
+    <p>
+      <a href="http://ncvtk.sourceforge.net/" >Ncvtk</a> is a program for
+      exploring planetary data stored in a NetCDF file.
+      The NetCDF file  should loosely follow the <a
+      href="http://www.cgd.ucar.edu/cms/eaton/cf-metadata/" >CF metadata
+      conventions</a>.
+    </p>
+    <p>
+      Ncvtk was designed from the ground up with the aim of offering a high
+      degree of interactivity to scientists who have a need to explore
+      structured, three-dimensional, time-dependent climate data on the
+      sphere. A graphical user interface allows users to interact with their
+      data via color/transparency/contour/vector plots, apply vertical slices,
+      probe data, apply an external sun light, overlay hydrographic and
+      geopolitical data, rotate, zoom, etc. with minimal fuss.
+    </p>
+    <p>
+      Ncvtk is written in python and is based on the <a
+      href="http://public.kitware.com/VTK/" >Visualization Toolkit
+      (VTK)</a>. Like python and VTK, Ncvtk is
+      highly portable and known to run on Windows and Linux (i386, ia64,
+      EMT64) platforms. More information about Ncvtk is available at <a
+      href="http://ncvtk.sourceforge.net"
+      >http://ncvtk.sourceforge.net</a>.
+    </p>
+
+    <p></p>
+
+    <h2><a id="netcdf_tools" name="netcdf_tools">Ivan Shmakov's netcdf tools</a></h2>
+
+    <p>
+      The NetCDF tools is a free software package consisting of a few
+      tools operating on NetCDF and, by utilizing the compatibility API,
+      HDF4 files, which are intended to be usable from Shell scripts.
+    </p>
+    <p>
+      The currently packaged tools are:
+    </p>
+    <ul>
+      <li>
+        a couple of simple shell wrappers over the respective NetCDF
+        functions (ncattget and ncattput);
+      </li>
+      <li>
+        a more sophisticated ncget tool.
+      </li>
+    </ul>
+    <p>
+      The ncget tool implements functionalilty that is similar to hdp
+      dumpsds (for NetCDF, which lacks such a tool), or complements it in
+      the case of HDF4. It can be seen as a complement to the ncdump tool
+      (included in both the NetCDF and HDF4 distributions) as well.
+    </p>
+    <p>
+      This tool allows a selected part of a NetCDF variable or an HDF4
+      scientific data set (SDS) to be extracted in either an ASCII or
+      binary form, applying the transformation specified by the usual
+      scale_factor and add_offset attributes. It allows one to feed the
+      data contained in NetCDF variables (or HDF4 SDS) to the tools
+      designed to operate on either ASCII (text) or raw (binary) data.
+    </p>
+    <p>
+      This version of the package is the first one to be announced to the
+      public. It has some known bugs and limitations, but it's proved to
+      be quite usable.  A <a
+      href="http://freshmeat.net/projects/netcdf-tools" >project page</a> on
+      freshmeat.net.  The <a
+      href="http://waterlily.siamics.net/~ivan/src/netcdf-tools-0.1-rc1.tar.gz"
+      >source</a> is also available.
+    </p>
+
+    <h2><a id="netcdf4excel" name="netcdf4excel">netcdf4excel (add-in for MS Excel)</a></h2>
+    <p>
+      Alexander Bruhns
+      <bruhns at free.fr>
+        has developed <a
+        href="http://code.google.com/p/netcdf4excel/" >a netCDF add-in written in
+        Visual Basic for MS Excel</a>.  This add-in simplifies the use of
+        NetCDF data in Excel, providing a ready to use solution for
+        manipulating this type of data.
+    </p>
+    <p>
+      For developers, the open-source (GPL V3 license) can be downloaded
+      directly or checked out with Mercurial.
+    </p>
+    <p>
+      The add-in is written in VBA 6.0 (so it won't work with Office 2010 64 bits) and is designed for Excel 2007 running with the Microsoft Windows operating system.
+      It supports opening netCDF classic format data with Excel for read or
+      write access.
+    </p>
+    <p>
+      More details are available on the <a
+      href="http://code.google.com/p/netcdf4excel/" >netcdf4excel web
+      site</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="netcdf95" name="netcdf95">NetCDF95 alternative Fortran API</a></h2>
+
+    <p>
+      Lionel Guez has developed and made feely available <a
+      href="http://web.lmd.jussieu.fr/~lglmd/NetCDF95" >NetCDF95</a>, a new
+      alternative Fortran interface to the NetCDF library.  Compared to the
+      Unidata-provided Fortran 90 netCDF interface, the NetCDF95 interface
+      is meant to be easier to use and more secure.
+    </p>
+
+    <h2><a id="Objective-C" name="Objective-C">Objective-C API</a></h2>
+
+    <p>
+      Tom Moore has an Objective-C API, available here: <a href="http://www.paleoterra.com/software" >www.paleoterra.com/software</a>.
+
+      The netCDF Framework is an open source (Argonne Open Source License)
+      MacOSX application framework that provides an Objective-C interface
+      to the NCAR netCDF library version 3.  The framework is available
+      both as source code and universal compiles (works on both PPC and
+      Intel macs).  The source code has also been compiled by users for the
+      GNUStep environment.   Version 2 of the framework will provide
+      classes for accessing multiple netCDF files, working with in-memory
+      data slabs using standard notation, and some support for
+      multithreading.
+
+      <h3>Mark Tracy's Objective-C API</h3>
+
+    <p>
+      Mark Tracy has written <a href="http://www.mt-se.com/nc_1.html"
+      >NetcdfStep</a>, an Objective-C
+      API for netCDF that uses Objective-C Foundation Classes.
+
+    <p>
+      NetcdfStep is framework for using the netCDF library in
+      object-oriented programming with Objective-C. It now
+      supports the full functionality of netCDF 3.6.2.
+    </p>
+    <p>
+      A <a
+      href="http://www.mt-se.com/pub/NetcdfStep-1.0.2.zip" > complete Mac OS X distribution</a> including pre-built static library and <a
+      href="http://www.mt-se.com/netcdfstep_doc/" >online documentation</a>
+      are available.  Applications linked to this framework have no external
+      dependencies (other than Mac OS X itself).
+      A <a href="http://www.mt-se.com/pub/NetcdfStep-GNUstep-0.6.1.tar.gz" > source-code only distribution</a> synced up to version 0.6.1 is
+      available for GNUstep for use on
+      Linux and other Unix platforms.
+    </p>
+
+    <p></p>
+    <h2><a id="NCMEX" name="NCMEX">Octave interface</a></h2>
+
+    <p>
+      The ARM Program has contributed NCMEX for Octave, a port of Chuck
+      Denham's MATLAB NCMEX to <a href="http://www.octave.org" >Octave</a>.  The
+      calling syntax
+      is identical, so scripts using NCMEX in MATLAB should in theory be
+      portable to Octave.  In order to build NCMEX, a compiled C NetCDF
+      library must already be installed.
+    </p>
+    <p>
+      In addition to the base NetCDF library interface, this package includes a
+      simple toolbox to automate the reading and writing of NetCDf files
+      within Octave using NCMEX.  These tools as well as the source for
+      NCMEX are available from <a
+      href="http://engineering.arm.gov/~sbeus/octavex/octavex.tar" > http://engineering.arm.gov/~sbeus/octavex/octavex.tar</a>
+      (NOTE: this .tar file contains other
+      Octave extension functions besides NCMEX.)
+    </p>
+    <p>
+      Also see <a href="http://ocgmod1.marine.usf.edu/octcdf/" >Octcdf</a>,
+      a netCDF toolbox for Octave.
+    </p>
+    <p>
+      For installation instructions, see the README file inside the .tar file.
+    </p>
+
+    <p></p>
+
+    <h2><a id="Octave" name="Octave">Octave interface (Barth)</a></h2>
+
+    <p>
+      Alexander Barth has contributed the following:
+    </p>
+    <p>
+      Octcdf is a netCDF toolbox for <a
+      href="http://www.octave.org/">Octave</a> which uses the same operator
+      syntax as the <a
+      href="http://mexcdf.sourceforge.net/netcdf_toolbox.html">matlab netCDF
+      toolbox</a> of Charles R. Denham. NetCDF dimensions, attributes and
+      variables are Octave objects and can be accessed, sliced and changed
+      just as regular variables. Unlike most netCDF toolboxes for matlab, it
+      does not depend on the NCMEX wrapper around the netCDF interface. This
+      octave toolbox is written in C++ calling directly the netCDF library.
+      The octcdf toolbox can also be used to download data from an OpenDAP
+      server. The octcdf source code is available at <a
+      href="http://modb.oce.ulg.ac.be/mediawiki/index.php/NetCDF_toolbox_for_Octave"> http://modb.oce.ulg.ac.be/mediawiki/index.php/NetCDF_toolbox_for_Octave</a>.
+      It was also included in the Octave Repository <a
+      href="http://octave.sourceforge.net/">octave-forge</a>.
+    </p>
+
+    <p></p>
+
+    <h2><a id="OPeNDAP" name="OPeNDAP">OPeNDAP (formerly DODS)</a></h2>
+
+    <p>
+      The <a href="http://opendap.org/">OPeNDAP</a> (formerly known as
+      DODS) is an Open-source Project for a Network Data Access Protocol
+      that makes local data and subsets of local data accessible to remote
+      locations independent of the local storage format. OPeNDAP also
+      provides tools for transforming existing applications into OPeNDAP
+      clients, enabling them to remotely access OPeNDAP served data.
+      OPeNDAP is based on existing data access tools; rather than developing
+      a self contained system, it makes extensive use of existing data
+      access APIs.
+    </p>
+
+    <p>
+      OPeNDAP can be used to make netCDF data files available over the
+      Internet and it can also be used to adapt existing software which use
+      the netCDF API (by re-linking) to read data served by an OPeNDAP data
+      server. In principle, any program written using netCDF can be adapted
+      to read data from an OPeNDAP server - in other words any program
+      which uses netCDF can become a client in the OPeNDAP client-server
+      system. Included in the source and binary distributions are two freely
+      available programs that have already been modified (re-linked).
+    </p>
+
+    <p>
+      With a client program accessing data from a netCDF server, it is
+      possible to access a small subset of a large dataset over the Internet
+      without copying the entire dataset (as you would have to do with FTP
+      or AFS). The client can see changes to the netCDF dataset, e.g. when
+      new records are added (which would not be possible with FTP). Finally,
+      the client can also access cross-sections of variable data without
+      paging large amounts of data across the network (as you would have to
+      do with NFS, for example).
+    </p>
+
+    <p>
+      OPeNDAP software is freely available in both
+      source form or binary form for selected platforms.
+    </p>
+
+    <p></p>
+
+    <h2><a id="OpenDX" name="OpenDX">OpenDX</a></h2>
+    <a href="http://www.opendx.org/about.html">OpenDX</a> (formerly IBM Data Explorer,
+    also known as simply DX) is a general-purpose software package for data visualization
+    and analysis. It employs a data-flow driven client-server execution model and
+    provides a graphical program editor that allows the user to create a visualization
+    using a point and click interface.
+    <p>
+      DX runs on 7 major UNIX platforms as well as Windows 95/NT and is designed
+      to take full advantage of multi-processor systems from IBM, SGI and Sun.
+    </p>
+    <p>
+      DX is built upon an internal data model, which describes and provides uniform
+      access services for any data brought into, generated by, or exported from the
+      software. This data model supports a number of different classes of scientific
+      data, which can be described by their shape (size and number of dimensions),
+      rank (e.g., scalar, vector, tensor), type (float, integer, byte, etc. or real,
+      complex, quaternion), where the data are located in space (positions), how the
+      locations are related to each other (connections), aggregates or groups (e.g.,
+      hierarchies, series, composites, multizone grids, etc.). It also supports those
+      entities required for graphics and imaging operations within the context of
+      Data Explorer. Regular and irregular, deformed or curvilinear, structured and
+      unstructured data as well as "missing" or invalid data are supported.
+    </p>
+    <p>
+      The details of the data model are hidden at the user level. As a result DX
+      operations or modules are polymorphic and appear typeless. The DX Import module,
+      which reads data for use within Data Explorer directly utilizes data in netCDF
+      as well as other formats (e.g., HDF, CDF). One or more variables may be selected
+      as well as step(s) of a time series. Data in conventional netCDFs are directly
+      imported. Since the DX data model is more comprehensive than the netCDF data
+      model, a methodology to extend netCDF via attribute conventions (e.g., for unstructured
+      meshes, non-scalar data and hierarchies) for use with Data Explorer is available.
+    </p>
+    <p>
+      DX supports a number of realization techniques for generating renderable geometry
+      from data. These include color and opacity mapping (e.g., for surface and volume
+      rendering), contours and isosurfaces, histograms, two-dimensional and three-dimensional
+      plotting, surface deformation, etc. for scalar data. For vector data, arrow
+      plots, streamlines, streaklines, etc. are provided. Realizations may be annotated
+      with ribbons, tubes, axes, glyphs, text and display of data locations, meshes
+      and boundaries. Data probing, picking, arbitrary surface and volume sampling,
+      and arbitrary cutting/mapping planes are supported.
+    </p>
+    <p>
+      DX supports a number of non-graphical functions such as point-wise mathematical
+      expressions (e.g., arithmetic, transcendental, boolean, type conversion, etc.),
+      univariate statistics and image processing (e.g., transformation, filter, warp,
+      edge detection, convolution, equalization, blending, morphological operations,
+      etc.). Field/vector operations such as divergence, gradient and curl, dot and
+      cross products, etc. are provided. Non-gridded or scattered data may be interpolated
+      to an arbitrary grid or triangulated, depending on the analysis requirements.
+      The length, area or volume of various geometries may also be computed. Tools
+      for data manipulation such as removal of data points, subsetting by position,
+      sub/supersampling, grid construction, mapping, interpolation, regridding, transposition,
+      etc. are available.
+    </p>
+    <p>
+      Tools for doing cartographic projections and registration as well as earth,
+      space and environmental sciences examples are available at Cornell University
+      via info.tc.cornell.edu. Also see the <a href="#ncdx" >ncdx</a> tool for making
+      netCDF files OpenDX compliant.
+    </p>
+    <p></p>
+    <h2><a id="Panoply" name="Panoply">Panoply</a></h2>
+    <p>
+      <a href="http://www.giss.nasa.gov/tools/panoply/" >Panoply</a>
+      is an application that plots geo-gridded and other arrays from netCDF,
+      HDF, GRIB, and other datasets. Features include:
+    </p>
+    <ul>
+      <li>
+        Slice and plot geo-gridded latitude-longitude,
+        latitude-vertical, longitude-vertical, or
+        time-latitude arrays from larger multidimensional variables.
+      </li>
+      <li>
+        Two arrays may be combined in one plot by differencing, summing, or averaging.
+      </li>
+      <li>
+        Lon-lat data may be plotted as global maps (using any of over 75
+        map projections) or as zonal average plots.
+      </li>
+      <li>
+        Overlay continent outlines or masks on lon-lat plots.
+      </li>
+      <li>
+        Use your favorite CPT, GGR, PAL, or ACT color table for scale colorbar.
+      </li>
+      <li>
+        Save plots to disk in GIF, JPEG, PNG or TIFF bitmap images or as
+        PDF or PostScript graphics files.
+      </li>
+      <li>
+        Export lon-lat map plots in KMZ format.
+      </li>
+      <li>
+        Export animations as AVI or MOV video or as a collection of
+        invididual frame images.
+      </li>
+      <li>
+        Explore remote THREDDS and OpenDAP catalogs and open datasets served from them.
+      </li>
+    </ul>
+    <p>
+      Panoply requires that your computer have a Java SE 6 runtime
+      environment, or better, installed.
+    </p>
+    <p>
+      Panoply is developed at the NASA Goddard Institute for Space Studies. Questions
+      and suggestions should be directed to <a
+      href="http://www.giss.nasa.gov/staff/rschmunk.html" >Dr. Robert
+      B. Schmunk</a>.
+    </p>
+    <p></p>
+    <h2><a id="Parallel-NetCDF" name="Parallel-NetCDF">Parallel-NetCDF</a></h2>
+    <p>
+      A group of researchers at Northwestern University and Argonne National
+      Laboratory (Jianwei Li, Wei-keng Liao, Alok Choudhary, Robert Ross, Rajeev
+      Thakur, William Gropp, and Rob Latham) have designed and implemented a new
+      <a href="http://www.mcs.anl.gov/parallel-netcdf/" > parallel interface for writing and reading netCDF data</a>, tailored for use on
+      high performance platforms with parallel I/O.  The implementation builds on
+      the MPI-IO interface, providing portability to most platforms in use and
+      allowing users to leverage the many optimizations built into MPI-IO
+      implementations.  Testing so far has been on Linux platforms with ROMIO and
+      IBM SP machines using IBM's MPI.
+    </p>
+    <p>
+      Documentation and code for Parallel-NetCDF is now available for
+      testing.
+      Although a few interfaces are not implemented yet, the current implementation
+      is complete enough to provide significant I/O performance improvements on
+      parallel platforms, as described in a <a
+      href="ftp://info.mcs.anl.gov/pub/tech_reports/reports/P1048.pdf"
+      >technical report</a>.   Users are invited to test Parallel-NetCDF
+      in their applications.
+    </p>
+    <p></p>
+
+    <h2><a id="Paraview" name="Paraview">Paraview and vtkCSCSNetCDF</a></h2>
+
+    <p>
+      <a href="http://www.paraview.org/">http://www.paraview.org/</a>
+
+    <p>
+      ParaView is an application designed with the need to visualize large
+      data sets in mind. The goals of the ParaView project include the
+      following:
+
+      <ul>
+        <li>
+          Develop an open-source, multi-platform visualization application.
+        <li>
+          Support distributed computation models to process large data sets.
+        <li>
+          Create an open, flexible, and intuitive user interface.
+        <li>
+          Develop an extensible architecture based on open standards.
+      </ul>
+
+    <p>
+      ParaView runs on distributed and shared memory parallel as well as
+      single processor systems and has been successfully tested on
+      Windows, Linux and various Unix workstations and clusters. Under the
+      hood, ParaView uses the Visualization Toolkit as the data processing
+      and rendering engine and has a user interface written using a unique
+      blend of Tcl/Tk and C++.
+
+    <p>
+      A vtk/ParaView reader for netCDF files can be found
+      <a href="http://www.paraview.org/Wiki/ParaView/Users_Guide/List_of_readers#NetCDF_Reader">here</a>.
+
+      <h2><a id="Perl" name="Perl">Perl interfaces</a></h2>
+      There are two netCDF interfaces for Perl:
+      <ul>
+        <li>
+          <a
+          href="http://search.cpan.org/~dhunt/PDL-NetCDF-4.05/netcdf.pd" > PDL::NetCDF</a>,
+          Doug Hunt's perl interface which uses the PDL (perl data language) extension.
+        </li>
+        <li>
+          <a href="/software/netcdf-perl/" >NetCDFPerl</a>, Steve Emmerson's
+          extension module, based on version 2 of the netCDF package. Uses perl lists
+          for representing netCDF variables.
+        </li>
+      </ul>
+    <p></p>
+    <h2><a id="PolyPaint+" name="PolyPaint+">PolyPaint+</a></h2>
+    <a
+    href="http://lasp.colorado.edu/polypaint/home.html">PolyPaint+</a> is an interactive
+    scientific visualization tool that displays complex structures within three-dimensional
+    data fields. It provides both color shaded-surface display and simple volumetric
+    rendering in either index or true color. For shaded surface rendering, the PolyPaint+
+    routines first compute the polygon set that describes a desired surface within
+    the 3D data volume. These polygons are then rendered as continuously shaded surfaces.
+    PolyPaint+ contains a wide variety of options that control lighting, viewing,
+    and shading. Objects rendered volumetrically may be viewed along with shaded surfaces.
+    Additional data sets can be overlaid on shaded surfaces by color coding the data
+    according to a specified color ramp. 3D visualizations can be viewed in stereo
+    for added depth perspective.
+    <p>
+      Currently supported 3D visualizations are the following:
+    </p>
+    <ul>
+      <li>
+        Shaded isosurface
+      </li>
+      <li>
+        Transparent contour shells or isosurfaces at varying levels
+      </li>
+      <li>
+        Volumetric or density plot
+      </li>
+      <li>
+        Planes
+      </li>
+      <li>
+        Contour ribbons
+      </li>
+      <li>
+        Topographic surface from 2D geographic data sets
+      </li>
+    </ul>
+    <p>
+      3D data volumes may be sliced in the X, Y, or Z plane using an interactive
+      cutting plane. A cross section of the data volume can be viewed in a 2D window
+      as a 2D contour plot, a vector plot, a raster image or a combination of these
+      options superimposed. Map outlines can be used as a background for 2D cross
+      section plots of geographic data. All data is projected according to the coordinates
+      specified by the user for the cross section window.
+    </p>
+    <p>
+      The user interface provides direct manipulation tools for specifying the eye
+      position, center of view, light sources, and color ramps. Subsetting of data
+      can be done easily by selecting the data by index or geographic coordinate.
+      On-line contextual help provides easy access to more detail about the software.
+      Tutorials which range from very simple visualizations to complex combinations
+      of data sets provide the user with a quick learning tool.
+    </p>
+    <p>
+      Currently PolyPaint+ accepts only data which is in the NetCDF file format.
+      A file conversion utility which converts from raw binary data to netCDf is a
+      part of the application.
+    </p>
+    <p>
+      PolyPaint+ is a joint effort of the University of Colorado and NCAR (National
+      Center for Atmospheric Research) funded by the NASA AISRP program. A beta version
+      of PolyPaint+ is currently available free of charge using FTP or for a nominal
+      fee which would cover tape distribution. A license agreement must be signed
+      in order to use it.
+    </p>
+    <p>
+      You may order by...
+    </p>
+    <ul>
+      <li>
+        TELEPHONE : 303-492-7289 (Margi Klemp) : 303-497-8159 (Bill Boyd)
+      </li>
+      <li>
+        U.S. MAIL :         <pre>
+      Margi Klemp
+      University of Colorado / LASP
+      1234 Innovation Dr.
+      Boulder, CO 80303
+      USA
+
+      </pre>
+      </li>
+      <li>
+        E-MAIL : margi at aries.colorado.edu
+      </li>
+    </ul>
+    <p></p>
+    <h2><a id="pomegranate" name="pomegranate">Pomegranate</a></h2>
+    <p>
+      The P9E Team at
+      NASA JPL has developed <a href="http://pomegranate.jpl.nasa.gov/"
+      >Pomegranate</a>, a python application that "webifies" science data files.
+      Supported formats include netCDF, HDF4, HDF5, GRIB and FITS.
+    </p>
+    <p>
+      Pomegranate can be installed on web servers as either a WSGI or CGI application
+      to provide webification (w10n) services. To learn more about w10n of
+      science data files, please visit
+      <a href="http://webification.org/">http://webification.org/</a>.
+      A brief <a href="http://pomegranate.jpl.nasa.gov/test/help.txt"
+      >help</a> document describes how to use the <a
+      href="http://pomegranate.jpl.nasa.gov/test" >demo directory</a> to
+      browse or download metadata or data in netCDF, JSON, or other
+      formats by clicking on data folder and document icons.
+    </p>
+    <p>
+      Pomegranate can also be used as a standalone library or command line application.
+      This greatly simplifies the retrieval of metadata and data
+      from files in supported formats.
+    </p>
+    <p>
+      Pomegranate is open source software and can be downloaded from
+      <a href="http://www.openchannelsoftware.com/projects/Pomegranate/" > http://www.openchannelsoftware.com/projects/Pomegranate/</a>.
+    </p>
+
+    <h2><a id="PyNGL" name="PyNGL">PyNGL and PyNIO</a></h2>
+    <p>
+      NCAR's Computational and Information Systems Laboratory has developed
+      <a href="http://www.pyngl.ucar.edu/" >PyNGL</a>, a python package for
+      scientific visualization and data analysis and <a
+      href="http://www.pyngl.ucar.edu/Nio.shtml" >PyNIO</a>, a Python
+      package supporting access to a variety of data formats using an
+      interface modelled on netCDF.
+    </p>
+    <p></p>
+
+    <h2><a id="Python" name="Python">Python interfaces</a></h2>
+    <p>
+      Python is an interpreted, object-oriented language that is supported on a wide
+      range of hardware and operating systems. Python information and sources can be
+      obtained from <a
+      href="http://www.python.org/">http://www.python.org/</a>. There are now
+      several netCDF interfaces for Python.
+    </p>
+    <p>
+      Jeff Whitaker of the NOAA Earth System Research Lab has developed a
+      netCDF-4 module for python:
+      <a
+      href="http://code.google.com/p/netcdf4-python/"> http://code.google.com/p/netcdf4-python/</a>.  Most new features of
+      netCDF-4 are implemented, such as multiple unlimited dimensions,
+      groups and zlib data compression. All the new numeric data types (such
+      as 64-bit and unsigned integer types) are implemented. Compound and
+      variable length (vlen) data types are supported, but the enum and
+      opaque data types are not. Mixtures of compound and vlen data types
+      (compound types containing vlens, and vlens containing compound types)
+      are not supported.
+    </p>
+    <p>
+      <a href="#xray" >xray</a> is a higher-level interface that uses
+      netcdf4-python internally to implement a pandas-like package for N-D
+      labelled arrays for scientific data.
+    </p>
+    <p>
+      André Gosselin of the Institut Maurice-Lamontagne, Péches & Océans Canada,
+      has implemented pycdf, a new Python interface to the netCDF library.  It
+      is available from <a href="http://pysclint.sourceforge.net/pycdf/"
+      >http://pysclint.sourceforge.net/pycdf/</a>, where you will find the install
+      files, installation instructions, extensive documentation in text and html
+      format, and examples. pycdf requires the Numeric python package, and
+      installs through the simple "python setyp.py install" command.
+    </p>
+    <p>
+      Bill Noon (noon at snow.cit.cornell.edu) has implemented another netCDF Python
+      module that allows easy creation, access, and browsing of netCDF data. The bindings
+      also use the <a
+      href="/software/udunits/">udunits library</a> to do unit conversions.
+      More information and source for Noon's Python netCDF module are available
+      from <a
+      href="http://snow.cit.cornell.edu/noon/ncmodule.html">http://snow.cit.cornell.edu/noon/ncmodule.html</a>.
+    </p>
+
+    <p>
+      The package from Konrad Hinsen has been integrated into his <a
+      href="https://sourcesup.cru.fr/projects/scientific-py/">ScientificPython</a>
+      package.
+    </p>
+
+    <p>
+      Dave Brown of NCAR's Computational and Information Systems Laboratory has developed <a
+      href="http://www.pyngl.ucar.edu/Nio.shtml" >PyNIO</a>, a Python
+      package that allows read and/or write access to a variety of data
+      formats using an interface modelled on netCDF.  Currently supported
+      formats include netCDF, HDF4, GRIB1 and GRIB2 (read only), and HDF-EOS
+      2 Grid and Swath data (read only).
+    </p>
+
+    <p>
+      Vicente Galiano of Miguel Hernandez University has developed a Python interface to
+      PnetCDF. This Python's package called "PyPnetCDF" allows access to NetCDF files using MPI and
+      the library pnetCDF developed by http://www.mcs.anl.gov/parallel-netcdf/.
+      The tools are very similar to Konrad Hinsen's NetCDF package to Python
+      but can read and write in a parallel way. For more information, see:
+      <a
+      href="http://www.pyacts.org/pypnetcdf">http://www.pyacts.org/pypnetcdf</a>.
+    </p>
+    <p>
+      <a id="pupynere" name="pupynere">Pupynere (PUre PYthon NEtcdf
+      REader)</a>
+      Roberto De Almeida has developed <a
+      href="http://pypi.python.org/pypi/pupynere/" >pupynere</a>, a PUre
+      PYthon NEtcdf REader that allows read-access to netCDF files using the
+      same syntax as the Scientific.IO.NetCDF Python module. Even though it's
+      written in Python, the module is up to 40% faster than
+      Scientific.IO.NetCDF and pynetcdf.
+    </p>
+
+    <p></p>
+    <h2><a id="R" name="R">R interface</a></h2>
+    <p>
+      The R Project for Statistical Computing has developed <a
+      href="http://www.R-project.org/" > R</a>, a language and environment for statistical
+      computing and graphics. It provides a wide variety of statistical and graphical
+      techniques, including linear and nonlinear modelling, statistical tests, time
+      series analysis, classification, and clustering.
+    </p>
+    <p>
+      David Pierce has contributed the <a
+      href="http://cran.r-project.org/web/packages/ncdf4/index.html"
+      >ncdf4 package</a> for reading netCDF data into R and for creating new netCDF
+      dimensions, variables, and files, or manipulating existing netCDF
+      files from R.
+    </p>
+    <p>
+      Pavel Michna has contributed another package, <a href="http://cran.r-project.org/web/packages/RNetCDF/index.html" >RNetCDF</a>, that also provides access to netCDF data and to udunits
+      calendar functions from R.
+    </p>
+    <p>
+      Robert Hijmans (with additional contributors) has created the <a
+      href="http://cran.r-project.org/web/packages/raster/index.html"
+      >R raster package</a> for geographic data analysis and modeling. The
+      raster package can be used for reading, writing, manipulating,
+      analyzing and modeling gridded spatial data. The package is especially
+      useful for large datasets that don't fit into memory, because data is
+      processed in chunks. See <a
+      href="http://cran.r-project.org/web/packages/raster/vignettes/Raster.pdf"
+      >Introduction to the 'raster' package</a> for more information.
+    </p>
+
+    <p></p>
+    <h2><a id="QGIS" name="QGIS">Quantum GIS (QGIS)</a></h2>
+    <p>
+      <a href="http://www.qgis.org/" >Quantum GIS</a> (QGIS) is an Open
+      Source Geographic Information System (GIS) licensed
+      under the GNU General Public License. QGIS is an official project of
+      the Open Source Geospatial Foundation (OSGeo). It runs on Linux, Unix,
+      Mac OSX, and Windows and supports numerous vector, raster, and
+      database formats and functionalities.  QGIS supports a desktop,
+      browser, server, and client for viewing, editing, analysis,
+      serving, and accessing data.  Its server complies with the OGC WMS 1.3 standard.
+      In addition to PostGIS and SpatiaLite formats, it can access data in vector
+      formats supported by the OGR library as well as most raster formats
+      supported by the GDAL library, including netCDF.  For a more detailed list of
+      features of the QGIS desktop, browser, server, and client, see the
+      <a href="http://www.qgis.org/en/about-qgis/features.html" >QGIS features page</a>.
+    </p>
+    <p></p>
+
+    <h2><a id="Ruby" name="Ruby">Ruby interface</a></h2>
+    <p>
+      A group at the Research Institute for Sustainable Humanosphere (RISH) of Kyoto
+      University has developed a <a
+      href="http://www.gfd-dennou.org/arch/ruby/products/ruby-netcdf/" >netCDF interface
+      for Ruby</a>, an interpreted, object-oriented scripting language. This interface
+      is intended to cover all the functionality of the C library for netCDF. Also
+      available are combination functions such as iterators (which offer abstract
+      ways to scan files and variables). Numeric arrays are handled by the "NArray"
+      multi-dimensional array class, which is becoming the de facto standard multi-dimensional
+      array for Ruby.  See also the Ruby-based <a href="#Gfdnavi" >GPhys
+      software and Gfdnavi tool</a>
+      for accessing GRIB, GrADS, and netCDF data uniformly.
+    </p>
+    <p>
+      More information about Ruby is available from the <a href="http://www.ruby-lang.org/" >Ruby
+      web site</a>.
+    </p>
+    <p></p>
+    <h2><a id="SDS" name="SDS">Scientific DataSet (SDS) Library</a></h2>
+    <p>
+      The <a href="http://sds.codeplex.com" >Scientific DataSet Library and
+      Tools project</a>, developed jointly by
+      Microsoft Research Cambridge and Moscow State University,
+      is aimed at manipulation and visualization of multidimensional data
+      sets.
+    </p>
+    <p>
+      Scientific DataSet (or SDS in short) is a .NET class library for
+      manipulating scientific data  and their metadata. SDS provides a unified API
+      for convenient access to various data storages. Three types of storages are
+      supported by the first release: NetCDF files, CSV text files and volatile
+      in-memory datasets. SDS uses native NetCDF library built from version 4.0.1
+      both for 32 and 64-bit Windows platforms. New storage types can be added to
+      SDS infractructure as plugins. Support for accessing TIFF image files from
+      SDS as 2D arrays will be available soon as a separate CodePlex project.
+    </p>
+    <p>
+      Three applications are built on top of SDS:
+    </p>
+    <ul>
+      <li>
+        sds command line utility. It allows users to examine data set schema,
+        copy data sets, modify their metadata.
+      </li>
+      <li>
+        DataSetViewer application for visualization of data sets. DataSetViewer
+        is both a standalone application and Windows Presentation Foundation Control
+        that can be built into your applications. DataSetViewer has support for
+        interactive slicing of multidimensional data along any dimension.
+      </li>
+      <li>
+        DataSetEditor add-in for Microsoft Office Excel. DataSetEditor provides
+        ability to view and modify the contents of any data set as Excel
+        worksheets.
+      </li>
+    </ul>
+    <p>
+      You can read the Getting Started document at
+      <a
+      href="http://sds.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=127282"
+      > http://sds.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=127282 </a>
+      for a more detailed introduction to the Scientific DataSet
+      software. A Windows
+      Installation package for SDS binaries along with DataSet Viewer and DataSet
+      Editor are available also. You can also build core class libraries and
+      the sds utility under Mono. You may use, copy, and reproduce this
+      software for any non-commercial purpose. For further details see license at
+      <a href="http://sds.codeplex.com/license" >http://sds.codeplex.com/license</a>.
+    </p>
+    <p>
+      The SDS project is in beta phase and keeps evolving.  You are welcome to
+      join discussions or report issues at the CodePlex site:
+      <a href="http://sds.codeplex.com" >http://sds.codeplex.com</a>.
+    </p>
+    <p></p>
+    <h2><a id="SIS" name="SIS">Apache Spatial Information System (SIS)</a></h2>
+    <p>
+      <a href="https://builds.apache.org/job/sis-trunk/site/index.html"
+      >Apache Spatial Information System (SIS)</a> is a Java library for
+      developing geospatial applications. SIS enables representation of
+      coordinates for searching, data clustering, archiving, or any other
+      relevant spatial needs. The library is an implementation of GeoAPI 3.0
+      interfaces and can be used for desktop or server applications.
+    </p>
+    <p>
+      SIS provides data structures for geographic data and associated
+      metadata along with methods to manipulate those data structures. The
+      SIS metadata module forms the base of the library and enables the
+      creation of metadata objects which comply with the ISO 19115 metadata
+      model and which can be read from or written to ISO 19139 compliant XML
+      documents. The SIS referencing module will enable the construction of
+      geodetic data structures for geospatial referencing based on the ISO
+      19111 model such as axis, projection and coordinate reference system
+      definitions, along with the associated operations which enable the
+      mathematical conversion of coordinates between different systems of
+      reference. The SIS storage modules will provide a common approach to
+      the reading and writing of grid coverages applicable to simple imagery
+      and multidimensional data structures.
+    </p>
+    <p>
+      SIS supports creating ISO 19115 metadata from metadata in a netCDF
+      store from a given file, URL, stream, or NetcdfFile object.  SIS
+      netCDF storage is intended to be a bridge between NetCDF Climate and
+      Forecast (CF) conventions and ISO 19115 metadata.
+    </p>
+    <p>
+      SIS is under developement as an Apache project.  Release 0.3 is
+      currently available for download.
+    </p>
+    <p></p>
+    <h2><a id="Tcl/Tk" name="Tcl/Tk">Tcl/Tk interfaces</a></h2>
+    <p>
+      Dan Schmitt has developed <a
+      href="http://cnrit.tamu.edu/rsg/cdftcl/">cdftcl</a>, a <a
+      href="http://www.scriptics.com/">Tcl/Tk</a> interface for netCDF. It allows the
+      use of "wildcards" (*) or ranges (1-4) in the subscript notation,
+      and use of name references instead of variable IDs. Contact dan at computer.org
+      for more information.
+    </p>
+    <p></p>
+    <h2><a id="Tcl-nap" name="Tcl-nap">Tcl-nap</a></h2>
+    <p>
+      <a href="http://tcl-nap.sourceforge.net" >Tcl-nap</a> (n-dimensional array
+      processor) is a loadable extension of Tcl which provides a powerful and efficient
+      facility for processing data in the form of n-dimensional arrays. It has been
+      designed to provide an array-processing facility with much of the functionality
+      of languages such as <a href="http://www.acm.org/sigapl/" >APL</a>, Fortran-90, <a href="#IDL" >IDL</a>, <a href="http://www.jsoftware.com/" >J</a>, <a href="http://www.mathworks.com" >matlab</a>, and <a href="http://www.octave.org/" >octave</a>.
+    </p>
+    <p>
+      Support is provided for data based on n-dimensional grids, where the dimensions
+      correspond to continuous spatial coordinates. There are interfaces to the HDF
+      and netCDF file formats commonly used for such data, especially in Earth sciences
+      such as Oceanography and Meteorology.
+    </p>
+    <p>
+      The internal data structure is called a NAO (n-dimensional array object) and
+      contains similar information to that of HDF SDSs and netCDF variables.
+    </p>
+    <p>
+      Tcl-nap was developed as part of the <a
+      href="http://www.dar.csiro.au/rs/avhrr_processing_software.htm" >CSIRO CAPS project</a>,
+      but can be loaded and used without the (satellite oriented) CAPS extension.
+    </p>
+    <p></p>
+    <h2><a id="VB" name="VB">Visual Basic and VB.net interfaces</a></h2>
+    <p>
+      Carsten Wieczorrek has developed code in VB 6 to export chromatographic
+      data into the netcdf/ANDI format.
+      The application writes netCDF files that can be read by
+      CHROMELEON, for example.  For others interested in programming with
+      netcdf.dll from VB 6, see
+      Wieczorrek's web page on <a
+      href="http://www.mn-net.com/netcdf_vb6"
+      >netCDF and VB 6.0</a> and for VB.net, see <a
+      href="http://www.mn-net.com/netcdf_vbnet" >netCDF and VB.net</a>.
+    </p>
+    <p></p>
+    <h2><a id="VisAD" name="VisAD">VisAD</a></h2>
+    <a href="http://www.ssec.wisc.edu/~billh/visad.html">VisAD</a> is a Java class
+    library for interactive and collaborative visualization and analysis of numerical
+    data. It combines:
+    <ul>
+      <li>
+        The use of pure Java for platform independence and to support data sharing
+        and real-time collaboration among geographically distributed users. Support
+        for distributed computing is integrated at the lowest levels of the system
+        using Java RMI distributed objects.
+      </li>
+      <li>
+        A general mathematical data model that can be adapted to virtually any numerical
+        data, that supports data sharing among different users, different data sources
+        and different scientific disciplines, and that provides transparent access
+        to data independent of storage format and location (i.e., memory, disk or
+        remote). The data model has been adapted to netCDF, FITS, HDF-EOS, McIDAS,
+        Vis5D, GIF and JPEG file formats.
+      </li>
+      <li>
+        A general display model that supports interactive 3-D, data fusion, multiple
+        data views, direct manipulation, collaboration, and virtual reality. The display
+        model has been adapted to Java3D and Java2D and used in an ImmersaDesk virtual
+        reality display.
+      </li>
+      <li>
+        Data analysis and computation integrated with visualization to support computational
+        steering and other complex interaction modes.
+      </li>
+      <li>
+        Support for two distinct communities: developers who create domain- specific
+        systems based on VisAD, and users of those domain-specific systems. VisAD
+        is designed to support a wide variety of user interfaces, ranging from simple
+        data browser applets to complex applications that allow groups of scientists
+        to collaboratively develop data analysis algorithms.
+      </li>
+      <li>
+        Developer extensibility in as many ways as possible.
+      </li>
+    </ul>
+    VisAD was written by programmers at the <a
+    href="http://www.ssec.wisc.edu/~billh/vis.html">SSEC Visualization Project</a>
+    at the University of Wisconsin-Madison <a
+    href="http://www.ssec.wisc.edu/">Space Science and Engineering Center</a>, and
+    the <a href="/index.html">Unidata Program Center</a>. <p></p>
+    <h2><a id="WCT" name="WCT">Weather and Climate Toolkit (WCT)</a></h2>
+    <p>
       NOAA's <a href="https://www.ncdc.noaa.gov/wct/">Weather and
       Climate Toolkit (WCT)</a> is free, platform independent
       software distributed from NOAA's National Centers for
@@ -2833,10 +2833,10 @@ or using ECMWF reanalysis on a reduced grid
       visualization and data export of weather and climate data,
       including Radar, Satellite and Model data. The WCT also
       provides access to weather/climate web services provided
-      from NCEI and other organizations.
-    </p>
-
-    <p>
+      from NCEI and other organizations.
+    </p>
+
+    <p>
       The WCT provides tools for background maps, animations
       and basic filtering. The export of images and movies is
       provided in multiple formats. The data export feature
@@ -2848,848 +2848,848 @@ or using ECMWF reanalysis on a reduced grid
       software packages such as ArcGIS, Google Earth, MatLAB,
       QGIS, R and many more. Advanced data export support for
       Google Earth enables the 2-D and 3D export of rendered data
-      and isosurfaces.
-    </p>
-
-    <h2><a id="WebWinds" name="WebWinds">WebWinds</a></h2>
-    <p>
-      <a href="http://www.openchannelsoftware.com/projects/WebWinds/"> WebWinds</a> is a free Java-based
-      science visualization and analysis package. In addition to several new analysis
-      tools, the current fourth version does automatic scripting. This allows
-    </p>
-    <ol>
-      <li>
-        a user to rapidly and automatically create and store a session, either
-        for his own use, or for use by a collaborator on another machine;
-      </li>
-      <li>
-        a data provider to automatically create a specialized analysis environment
-        which can be downloaded (as a small script file) along with a dataset from
-        a Website; and
-      </li>
-      <li>
-        realtime collaboration or sharing of sessions over (even low-bandwidth)
-        networks, including the Internet.
-      </li>
-    </ol>
-    <p>
-      This scripting requires no knowledge of the scripting language syntax. Several
-      sample script files are included with the distribution.
-    </p>
-    <p>
-      In addition, this version contains a capability to geo-reference some data
-      and to read ASCII data in tabular format. Also new is the ability to output
-      data in numerical form (e.g. NetCDF) and a context sensitive, integrated help
-      system.
-    </p>
-    <p>
-      As with earlier versions, data in several different formats, including NetCDF,
-      can be read in easily from your local machine or from the Web. In addition,
-      most data can be subset or subsampled on load, making it possible to visualize
-      very large multidimensional and/or multispectral datasets. The package includes
-      several step-by-step examples. Installation of the software (including Java)
-      on the PC or Mac is a process requiring one file to be downloaded and opened.
-      If you need help getting started, a remote tutorial is available once you've
-      downloaded the package.
-    </p>
-    <p>
-      WebWinds is `point and click' rather than language driven and it runs well
-      on Unix, Windows (95/98/NT) and Mac platforms. It currently requires JDK 1.1.
-      To download a copy of this release, go to <a href="http://www.sci-conservices.com/rel4/webpage/wwhome.html"
-      >http://www.sci-conservices.com/rel4/webpage/wwhome.html</a>
-    </p>
-    <p></p>
-
-    <h2><a id="xray" name="xray">xray (Python N-D labelled arrays)</a></h2>
-    <p>
-      <a href="http://xray.readthedocs.org/en/stable/index.html" >xray</a>
-      is an open source project and Python package that aims to bring the
-      labeled data power of <a href="http://pandas.pydata.org/" >pandas</a>
-      to the physical sciences, by providing N-dimensional variants of the
-      core pandas data structures, Series and DataFrame: the xray DataArray
-      and Dataset.
-    </p>
-    <p>
-      xray adopts the <a
-      href="http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/CDM"
-      >Common Data Model</a> for self-describing scientific data in
-      widespread use in the Earth sciences (e.g., netCDF and OPeNDAP):
-      xray.Dataset is an in-memory representation of a netCDF file.
-    </p>
-    <p>
-      xray is being developed by Stephan Hoyer, Alex Kleeman, and <a
-      href="https://github.com/xray/xray/graphs/contributors" >other
-      contributors</a>.
-    </p>
-
-    <h2><a id="Zebra" name="Zebra">Zebra</a></h2>
-    <a href="http://www.atd.ucar.edu/rdp/zebra.html">Zebra</a> (formerly named Zeb)
-    is a system for data ingest, storage, integration and display, designed to operate
-    in both real time and postprocessing modes. Zebra was developed by Jonathan Corbet
-    and others in NCAR's <a
-    href="http://www.atd.ucar.edu/rdp/rdp_home.html">Research Data Program</a>.
-    <p>
-      Zebra's primary use is for the superpositioning of observational data sets
-      (such as those collected by satellite, radar, mesonet and aircraft) and analysis
-      products (such as model results, dual-Doppler synthesis or algorithm output).
-      Data may be overlaid on a variety of display types, including constant altitude
-      planes, vertical cross-sections, X-Y graphs, Skew-T plots and time-height profiles.
-      The fields for display, color tables, contour intervals and various other display
-      options are defined using an icon based user-interface. This highly flexible
-      system allows scientific investigators to interactively superimpose and highlight
-      diverse data sets; thus aiding data interpretation.
-    </p>
-    <p>
-      Data handling capabilities permit external analysis programs to be easily linked
-      with display and data storage processes. The data store accepts incoming data,
-      stores it on disk, and makes it available to processes which need it. An application
-      library is available for data handling. The library functions allow data storage,
-      retrieval and queries using a single applications interface, regardless of the
-      data's source and organization. NetCDF data that conforms to Zebra conventions
-      is supported by this interface.
-    </p>
-    <p>
-      Zebra is currently available to the university research community through the
-      NCAR/ATD Research Data Program. Email requests to rdp-support at atd.ucar.edu.
-      More information is on the web page http://www.atd.ucar.edu/rdp/zebra.html.
-    </p>
-
-    <hr />
-
-    <h1><a id="user" name="user">User-Contributed Software</a></h1>
-    <p>
-      Unidata makes available a separate
-      <a href="/software/netcdf/Contrib.html">catalog</a>
-      to a
-      <a href="ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/">directory</a>
-      of freely available, user-contributed software and documentation related to the
-      netCDF library. This software may be retrieved by anonymous FTP. We haven't
-      necessarily used or tested this software; we make it available "as is".
-    </p>
-    <p>
-      The criteria for inclusion in the netcdf/contrib/ directory of user-contributed
-      software are:
-    </p>
-    <p></p>
-    <ul>
-      <li>
-        General usefulness to a significant part of the netCDF community
-      </li>
-      <li>
-        Small size
-      </li>
-      <li>
-        Infrequent need for updates
-      </li>
-      <li>
-        Free availability
-      </li>
-    </ul>
-    <hr />
-
-    <h1 id="commercial">Commercial or Licensed Packages</h1>
-
-    <h2><a id="ArcGIS" name="ArcGIS">ArcGIS Pro - Space Time Pattern Mining Toolbox</a></h2>
-    <p>
-      The <a href="https://pro.arcgis.com/en/pro-app/tool-reference/space-time-pattern-mining/an-overview-of-the-space-time-pattern-mining-toolbox.htm">Space Time Pattern Mining toolbox</a> contains statistical tools for analyzing data distributions and patterns in the context of both space and time. It includes a toolset for visualizing the data stored in the space-time netCDF cube in both 2D and 3D.
-
-      Create Space Time Cube takes point datasets and builds a multidimensional cube data structure (netCDF) for analysis. Emerging Hot Spot Analysis then takes the cube as input and identifies statistically significant hot and cold spot trends over time. You might use the Emerging Hot Spot Analysis tool to analyze crime or disease outbreak data in order to locate new, intensifying, persistent, or sporadic hot spot patterns at different time-step intervals. The Local Outlier Analysis too [...]
-    </p>
-    <p></p>
-
-    <h2><a id="Agrimetsoft" name="Agrimetsoft">AgriMetSoft Netcdf-Extractor</a></h2>
-      There are different software packages or various codes that may be used for manipulating or displaying NetCDF data. Some of them such as MATLAB programming language needs to enough information about provide codes in MATLAB as well as to know run codes and statements. Furthermore, user should have to pay for MATLAB programming and install it in her/his system. Also, another of them are related to other programming languages such as R, NCL (NCAR Command Language), and etc. It has bee [...]
-    <p>
-
-
-    <p></p>
-
-    <h2><a id="ViewNcDap" name="ViewNcDap">ASA ViewNcDap</a></h2>
-    <p>
-      Applied Science Associates, Inc. has made the ASA View NC/Dap
-      application freely available for <a
-      href="http://www.asascience.com/downloads" >download</a>.  ViewNcDap
-      is a stand-alone research-based tool (with included demonstration
-      data) that allows a user to visualize four dimensional NetCDF and
-      OPeNDAP data.  ViewNcDap is a Windows application that includes
-      temporal/time step functionality for viewing animations of data that
-      include temporal information.  The application may be used to
-      visualize a variety of time-varying geospatial scientific data in a
-      simple map framework.  It handles CF conventions and includes some
-      aliasing features that could permit additional formats to be read.
-      It should not be considered a GIS system, but
-      is used to quickly preview a variety of data on a simple map. Data may
-      also be filtered and saved to a local netCDF file.
-    </p>
-    <p></p>
-
-    <h2><a id="Avizo" name="Avizo">Avizo</a></h2>
-    <p>
-      <a href="http://www.avizo3d.com/" >Avizo</a> software is a powerful
-      tool for 3D data visualization and
-      analysis.  It offers a comprehensive feature set that addresses
-      visualization, processing, analysis, communication and
-      presentation. <a href="http://www.vsg3d.com/vsg_prod_avizo_green.php"
-      > Avizo Green Edition</a> includes an advanced set of
-      features dedicated to climate, oceanography, environmental or
-      earth-mapped data.  It provides high-level support for the netCDF
-      format, a dedicated Earth visualization module, and a set of advanced
-      geographical projections applicable to a wide range of fast 2D and 3D
-      data representations.
-    </p>
-    <p>
-      For more information, see <a
-      href="http://www.avizo3d.com/" >www.avizo3d.com</a>.
-    </p>
-
-    <h2><a id="AVS" name="AVS">AVS</a></h2>
-    <a href="ftp://testavs.ncsc.org/avs/Info/WHAT_IS_AVS">AVS</a> (Application Visualization
-    System) is a visualization application software and development environment. An
-    AVS module has been written that allows multi-dimensional netCDF data sets to
-    read into AVS as uniform or rectilinear field files. The AVS user can point and
-    click to specify the name of the variable in the selected netCDF file, as well
-    as selecting the hyperslab. If 1D coordinate variables exist (a variable that
-    has the same name as a dimension) then the coordinate variable will be used to
-    specify the coordinates of resulting rectilinear field file. If no coordinate
-    variable exists, then the resulting field file will be uniform. Once in AVS, there
-    are hundreds of analysis and display modules available for image processing, isosurface
-    rendering, arbitrary slicing, alpha blending, streamline and vorticity calculation,
-    particle advection, etc. AVS runs on many different platforms (Stardent, DEC,
-    Cray, Convex, E and S, SET, Sun, IBM, SGI, HP, FPS and WaveTracer), and it has
-    a flexible data model capable of handling multidimensional data on non-Cartesian
-    grids.
-    <p>
-      The module source code and documentation is available from the <a href="http://iac.ncsc.org/">International
-      AVS Center</a>, in the <a
-      href="ftp://testavs.ncsc.org/avs/AVS5/Module_Src/data_input/read_netcdf/"> ftp://testavs.ncsc.org/avs/AVS5/Module_Src/data_input/read_netcdf/</a>
-      directory.
-    </p>
-    <p>
-      See also the information on <a href="#DDI">DDI</a> for another way to use netCDF
-      data with AVS.
-    </p>
-    <p></p>
-
-    <h2><a id="BCS-UFI" name="BCS-UFI" >Barrodale UFI</a></h2>
-
-    <p>
-      <a href="http://www.barrodale.com" >Barrodale Computing Services
-      Ltd.</a> (BCS) has developed a product that addresses one of
-      the main objections heard from "technologists" (e.g., scientists,
-      engineers, and other researchers) who avoid using databases to manage
-      their data: "my very large data files are too
-      cumbersome/difficult/slow/costly to load into a database".  In
-      addition to netCDF, these files come in a variety of formats (HDF5, GRIB,
-      NITFS, FITS, etc.).
-    </p>
-    <p>
-      This BCS product is called the <a
-      href="http://www.barrodale.com/bcs/universal-file-interface-ufi"
-      >Universal File Interface (UFI)</a>; it's a
-      database extension based on the IBM Informix Virtual Table Interface
-      (VTI). <em>(Please continue reading even if you don't have
-      Informix running on your system, because IBM has just made available, at
-      no charge, the <a
-      href="http://www-01.ibm.com/software/data/informix/innovator-c-edition/"
-      >Innovator-C Edition</a> of Informix.)</em> A demo that uses UFI to
-      access wind speeds can be seen <a
-      href="http://www.barrodale.com/bcs/universal-file-interface-animation"
-      >here</a>.
-    </p>
-    <p>
-      VTI is a technology that supports making external datasets appear as tables
-      to SQL queries and statements.  UFI is a BCS database extension for
-      delivering the contents of external data files as though they were rows in
-      a database table.  UFI makes a file look like a set of database tables, so
-      "UFI managed tables" are actually virtual database tables.   Consequently,
-      users of UFI can perform SQL queries on their files without having to first
-      load them into a database.
-    </p>
-
-    <p></p>
-
-    <h2><a id=></a></h2>
-
-    <h2><a id="DioVISTA/Storm" name="DioVISTA/Storm" >DioVISTA/Storm</a></h2>
-    <p>
-      <a href="http://www.hitachi-power-solutions.com/products/product03/p03_61.html"
-      >DioVISTA/Storm</a> is a commercial software package that visualizes content
-      of netCDF files as a time series of grids, isosurfaces, and arrows on a 3D
-      virtual earth. Its user interface is similar to standard 3D earth
-      visualizing software. It displays OGC KML files, Shapefiles, and online
-      map resources through OGC Web Tile Map Services (WTMS). It supports CF
-      Conventions version 1.6 (lon-lat-alt-time axis and trajectory). Its first
-      version was released on Aug 5 2014.
-    </p>
-
-    <p></p>
-
-    <h2><a id="Environmental WorkBench"
-    name="Environmental WorkBench">Environmental WorkBench</a></h2>
-    <a href="http://www.ssesco.com/">SuperComputer Systems Engineering and Services
-    Company</a> (SSESCO) has developed the <a
-    href="http://www.ssesco.com/files/ewb.html">Environmental WorkBench</a> (EWB),
-    an easy to use visualization and analysis application targeted at environmental
-    data. The EWB currently has numerous users in the fields of meteorological research,
-    air quality work, and groundwater remediation.
-    <p>
-      EWB system features include:
-    </p>
-    <ul>
-      <li>
-        Random access file structure using the netCDF-based public domain MeRAF
-        file system with support for gridded, discrete (non-grid-based observation),
-        and particle types
-      </li>
-      <li>
-        Support for geo-referenced or Cartesian coordinate systems
-      </li>
-      <li>
-        Object oriented Graphical User Interface (GUI) that is very easy to use
-      </li>
-      <li>
-        Tools for converting model and observational data sets and data writers
-        to netCDF
-      </li>
-      <li>
-        Interactive rotation/translation of scenes in 3D space
-      </li>
-      <li>
-        Time sequencing controls to step forward/backward, animate sequentially,
-        or go to a chosen time step; including multiple asynchronous or non-uniform
-        time steps
-      </li>
-      <li>
-        Interactive slicers to select cross sections through 3D data sets
-      </li>
-      <li>
-        Display operators available on the slices, including
-        <ul>
-          <li>
-            Contour lines with selectable contour levels
-          </li>
-          <li>
-            Color shading by data value with variable transparency level
-          </li>
-          <li>
-            Arrow and streamline representation for vector quantities
-          </li>
-          <li>
-            Positional reference lines at user selected intervals
-          </li>
-          <li>
-            Color coded shapes at each grid node
-          </li>
-        </ul>
-      </li>
-      <li>
-        Multiple 3D isosurfaces at selected parameters and values with variable
-        transparency
-      </li>
-      <li>
-        Display of particle positions with coloring by type, height, and source
-      </li>
-      <li>
-        Display of discrete data using colored spheres and labels for scalar data
-        and arrows for vectors (with arrowheads or meteorological style)
-      </li>
-      <li>
-        Multiple user definable color maps to which isosurface and colored field
-        shading may be separately assigned
-      </li>
-      <li>
-        On screen annotation for generation of report ready figures
-      </li>
-      <li>
-        Image export in any of the common image formats (gif, tiff, encapsulated
-        postscript, etc.)
-      </li>
-      <li>
-        Graceful handling of missing or bad data values by all the graphics rendering
-        routines
-      </li>
-      <li>
-        Automatic data synchronization to allow automatic screen updating as new
-        data arrives in real-time from a model or set of sensors
-      </li>
-      <li>
-        Two and three dimensional interpolation from scattered observations to a
-        grid, using the Natural Neighbor Method. This robust volume based method yields
-        results far superior to distance weighting schemes.
-      </li>
-    </ul>
-    <p>
-      Systems currently supported include Win95, WinNT, OS/2, IBM RS/6000, Silicon
-      Graphics, HP and SUN workstations.
-    </p>
-    <p>
-      SSESCO has implemented a meta-file layer on top of the netCDF library, called
-      MeRAF. It handles multiple netCDF files as well as automatic max-min calculations,
-      time-varying gridded, particle, and discrete data, logical groupings for discrete
-      data, and an overall simplified and flexible interface for storing scientific
-      data. MeRAF is being used by the DOE at the Hanford-Meteorological Site for
-      observational data and will be used for their weather-modeling.
-    </p>
-    <p></p>
-
-    <h2><a id="ESRI" name="ESRI">ESRI</a></h2>
-
-    <p>
-      <a href="http://www.esri.com/software/arcgis/index.html" >ESRI
-      ArcGIS</a> version 9.2 and later support <a
-      href="http://webhelp.esri.com/arcgisdesktop/9.2/index.cfm?TopicName=An_overview_of_data_support_in_ArcGIS"
-      >accessing netCDF time-based and multidimensional data</a> that
-      follows CF or COARDS conventions for associating spatial locations
-      with data.  A selected slice of netCDF data may be displayed in ArcGIS
-      as a raster layer, feature layer, or table.  You can also drag a
-      netCDF file from Windows Explorer and drop it in an ESRI application
-      such as ArcMap.
-    </p>
-
-    <p></p>
-
-    <h2><a id="FME">FME</a></h2>
-
-    <p>
-      <a href="http://www.safe.com/fme">FME</a>, developed by <a
-      href="http://www.safe.com">Safe Software Inc.</a>, is a tool for transforming
-      data for exchange between over <a href="http://www.safe.com/fme/format-search/">300
-      different formats and models</a>, including netCDF. FME's
-      read and write support for netCDF allows users to
-      move data into the netCDF common standard, regardless
-      of its source, and conversely enables end-users to consume netCDF
-      data for use in their preferred systems. For more information visit <a
-      href="http://www.safe.com/fme">http://www.safe.com/fme</a>.
-    </p>
-
-    <p></p>
-
-    <h2><a id="HDF-Explorer" name="HDF-Explorer">HDF Explorer</a></h2>
-    <p>
-      <a href="http://www.space-research.org/" >HDF Explorer</a>
-      is a data visualization program that reads the HDF, HDF5
-      and netCDF data file formats (including netCDF classic format data).
-      HDF Explorer runs in the Microsoft
-      Windows operating systems.
-    </p>
-    <p>
-      HDF Explorer offers a simple yet powerful interface for the
-      visualization of HDF and netCDF data.  The data is just a click of the mouse
-      away. Data is first viewed in a tree-like interface, and then
-      optionally loaded and visualized in a variety of ways.
-      HDF Explorer features include fast access to data, grid, scalar and
-      vector views. It also allows exporting your data either as an ASCII
-      text file or a bitmap image.
-    </p>
-    <p></p>
-
-    <h2><a id="IDL" name="IDL">IDL Interface</a></h2>
-    <a href="http://www.exelisvis.com/ProductsServices/IDL.aspx">IDL</a> (Interactive Data Language)
-    is a scientific computing environment, developed and supported by <a
-    href="http://www.exelisvis.com/" >Excelis Visual Information
-    Solutions</a>, that combines mathematics, advanced data
-    visualization, scientific graphics, and a graphical user interface toolkit to
-    analyze and visualize scientific data. Designed for use by scientists and scientific
-    application developers, IDL's array-oriented, fourth-generation programming
-    language allows you to prototype and develop complete applications. IDL now supports
-    data in netCDF format.
-    <p>
-      As an example, here is how to read data from a netCDF variable named GP in
-      a file named "data/aprin.nc" into an IDL variable named gp using the
-      IDL language:
-    </p>
-    <p></p>
-    <pre>
-      id = ncdf_open('data/april.nc')
-      ncdf_varget,id, ncdf_varid( id, 'GP'), gp
-      </pre>
-      Now you can visualize the data in the gp variable in a large variety of ways and
-      use it in other computations in IDL. You can FTP a demo version of IDL, including
-      the netCDF interface, by following the instructions in pub/idl/README available
-      via anonymous FTP from gateway.rsinc.com or boulder.colorado.edu.
-
-    <p>
-      Other software packages that use or interoperate with IDL to access netCDF
-      data includes <a href="#ARGOS">ARGOS</a>, <a
-      href="#CIDS Tools">CIDS Tools</a>, <a href="#DDI">DDI</a>, <a
-      href="#HIPHOP">HIPHOP</a>, <a
-      href="Hyperslab OPerator Suite (HOPS)">Hyperslab OPerator Suite (HOPS)</a>, and <a href="Noesys">Noesys</a>.
-    </p>
-    <p></p>
-
-    <p></p>
-    <h2><a id="InterFormat" name="InterFormat">InterFormat</a></h2>
-    <a href="http://www.radio-logic.com/">InterFormat</a> is a medical image format
-    conversion program with both Motif and character interfaces. InterFormat can automatically
-    identify and convert most popular medical image formats and write output files
-    in many standard medical image formats, or in formats such as netCDF that are
-    suitable for input to leading scientific visualization packages. InterFormat runs
-    on UNIX workstations; a version for OpenVMS is also available. A separate external
-    module for <a
-    href="#OpenDX">IBM Data Explorer</a> is available for use in IBM Data Explorer's
-    Visual Program Editor.
-    <p>
-      For more details about the formats handled, program features, and pricing,
-      see the Radio-Logic web site at <a
-      href="http://www.radio-logic.com"><http://www.radio-logic.com></a>.
-    </p>
-    <h2><a id="IRIS Explorer Module" name="IRIS Explorer Module">IRIS Explorer Module</a></h2>
-    <p>
-      The Atmospheric and Oceanic Sciences Group at the National Center for Supercomputing
-      Applications (NCSA) and the Mesoscale Dynamics and Precipitation Branch at NASA-Goddard
-      Space Flight Center have developed the NCSA PATHFINDER module set for <a
-      href="http://www.nag.co.uk:70/1h/Welcome_IEC">IRIS Explorer</a>. Two of the modules, <a
-      href="http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/explorer/ReadDFG/ReadDFG.html"> ReadDFG</a> (to output Grids), and <a
-      href="http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/explorer/ReadDF/ReadDF.html"> ReadDF</a> (to output Lattices) are capable of reading from NCSA HDF files, MFHDF/3.3
-      files, and Unidata netCDF files. A user-friendly interface provides control and
-      information about the contents of the files.
-    </p>
-    <p>
-      For ReadDF, the format translation is handled transparently. Up to five unique
-      lattices may be generated from the file (as these files can contain multiple
-      data fields) using a single module. A variety of dimensionalities and data types
-      are supported also. Multiple variables may be combined in a single lattice to
-      generate vector data. All three Explorer coordinate systems are supported.
-    </p>
-    <p>
-      With ReadDFG, user selected variables from the file are output in up to five
-      PATHFINDER grids. Each grid can consist of scalar data from one variable or
-      vector data from multiple variables. Coordinate information from the file is
-      also included in the grids. Any number of dimensions in any of the Explorer
-      coordinate types are supported.
-    </p>
-    <p>
-      For more information on the NCSA PATHFINDER project and other available modules,
-      visit the WWW/Mosaic PATHFINDER Home Page at <a
-      href="http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/top/top.html"> http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/top/top.html</a>
-      The ReadDF module may be downloaded either via the WWW server or anonymous ftp
-      at redrock.ncsa.uiuc.edu in the /pub/PATHFINDER directory. For more information
-      please send email to: pathfinder at redrock.ncsa.uiuc.edu
-    </p>
-    <p>
-      See also the information on <a href="#DDI">DDI</a> for another way to use netCDF
-      data with IRIS Explorer.
-    </p>
-    <p></p>
-    <h2><a id="LeoNetCDF" name="LeoNetCDF">LeoNetCDF</a></h2>
-    <p>
-      <a href="http://www.leokrut.com/leonetcdf.html" >LeoNetCDF</a> is a
-      Windows application (Windows96/NT and higher) for editing netCDF
-      files.  It can display content of netCDF files in tree style control
-      and permits editing its parameters in a standard Windows interface
-      environment.
-    </p>
-    <p></p>
-    <h2><a id="Mathematica" name="Mathematica">Mathematica</a></h2>
-    <p>
-      <a href="http://www.wolfram.com/products/mathematica/index.html"
-      >Mathematica</a> is a technical computing environment that provides
-      advanced numerical and symbolic computation and visualization.
-      As of version 6, Mathematica adds classic
-      <a href="http://reference.wolfram.com/mathematica/ref/format/NetCDF.html" >netCDF data</a> to the many forms of
-      data it can import, export, and visualize.
-    </p>
-    <p></p>
-    <h2><a id="MATLAB" name="MATLAB">MATLAB</a></h2>
-    <a href="http://www.mathworks.com/products/matlab/">MATLAB</a> is an integrated
-    technical computing environment that combines numeric computation, advanced graphics
-    and visualization, and a high-level programming language.
-    Versions 7.7 and later of MATLAB have built-in support for reading and
-    writing netCDF data.  MATLAB version 2012a includes the netCDF 4.1.2 library
-    with OPeNDAP client support turned on, so remote access to netCDF and
-    other data formats supported by OPeNDAP servers is available.
-    </p>
-    <p>
-      For earlier versions, several freely-available software packages that implement a MATLAB/netCDF interface
-      are available:
-      <a href="#nctoolbox" >nctoolbox</a>, <a href="#NC4ML5">NetCDF Toolbox for MATLAB-5</a>, <a href="#MexEPS">MexEPS</a>,
-      the <a
-      href="#CSIRO-MATLAB">CSIRO MATLAB/netCDF interface</a>, <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15177&objectType=file"
-      >NetCDF reader</a>,  and <a href="/software/netcdf/Contrib.html">fanmat</a>.
-    </p>
-    <h2><a id="Noesys" name="Noesys">Noesys</a></h2>
-    <a href="http://www.rsinc.com/NOeSYS/index.cfm" >Noesys</a> is software for desktop
-    science data access and visualization. Available for both Windows and Power Macintosh
-    platforms, Noesys allows users to access, process, organize and visualize large
-    amounts of technical data.
-    <p>
-      Noesys can be used to:
-    </p>
-    <ul>
-      <li>
-        Access and organize complex technical data
-      </li>
-      <li>
-        Export data objects to text and binary
-      </li>
-      <li>
-        View and edit large multidimensional data sets (up to 7D) in a spreadsheet-like
-        environment
-      </li>
-      <li>
-        Manipulate and process data using <a
-        href="http://www.exelisvis.com/ProductsServices/IDL.aspx">IDL®</a>, the Interactive Data Language,
-        from Research Systems, Inc.
-      </li>
-      <li>
-        Interactively visualize column, matrix, and volumetric data sets
-      </li>
-      <li>
-        Image global datasets as various map projections
-      </li>
-      <li>
-        Create various projections from partial data or partial projections from
-        global data (Windows only)
-      </li>
-      <li>
-        View and Edit HDF-EOS grid object data
-      </li>
-      <li>
-        Subset datasets and data tables with a GUI dialog
-      </li>
-      <li>
-        Change and save the number format of datasets and data table fields
-      </li>
-      <li>
-        Drag and Drop HDF objects between files to organize or subset files
-      </li>
-      <li>
-        Attach text annotations directly to the data file
-      </li>
-      <li>
-        Add new data objects to files and create hierarchical groups
-      </li>
-      <li>
-        Edit or create new color palettes
-      </li>
-      <li>
-        Generate publication-quality graphics for data presentation
-      </li>
-    </ul>
-    <p>
-      Noesys has an interface to IDL®, allowing data to move back and forth between
-      Noesys and IDL with the click of a mouse. Noesys includes the visual data analysis
-      tools, Transform, T3D and Plot, for menu driven plotting, rendering, and image
-      analysis. Noesys can import HDF, HDF-EOS, netCDF, ASCII, Binary, DTED, GeoTIFF,
-      SDTS, TIFF, PICT, and BMP files, create annotations, macros, images, projections
-      and color palettes specific to the data and save it the result as an HDF file.
-      Noesys also includes an HDF-EOS Grid Editor. Noesys runs on Windows 95/98 &
-      NT and Power Macintosh OS. More details and information about ordering Noesys
-      are available from <a
-      href="http://www.rsinc.com/NOeSYS/index.cfm"><http://www.rsinc.com/NOeSYS/index.cfm></a>.
-    </p>
-
-    <h2><a id="Origin" name="Origin">Origin</a></h2>
-
-    <p>
-      Ryan Toomey reports:
-
-    <p>
-      Our website is <a href="http://www.originlab.com/" >http://www.originlab.com/</a>
-    </p>
-    <p>
-      A general description of Origin: Origin includes a suite of features
-      that cater to the needs of scientists and engineers alike. Multi-sheet
-      workbooks, publication-quality graphics, and standardized analysis
-      tools provide a tightly integrated workspace for you to import data,
-      create and annotate graphs, explore and analyze data, and publish your
-      work. To ensure that Origin meets your data analysis requirements,
-      intuitive tools for advanced statistics, regression, nonlinear curve
-      fitting, signal processing, image processing and peak analysis are
-      built-in. Since any analysis operation can be set to automatically
-      recalculate, you can reuse your projects as templates for future work,
-      thereby simplifying your daily routine.
-    </p>
-    <p>
-      A general description of OriginPro: OriginPro offers all of the
-      features of Origin plus extended analysis tools for statistics, 3D
-      fitting, image processing and signal processing.
-    </p>
-    <p>
-      A general description of OriginLab Corporation: "OriginLab Corporation
-      produces professional data analysis and graphing software for
-      scientists and engineers. Our products are designed to be easy-to-use,
-      yet have the power and versatility to provide for the most demanding
-      user."
-    </p>
-
-    <h2><a id="PPLUS" name="PPLUS">PPLUS</a></h2>
-    <a href="http://dwd6.home.mindspring.com/">Plot-Plus (PPLUS)</a> is a general
-    purpose scientific graphics package, which is used in several PMEL applications.
-    It will read most standard ascii or binary files, as well as netCDF file format,
-    which used by the TOGA-TAO Project and the EPIC system for management display
-    and analysis. PPLUS is an interactive, command driven, scientific graphics package
-    which includes features such as Mercator projection, Polar Stereographic projection,
-    color or gray scale area-fill contour plotting, and support for many devices:
-    X-windows, PostScript, HP, Tektronix, and others. This powerful and flexible package
-    recognizes netCDF data format, and it can extract axis lables and graph titles
-    from the data files. The user can customize a plots, or combine several plots
-    into a composite. Plots are of publication quality. The PPLUS graphics package
-    is used for all the TAO workstation displays, including the animations. The animations
-    are created by generating a PPLUS plot for each frame, transforming the PPLUS
-    metacode files into HDF format with the PPLUS m2hdf filter, and then displaying
-    the resulting bit maps as an animation with the XDataSlice utility, which is freely
-    available on Internet from the National Center for Supercomputing Applications,
-    at anonymous at ftp.ncsa.uiuc.edu (141.142.20.50). There is also a new m2gif utility
-    which produces GIF files from PPLUS metacode files.
-    <p>
-      PPLUS is supported for most Unix systems and for VAX/VMS, and is in use at
-      many oceanographic institutes in the US (e.g., (PMEL, Harvard, WHOI, Scripps,
-      NCAR, NASA, University of Rhode Island, University of Oregon, Texas A&M...)
-      and also internationally (Japan, Germany, Australia, Korea...).
-    </p>
-    <p>
-      Plot Plus is now available at no charge. It does require licensing on a per
-      computer basis, but the license is at no cost. For more information about licensing,
-      see <a
-      href="http://dwd6.home.mindspring.com/pplus_license.html">http://dwd6.home.mindspring.com/pplus_license.html/</a>;
-      source and documentation are available via anonymous FTP from <a
-      href="ftp://ftp.halcyon.com/pub/users/dwd/pplus1_3_2.tar.gz">ftp://ftp.halcyon.com/pub/users/dwd/pplus1_3_2.tar.gz</a>
-      and <a
-      href="ftp://ftp.pmel.noaa.gov/epic/manual-dir/pplus.pdf">ftp://ftp.pmel.noaa.gov/epic/manual-dir/pplus.pdf</a>.
-    </p>
-    <pre>
-      Email:      plot_plus at halcyon.com
-      Postal mail:    c/o Donald Denbo
-      2138 N 186th St
-      Shoreline, WA 98133
-      Fax and Voice:  (206) 366-0624
-      </pre>
-    <h2><a id="PV-Wave" name="PV-Wave">PV-Wave</a></h2>
-    <a href="http://www.vni.com/products/wave/index.html">PV-Wave</a> is a software
-    environment from <a href="http://www.vni.com/">Visual Numerics</a> for solving
-    problems requiring the application of graphics, mathematics, numerics and statistics
-    to data and equations.
-    <p>
-      PV-WAVE uses a fourth generation language (4GL) that analyzes and displays
-      data as you enter commands. PV-WAVE includes integrated graphics, numerics,
-      data I/O, and data management. The latest version of PV-Wave supports data access
-      in numerous formats, including netCDF.
-    </p>
-    <p>
-      See also the information on <a href="#DDI">DDI</a> for another way to use netCDF
-      data with PV-Wave.
-    </p>
-    <p></p>
-    <h2><a id="SlicerDicer" name="SlicerDicer">Slicer Dicer</a></h2>
-    <a href="http://www.slicerdicer.com/">Slicer Dicer</a> is a volumetric data visualization
-    tool, currently available for Windows and under development for other platforms.
-    The Slicer Dicer Web site includes a complete list of features, an on-line user's
-    guide, and examples of Slicer Dicer output. Visualizations features include:
-    <ul>
-      <li>
-        Perspective view of data rendered on interactively selected orthogonal slices,
-        oblique slices, blocks (arbitrary rectilinear sub-volumes), cutouts, isosurfaces,
-        and projected volumes (projected maximum, minimum, maximum absolute, or minimum
-        absolute).
-      </li>
-      <li>
-        Optional annotations: caption, axes ticks and labels (default "pretty"
-        ticks, or override to place ticks where you want them), color legend, data-cube
-        outline.
-      </li>
-      <li>
-        Animation modes: slices, space, time (any parametric dimension), transparency,
-        oblique slice orientation, rotation. Built-in animation viewer supports speed
-        and image size controls, single-step, forward, backward, loop, and back-and-forth
-        modes.
-      </li>
-      <li>
-        Select color scale from 25+ built in color tables, or import from palette
-        file. Any data level or range of levels can be painted with an arbitrary color.
-      </li>
-      <li>
-        Any data level or range of levels can be rendered as either opaque or transparent.
-      </li>
-    </ul>
-    <p></p>
-    <h2><a id="Surfer" name="Surfer">Surfer</a></h2>
-    <p>
-      <a href="http://www.goldensoftware.com/products/surfer">Surfer</a> is a
-      full-function contouring, gridding and 3D surface mapping
-      visualization software package. Surfer's sophisticated
-      interpolation engine transforms XYZ data into
-      publication-quality maps. Surfer imports from and exports to
-      a multitude of file formats, including NetCDF grids.
-    </p>
-
-    <h2><a id="vGeo" name="vGeo">vGeo</a></h2>
-    <p>
-      <a href="http://www.vrco.com/products/vgeo/vgeo.html" >vGeo</a> (Virtual Global
-      Explorer and Observatory) is an end-user product from <a href="http://www.vrco.com/" >VRCO</a>
-      designed to import and visualize multiple disparate data sets, including computer
-      simulations, observed measurements, images, model objects, and more. vGeo is
-      available for IRIX, Linux and Windows platforms and supports displays ranging
-      from desktop monitors to multi-walled projection systems. It accepts data in
-      a variety of formats, including netCDF, and allows the user to specify how multiple
-      files and variables are mapped into a data source. 3D graphics are built from
-      the underlying data in real-time, and the user has interactive control of graphics,
-      navigation, animation, and more.
-    </p>
-    <p></p>
-    <h2><a id="VISAGE and Decimate" name="VISAGE and Decimate">VISAGE and Decimate</a></h2>
-    <p>
-      <a
-      href="http://www.crd.ge.com/esl/cgsp/projects/visage/">VISAGE</a> (VISualization,
-      Animation, and Graphics Environment) is a turnkey 3D visualization system developed
-      at General Electric Corporate Research and Development, (Schroeder, WJ et al,
-      "VISAGE: An Object-Oriented Scientific Visualization System", Proceedings
-      of Visualization `92 Conference). VISAGE is designed to interface with a wide
-      variety of data, and uses netCDF as the preferred format.
-    </p>
-    <p>
-      VISAGE is used at GE Corporate R & D, GE Aircraft Engine, GE Canada, GE
-      Power Generation, as well as ETH Zurich, Switzerland, MQS In Chieti, Italy,
-      and Rensselaer Polytechnic Institute in Troy, New York.
-    </p>
-    <p>
-      GE has another application called "Decimate" that does polygon reduction/decimation
-      (Schroeder,WJ et al, "Decimation of Triangle Meshes", Proceedings
-      of SIGGRAPH `92). This application uses netCDF as a preferred format. Decimate
-      is currently licensed to Cyberware, Inc., makers of 3D laser digitizing hardware.
-      Decimate is currently bundled with the scanners, and will soon be available
-      as a commercial product.
-    </p>
-    <p></p>
-    <h2><a id="Voyager" name="Voyager">Voyager</a></h2>
-    <p>
-      <a href="http://voyager.makai.com/" >Makai Voyager</a>, developed by
-      Makai Ocean Engineering, Inc., is 3D/4D
-      geospatial visualization software that enables users to import, fuse, view, and analyze large
-      earth, ocean, and atmosphere scientific data as it is collected or
-      simulated in a global geo-referenced GIS platform. The key differentiator
-      of Makai Voyager is its level-of-detail (LOD) technology that enables
-      users to stream big data rapidly over a network or the web.
-    </p>
-    <p>
-      Features in Makai Voyager Version 1.2 include:
-    </p>
-    <ul>
-      <li>
-        Preprocessing LiDAR, GIS, & volumetric data from common formats
-        into streamable files
-      </li>
-      <li>
-        Volume rendering for large 4D (3D + time) data, such as
-        NetCDF
-      </li>
-      <li>
-        Analysis tools and customizable graphs
-      </li>
-      <li>
-        WMS and other streamable formats
-      </li>
-    </ul>
-    <p>
-      Individual or group licenses are available for Windows (32- and
-      64-bit), Linux, and Mac OS X.
-      A full-featured 30-day trial version of Makai Voyager is <a
-      href="http://voyager.makai.com " >available for download</a>.
-    </p>
-    <hr>
-
-    <!-- InstanceEndEditable -->
-  </body>
-</html>
-
-<!-- InstanceEnd -->
+      and isosurfaces.
+    </p>
+
+    <h2><a id="WebWinds" name="WebWinds">WebWinds</a></h2>
+    <p>
+      <a href="http://www.openchannelsoftware.com/projects/WebWinds/"> WebWinds</a> is a free Java-based
+      science visualization and analysis package. In addition to several new analysis
+      tools, the current fourth version does automatic scripting. This allows
+    </p>
+    <ol>
+      <li>
+        a user to rapidly and automatically create and store a session, either
+        for his own use, or for use by a collaborator on another machine;
+      </li>
+      <li>
+        a data provider to automatically create a specialized analysis environment
+        which can be downloaded (as a small script file) along with a dataset from
+        a Website; and
+      </li>
+      <li>
+        realtime collaboration or sharing of sessions over (even low-bandwidth)
+        networks, including the Internet.
+      </li>
+    </ol>
+    <p>
+      This scripting requires no knowledge of the scripting language syntax. Several
+      sample script files are included with the distribution.
+    </p>
+    <p>
+      In addition, this version contains a capability to geo-reference some data
+      and to read ASCII data in tabular format. Also new is the ability to output
+      data in numerical form (e.g. NetCDF) and a context sensitive, integrated help
+      system.
+    </p>
+    <p>
+      As with earlier versions, data in several different formats, including NetCDF,
+      can be read in easily from your local machine or from the Web. In addition,
+      most data can be subset or subsampled on load, making it possible to visualize
+      very large multidimensional and/or multispectral datasets. The package includes
+      several step-by-step examples. Installation of the software (including Java)
+      on the PC or Mac is a process requiring one file to be downloaded and opened.
+      If you need help getting started, a remote tutorial is available once you've
+      downloaded the package.
+    </p>
+    <p>
+      WebWinds is `point and click' rather than language driven and it runs well
+      on Unix, Windows (95/98/NT) and Mac platforms. It currently requires JDK 1.1.
+      To download a copy of this release, go to <a href="http://www.sci-conservices.com/rel4/webpage/wwhome.html"
+      >http://www.sci-conservices.com/rel4/webpage/wwhome.html</a>
+    </p>
+    <p></p>
+
+    <h2><a id="xray" name="xray">xray (Python N-D labelled arrays)</a></h2>
+    <p>
+      <a href="http://xray.readthedocs.org/en/stable/index.html" >xray</a>
+      is an open source project and Python package that aims to bring the
+      labeled data power of <a href="http://pandas.pydata.org/" >pandas</a>
+      to the physical sciences, by providing N-dimensional variants of the
+      core pandas data structures, Series and DataFrame: the xray DataArray
+      and Dataset.
+    </p>
+    <p>
+      xray adopts the <a
+      href="http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/CDM"
+      >Common Data Model</a> for self-describing scientific data in
+      widespread use in the Earth sciences (e.g., netCDF and OPeNDAP):
+      xray.Dataset is an in-memory representation of a netCDF file.
+    </p>
+    <p>
+      xray is being developed by Stephan Hoyer, Alex Kleeman, and <a
+      href="https://github.com/xray/xray/graphs/contributors" >other
+      contributors</a>.
+    </p>
+
+    <h2><a id="Zebra" name="Zebra">Zebra</a></h2>
+    <a href="http://www.atd.ucar.edu/rdp/zebra.html">Zebra</a> (formerly named Zeb)
+    is a system for data ingest, storage, integration and display, designed to operate
+    in both real time and postprocessing modes. Zebra was developed by Jonathan Corbet
+    and others in NCAR's <a
+    href="http://www.atd.ucar.edu/rdp/rdp_home.html">Research Data Program</a>.
+    <p>
+      Zebra's primary use is for the superpositioning of observational data sets
+      (such as those collected by satellite, radar, mesonet and aircraft) and analysis
+      products (such as model results, dual-Doppler synthesis or algorithm output).
+      Data may be overlaid on a variety of display types, including constant altitude
+      planes, vertical cross-sections, X-Y graphs, Skew-T plots and time-height profiles.
+      The fields for display, color tables, contour intervals and various other display
+      options are defined using an icon based user-interface. This highly flexible
+      system allows scientific investigators to interactively superimpose and highlight
+      diverse data sets; thus aiding data interpretation.
+    </p>
+    <p>
+      Data handling capabilities permit external analysis programs to be easily linked
+      with display and data storage processes. The data store accepts incoming data,
+      stores it on disk, and makes it available to processes which need it. An application
+      library is available for data handling. The library functions allow data storage,
+      retrieval and queries using a single applications interface, regardless of the
+      data's source and organization. NetCDF data that conforms to Zebra conventions
+      is supported by this interface.
+    </p>
+    <p>
+      Zebra is currently available to the university research community through the
+      NCAR/ATD Research Data Program. Email requests to rdp-support at atd.ucar.edu.
+      More information is on the web page http://www.atd.ucar.edu/rdp/zebra.html.
+    </p>
+
+    <hr />
+
+    <h1><a id="user" name="user">User-Contributed Software</a></h1>
+    <p>
+      Unidata makes available a separate
+      <a href="/software/netcdf/Contrib.html">catalog</a>
+      to a
+      <a href="ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/">directory</a>
+      of freely available, user-contributed software and documentation related to the
+      netCDF library. This software may be retrieved by anonymous FTP. We haven't
+      necessarily used or tested this software; we make it available "as is".
+    </p>
+    <p>
+      The criteria for inclusion in the netcdf/contrib/ directory of user-contributed
+      software are:
+    </p>
+    <p></p>
+    <ul>
+      <li>
+        General usefulness to a significant part of the netCDF community
+      </li>
+      <li>
+        Small size
+      </li>
+      <li>
+        Infrequent need for updates
+      </li>
+      <li>
+        Free availability
+      </li>
+    </ul>
+    <hr />
+
+    <h1 id="commercial">Commercial or Licensed Packages</h1>
+
+    <h2><a id="ArcGIS" name="ArcGIS">ArcGIS Pro - Space Time Pattern Mining Toolbox</a></h2>
+    <p>
+      The <a href="https://pro.arcgis.com/en/pro-app/tool-reference/space-time-pattern-mining/an-overview-of-the-space-time-pattern-mining-toolbox.htm">Space Time Pattern Mining toolbox</a> contains statistical tools for analyzing data distributions and patterns in the context of both space and time. It includes a toolset for visualizing the data stored in the space-time netCDF cube in both 2D and 3D.
+
+      Create Space Time Cube takes point datasets and builds a multidimensional cube data structure (netCDF) for analysis. Emerging Hot Spot Analysis then takes the cube as input and identifies statistically significant hot and cold spot trends over time. You might use the Emerging Hot Spot Analysis tool to analyze crime or disease outbreak data in order to locate new, intensifying, persistent, or sporadic hot spot patterns at different time-step intervals. The Local Outlier Analysis too [...]
+    </p>
+    <p></p>
+
+    <h2><a id="Agrimetsoft" name="Agrimetsoft">AgriMetSoft Netcdf-Extractor</a></h2>
+      There are different software packages or various codes that may be used for manipulating or displaying NetCDF data. Some of them such as MATLAB programming language needs to enough information about provide codes in MATLAB as well as to know run codes and statements. Furthermore, user should have to pay for MATLAB programming and install it in her/his system. Also, another of them are related to other programming languages such as R, NCL (NCAR Command Language), and etc. It has bee [...]
+    <p>
+
+
+    <p></p>
+
+    <h2><a id="ViewNcDap" name="ViewNcDap">ASA ViewNcDap</a></h2>
+    <p>
+      Applied Science Associates, Inc. has made the ASA View NC/Dap
+      application freely available for <a
+      href="http://www.asascience.com/downloads" >download</a>.  ViewNcDap
+      is a stand-alone research-based tool (with included demonstration
+      data) that allows a user to visualize four dimensional NetCDF and
+      OPeNDAP data.  ViewNcDap is a Windows application that includes
+      temporal/time step functionality for viewing animations of data that
+      include temporal information.  The application may be used to
+      visualize a variety of time-varying geospatial scientific data in a
+      simple map framework.  It handles CF conventions and includes some
+      aliasing features that could permit additional formats to be read.
+      It should not be considered a GIS system, but
+      is used to quickly preview a variety of data on a simple map. Data may
+      also be filtered and saved to a local netCDF file.
+    </p>
+    <p></p>
+
+    <h2><a id="Avizo" name="Avizo">Avizo</a></h2>
+    <p>
+      <a href="http://www.avizo3d.com/" >Avizo</a> software is a powerful
+      tool for 3D data visualization and
+      analysis.  It offers a comprehensive feature set that addresses
+      visualization, processing, analysis, communication and
+      presentation. <a href="http://www.vsg3d.com/vsg_prod_avizo_green.php"
+      > Avizo Green Edition</a> includes an advanced set of
+      features dedicated to climate, oceanography, environmental or
+      earth-mapped data.  It provides high-level support for the netCDF
+      format, a dedicated Earth visualization module, and a set of advanced
+      geographical projections applicable to a wide range of fast 2D and 3D
+      data representations.
+    </p>
+    <p>
+      For more information, see <a
+      href="http://www.avizo3d.com/" >www.avizo3d.com</a>.
+    </p>
+
+    <h2><a id="AVS" name="AVS">AVS</a></h2>
+    <a href="ftp://testavs.ncsc.org/avs/Info/WHAT_IS_AVS">AVS</a> (Application Visualization
+    System) is a visualization application software and development environment. An
+    AVS module has been written that allows multi-dimensional netCDF data sets to
+    read into AVS as uniform or rectilinear field files. The AVS user can point and
+    click to specify the name of the variable in the selected netCDF file, as well
+    as selecting the hyperslab. If 1D coordinate variables exist (a variable that
+    has the same name as a dimension) then the coordinate variable will be used to
+    specify the coordinates of resulting rectilinear field file. If no coordinate
+    variable exists, then the resulting field file will be uniform. Once in AVS, there
+    are hundreds of analysis and display modules available for image processing, isosurface
+    rendering, arbitrary slicing, alpha blending, streamline and vorticity calculation,
+    particle advection, etc. AVS runs on many different platforms (Stardent, DEC,
+    Cray, Convex, E and S, SET, Sun, IBM, SGI, HP, FPS and WaveTracer), and it has
+    a flexible data model capable of handling multidimensional data on non-Cartesian
+    grids.
+    <p>
+      The module source code and documentation is available from the <a href="http://iac.ncsc.org/">International
+      AVS Center</a>, in the <a
+      href="ftp://testavs.ncsc.org/avs/AVS5/Module_Src/data_input/read_netcdf/"> ftp://testavs.ncsc.org/avs/AVS5/Module_Src/data_input/read_netcdf/</a>
+      directory.
+    </p>
+    <p>
+      See also the information on <a href="#DDI">DDI</a> for another way to use netCDF
+      data with AVS.
+    </p>
+    <p></p>
+
+    <h2><a id="BCS-UFI" name="BCS-UFI" >Barrodale UFI</a></h2>
+
+    <p>
+      <a href="http://www.barrodale.com" >Barrodale Computing Services
+      Ltd.</a> (BCS) has developed a product that addresses one of
+      the main objections heard from "technologists" (e.g., scientists,
+      engineers, and other researchers) who avoid using databases to manage
+      their data: "my very large data files are too
+      cumbersome/difficult/slow/costly to load into a database".  In
+      addition to netCDF, these files come in a variety of formats (HDF5, GRIB,
+      NITFS, FITS, etc.).
+    </p>
+    <p>
+      This BCS product is called the <a
+      href="http://www.barrodale.com/bcs/universal-file-interface-ufi"
+      >Universal File Interface (UFI)</a>; it's a
+      database extension based on the IBM Informix Virtual Table Interface
+      (VTI). <em>(Please continue reading even if you don't have
+      Informix running on your system, because IBM has just made available, at
+      no charge, the <a
+      href="http://www-01.ibm.com/software/data/informix/innovator-c-edition/"
+      >Innovator-C Edition</a> of Informix.)</em> A demo that uses UFI to
+      access wind speeds can be seen <a
+      href="http://www.barrodale.com/bcs/universal-file-interface-animation"
+      >here</a>.
+    </p>
+    <p>
+      VTI is a technology that supports making external datasets appear as tables
+      to SQL queries and statements.  UFI is a BCS database extension for
+      delivering the contents of external data files as though they were rows in
+      a database table.  UFI makes a file look like a set of database tables, so
+      "UFI managed tables" are actually virtual database tables.   Consequently,
+      users of UFI can perform SQL queries on their files without having to first
+      load them into a database.
+    </p>
+
+    <p></p>
+
+    <h2><a id=></a></h2>
+
+    <h2><a id="DioVISTA/Storm" name="DioVISTA/Storm" >DioVISTA/Storm</a></h2>
+    <p>
+      <a href="http://www.hitachi-power-solutions.com/products/product03/p03_61.html"
+      >DioVISTA/Storm</a> is a commercial software package that visualizes content
+      of netCDF files as a time series of grids, isosurfaces, and arrows on a 3D
+      virtual earth. Its user interface is similar to standard 3D earth
+      visualizing software. It displays OGC KML files, Shapefiles, and online
+      map resources through OGC Web Tile Map Services (WTMS). It supports CF
+      Conventions version 1.6 (lon-lat-alt-time axis and trajectory). Its first
+      version was released on Aug 5 2014.
+    </p>
+
+    <p></p>
+
+    <h2><a id="Environmental WorkBench"
+    name="Environmental WorkBench">Environmental WorkBench</a></h2>
+    <a href="http://www.ssesco.com/">SuperComputer Systems Engineering and Services
+    Company</a> (SSESCO) has developed the <a
+    href="http://www.ssesco.com/files/ewb.html">Environmental WorkBench</a> (EWB),
+    an easy to use visualization and analysis application targeted at environmental
+    data. The EWB currently has numerous users in the fields of meteorological research,
+    air quality work, and groundwater remediation.
+    <p>
+      EWB system features include:
+    </p>
+    <ul>
+      <li>
+        Random access file structure using the netCDF-based public domain MeRAF
+        file system with support for gridded, discrete (non-grid-based observation),
+        and particle types
+      </li>
+      <li>
+        Support for geo-referenced or Cartesian coordinate systems
+      </li>
+      <li>
+        Object oriented Graphical User Interface (GUI) that is very easy to use
+      </li>
+      <li>
+        Tools for converting model and observational data sets and data writers
+        to netCDF
+      </li>
+      <li>
+        Interactive rotation/translation of scenes in 3D space
+      </li>
+      <li>
+        Time sequencing controls to step forward/backward, animate sequentially,
+        or go to a chosen time step; including multiple asynchronous or non-uniform
+        time steps
+      </li>
+      <li>
+        Interactive slicers to select cross sections through 3D data sets
+      </li>
+      <li>
+        Display operators available on the slices, including
+        <ul>
+          <li>
+            Contour lines with selectable contour levels
+          </li>
+          <li>
+            Color shading by data value with variable transparency level
+          </li>
+          <li>
+            Arrow and streamline representation for vector quantities
+          </li>
+          <li>
+            Positional reference lines at user selected intervals
+          </li>
+          <li>
+            Color coded shapes at each grid node
+          </li>
+        </ul>
+      </li>
+      <li>
+        Multiple 3D isosurfaces at selected parameters and values with variable
+        transparency
+      </li>
+      <li>
+        Display of particle positions with coloring by type, height, and source
+      </li>
+      <li>
+        Display of discrete data using colored spheres and labels for scalar data
+        and arrows for vectors (with arrowheads or meteorological style)
+      </li>
+      <li>
+        Multiple user definable color maps to which isosurface and colored field
+        shading may be separately assigned
+      </li>
+      <li>
+        On screen annotation for generation of report ready figures
+      </li>
+      <li>
+        Image export in any of the common image formats (gif, tiff, encapsulated
+        postscript, etc.)
+      </li>
+      <li>
+        Graceful handling of missing or bad data values by all the graphics rendering
+        routines
+      </li>
+      <li>
+        Automatic data synchronization to allow automatic screen updating as new
+        data arrives in real-time from a model or set of sensors
+      </li>
+      <li>
+        Two and three dimensional interpolation from scattered observations to a
+        grid, using the Natural Neighbor Method. This robust volume based method yields
+        results far superior to distance weighting schemes.
+      </li>
+    </ul>
+    <p>
+      Systems currently supported include Win95, WinNT, OS/2, IBM RS/6000, Silicon
+      Graphics, HP and SUN workstations.
+    </p>
+    <p>
+      SSESCO has implemented a meta-file layer on top of the netCDF library, called
+      MeRAF. It handles multiple netCDF files as well as automatic max-min calculations,
+      time-varying gridded, particle, and discrete data, logical groupings for discrete
+      data, and an overall simplified and flexible interface for storing scientific
+      data. MeRAF is being used by the DOE at the Hanford-Meteorological Site for
+      observational data and will be used for their weather-modeling.
+    </p>
+    <p></p>
+
+    <h2><a id="ESRI" name="ESRI">ESRI</a></h2>
+
+    <p>
+      <a href="http://www.esri.com/software/arcgis/index.html" >ESRI
+      ArcGIS</a> version 9.2 and later support <a
+      href="http://webhelp.esri.com/arcgisdesktop/9.2/index.cfm?TopicName=An_overview_of_data_support_in_ArcGIS"
+      >accessing netCDF time-based and multidimensional data</a> that
+      follows CF or COARDS conventions for associating spatial locations
+      with data.  A selected slice of netCDF data may be displayed in ArcGIS
+      as a raster layer, feature layer, or table.  You can also drag a
+      netCDF file from Windows Explorer and drop it in an ESRI application
+      such as ArcMap.
+    </p>
+
+    <p></p>
+
+    <h2><a id="FME">FME</a></h2>
+
+    <p>
+      <a href="http://www.safe.com/fme">FME</a>, developed by <a
+      href="http://www.safe.com">Safe Software Inc.</a>, is a tool for transforming
+      data for exchange between over <a href="http://www.safe.com/fme/format-search/">300
+      different formats and models</a>, including netCDF. FME's
+      read and write support for netCDF allows users to
+      move data into the netCDF common standard, regardless
+      of its source, and conversely enables end-users to consume netCDF
+      data for use in their preferred systems. For more information visit <a
+      href="http://www.safe.com/fme">http://www.safe.com/fme</a>.
+    </p>
+
+    <p></p>
+
+    <h2><a id="HDF-Explorer" name="HDF-Explorer">HDF Explorer</a></h2>
+    <p>
+      <a href="http://www.space-research.org/" >HDF Explorer</a>
+      is a data visualization program that reads the HDF, HDF5
+      and netCDF data file formats (including netCDF classic format data).
+      HDF Explorer runs in the Microsoft
+      Windows operating systems.
+    </p>
+    <p>
+      HDF Explorer offers a simple yet powerful interface for the
+      visualization of HDF and netCDF data.  The data is just a click of the mouse
+      away. Data is first viewed in a tree-like interface, and then
+      optionally loaded and visualized in a variety of ways.
+      HDF Explorer features include fast access to data, grid, scalar and
+      vector views. It also allows exporting your data either as an ASCII
+      text file or a bitmap image.
+    </p>
+    <p></p>
+
+    <h2><a id="IDL" name="IDL">IDL Interface</a></h2>
+    <a href="http://www.exelisvis.com/ProductsServices/IDL.aspx">IDL</a> (Interactive Data Language)
+    is a scientific computing environment, developed and supported by <a
+    href="http://www.exelisvis.com/" >Excelis Visual Information
+    Solutions</a>, that combines mathematics, advanced data
+    visualization, scientific graphics, and a graphical user interface toolkit to
+    analyze and visualize scientific data. Designed for use by scientists and scientific
+    application developers, IDL's array-oriented, fourth-generation programming
+    language allows you to prototype and develop complete applications. IDL now supports
+    data in netCDF format.
+    <p>
+      As an example, here is how to read data from a netCDF variable named GP in
+      a file named "data/aprin.nc" into an IDL variable named gp using the
+      IDL language:
+    </p>
+    <p></p>
+    <pre>
+      id = ncdf_open('data/april.nc')
+      ncdf_varget,id, ncdf_varid( id, 'GP'), gp
+      </pre>
+      Now you can visualize the data in the gp variable in a large variety of ways and
+      use it in other computations in IDL. You can FTP a demo version of IDL, including
+      the netCDF interface, by following the instructions in pub/idl/README available
+      via anonymous FTP from gateway.rsinc.com or boulder.colorado.edu.
+
+    <p>
+      Other software packages that use or interoperate with IDL to access netCDF
+      data includes <a href="#ARGOS">ARGOS</a>, <a
+      href="#CIDS Tools">CIDS Tools</a>, <a href="#DDI">DDI</a>, <a
+      href="#HIPHOP">HIPHOP</a>, <a
+      href="Hyperslab OPerator Suite (HOPS)">Hyperslab OPerator Suite (HOPS)</a>, and <a href="Noesys">Noesys</a>.
+    </p>
+    <p></p>
+
+    <p></p>
+    <h2><a id="InterFormat" name="InterFormat">InterFormat</a></h2>
+    <a href="http://www.radio-logic.com/">InterFormat</a> is a medical image format
+    conversion program with both Motif and character interfaces. InterFormat can automatically
+    identify and convert most popular medical image formats and write output files
+    in many standard medical image formats, or in formats such as netCDF that are
+    suitable for input to leading scientific visualization packages. InterFormat runs
+    on UNIX workstations; a version for OpenVMS is also available. A separate external
+    module for <a
+    href="#OpenDX">IBM Data Explorer</a> is available for use in IBM Data Explorer's
+    Visual Program Editor.
+    <p>
+      For more details about the formats handled, program features, and pricing,
+      see the Radio-Logic web site at <a
+      href="http://www.radio-logic.com"><http://www.radio-logic.com></a>.
+    </p>
+    <h2><a id="IRIS Explorer Module" name="IRIS Explorer Module">IRIS Explorer Module</a></h2>
+    <p>
+      The Atmospheric and Oceanic Sciences Group at the National Center for Supercomputing
+      Applications (NCSA) and the Mesoscale Dynamics and Precipitation Branch at NASA-Goddard
+      Space Flight Center have developed the NCSA PATHFINDER module set for <a
+      href="http://www.nag.co.uk:70/1h/Welcome_IEC">IRIS Explorer</a>. Two of the modules, <a
+      href="http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/explorer/ReadDFG/ReadDFG.html"> ReadDFG</a> (to output Grids), and <a
+      href="http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/explorer/ReadDF/ReadDF.html"> ReadDF</a> (to output Lattices) are capable of reading from NCSA HDF files, MFHDF/3.3
+      files, and Unidata netCDF files. A user-friendly interface provides control and
+      information about the contents of the files.
+    </p>
+    <p>
+      For ReadDF, the format translation is handled transparently. Up to five unique
+      lattices may be generated from the file (as these files can contain multiple
+      data fields) using a single module. A variety of dimensionalities and data types
+      are supported also. Multiple variables may be combined in a single lattice to
+      generate vector data. All three Explorer coordinate systems are supported.
+    </p>
+    <p>
+      With ReadDFG, user selected variables from the file are output in up to five
+      PATHFINDER grids. Each grid can consist of scalar data from one variable or
+      vector data from multiple variables. Coordinate information from the file is
+      also included in the grids. Any number of dimensions in any of the Explorer
+      coordinate types are supported.
+    </p>
+    <p>
+      For more information on the NCSA PATHFINDER project and other available modules,
+      visit the WWW/Mosaic PATHFINDER Home Page at <a
+      href="http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/top/top.html"> http://redrock.ncsa.uiuc.edu/PATHFINDER/pathrel2/top/top.html</a>
+      The ReadDF module may be downloaded either via the WWW server or anonymous ftp
+      at redrock.ncsa.uiuc.edu in the /pub/PATHFINDER directory. For more information
+      please send email to: pathfinder at redrock.ncsa.uiuc.edu
+    </p>
+    <p>
+      See also the information on <a href="#DDI">DDI</a> for another way to use netCDF
+      data with IRIS Explorer.
+    </p>
+    <p></p>
+    <h2><a id="LeoNetCDF" name="LeoNetCDF">LeoNetCDF</a></h2>
+    <p>
+      <a href="http://www.leokrut.com/leonetcdf.html" >LeoNetCDF</a> is a
+      Windows application (Windows96/NT and higher) for editing netCDF
+      files.  It can display content of netCDF files in tree style control
+      and permits editing its parameters in a standard Windows interface
+      environment.
+    </p>
+    <p></p>
+    <h2><a id="Mathematica" name="Mathematica">Mathematica</a></h2>
+    <p>
+      <a href="http://www.wolfram.com/products/mathematica/index.html"
+      >Mathematica</a> is a technical computing environment that provides
+      advanced numerical and symbolic computation and visualization.
+      As of version 6, Mathematica adds classic
+      <a href="http://reference.wolfram.com/mathematica/ref/format/NetCDF.html" >netCDF data</a> to the many forms of
+      data it can import, export, and visualize.
+    </p>
+    <p></p>
+    <h2><a id="MATLAB" name="MATLAB">MATLAB</a></h2>
+    <a href="http://www.mathworks.com/products/matlab/">MATLAB</a> is an integrated
+    technical computing environment that combines numeric computation, advanced graphics
+    and visualization, and a high-level programming language.
+    Versions 7.7 and later of MATLAB have built-in support for reading and
+    writing netCDF data.  MATLAB version 2012a includes the netCDF 4.1.2 library
+    with OPeNDAP client support turned on, so remote access to netCDF and
+    other data formats supported by OPeNDAP servers is available.
+    </p>
+    <p>
+      For earlier versions, several freely-available software packages that implement a MATLAB/netCDF interface
+      are available:
+      <a href="#nctoolbox" >nctoolbox</a>, <a href="#NC4ML5">NetCDF Toolbox for MATLAB-5</a>, <a href="#MexEPS">MexEPS</a>,
+      the <a
+      href="#CSIRO-MATLAB">CSIRO MATLAB/netCDF interface</a>, <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15177&objectType=file"
+      >NetCDF reader</a>,  and <a href="/software/netcdf/Contrib.html">fanmat</a>.
+    </p>
+    <h2><a id="Noesys" name="Noesys">Noesys</a></h2>
+    <a href="http://www.rsinc.com/NOeSYS/index.cfm" >Noesys</a> is software for desktop
+    science data access and visualization. Available for both Windows and Power Macintosh
+    platforms, Noesys allows users to access, process, organize and visualize large
+    amounts of technical data.
+    <p>
+      Noesys can be used to:
+    </p>
+    <ul>
+      <li>
+        Access and organize complex technical data
+      </li>
+      <li>
+        Export data objects to text and binary
+      </li>
+      <li>
+        View and edit large multidimensional data sets (up to 7D) in a spreadsheet-like
+        environment
+      </li>
+      <li>
+        Manipulate and process data using <a
+        href="http://www.exelisvis.com/ProductsServices/IDL.aspx">IDL®</a>, the Interactive Data Language,
+        from Research Systems, Inc.
+      </li>
+      <li>
+        Interactively visualize column, matrix, and volumetric data sets
+      </li>
+      <li>
+        Image global datasets as various map projections
+      </li>
+      <li>
+        Create various projections from partial data or partial projections from
+        global data (Windows only)
+      </li>
+      <li>
+        View and Edit HDF-EOS grid object data
+      </li>
+      <li>
+        Subset datasets and data tables with a GUI dialog
+      </li>
+      <li>
+        Change and save the number format of datasets and data table fields
+      </li>
+      <li>
+        Drag and Drop HDF objects between files to organize or subset files
+      </li>
+      <li>
+        Attach text annotations directly to the data file
+      </li>
+      <li>
+        Add new data objects to files and create hierarchical groups
+      </li>
+      <li>
+        Edit or create new color palettes
+      </li>
+      <li>
+        Generate publication-quality graphics for data presentation
+      </li>
+    </ul>
+    <p>
+      Noesys has an interface to IDL®, allowing data to move back and forth between
+      Noesys and IDL with the click of a mouse. Noesys includes the visual data analysis
+      tools, Transform, T3D and Plot, for menu driven plotting, rendering, and image
+      analysis. Noesys can import HDF, HDF-EOS, netCDF, ASCII, Binary, DTED, GeoTIFF,
+      SDTS, TIFF, PICT, and BMP files, create annotations, macros, images, projections
+      and color palettes specific to the data and save it the result as an HDF file.
+      Noesys also includes an HDF-EOS Grid Editor. Noesys runs on Windows 95/98 &
+      NT and Power Macintosh OS. More details and information about ordering Noesys
+      are available from <a
+      href="http://www.rsinc.com/NOeSYS/index.cfm"><http://www.rsinc.com/NOeSYS/index.cfm></a>.
+    </p>
+
+    <h2><a id="Origin" name="Origin">Origin</a></h2>
+
+    <p>
+      Ryan Toomey reports:
+
+    <p>
+      Our website is <a href="http://www.originlab.com/" >http://www.originlab.com/</a>
+    </p>
+    <p>
+      A general description of Origin: Origin includes a suite of features
+      that cater to the needs of scientists and engineers alike. Multi-sheet
+      workbooks, publication-quality graphics, and standardized analysis
+      tools provide a tightly integrated workspace for you to import data,
+      create and annotate graphs, explore and analyze data, and publish your
+      work. To ensure that Origin meets your data analysis requirements,
+      intuitive tools for advanced statistics, regression, nonlinear curve
+      fitting, signal processing, image processing and peak analysis are
+      built-in. Since any analysis operation can be set to automatically
+      recalculate, you can reuse your projects as templates for future work,
+      thereby simplifying your daily routine.
+    </p>
+    <p>
+      A general description of OriginPro: OriginPro offers all of the
+      features of Origin plus extended analysis tools for statistics, 3D
+      fitting, image processing and signal processing.
+    </p>
+    <p>
+      A general description of OriginLab Corporation: "OriginLab Corporation
+      produces professional data analysis and graphing software for
+      scientists and engineers. Our products are designed to be easy-to-use,
+      yet have the power and versatility to provide for the most demanding
+      user."
+    </p>
+
+    <h2><a id="PPLUS" name="PPLUS">PPLUS</a></h2>
+    <a href="http://dwd6.home.mindspring.com/">Plot-Plus (PPLUS)</a> is a general
+    purpose scientific graphics package, which is used in several PMEL applications.
+    It will read most standard ascii or binary files, as well as netCDF file format,
+    which used by the TOGA-TAO Project and the EPIC system for management display
+    and analysis. PPLUS is an interactive, command driven, scientific graphics package
+    which includes features such as Mercator projection, Polar Stereographic projection,
+    color or gray scale area-fill contour plotting, and support for many devices:
+    X-windows, PostScript, HP, Tektronix, and others. This powerful and flexible package
+    recognizes netCDF data format, and it can extract axis lables and graph titles
+    from the data files. The user can customize a plots, or combine several plots
+    into a composite. Plots are of publication quality. The PPLUS graphics package
+    is used for all the TAO workstation displays, including the animations. The animations
+    are created by generating a PPLUS plot for each frame, transforming the PPLUS
+    metacode files into HDF format with the PPLUS m2hdf filter, and then displaying
+    the resulting bit maps as an animation with the XDataSlice utility, which is freely
+    available on Internet from the National Center for Supercomputing Applications,
+    at anonymous at ftp.ncsa.uiuc.edu (141.142.20.50). There is also a new m2gif utility
+    which produces GIF files from PPLUS metacode files.
+    <p>
+      PPLUS is supported for most Unix systems and for VAX/VMS, and is in use at
+      many oceanographic institutes in the US (e.g., (PMEL, Harvard, WHOI, Scripps,
+      NCAR, NASA, University of Rhode Island, University of Oregon, Texas A&M...)
+      and also internationally (Japan, Germany, Australia, Korea...).
+    </p>
+    <p>
+      Plot Plus is now available at no charge. It does require licensing on a per
+      computer basis, but the license is at no cost. For more information about licensing,
+      see <a
+      href="http://dwd6.home.mindspring.com/pplus_license.html">http://dwd6.home.mindspring.com/pplus_license.html/</a>;
+      source and documentation are available via anonymous FTP from <a
+      href="ftp://ftp.halcyon.com/pub/users/dwd/pplus1_3_2.tar.gz">ftp://ftp.halcyon.com/pub/users/dwd/pplus1_3_2.tar.gz</a>
+      and <a
+      href="ftp://ftp.pmel.noaa.gov/epic/manual-dir/pplus.pdf">ftp://ftp.pmel.noaa.gov/epic/manual-dir/pplus.pdf</a>.
+    </p>
+    <pre>
+      Email:      plot_plus at halcyon.com
+      Postal mail:    c/o Donald Denbo
+      2138 N 186th St
+      Shoreline, WA 98133
+      Fax and Voice:  (206) 366-0624
+      </pre>
+    <h2><a id="PV-Wave" name="PV-Wave">PV-Wave</a></h2>
+    <a href="http://www.vni.com/products/wave/index.html">PV-Wave</a> is a software
+    environment from <a href="http://www.vni.com/">Visual Numerics</a> for solving
+    problems requiring the application of graphics, mathematics, numerics and statistics
+    to data and equations.
+    <p>
+      PV-WAVE uses a fourth generation language (4GL) that analyzes and displays
+      data as you enter commands. PV-WAVE includes integrated graphics, numerics,
+      data I/O, and data management. The latest version of PV-Wave supports data access
+      in numerous formats, including netCDF.
+    </p>
+    <p>
+      See also the information on <a href="#DDI">DDI</a> for another way to use netCDF
+      data with PV-Wave.
+    </p>
+    <p></p>
+    <h2><a id="SlicerDicer" name="SlicerDicer">Slicer Dicer</a></h2>
+    <a href="http://www.slicerdicer.com/">Slicer Dicer</a> is a volumetric data visualization
+    tool, currently available for Windows and under development for other platforms.
+    The Slicer Dicer Web site includes a complete list of features, an on-line user's
+    guide, and examples of Slicer Dicer output. Visualizations features include:
+    <ul>
+      <li>
+        Perspective view of data rendered on interactively selected orthogonal slices,
+        oblique slices, blocks (arbitrary rectilinear sub-volumes), cutouts, isosurfaces,
+        and projected volumes (projected maximum, minimum, maximum absolute, or minimum
+        absolute).
+      </li>
+      <li>
+        Optional annotations: caption, axes ticks and labels (default "pretty"
+        ticks, or override to place ticks where you want them), color legend, data-cube
+        outline.
+      </li>
+      <li>
+        Animation modes: slices, space, time (any parametric dimension), transparency,
+        oblique slice orientation, rotation. Built-in animation viewer supports speed
+        and image size controls, single-step, forward, backward, loop, and back-and-forth
+        modes.
+      </li>
+      <li>
+        Select color scale from 25+ built in color tables, or import from palette
+        file. Any data level or range of levels can be painted with an arbitrary color.
+      </li>
+      <li>
+        Any data level or range of levels can be rendered as either opaque or transparent.
+      </li>
+    </ul>
+    <p></p>
+    <h2><a id="Surfer" name="Surfer">Surfer</a></h2>
+    <p>
+      <a href="http://www.goldensoftware.com/products/surfer">Surfer</a> is a
+      full-function contouring, gridding and 3D surface mapping
+      visualization software package. Surfer's sophisticated
+      interpolation engine transforms XYZ data into
+      publication-quality maps. Surfer imports from and exports to
+      a multitude of file formats, including NetCDF grids.
+    </p>
+
+    <h2><a id="vGeo" name="vGeo">vGeo</a></h2>
+    <p>
+      <a href="http://www.vrco.com/products/vgeo/vgeo.html" >vGeo</a> (Virtual Global
+      Explorer and Observatory) is an end-user product from <a href="http://www.vrco.com/" >VRCO</a>
+      designed to import and visualize multiple disparate data sets, including computer
+      simulations, observed measurements, images, model objects, and more. vGeo is
+      available for IRIX, Linux and Windows platforms and supports displays ranging
+      from desktop monitors to multi-walled projection systems. It accepts data in
+      a variety of formats, including netCDF, and allows the user to specify how multiple
+      files and variables are mapped into a data source. 3D graphics are built from
+      the underlying data in real-time, and the user has interactive control of graphics,
+      navigation, animation, and more.
+    </p>
+    <p></p>
+    <h2><a id="VISAGE and Decimate" name="VISAGE and Decimate">VISAGE and Decimate</a></h2>
+    <p>
+      <a
+      href="http://www.crd.ge.com/esl/cgsp/projects/visage/">VISAGE</a> (VISualization,
+      Animation, and Graphics Environment) is a turnkey 3D visualization system developed
+      at General Electric Corporate Research and Development, (Schroeder, WJ et al,
+      "VISAGE: An Object-Oriented Scientific Visualization System", Proceedings
+      of Visualization `92 Conference). VISAGE is designed to interface with a wide
+      variety of data, and uses netCDF as the preferred format.
+    </p>
+    <p>
+      VISAGE is used at GE Corporate R & D, GE Aircraft Engine, GE Canada, GE
+      Power Generation, as well as ETH Zurich, Switzerland, MQS In Chieti, Italy,
+      and Rensselaer Polytechnic Institute in Troy, New York.
+    </p>
+    <p>
+      GE has another application called "Decimate" that does polygon reduction/decimation
+      (Schroeder,WJ et al, "Decimation of Triangle Meshes", Proceedings
+      of SIGGRAPH `92). This application uses netCDF as a preferred format. Decimate
+      is currently licensed to Cyberware, Inc., makers of 3D laser digitizing hardware.
+      Decimate is currently bundled with the scanners, and will soon be available
+      as a commercial product.
+    </p>
+    <p></p>
+    <h2><a id="Voyager" name="Voyager">Voyager</a></h2>
+    <p>
+      <a href="http://voyager.makai.com/" >Makai Voyager</a>, developed by
+      Makai Ocean Engineering, Inc., is 3D/4D
+      geospatial visualization software that enables users to import, fuse, view, and analyze large
+      earth, ocean, and atmosphere scientific data as it is collected or
+      simulated in a global geo-referenced GIS platform. The key differentiator
+      of Makai Voyager is its level-of-detail (LOD) technology that enables
+      users to stream big data rapidly over a network or the web.
+    </p>
+    <p>
+      Features in Makai Voyager Version 1.2 include:
+    </p>
+    <ul>
+      <li>
+        Preprocessing LiDAR, GIS, & volumetric data from common formats
+        into streamable files
+      </li>
+      <li>
+        Volume rendering for large 4D (3D + time) data, such as
+        NetCDF
+      </li>
+      <li>
+        Analysis tools and customizable graphs
+      </li>
+      <li>
+        WMS and other streamable formats
+      </li>
+    </ul>
+    <p>
+      Individual or group licenses are available for Windows (32- and
+      64-bit), Linux, and Mac OS X.
+      A full-featured 30-day trial version of Makai Voyager is <a
+      href="http://voyager.makai.com " >available for download</a>.
+    </p>
+    <hr>
+
+    <!-- InstanceEndEditable -->
+  </body>
+</html>
+
+<!-- InstanceEnd -->
diff --git a/docs/tutorial.dox b/docs/tutorial.dox
index b546ff0..640204b 100644
--- a/docs/tutorial.dox
+++ b/docs/tutorial.dox
@@ -432,6 +432,11 @@ examples are included with the netCDF Fortran and C++ APIs.
 - \ref example_sfc_pres_temp
 - \ref example_pres_temp_4D
 
+Additionally, there is a example program demonstrating
+how to use the filter API. This is C only and only accessible
+when built with automake currently.
+- \ref example_filter
+
 Any existing netCDF applications can be converted to generate
 netCDF-4/HDF5 files. Simply change the file creation call to include
 the correct mode flag.
@@ -677,6 +682,12 @@ data file.
 - simple_xy_nc4_wr.c
 - simple_xy_nc4_rd.c
 
+\section example_filter The filter example
+
+This example demonstrates how to write and read a variable that is
+compressed using, in this example, bzip2 compression.
+- filter_example.c
+
 \page interoperability_hdf5 Interoperability with HDF5
 
 NetCDF-4 allows some interoperability with HDF5.
diff --git a/docs/windows-binaries.md b/docs/windows-binaries.md
index 295b2db..0392214 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.55.1
 * `zlib`:    1.2.8
 
-## Latest Release (netCDF-C 4.5.0) {#msvc-latest-release}
+## Latest Release (netCDF-C 4.6.0) {#msvc-latest-release}
 
 Configuration		| 32-bit 						| 64-bit |
 :-------------------|:--------							|:-------|
-netCDF 3		| [netCDF4.5.0-NC3-32.exe][r1]		| [netCDF4.5.0-NC3-64.exe][r6]
-netCDF3+DAP		| [netCDF4.5.0-NC3-DAP-32.exe][r2]	| [netCDF4.5.0-NC3-DAP-64.exe][r6]
-netCDF4			| [netCDF4.5.0-NC4-32.exe][r3]		| [netCDF4.5.0-NC4-64.exe][r7]
-netCDF4+DAP		| [netCDF4.5.0-NC4-DAP-32.exe][r4]	| [netCDF4.5.0-NC4-DAP-64.exe][r8]
+netCDF 3		| [netCDF4.6.0-NC3-32.exe][r1]		| [netCDF4.6.0-NC3-64.exe][r5]
+netCDF3+DAP		| [netCDF4.6.0-NC3-DAP-32.exe][r2]	| [netCDF4.6.0-NC3-DAP-64.exe][r6]
+netCDF4			| [netCDF4.6.0-NC4-32.exe][r3]		| [netCDF4.6.0-NC4-64.exe][r7]
+netCDF4+DAP		| [netCDF4.6.0-NC4-DAP-32.exe][r4]	| [netCDF4.6.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.5.0-NC3-32.exe
-[r2]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC3-DAP-32.exe
-[r3]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC4-32.exe
-[r4]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC4-DAP-32.exe
-[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC3-64.exe
-[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC3-DAP-64.exe
-[r7]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC4-64.exe
-[r8]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.5.0-NC4-DAP-64.exe
+[r1]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC3-32.exe
+[r2]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC3-DAP-32.exe
+[r3]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC4-32.exe
+[r4]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC4-DAP-32.exe
+[r5]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC3-64.exe
+[r6]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC3-DAP-64.exe
+[r7]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC4-64.exe
+[r8]: http://www.unidata.ucar.edu/downloads/netcdf/ftp/netCDF4.6.0-NC4-DAP-64.exe
diff --git a/examples/C/CMakeLists.txt b/examples/C/CMakeLists.txt
index da62844..8b60b18 100644
--- a/examples/C/CMakeLists.txt
+++ b/examples/C/CMakeLists.txt
@@ -8,13 +8,11 @@ FOREACH(F ${exam_C_tests})
   add_bin_test(C_tests ${F})
 ENDFOREACH()
 
+SET_TESTS_PROPERTIES(C_tests_simple_xy_rd PROPERTIES DEPENDS C_tests_simple_xy_wr)
+SET_TESTS_PROPERTIES(C_tests_sfc_pres_temp_rd PROPERTIES DEPENDS C_tests_sfc_pres_temp_wr)
+SET_TESTS_PROPERTIES(C_tests_pres_temp_4D_rd PROPERTIES DEPENDS C_tests_pres_temp_4D_wr)
 
-## Specify files to be distributed by 'make dist'
-FILE(GLOB CUR_EXTRA_DIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.sh)
-SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am)
-ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
-
+ADD_SUBDIRECTORY(hdf5plugins)
 
 SET(CLEANFILES sfc_pres_temp.nc simple_xy.nc pres_temp_4D.nc simple_nc4.nc simple_xy_nc4.nc)
 SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}")
-
diff --git a/examples/C/Makefile.am b/examples/C/Makefile.am
index 72a84f4..e39debb 100644
--- a/examples/C/Makefile.am
+++ b/examples/C/Makefile.am
@@ -3,33 +3,50 @@
 
 # This file builds the C examples.
 
-# $Id: Makefile.am,v 1.26 2010/05/29 00:17:41 dmh Exp $
+# Ed Hartnett, Ward Fisher, Dennis Heimbigner
+
+# Un comment to use a more verbose test driver
+#SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
 
 LDADD = -lm
 AM_CPPFLAGS = -I$(top_srcdir)/include
 AM_LDFLAGS =
 
-# These are the netCDF-3 examples. 
-TESTPROGRAMS = simple_xy_wr simple_xy_rd sfc_pres_temp_wr	\
+# These are the netCDF-3 examples.
+check_PROGRAMS = simple_xy_wr simple_xy_rd sfc_pres_temp_wr	\
 sfc_pres_temp_rd pres_temp_4D_wr pres_temp_4D_rd
 
+TESTS = run_examples.sh
+
 # To build netcdf-4, or not to build netcdf-4, that is the question...
 if USE_NETCDF4
-# These are the extra netCDF-4 examples. 
-TESTPROGRAMS += simple_nc4_wr simple_nc4_rd simple_xy_nc4_wr	\
+# These are the extra netCDF-4 examples.
+check_PROGRAMS += simple_nc4_wr simple_nc4_rd simple_xy_nc4_wr	\
 simple_xy_nc4_rd
+
+# This subdir should be same as nc_test4/hdf5plugins
+SUBDIRS = hdf5plugins
+
+if ENABLE_FILTER_TESTING
+# filter_example.c should be same as nc_test4/test_filter.c
+check_PROGRAMS += filter_example
+endif
+
 endif #USE_NETCDF4
 
 if USE_PNETCDF
-# These are the extra netCDF-4 examples. 
-TESTPROGRAMS += parallel_vara
+# These are the extra netCDF-4 examples.
+check_PROGRAMS += parallel_vara
+TESTS += parallel_vara
 endif #USE_PNETCDF
 
 AM_CPPFLAGS += -I$(top_builddir)/liblib
 AM_LDFLAGS += ${top_builddir}/liblib/libnetcdf.la
 
-check_PROGRAMS = $(TESTPROGRAMS)
-TESTS = $(TESTPROGRAMS)
+if USE_NETCDF4
+TESTS += run_examples4.sh
+endif #USE_NETCDF4
 
 # This will run a bunch of the test programs with valgrind, the memory
 # checking tool. (Valgrind must be present for this to work.)
@@ -43,7 +60,15 @@ endif # USE_VALGRIND_TESTS
 endif # USE_NETCDF4
 
 # These files are created by the tests.
-CLEANFILES = sfc_pres_temp.nc simple_xy.nc pres_temp_4D.nc	\
-simple_nc4.nc simple_xy_nc4.nc testfile.nc
+CLEANFILES = *.nc
+
+EXTRA_DIST = run_valgrind_tests.sh run_nc4_valgrind_tests.sh	\
+CMakeLists.txt run_examples.sh run_examples4.sh
+
+if ENABLE_FILTER_TESTING # => shared and netcdf-4
+BUILT_SOURCES = findplugin.sh
+findplugin.sh:
+	cp ${top_builddir}/nc_test4/findplugin.sh ${builddir}
+endif
 
-EXTRA_DIST = run_valgrind_tests.sh run_nc4_valgrind_tests.sh CMakeLists.txt
+DISTCLEANFILES = findplugin.sh
diff --git a/examples/C/Makefile.in b/examples/C/Makefile.in
index 7d3c8df..3d3034b 100644
--- a/examples/C/Makefile.in
+++ b/examples/C/Makefile.in
@@ -19,7 +19,11 @@
 
 # This file builds the C examples.
 
-# $Id: Makefile.am,v 1.26 2010/05/29 00:17:41 dmh Exp $
+# Ed Hartnett, Ward Fisher, Dennis Heimbigner
+
+# Un comment to use a more verbose test driver
+#SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -95,22 +99,31 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
+check_PROGRAMS = simple_xy_wr$(EXEEXT) simple_xy_rd$(EXEEXT) \
+	sfc_pres_temp_wr$(EXEEXT) sfc_pres_temp_rd$(EXEEXT) \
+	pres_temp_4D_wr$(EXEEXT) pres_temp_4D_rd$(EXEEXT) \
+	$(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
+TESTS = run_examples.sh $(am__EXEEXT_3) $(am__append_5) \
+	$(am__append_6) $(am__append_7)
 
 # To build netcdf-4, or not to build netcdf-4, that is the question...
-# These are the extra netCDF-4 examples. 
+# These are the extra netCDF-4 examples.
 @USE_NETCDF4_TRUE at am__append_1 = simple_nc4_wr simple_nc4_rd simple_xy_nc4_wr	\
 @USE_NETCDF4_TRUE at simple_xy_nc4_rd
 
 
-# These are the extra netCDF-4 examples. 
- at USE_PNETCDF_TRUE@am__append_2 = parallel_vara
-check_PROGRAMS = $(am__EXEEXT_3)
-TESTS = $(am__EXEEXT_3) $(am__append_3) $(am__append_4)
+# filter_example.c should be same as nc_test4/test_filter.c
+ at ENABLE_FILTER_TESTING_TRUE@@USE_NETCDF4_TRUE at am__append_2 = filter_example
+
+# These are the extra netCDF-4 examples.
+ at USE_PNETCDF_TRUE@am__append_3 = parallel_vara
+ at USE_PNETCDF_TRUE@am__append_4 = parallel_vara
+ at USE_NETCDF4_TRUE@am__append_5 = run_examples4.sh
 
 # This will run a bunch of the test programs with valgrind, the memory
 # checking tool. (Valgrind must be present for this to work.)
- at USE_VALGRIND_TESTS_TRUE@am__append_3 = run_valgrind_tests.sh
- at USE_NETCDF4_TRUE@@USE_VALGRIND_TESTS_TRUE at am__append_4 = run_nc4_valgrind_tests.sh
+ at USE_VALGRIND_TESTS_TRUE@am__append_6 = run_valgrind_tests.sh
+ at USE_NETCDF4_TRUE@@USE_VALGRIND_TESTS_TRUE at am__append_7 = run_nc4_valgrind_tests.sh
 subdir = examples/C
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -128,19 +141,20 @@ CONFIG_CLEAN_VPATH_FILES =
 @USE_NETCDF4_TRUE@	simple_nc4_rd$(EXEEXT) \
 @USE_NETCDF4_TRUE@	simple_xy_nc4_wr$(EXEEXT) \
 @USE_NETCDF4_TRUE@	simple_xy_nc4_rd$(EXEEXT)
- at USE_PNETCDF_TRUE@am__EXEEXT_2 = parallel_vara$(EXEEXT)
-am__EXEEXT_3 = simple_xy_wr$(EXEEXT) simple_xy_rd$(EXEEXT) \
-	sfc_pres_temp_wr$(EXEEXT) sfc_pres_temp_rd$(EXEEXT) \
-	pres_temp_4D_wr$(EXEEXT) pres_temp_4D_rd$(EXEEXT) \
-	$(am__EXEEXT_1) $(am__EXEEXT_2)
-parallel_vara_SOURCES = parallel_vara.c
-parallel_vara_OBJECTS = parallel_vara.$(OBJEXT)
-parallel_vara_LDADD = $(LDADD)
-parallel_vara_DEPENDENCIES =
+ at ENABLE_FILTER_TESTING_TRUE@@USE_NETCDF4_TRUE at am__EXEEXT_2 = filter_example$(EXEEXT)
+ at USE_PNETCDF_TRUE@am__EXEEXT_3 = parallel_vara$(EXEEXT)
+filter_example_SOURCES = filter_example.c
+filter_example_OBJECTS = filter_example.$(OBJEXT)
+filter_example_LDADD = $(LDADD)
+filter_example_DEPENDENCIES =
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
+parallel_vara_SOURCES = parallel_vara.c
+parallel_vara_OBJECTS = parallel_vara.$(OBJEXT)
+parallel_vara_LDADD = $(LDADD)
+parallel_vara_DEPENDENCIES =
 pres_temp_4D_rd_SOURCES = pres_temp_4D_rd.c
 pres_temp_4D_rd_OBJECTS = pres_temp_4D_rd.$(OBJEXT)
 pres_temp_4D_rd_LDADD = $(LDADD)
@@ -215,19 +229,35 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = parallel_vara.c pres_temp_4D_rd.c pres_temp_4D_wr.c \
-	sfc_pres_temp_rd.c sfc_pres_temp_wr.c simple_nc4_rd.c \
-	simple_nc4_wr.c simple_xy_nc4_rd.c simple_xy_nc4_wr.c \
-	simple_xy_rd.c simple_xy_wr.c
-DIST_SOURCES = parallel_vara.c pres_temp_4D_rd.c pres_temp_4D_wr.c \
-	sfc_pres_temp_rd.c sfc_pres_temp_wr.c simple_nc4_rd.c \
-	simple_nc4_wr.c simple_xy_nc4_rd.c simple_xy_nc4_wr.c \
-	simple_xy_rd.c simple_xy_wr.c
+SOURCES = filter_example.c parallel_vara.c pres_temp_4D_rd.c \
+	pres_temp_4D_wr.c sfc_pres_temp_rd.c sfc_pres_temp_wr.c \
+	simple_nc4_rd.c simple_nc4_wr.c simple_xy_nc4_rd.c \
+	simple_xy_nc4_wr.c simple_xy_rd.c simple_xy_wr.c
+DIST_SOURCES = filter_example.c parallel_vara.c pres_temp_4D_rd.c \
+	pres_temp_4D_wr.c sfc_pres_temp_rd.c sfc_pres_temp_wr.c \
+	simple_nc4_rd.c simple_nc4_wr.c simple_xy_nc4_rd.c \
+	simple_xy_nc4_wr.c simple_xy_rd.c simple_xy_wr.c
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	check recheck distdir
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -430,7 +460,6 @@ am__set_TESTS_bases = \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
 RECHECK_LOGS = $(TEST_LOGS)
-AM_RECURSIVE_TARGETS = check recheck
 TEST_SUITE_LOG = test-suite.log
 TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
@@ -451,9 +480,35 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
+DIST_SUBDIRS = hdf5plugins
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
 	$(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
 ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
@@ -462,7 +517,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/liblib
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = ${top_builddir}/liblib/libnetcdf.la
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -485,12 +539,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -516,6 +572,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -530,6 +587,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -635,17 +693,18 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 LDADD = -lm
 
-# These are the netCDF-3 examples. 
-TESTPROGRAMS = simple_xy_wr simple_xy_rd sfc_pres_temp_wr \
-	sfc_pres_temp_rd pres_temp_4D_wr pres_temp_4D_rd \
-	$(am__append_1) $(am__append_2)
+# This subdir should be same as nc_test4/hdf5plugins
+ at USE_NETCDF4_TRUE@SUBDIRS = hdf5plugins
 
 # These files are created by the tests.
-CLEANFILES = sfc_pres_temp.nc simple_xy.nc pres_temp_4D.nc	\
-simple_nc4.nc simple_xy_nc4.nc testfile.nc
+CLEANFILES = *.nc
+EXTRA_DIST = run_valgrind_tests.sh run_nc4_valgrind_tests.sh	\
+CMakeLists.txt run_examples.sh run_examples4.sh
 
-EXTRA_DIST = run_valgrind_tests.sh run_nc4_valgrind_tests.sh CMakeLists.txt
-all: all-am
+ at ENABLE_FILTER_TESTING_TRUE@BUILT_SOURCES = findplugin.sh
+DISTCLEANFILES = findplugin.sh
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
 .SUFFIXES:
 .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
@@ -688,6 +747,10 @@ clean-checkPROGRAMS:
 	echo " rm -f" $$list; \
 	rm -f $$list
 
+filter_example$(EXEEXT): $(filter_example_OBJECTS) $(filter_example_DEPENDENCIES) $(EXTRA_filter_example_DEPENDENCIES) 
+	@rm -f filter_example$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(filter_example_OBJECTS) $(filter_example_LDADD) $(LIBS)
+
 parallel_vara$(EXEEXT): $(parallel_vara_OBJECTS) $(parallel_vara_DEPENDENCIES) $(EXTRA_parallel_vara_DEPENDENCIES) 
 	@rm -f parallel_vara$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(parallel_vara_OBJECTS) $(parallel_vara_LDADD) $(LIBS)
@@ -738,6 +801,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/filter_example.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/parallel_vara.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pres_temp_4D_rd.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pres_temp_4D_wr.Po at am__quote@
@@ -780,14 +844,61 @@ mostlyclean-libtool:
 clean-libtool:
 	-rm -rf .libs _libs
 
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
+tags: tags-recursive
 TAGS: tags
 
 tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
 	set x; \
 	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
 	$(am__define_uniq_tagged_files); \
 	shift; \
 	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
@@ -800,7 +911,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
 	      $$unique; \
 	  fi; \
 	fi
-ctags: ctags-am
+ctags: ctags-recursive
 
 CTAGS: ctags
 ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
@@ -813,7 +924,7 @@ GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
 	  && $(am__cd) $(top_srcdir) \
 	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
+cscopelist: cscopelist-recursive
 
 cscopelist-am: $(am__tagged_files)
 	list='$(am__tagged_files)'; \
@@ -973,79 +1084,23 @@ recheck: all $(check_PROGRAMS)
 	        am__force_recheck=am--force-recheck \
 	        TEST_LOGS="$$log_list"; \
 	exit $$?
-simple_xy_wr.log: simple_xy_wr$(EXEEXT)
-	@p='simple_xy_wr$(EXEEXT)'; \
-	b='simple_xy_wr'; \
-	$(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)
-simple_xy_rd.log: simple_xy_rd$(EXEEXT)
-	@p='simple_xy_rd$(EXEEXT)'; \
-	b='simple_xy_rd'; \
+run_examples.sh.log: run_examples.sh
+	@p='run_examples.sh'; \
+	b='run_examples.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)
-sfc_pres_temp_wr.log: sfc_pres_temp_wr$(EXEEXT)
-	@p='sfc_pres_temp_wr$(EXEEXT)'; \
-	b='sfc_pres_temp_wr'; \
-	$(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)
-sfc_pres_temp_rd.log: sfc_pres_temp_rd$(EXEEXT)
-	@p='sfc_pres_temp_rd$(EXEEXT)'; \
-	b='sfc_pres_temp_rd'; \
-	$(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)
-pres_temp_4D_wr.log: pres_temp_4D_wr$(EXEEXT)
-	@p='pres_temp_4D_wr$(EXEEXT)'; \
-	b='pres_temp_4D_wr'; \
-	$(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)
-pres_temp_4D_rd.log: pres_temp_4D_rd$(EXEEXT)
-	@p='pres_temp_4D_rd$(EXEEXT)'; \
-	b='pres_temp_4D_rd'; \
-	$(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)
-simple_nc4_wr.log: simple_nc4_wr$(EXEEXT)
-	@p='simple_nc4_wr$(EXEEXT)'; \
-	b='simple_nc4_wr'; \
-	$(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)
-simple_nc4_rd.log: simple_nc4_rd$(EXEEXT)
-	@p='simple_nc4_rd$(EXEEXT)'; \
-	b='simple_nc4_rd'; \
-	$(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)
-simple_xy_nc4_wr.log: simple_xy_nc4_wr$(EXEEXT)
-	@p='simple_xy_nc4_wr$(EXEEXT)'; \
-	b='simple_xy_nc4_wr'; \
-	$(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)
-simple_xy_nc4_rd.log: simple_xy_nc4_rd$(EXEEXT)
-	@p='simple_xy_nc4_rd$(EXEEXT)'; \
-	b='simple_xy_nc4_rd'; \
+parallel_vara.log: parallel_vara$(EXEEXT)
+	@p='parallel_vara$(EXEEXT)'; \
+	b='parallel_vara'; \
 	$(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)
-parallel_vara.log: parallel_vara$(EXEEXT)
-	@p='parallel_vara$(EXEEXT)'; \
-	b='parallel_vara'; \
+run_examples4.sh.log: run_examples4.sh
+	@p='run_examples4.sh'; \
+	b='run_examples4.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) \
@@ -1109,21 +1164,49 @@ distdir: $(DISTFILES)
 	    || exit 1; \
 	  fi; \
 	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
 check-am: all-am
 	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
 	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-recursive
 all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+installdirs: installdirs-recursive
+installdirs-am:
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
 
 install-am: all-am
 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
-installcheck: installcheck-am
+installcheck: installcheck-recursive
 install-strip:
 	if test -z '$(STRIP)'; then \
 	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@@ -1145,99 +1228,105 @@ clean-generic:
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
 
 clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
 	mostlyclean-am
 
-distclean: distclean-am
+distclean: distclean-recursive
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
 
-dvi: dvi-am
+dvi: dvi-recursive
 
 dvi-am:
 
-html: html-am
+html: html-recursive
 
 html-am:
 
-info: info-am
+info: info-recursive
 
 info-am:
 
 install-data-am:
 
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
 
 install-dvi-am:
 
 install-exec-am:
 
-install-html: install-html-am
+install-html: install-html-recursive
 
 install-html-am:
 
-install-info: install-info-am
+install-info: install-info-recursive
 
 install-info-am:
 
 install-man:
 
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
 
 install-pdf-am:
 
-install-ps: install-ps-am
+install-ps: install-ps-recursive
 
 install-ps-am:
 
 installcheck-am:
 
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
 
 mostlyclean-am: mostlyclean-compile mostlyclean-generic \
 	mostlyclean-libtool
 
-pdf: pdf-am
+pdf: pdf-recursive
 
 pdf-am:
 
-ps: ps-am
+ps: ps-recursive
 
 ps-am:
 
 uninstall-am:
 
-.MAKE: check-am install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
-	clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
-	ctags ctags-am distclean distclean-compile distclean-generic \
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	recheck tags tags-am uninstall uninstall-am
+.MAKE: $(am__recursive_targets) all check check-am install install-am \
+	install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-TESTS check-am clean clean-checkPROGRAMS clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
+	uninstall uninstall-am
 
 .PRECIOUS: Makefile
 
+ at ENABLE_FILTER_TESTING_TRUE@findplugin.sh:
+ at ENABLE_FILTER_TESTING_TRUE@	cp ${top_builddir}/nc_test4/findplugin.sh ${builddir}
 
 # 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/examples/C/filter_example.c b/examples/C/filter_example.c
new file mode 100644
index 0000000..3c73f35
--- /dev/null
+++ b/examples/C/filter_example.c
@@ -0,0 +1,309 @@
+/*
+  Copyright 2018, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
+*/
+/*
+This file is the same as nc_test4/test_filter.c 
+*/
+
+/*! \file
+Example program for write then read of a variable using bzip2 compression.
+
+\ingroup tutorial
+
+This is an example which 
+creates a file with a variable that is compressed using bzip2.
+Then it reads that file and verifies that it returned the correct
+uncompressed data.
+
+The meta-data (.cdl) for the created file is as follows:
+\code
+netcdf bzip2 {
+dimensions:
+	dim0 = 4 ;
+	dim1 = 4 ;
+	dim2 = 4 ;
+	dim3 = 4 ;
+variables:
+	float var(dim0, dim1, dim2, dim3) ;
+		var:_Storage = "chunked" ;
+		var:_ChunkSizes = 4, 4, 4, 4 ;
+		var:_Filter = "307,9" ;
+		var:_NoFill = "true" ;
+data:
+
+ var =
+  0, 1, 2, 3,
+  4, 5, 6, 7,
+  ...
+  252, 253, 254, 255 ;
+}
+\endcode
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <hdf5.h>
+#include "netcdf.h"
+
+/* The HDF assigned id for bzip compression */
+#define BZIP2_ID 307
+/* The compression level used in this example */
+#define BZIP2_LEVEL 9
+
+#define TESTFILE "bzip2.nc"
+
+/* Point at which we give up */
+#define MAXERRS 8
+
+#define NDIMS 4
+#define DIMSIZE 4
+#define CHUNKSIZE 4 /* Note: not the total size of the chunk, but size wrt a dim*/
+
+static size_t dimsize = DIMSIZE;
+static size_t chunksize = CHUNKSIZE;
+static size_t actualdims = NDIMS;
+
+static size_t actualproduct = 1; /* x-product over dim sizes */
+static size_t chunkproduct = 1; /* x-product over chunksizes */
+
+static size_t dims[NDIMS];
+static size_t chunks[NDIMS];
+
+static int nerrs = 0;
+
+static int ncid, varid;
+static int dimids[NDIMS];
+static float* array = NULL;
+static float* expected = NULL;
+static unsigned int filterid = 0;
+static unsigned int* params = NULL;
+
+/* Forward */
+static void init(int argc, char** argv);
+static int test_bzip2(void);
+static int verifychunks(void);
+
+#define ERRR do { \
+fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
+fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
+	__FILE__, __LINE__);				    \
+nerrs++;\
+} while (0)
+
+static int
+check(int err,int line)
+{
+    if(err != NC_NOERR) {
+	fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
+	fflush(stderr);
+	exit(1);
+    }
+    return NC_NOERR;
+}
+
+#define CHECK(x) check(x,__LINE__)
+
+/*
+Read the chunking information about the variable
+and verify that it is as expected.
+*/
+
+static int
+verifychunks(void)
+{
+    int i;
+    int store = -1;
+    size_t chunksizes[NDIMS];
+    memset(chunksizes,0,sizeof(chunksizes));
+    CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes));
+    /* Storate must be chunked, not contiguous */
+    if(store != NC_CHUNKED) {
+	fprintf(stderr,"bad chunk store\n");
+	return NC_ESTORAGE;
+    }
+    /* Chunk sizes must match our predefined set */
+    for(i=0;i<actualdims;i++) {
+        if(chunksizes[i] != chunks[i]) {
+	    fprintf(stderr,"bad chunk size: %d\n",i);
+	    return NC_EBADCHUNK;
+	}
+    }
+    return 1;
+}
+
+/*
+Compare the data we wrote against the data we read.
+*/
+
+static int
+compare(void)
+{
+    int errs = 0;
+    int i;
+    printf("data comparison: |array|=%ld\n",(unsigned long)actualproduct);
+    for(i=0;i<actualproduct;i++) {
+	if(expected[i] != array[i]) {
+	    printf("mismatch: array[%d]=%f expected[%d]=%f\n",
+                            i,array[i],i,expected[i]);
+            errs++;
+            if(errs >= MAXERRS)
+                break;
+	}
+   }
+   if(errs == 0)
+        printf("no data errors\n");
+   if(actualproduct <= 1)
+	return NC_EBADDIM;
+   return (errs == 0 ? NC_NOERR: NC_EINVAL);
+}
+
+/*
+Create the file, write it, then re-read for comparison.
+*/
+static int
+test_bzip2(void)
+{
+    int i;
+    unsigned int level = BZIP2_LEVEL;
+    unsigned int id=0;
+    size_t nparams = 0;
+
+    printf("\n*** Testing API: bzip2 compression.\n");
+
+    /* Clear the data array */
+    memset(array,0,sizeof(float)*actualproduct);
+
+    /* Create a file */
+    CHECK(nc_create(TESTFILE, NC_NETCDF4|NC_CLOBBER, &ncid));
+
+    /* Do not use fill for this file */
+    CHECK(nc_set_fill(ncid, NC_NOFILL, NULL));
+
+    /* Define the dimensions */
+    for(i=0;i<actualdims;i++) {
+	char dimname[1024];
+	snprintf(dimname,sizeof(dimname),"dim%d",i);
+        CHECK(nc_def_dim(ncid, dimname, dims[i], &dimids[i]));
+    }
+
+    /* Define the variable */
+    CHECK(nc_def_var(ncid, "var", NC_FLOAT, actualdims, dimids, &varid));
+
+    /* Set chunking on the variable */
+    CHECK(nc_def_var_chunking(ncid,varid,NC_CHUNKED,chunks));
+
+    /* Verify that chunking succeeded */
+    if(!verifychunks())
+	return NC_EINVAL;
+    /* Set bzip2 compression for the variable: takes one parameter == level */
+    CHECK(nc_def_var_filter(ncid,varid,BZIP2_ID,1,&level));
+
+    /* Read back the compression info and verify it */
+    level = 0;
+    CHECK(nc_inq_var_filter(ncid,varid,&id,&nparams,&level));
+    if(id != BZIP2_ID || nparams != 1 || level != BZIP2_LEVEL) {
+        printf("test_filter: filter def/inq mismatch\n");
+	return NC_EFILTER;
+    }
+    /* Show the level */
+    printf("show parameters for bzip2: level=%u\n",level);
+    /* Show chunking */ 
+    printf("show chunks:");
+    for(i=0;i<actualdims;i++)
+	printf("%s%d",(i==0?" chunks=":","),chunks[i]);
+    printf("\n");
+
+    /* prepare to write */
+    CHECK(nc_enddef(ncid));
+
+    /* Fill in the array */
+    for(i=0;i<actualproduct;i++)
+	expected[i] = (float)i;
+
+    /* write array */
+    CHECK(nc_put_var(ncid,varid,expected));
+
+    /* Close file */
+    CHECK(nc_close(ncid));
+
+    /* Now re-open and verify */
+    printf("\n*** Testing API: bzip2 decompression.\n");
+
+    /* Clear the data array */
+    memset(array,0,sizeof(float)*actualproduct);
+
+    /* Open the file */
+    CHECK(nc_open(TESTFILE, NC_NOWRITE, &ncid));
+
+    /* Get the variable id */
+    CHECK(nc_inq_varid(ncid, "var", &varid));
+
+    /* Check the compression algorithm */
+    filterid = 0;
+    nparams = 0;
+    params = NULL;
+    CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,NULL));
+    if(nparams > 0) {
+        params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
+	if(params == NULL)
+	    return NC_ENOMEM;
+        CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+    }
+    if(filterid != BZIP2_ID) {
+         printf("Bzip2 id mismatch: %d\n",filterid);
+	return NC_EFILTER;
+    }
+    if(nparams != 1 && params != NULL && params[0] != BZIP2_LEVEL) {
+	printf("Compression parameter mismatch\n");
+	return NC_EFILTER; 
+    }
+
+    /* Verify chunking */
+    if(!verifychunks())
+	return 0;
+
+    /* Read the data */
+    CHECK(nc_get_var_float(ncid, varid, array));
+
+    /* Close the file */
+    CHECK(nc_close(ncid));
+    return (compare() == NC_NOERR ? 0 : 1);
+}
+
+/**************************************************/
+/* Utilities */
+
+static void
+init(int argc, char** argv)
+{
+    int i;
+    /* Setup various variables */
+    actualproduct = 1;
+    chunkproduct = 1;
+    for(i=0;i<NDIMS;i++) {
+	dims[i] = dimsize;
+	chunks[i] = chunksize;
+	if(i < actualdims) {
+	    actualproduct *= dims[i];
+	    chunkproduct *= chunks[i];
+	}
+    }
+    /* Allocate max size */
+    array = (float*)calloc(1,sizeof(float)*actualproduct);
+    expected = (float*)calloc(1,sizeof(float)*actualproduct);
+}
+
+/**************************************************/
+int
+main(int argc, char **argv)
+{
+    H5Eprint(stderr);
+    init(argc,argv);
+    if(test_bzip2() != NC_NOERR) ERRR;
+    exit(nerrs > 0?1:0);
+}
+
diff --git a/examples/C/hdf5plugins/CMakeLists.txt b/examples/C/hdf5plugins/CMakeLists.txt
new file mode 100644
index 0000000..ea7e06d
--- /dev/null
+++ b/examples/C/hdf5plugins/CMakeLists.txt
@@ -0,0 +1,37 @@
+SET(CMAKE_BUILD_TYPE "")
+
+SET(libbzip2_SOURCES bzlib.h bzlib_private.h
+         blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
+         H5Zbzip2.c h5bzip2.h
+)
+
+# Get the compilable sources from nc_test4/hdf5plugins
+FOREACH(S ${libbzip2_SOURCES})
+  FILE(COPY ${CMAKE_SOURCE_DIR}/nc_test4/hdf5plugins/${S} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
+ENDFOREACH(S)
+
+IF(ENABLE_FILTER_TESTING)
+IF(BUILD_UTILITIES)
+
+# LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+
+ADD_LIBRARY(bzip2 MODULE ${libbzip2_SOURCES})
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES LIBRARY_OUTPUT_NAME "bzip2")
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES ARCHIVE_OUTPUT_NAME "bzip2")
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES RUNTIME_OUTPUT_NAME "bzip2")
+TARGET_LINK_LIBRARIES(bzip2 ${HDF5_HL_LIBRARIES} ${HDF5_C_LIBRARIES})
+
+ADD_LIBRARY(misc MODULE ${libmisc_SOURCES})
+SET_TARGET_PROPERTIES(misc PROPERTIES LIBRARY_OUTPUT_NAME "misc")
+SET_TARGET_PROPERTIES(misc PROPERTIES ARCHIVE_OUTPUT_NAME "misc")
+SET_TARGET_PROPERTIES(misc PROPERTIES RUNTIME_OUTPUT_NAME "misc")
+TARGET_LINK_LIBRARIES(misc ${HDF5_HL_LIBRARIES} ${HDF5_C_LIBRARIES})
+
+ENDIF(BUILD_UTILITIES)
+ENDIF(ENABLE_FILTER_TESTING)
+
+# Copy some test files from current source dir to out-of-tree build dir.
+FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+IF(MSVC)
+  FILE(COPY ${COPY_FILES} DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}/)
+ENDIF()
diff --git a/examples/C/hdf5plugins/H5Zbzip2.c b/examples/C/hdf5plugins/H5Zbzip2.c
new file mode 100644
index 0000000..99c98b2
--- /dev/null
+++ b/examples/C/hdf5plugins/H5Zbzip2.c
@@ -0,0 +1,181 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+
+#ifndef DLL_EXPORT
+#define DLL_EXPORT
+#endif
+
+#include "h5bzip2.h"
+
+const H5Z_class2_t H5Z_BZIP2[1] = {{
+    H5Z_CLASS_T_VERS,       /* H5Z_class_t version */
+    (H5Z_filter_t)H5Z_FILTER_BZIP2,         /* Filter id number             */
+    1,              /* encoder_present flag (set to true) */
+    1,              /* decoder_present flag (set to true) */
+    "bzip2",                  /* Filter name for debugging    */
+    (H5Z_can_apply_func_t)H5Z_bzip2_can_apply, /* The "can apply" callback  */
+    NULL,                       /* The "set local" callback     */
+    (H5Z_func_t)H5Z_filter_bzip2,         /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_BZIP2;
+}
+
+/* Make this explicit */
+/*
+ * The "can_apply" callback returns positive a valid combination, zero for an
+ * invalid combination and negative for an error.
+ */
+htri_t
+H5Z_bzip2_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+{
+    return 1; /* Assume it can always apply */
+}
+
+size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+  char *outbuf = NULL;
+  size_t outbuflen, outdatalen;
+  int ret;
+
+  if (flags & H5Z_FLAG_REVERSE) {
+
+    /** Decompress data.
+     **
+     ** This process is troublesome since the size of uncompressed data
+     ** is unknown, so the low-level interface must be used.
+     ** Data is decompressed to the output buffer (which is sized
+     ** for the average case); if it gets full, its size is doubled
+     ** and decompression continues.  This avoids repeatedly trying to
+     ** decompress the whole block, which could be really inefficient.
+     **/
+
+    bz_stream stream;
+    char *newbuf = NULL;
+    size_t newbuflen;
+
+    /* Prepare the output buffer. */
+    outbuflen = nbytes * 3 + 1;  /* average bzip2 compression ratio is 3:1 */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Use standard malloc()/free() for internal memory handling. */
+    stream.bzalloc = NULL;
+    stream.bzfree = NULL;
+    stream.opaque = NULL;
+
+    /* Start decompression. */
+    ret = BZ2_bzDecompressInit(&stream, 0, 0);
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 decompression start failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+
+    /* Feed data to the decompression process and get decompressed data. */
+    stream.next_out = outbuf;
+    stream.avail_out = outbuflen;
+    stream.next_in = *buf;
+    stream.avail_in = nbytes;
+    do {
+      ret = BZ2_bzDecompress(&stream);
+      if (ret < 0) {
+	fprintf(stderr, "BUG: bzip2 decompression failed with error %d\n", ret);
+	goto cleanupAndFail;
+      }
+
+      if (ret != BZ_STREAM_END && stream.avail_out == 0) {
+        /* Grow the output buffer. */
+        newbuflen = outbuflen * 2;
+        newbuf = realloc(outbuf, newbuflen);
+        if (newbuf == NULL) {
+          fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
+          goto cleanupAndFail;
+        }
+        stream.next_out = newbuf + outbuflen;  /* half the new buffer behind */
+        stream.avail_out = outbuflen;  /* half the new buffer ahead */
+        outbuf = newbuf;
+        outbuflen = newbuflen;
+      }
+    } while (ret != BZ_STREAM_END);
+
+    /* End compression. */
+    outdatalen = stream.total_out_lo32;
+    ret = BZ2_bzDecompressEnd(&stream);
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 compression end failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+
+  } else {
+
+    /** Compress data.
+     **
+     ** This is quite simple, since the size of compressed data in the worst
+     ** case is known and it is not much bigger than the size of uncompressed
+     ** data.  This allows us to use the simplified one-shot interface to
+     ** compression.
+     **/
+
+    unsigned int odatalen;  /* maybe not the same size as outdatalen */
+    int blockSize100k = 9;
+
+    /* Get compression block size if present. */
+    if (cd_nelmts > 0) {
+      blockSize100k = cd_values[0];
+      if (blockSize100k < 1 || blockSize100k > 9) {
+	fprintf(stderr, "invalid compression block size: %d\n", blockSize100k);
+	goto cleanupAndFail;
+      }
+    }
+
+    /* Prepare the output buffer. */
+    outbuflen = nbytes + nbytes / 100 + 600;  /* worst case (bzip2 docs) */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for bzip2 compression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Compress data. */
+    odatalen = outbuflen;
+    ret = BZ2_bzBuffToBuffCompress(outbuf, &odatalen, *buf, nbytes,
+                                   blockSize100k, 0, 0);
+    outdatalen = odatalen;
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 compression failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+  }
+
+  /* Always replace the input buffer with the output buffer. */
+  free(*buf);
+  *buf = outbuf;
+  *buf_size = outbuflen;
+  return outdatalen;
+
+ cleanupAndFail:
+  if (outbuf)
+    free(outbuf);
+  return 0;
+}
diff --git a/examples/C/hdf5plugins/Makefile.am b/examples/C/hdf5plugins/Makefile.am
new file mode 100644
index 0000000..ffd0667
--- /dev/null
+++ b/examples/C/hdf5plugins/Makefile.am
@@ -0,0 +1,28 @@
+#    Copyright 2018, UCAR/Unidata
+#    See netcdf/COPYRIGHT file for copying and redistribution conditions.
+
+BZIP2SRC = bzlib.h bzlib_private.h blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
+
+PLUGINSRC = H5Zbzip2.c h5bzip2.h
+
+TARGETS = ${PLUGINSRC} ${BZIP2SRC}
+
+BUILT_SOURCES = ${TARGETS}
+
+${TARGETS}:
+	for x in ${TARGETS} ; do 'cp' -f ${top_srcdir}/nc_test4/hdf5plugins/$$x . ; done
+
+CLEANFILES = ${TARGETS}
+
+if ENABLE_FILTER_TESTING
+
+DLLSRC=${PLUGINSRC} ${BZIP2SRC}
+
+lib_LTLIBRARIES = libbzip2.la
+
+libbzip2_la_SOURCES = ${DLLSRC}
+libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+
+endif #ENABLE_FILTER_TESTING
+EXTRA_DIST = CMakeLists.txt H5Zbzip2.c Makefile.am blocksort.c bzlib.c bzlib.h bzlib_private.h compress.c \
+crctable.c decompress.c h5bzip2.h huffman.c randtable.c bzip2.nc
diff --git a/liblib/Makefile.in b/examples/C/hdf5plugins/Makefile.in
similarity index 80%
copy from liblib/Makefile.in
copy to examples/C/hdf5plugins/Makefile.in
index c2a4318..5c60ebb 100644
--- a/liblib/Makefile.in
+++ b/examples/C/hdf5plugins/Makefile.in
@@ -14,20 +14,8 @@
 
 @SET_MAKE@
 
-# Copyright 2010, see the COPYRIGHT file for more information.
-
-# This Makefile assembles the correct libnetcdf based on various
-# configure flags. It is assumed that all the relevant convenience
-# libraries have been built (e.g. libsrc, libsrc4, libncdap3, libcdmr,
-# libncdap4, fortran).
-
-# This is part of the netCDF package.
-# Copyright 2005 University Corporation for Atmospheric Research/Unidata
-# See COPYRIGHT file for conditions of use.
-# 
-# Assemble the CPPFLAGS and LDFLAGS that point to all the needed
-# libraries for netCDF-4.
-#
+#    Copyright 2018, UCAR/Unidata
+#    See netcdf/COPYRIGHT file for copying and redistribution conditions.
 
 VPATH = @srcdir@
 am__is_gnu_make = { \
@@ -104,39 +92,7 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
- at USE_DAP_TRUE@am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
-# Turn on some extra stuff when building a DLL for windows.
- at BUILD_DLL_TRUE@am__append_3 = -no-undefined -Wl,--output-def,netcdfdll.def
- at BUILD_DLL_TRUE@am__append_4 = -DDLL_EXPORT
-
-# The v2 API...
- at BUILD_V2_TRUE@am__append_5 = ${top_builddir}/libdispatch/libnetcdf2.la
-
-# + pnetcdf
- at USE_PNETCDF_TRUE@am__append_6 = -I${top_srcdir}/libsrcp
- at USE_PNETCDF_TRUE@am__append_7 = ${top_builddir}/libsrcp/libnetcdfp.la
-
-# + dap
- at ENABLE_DAP_TRUE@am__append_8 = -I${top_srcdir}/libdap2 -I${top_srcdir}/oc
- at ENABLE_DAP_TRUE@am__append_9 = ${top_builddir}/libdap2/libdap2.la \
- at ENABLE_DAP_TRUE@	${top_builddir}/oc2/liboc.la
- at ENABLE_DAP4_TRUE@am__append_10 = -I${top_srcdir}/libdap4
- at ENABLE_DAP4_TRUE@am__append_11 = ${top_builddir}/libdap4/libdap4.la
-
-# NetCDF-4 ...
- at USE_NETCDF4_TRUE@am__append_12 = -I${top_srcdir}/libsrc4
- at USE_NETCDF4_TRUE@am__append_13 = ${top_builddir}/libsrc4/libnetcdf4.la
-
-# Not ready for prime time yet
-# libnetcdf_la_LIBADD += ${top_builddir}/libdiskless/libdiskless.la
-
-# Force binary mode for file read/write
- at ISCYGWIN_TRUE@am__append_14 = -lbinmode
-subdir = liblib
+subdir = examples/C/hdf5plugins
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -178,19 +134,25 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
-libnetcdf_la_DEPENDENCIES = $(am__append_5) \
-	${top_builddir}/libdispatch/libdispatch.la \
-	${top_builddir}/libsrc/libnetcdf3.la $(am__append_7) \
-	$(am__append_9) $(am__append_11) $(am__append_13)
-am_libnetcdf_la_OBJECTS = libnetcdf_la-nc_initialize.lo
-libnetcdf_la_OBJECTS = $(am_libnetcdf_la_OBJECTS)
+libbzip2_la_LIBADD =
+am__libbzip2_la_SOURCES_DIST = H5Zbzip2.c h5bzip2.h bzlib.h \
+	bzlib_private.h blocksort.c huffman.c crctable.c randtable.c \
+	compress.c decompress.c bzlib.c
+am__objects_1 = H5Zbzip2.lo
+am__objects_2 = blocksort.lo huffman.lo crctable.lo randtable.lo \
+	compress.lo decompress.lo bzlib.lo
+ at ENABLE_FILTER_TESTING_TRUE@am__objects_3 = $(am__objects_1) \
+ at ENABLE_FILTER_TESTING_TRUE@	$(am__objects_2)
+ at ENABLE_FILTER_TESTING_TRUE@am_libbzip2_la_OBJECTS = $(am__objects_3)
+libbzip2_la_OBJECTS = $(am_libbzip2_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-libnetcdf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+libbzip2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(libnetcdf_la_LDFLAGS) $(LDFLAGS) -o $@
+	$(libbzip2_la_LDFLAGS) $(LDFLAGS) -o $@
+ at ENABLE_FILTER_TESTING_TRUE@am_libbzip2_la_rpath = -rpath $(libdir)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -225,8 +187,8 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libnetcdf_la_SOURCES)
-DIST_SOURCES = $(libnetcdf_la_SOURCES)
+SOURCES = $(libbzip2_la_SOURCES)
+DIST_SOURCES = $(am__libbzip2_la_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -251,20 +213,16 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/lib_flags.am
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
-	$(am__append_6) $(am__append_8) $(am__append_10) \
-	$(am__append_12)
+AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AM_LDFLAGS = $(am__append_14)
+AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -287,12 +245,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -318,6 +278,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -332,6 +293,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -435,35 +397,24 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
-
-# Put together AM_CPPFLAGS and AM_LDFLAGS.
-
-# This is our output, the netcdf library the user will install.
-lib_LTLIBRARIES = libnetcdf.la
-
-# These linker flags specify libtool version info.
-# See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
-# for information regarding incrementing `-version-info`.
-libnetcdf_la_LDFLAGS = -version-info 13:0:0 $(am__append_3)
-libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_4)
-
-# The output library will always include netcdf3 and dispatch
-# libraries
-libnetcdf_la_LIBADD = $(am__append_5) \
-	${top_builddir}/libdispatch/libdispatch.la \
-	${top_builddir}/libsrc/libnetcdf3.la $(am__append_7) \
-	$(am__append_9) $(am__append_11) $(am__append_13)
-CLEANFILES = 
-
-# We need at least one source file
-libnetcdf_la_SOURCES = nc_initialize.c
-EXTRA_DIST = CMakeLists.txt
-all: all-am
+BZIP2SRC = bzlib.h bzlib_private.h blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
+PLUGINSRC = H5Zbzip2.c h5bzip2.h
+TARGETS = ${PLUGINSRC} ${BZIP2SRC}
+BUILT_SOURCES = ${TARGETS}
+CLEANFILES = ${TARGETS}
+ at ENABLE_FILTER_TESTING_TRUE@DLLSRC = ${PLUGINSRC} ${BZIP2SRC}
+ at ENABLE_FILTER_TESTING_TRUE@lib_LTLIBRARIES = libbzip2.la
+ at ENABLE_FILTER_TESTING_TRUE@libbzip2_la_SOURCES = ${DLLSRC}
+ at ENABLE_FILTER_TESTING_TRUE@libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+EXTRA_DIST = CMakeLists.txt H5Zbzip2.c Makefile.am blocksort.c bzlib.c bzlib.h bzlib_private.h compress.c \
+crctable.c decompress.c h5bzip2.h huffman.c randtable.c bzip2.nc
+
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
 
 .SUFFIXES:
 .SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
@@ -472,9 +423,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign liblib/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/C/hdf5plugins/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign liblib/Makefile
+	  $(AUTOMAKE) --foreign examples/C/hdf5plugins/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -483,7 +434,6 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
-$(top_srcdir)/lib_flags.am $(am__empty):
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -529,8 +479,8 @@ clean-libLTLIBRARIES:
 	  rm -f $${locs}; \
 	}
 
-libnetcdf.la: $(libnetcdf_la_OBJECTS) $(libnetcdf_la_DEPENDENCIES) $(EXTRA_libnetcdf_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libnetcdf_la_LINK) -rpath $(libdir) $(libnetcdf_la_OBJECTS) $(libnetcdf_la_LIBADD) $(LIBS)
+libbzip2.la: $(libbzip2_la_OBJECTS) $(libbzip2_la_DEPENDENCIES) $(EXTRA_libbzip2_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libbzip2_la_LINK) $(am_libbzip2_la_rpath) $(libbzip2_la_OBJECTS) $(libbzip2_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -538,7 +488,14 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libnetcdf_la-nc_initialize.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/H5Zbzip2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/blocksort.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bzlib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/compress.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/crctable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/decompress.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/huffman.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/randtable.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -564,13 +521,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
-libnetcdf_la-nc_initialize.lo: nc_initialize.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetcdf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetcdf_la-nc_initialize.lo -MD -MP -MF $(DEPDIR)/libnetcdf_la-nc_initialize.Tpo -c -o libnetcdf_la-nc_initialize.lo `test -f 'nc_initialize.c' || echo '$(srcdir)/'`nc_initialize.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libnetcdf_la-nc_initialize.Tpo $(DEPDIR)/libnetcdf_la-nc_initialize.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nc_initialize.c' object='libnetcdf_la-nc_initialize.lo' libtool=yes @AMDEPBACKSLASH@
- at 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) $(libnetcdf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetcdf_la-nc_initialize.lo `test -f 'nc_initialize.c' || echo '$(srcdir)/'`nc_initialize.c
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -660,13 +610,15 @@ distdir: $(DISTFILES)
 	  fi; \
 	done
 check-am: all-am
-check: check-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
 all-am: Makefile $(LTLIBRARIES)
 installdirs:
 	for dir in "$(DESTDIR)$(libdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
-install: install-am
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
 install-exec: install-exec-am
 install-data: install-data-am
 uninstall: uninstall-am
@@ -697,6 +649,7 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
 clean: clean-am
 
 clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
@@ -768,7 +721,7 @@ ps-am:
 
 uninstall-am: uninstall-libLTLIBRARIES
 
-.MAKE: install-am install-strip
+.MAKE: all check install install-am install-strip
 
 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
 	clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
@@ -787,6 +740,9 @@ uninstall-am: uninstall-libLTLIBRARIES
 .PRECIOUS: Makefile
 
 
+${TARGETS}:
+	for x in ${TARGETS} ; do 'cp' -f ${top_srcdir}/nc_test4/hdf5plugins/$$x . ; done
+
 # 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.
 .NOEXPORT:
diff --git a/examples/C/hdf5plugins/blocksort.c b/examples/C/hdf5plugins/blocksort.c
new file mode 100644
index 0000000..d0d662c
--- /dev/null
+++ b/examples/C/hdf5plugins/blocksort.c
@@ -0,0 +1,1094 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+__inline__
+void fallbackSimpleSort ( UInt32* fmap, 
+                          UInt32* eclass, 
+                          Int32   lo, 
+                          Int32   hi )
+{
+   Int32 i, j, tmp;
+   UInt32 ec_tmp;
+
+   if (lo == hi) return;
+
+   if (hi - lo > 3) {
+      for ( i = hi-4; i >= lo; i-- ) {
+         tmp = fmap[i];
+         ec_tmp = eclass[tmp];
+         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+            fmap[j-4] = fmap[j];
+         fmap[j-4] = tmp;
+      }
+   }
+
+   for ( i = hi-1; i >= lo; i-- ) {
+      tmp = fmap[i];
+      ec_tmp = eclass[tmp];
+      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+         fmap[j-1] = fmap[j];
+      fmap[j-1] = tmp;
+   }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      fswap(fmap[yyp1], fmap[yyp2]);  \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+                       stackHi[sp] = hz; \
+                       sp++; }
+
+#define fpop(lz,hz) { sp--;              \
+                      lz = stackLo[sp];  \
+                      hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap, 
+                      UInt32* eclass,
+                      Int32   loSt, 
+                      Int32   hiSt )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m;
+   Int32 sp, lo, hi;
+   UInt32 med, r, r3;
+   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+   r = 0;
+
+   sp = 0;
+   fpush ( loSt, hiSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+      fpop ( lo, hi );
+      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+         fallbackSimpleSort ( fmap, eclass, lo, hi );
+         continue;
+      }
+
+      /* Random partitioning.  Median of 3 sometimes fails to
+         avoid bad cases.  Median of 9 seems to help but 
+         looks rather expensive.  This too seems to work but
+         is cheaper.  Guidance for the magic constants 
+         7621 and 32768 is taken from Sedgewick's algorithms
+         book, chapter 35.
+      */
+      r = ((r * 7621) + 1) % 32768;
+      r3 = r % 3;
+      if (r3 == 0) med = eclass[fmap[lo]]; else
+      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+                   med = eclass[fmap[hi]];
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (1) {
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unLo], fmap[ltLo]); 
+               ltLo++; unLo++; 
+               continue; 
+            };
+            if (n > 0) break;
+            unLo++;
+         }
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unHi], fmap[gtHi]); 
+               gtHi--; unHi--; 
+               continue; 
+            };
+            if (n < 0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+      if (gtHi < ltLo) continue;
+
+      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      if (n - lo > hi - m) {
+         fpush ( lo, n );
+         fpush ( m, hi );
+      } else {
+         fpush ( m, hi );
+         fpush ( lo, n );
+      }
+   }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      eclass exists for [0 .. nblock-1]
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      All other areas of eclass destroyed
+      fmap [0 .. nblock-1] holds sorted order
+      bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define      WORD_BH(zz)  bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    UInt32* bhtab,
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   /*--
+      Initial 1-char radix sort to generate
+      initial fmap and initial BH bits.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        bucket sorting ...\n" );
+   for (i = 0; i < 257;    i++) ftab[i] = 0;
+   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i < nblock; i++) {
+      j = eclass8[i];
+      k = ftab[j] - 1;
+      ftab[j] = k;
+      fmap[k] = i;
+   }
+
+   nBhtab = 2 + (nblock / 32);
+   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+   /*--
+      Inductively refine the buckets.  Kind-of an
+      "exponential radix sort" (!), inspired by the
+      Manber-Myers suffix array construction algorithm.
+   --*/
+
+   /*-- set sentinel bits for block-end detection --*/
+   for (i = 0; i < 32; i++) { 
+      SET_BH(nblock + 2*i);
+      CLEAR_BH(nblock + 2*i + 1);
+   }
+
+   /*-- the log(N) loop --*/
+   H = 1;
+   while (1) {
+
+      if (verb >= 4) 
+         VPrintf1 ( "        depth %6d has ", H );
+
+      j = 0;
+      for (i = 0; i < nblock; i++) {
+         if (ISSET_BH(i)) j = i;
+         k = fmap[i] - H; if (k < 0) k += nblock;
+         eclass[k] = j;
+      }
+
+      nNotDone = 0;
+      r = -1;
+      while (1) {
+
+	 /*-- find the next non-singleton bucket --*/
+         k = r + 1;
+         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (ISSET_BH(k)) {
+            while (WORD_BH(k) == 0xffffffff) k += 32;
+            while (ISSET_BH(k)) k++;
+         }
+         l = k - 1;
+         if (l >= nblock) break;
+         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (!ISSET_BH(k)) {
+            while (WORD_BH(k) == 0x00000000) k += 32;
+            while (!ISSET_BH(k)) k++;
+         }
+         r = k - 1;
+         if (r >= nblock) break;
+
+         /*-- now [l, r] bracket current bucket --*/
+         if (r > l) {
+            nNotDone += (r - l + 1);
+            fallbackQSort3 ( fmap, eclass, l, r );
+
+            /*-- scan bucket and generate header bits-- */
+            cc = -1;
+            for (i = l; i <= r; i++) {
+               cc1 = eclass[fmap[i]];
+               if (cc != cc1) { SET_BH(i); cc = cc1; };
+            }
+         }
+      }
+
+      if (verb >= 4) 
+         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+      H *= 2;
+      if (H > nblock || nNotDone == 0) break;
+   }
+
+   /*-- 
+      Reconstruct the original block in
+      eclass8 [0 .. nblock-1], since the
+      previous phase destroyed it.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        reconstructing block ...\n" );
+   j = 0;
+   for (i = 0; i < nblock; i++) {
+      while (ftabCopy[j] == 0) j++;
+      ftabCopy[j]--;
+      eclass8[fmap[i]] = (UChar)j;
+   }
+   AssertH ( j < 256, 1005 );
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for "normal"       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32  i1, 
+               UInt32  i2,
+               UChar*  block, 
+               UInt16* quadrant,
+               UInt32  nblock,
+               Int32*  budget )
+{
+   Int32  k;
+   UChar  c1, c2;
+   UInt16 s1, s2;
+
+   AssertD ( i1 != i2, "mainGtU" );
+   /* 1 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 2 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 3 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 4 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 5 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 6 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 7 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 8 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 9 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 10 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 11 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 12 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+
+   k = nblock + 8;
+
+   do {
+      /* 1 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 2 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 3 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 4 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 5 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 6 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 7 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 8 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+
+      if (i1 >= nblock) i1 -= nblock;
+      if (i2 >= nblock) i2 -= nblock;
+
+      k -= 8;
+      (*budget)--;
+   }
+      while (k >= 0);
+
+   return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Knuth's increments seem to work better
+   than Incerpi-Sedgewick here.  Possibly
+   because the number of elems to sort is
+   usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+                   9841, 29524, 88573, 265720,
+                   797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+                      UChar*  block,
+                      UInt16* quadrant,
+                      Int32   nblock,
+                      Int32   lo, 
+                      Int32   hi, 
+                      Int32   d,
+                      Int32*  budget )
+{
+   Int32 i, j, h, bigN, hp;
+   UInt32 v;
+
+   bigN = hi - lo + 1;
+   if (bigN < 2) return;
+
+   hp = 0;
+   while (incs[hp] < bigN) hp++;
+   hp--;
+
+   for (; hp >= 0; hp--) {
+      h = incs[hp];
+
+      i = lo + h;
+      while (True) {
+
+         /*-- copy 1 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 2 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 3 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         if (*budget < 0) return;
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+/*--
+   The following is an implementation of
+   an elegant 3-way quicksort for strings,
+   described in a paper "Fast Algorithms for
+   Sorting and Searching Strings", by Robert
+   Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      mswap(ptr[yyp1], ptr[yyp2]);    \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+static 
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+   UChar t;
+   if (a > b) { t = a; a = b; b = t; };
+   if (b > c) { 
+      b = c;
+      if (a > b) b = a;
+   }
+   return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+                          stackHi[sp] = hz; \
+                          stackD [sp] = dz; \
+                          sp++; }
+
+#define mpop(lz,hz,dz) { sp--;             \
+                         lz = stackLo[sp]; \
+                         hz = stackHi[sp]; \
+                         dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz)                                        \
+   { Int32 tz;                                                  \
+     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+                  UChar*  block,
+                  UInt16* quadrant,
+                  Int32   nblock,
+                  Int32   loSt, 
+                  Int32   hiSt, 
+                  Int32   dSt,
+                  Int32*  budget )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+   Int32 sp, lo, hi, d;
+
+   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+   Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+   Int32 nextLo[3];
+   Int32 nextHi[3];
+   Int32 nextD [3];
+
+   sp = 0;
+   mpush ( loSt, hiSt, dSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+      mpop ( lo, hi, d );
+      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
+          d > MAIN_QSORT_DEPTH_THRESH) {
+         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+         if (*budget < 0) return;
+         continue;
+      }
+
+      med = (Int32) 
+            mmed3 ( block[ptr[ lo         ]+d],
+                    block[ptr[ hi         ]+d],
+                    block[ptr[ (lo+hi)>>1 ]+d] );
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (True) {
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unLo]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unLo], ptr[ltLo]); 
+               ltLo++; unLo++; continue; 
+            };
+            if (n >  0) break;
+            unLo++;
+         }
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unHi]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unHi], ptr[gtHi]); 
+               gtHi--; unHi--; continue; 
+            };
+            if (n <  0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+      if (gtHi < ltLo) {
+         mpush(lo, hi, d+1 );
+         continue;
+      }
+
+      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+      mpush (nextLo[0], nextHi[0], nextD[0]);
+      mpush (nextLo[1], nextHi[1], nextD[1]);
+      mpush (nextLo[2], nextHi[2], nextD[2]);
+   }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > N_OVERSHOOT
+      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      All other areas of block32 destroyed
+      ftab [0 .. 65536 ] destroyed
+      ptr [0 .. nblock-1] holds sorted order
+      if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr, 
+                UChar*  block,
+                UInt16* quadrant, 
+                UInt32* ftab,
+                Int32   nblock,
+                Int32   verb,
+                Int32*  budget )
+{
+   Int32  i, j, k, ss, sb;
+   Int32  runningOrder[256];
+   Bool   bigDone[256];
+   Int32  copyStart[256];
+   Int32  copyEnd  [256];
+   UChar  c1;
+   Int32  numQSorted;
+   UInt16 s;
+   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
+
+   /*-- set up the 2-byte frequency table --*/
+   for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+   j = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+      quadrant[i-1] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+      ftab[j]++;
+      quadrant[i-2] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+      ftab[j]++;
+      quadrant[i-3] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+      ftab[j]++;
+   }
+   for (; i >= 0; i--) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+   }
+
+   /*-- (emphasises close relationship of block & quadrant) --*/
+   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+      block   [nblock+i] = block[i];
+      quadrant[nblock+i] = 0;
+   }
+
+   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
+
+   /*-- Complete the initial radix sort --*/
+   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+   s = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+      s = (s >> 8) | (block[i-1] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-1;
+      s = (s >> 8) | (block[i-2] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-2;
+      s = (s >> 8) | (block[i-3] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-3;
+   }
+   for (; i >= 0; i--) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+   }
+
+   /*--
+      Now ftab contains the first loc of every small bucket.
+      Calculate the running order, from smallest to largest
+      big bucket.
+   --*/
+   for (i = 0; i <= 255; i++) {
+      bigDone     [i] = False;
+      runningOrder[i] = i;
+   }
+
+   {
+      Int32 vv;
+      Int32 h = 1;
+      do h = 3 * h + 1; while (h <= 256);
+      do {
+         h = h / 3;
+         for (i = h; i <= 255; i++) {
+            vv = runningOrder[i];
+            j = i;
+            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+               runningOrder[j] = runningOrder[j-h];
+               j = j - h;
+               if (j <= (h - 1)) goto zero;
+            }
+            zero:
+            runningOrder[j] = vv;
+         }
+      } while (h != 1);
+   }
+
+   /*--
+      The main sorting loop.
+   --*/
+
+   numQSorted = 0;
+
+   for (i = 0; i <= 255; i++) {
+
+      /*--
+         Process big buckets, starting with the least full.
+         Basically this is a 3-step process in which we call
+         mainQSort3 to sort the small buckets [ss, j], but
+         also make a big effort to avoid the calls if we can.
+      --*/
+      ss = runningOrder[i];
+
+      /*--
+         Step 1:
+         Complete the big bucket [ss] by quicksorting
+         any unsorted small buckets [ss, j], for j != ss.  
+         Hopefully previous pointer-scanning phases have already
+         completed many of the small buckets [ss, j], so
+         we don't have to sort them at all.
+      --*/
+      for (j = 0; j <= 255; j++) {
+         if (j != ss) {
+            sb = (ss << 8) + j;
+            if ( ! (ftab[sb] & SETMASK) ) {
+               Int32 lo = ftab[sb]   & CLEARMASK;
+               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+               if (hi > lo) {
+                  if (verb >= 4)
+                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
+                                "done %d   this %d\n",
+                                ss, j, numQSorted, hi - lo + 1 );
+                  mainQSort3 ( 
+                     ptr, block, quadrant, nblock, 
+                     lo, hi, BZ_N_RADIX, budget 
+                  );   
+                  numQSorted += (hi - lo + 1);
+                  if (*budget < 0) return;
+               }
+            }
+            ftab[sb] |= SETMASK;
+         }
+      }
+
+      AssertH ( !bigDone[ss], 1006 );
+
+      /*--
+         Step 2:
+         Now scan this big bucket [ss] so as to synthesise the
+         sorted order for small buckets [t, ss] for all t,
+         including, magically, the bucket [ss,ss] too.
+         This will avoid doing Real Work in subsequent Step 1's.
+      --*/
+      {
+         for (j = 0; j <= 255; j++) {
+            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
+            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+         }
+         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1])
+               ptr[ copyStart[c1]++ ] = k;
+         }
+         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1]) 
+               ptr[ copyEnd[c1]-- ] = k;
+         }
+      }
+
+      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+                || 
+                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+                   Necessity for this case is demonstrated by compressing 
+                   a sequence of approximately 48.5 million of character 
+                   251; 1.0.0/1.0.1 will then die here. */
+                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+                1007 )
+
+      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+      /*--
+         Step 3:
+         The [ss] big bucket is now done.  Record this fact,
+         and update the quadrant descriptors.  Remember to
+         update quadrants in the overshoot area too, if
+         necessary.  The "if (i < 255)" test merely skips
+         this updating for the last bucket processed, since
+         updating for the last bucket is pointless.
+
+         The quadrant array provides a way to incrementally
+         cache sort orderings, as they appear, so as to 
+         make subsequent comparisons in fullGtU() complete
+         faster.  For repetitive blocks this makes a big
+         difference (but not big enough to be able to avoid
+         the fallback sorting mechanism, exponential radix sort).
+
+         The precise meaning is: at all times:
+
+            for 0 <= i < nblock and 0 <= j <= nblock
+
+            if block[i] != block[j], 
+
+               then the relative values of quadrant[i] and 
+                    quadrant[j] are meaningless.
+
+               else {
+                  if quadrant[i] < quadrant[j]
+                     then the string starting at i lexicographically
+                     precedes the string starting at j
+
+                  else if quadrant[i] > quadrant[j]
+                     then the string starting at j lexicographically
+                     precedes the string starting at i
+
+                  else
+                     the relative ordering of the strings starting
+                     at i and j has not yet been determined.
+               }
+      --*/
+      bigDone[ss] = True;
+
+      if (i < 255) {
+         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
+         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+         Int32 shifts   = 0;
+
+         while ((bbSize >> shifts) > 65534) shifts++;
+
+         for (j = bbSize-1; j >= 0; j--) {
+            Int32 a2update     = ptr[bbStart + j];
+            UInt16 qVal        = (UInt16)(j >> shifts);
+            quadrant[a2update] = qVal;
+            if (a2update < BZ_N_OVERSHOOT)
+               quadrant[a2update + nblock] = qVal;
+         }
+         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+      }
+
+   }
+
+   if (verb >= 4)
+      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
+                 nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)arr2)  [0 .. nblock-1] holds block
+      arr1 exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)arr2) [0 .. nblock-1] holds block
+      All other areas of block destroyed
+      ftab [ 0 .. 65536 ] destroyed
+      arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+   UInt32* ptr    = s->ptr; 
+   UChar*  block  = s->block;
+   UInt32* ftab   = s->ftab;
+   Int32   nblock = s->nblock;
+   Int32   verb   = s->verbosity;
+   Int32   wfact  = s->workFactor;
+   UInt16* quadrant;
+   Int32   budget;
+   Int32   budgetInit;
+   Int32   i;
+
+   if (nblock < 10000) {
+      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+   } else {
+      /* Calculate the location for quadrant, remembering to get
+         the alignment right.  Assumes that &(block[0]) is at least
+         2-byte aligned -- this should be ok since block is really
+         the first section of arr2.
+      */
+      i = nblock+BZ_N_OVERSHOOT;
+      if (i & 1) i++;
+      quadrant = (UInt16*)(&(block[i]));
+
+      /* (wfact-1) / 3 puts the default-factor-30
+         transition point at very roughly the same place as 
+         with v0.1 and v0.9.0.  
+         Not that it particularly matters any more, since the
+         resulting compressed stream is now the same regardless
+         of whether or not we use the main sort or fallback sort.
+      */
+      if (wfact < 1  ) wfact = 1;
+      if (wfact > 100) wfact = 100;
+      budgetInit = nblock * ((wfact-1) / 3);
+      budget = budgetInit;
+
+      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+      if (verb >= 3) 
+         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
+                    budgetInit - budget,
+                    nblock, 
+                    (float)(budgetInit - budget) /
+                    (float)(nblock==0 ? 1 : nblock) ); 
+      if (budget < 0) {
+         if (verb >= 2) 
+            VPrintf0 ( "    too repetitive; using fallback"
+                       " sorting algorithm\n" );
+         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+      }
+   }
+
+   s->origPtr = -1;
+   for (i = 0; i < s->nblock; i++)
+      if (ptr[i] == 0)
+         { s->origPtr = i; break; };
+
+   AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/bzip2.nc b/examples/C/hdf5plugins/bzip2.nc
new file mode 100644
index 0000000..8d1bd8b
Binary files /dev/null and b/examples/C/hdf5plugins/bzip2.nc differ
diff --git a/examples/C/hdf5plugins/bzlib.c b/examples/C/hdf5plugins/bzlib.c
new file mode 100644
index 0000000..bd358a7
--- /dev/null
+++ b/examples/C/hdf5plugins/bzlib.c
@@ -0,0 +1,1572 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* CHANGES
+   0.9.0    -- original version.
+   0.9.0a/b -- no changes in this file.
+   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+     fixed bzWrite/bzRead to ignore zero-length requests.
+     fixed bzread to correctly handle read requests after EOF.
+     wrong parameter order in call to bzDecompressInit in
+     bzBuffToBuffDecompress.  Fixed.
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+   fprintf(stderr, 
+      "\n\nbzip2/libbzip2: internal error number %d.\n"
+      "This is a bug in bzip2/libbzip2, %s.\n"
+      "Please report it to me at: jseward at bzip.org.  If this happened\n"
+      "when you were using some program which uses libbzip2 as a\n"
+      "component, you should also report this bug to the author(s)\n"
+      "of that program.  Please make an effort to report this bug;\n"
+      "timely and accurate bug reports eventually lead to higher\n"
+      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
+      errcode,
+      BZ2_bzlibVersion()
+   );
+
+   if (errcode == 1007) {
+   fprintf(stderr,
+      "\n*** A special note about internal error number 1007 ***\n"
+      "\n"
+      "Experience suggests that a common cause of i.e. 1007\n"
+      "is unreliable memory or other hardware.  The 1007 assertion\n"
+      "just happens to cross-check the results of huge numbers of\n"
+      "memory reads/writes, and so acts (unintendedly) as a stress\n"
+      "test of your memory system.\n"
+      "\n"
+      "I suggest the following: try compressing the file again,\n"
+      "possibly monitoring progress in detail with the -vv flag.\n"
+      "\n"
+      "* If the error cannot be reproduced, and/or happens at different\n"
+      "  points in compression, you may have a flaky memory system.\n"
+      "  Try a memory-test program.  I have used Memtest86\n"
+      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
+      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
+      "  power-on test, and may find failures that the BIOS doesn't.\n"
+      "\n"
+      "* If the error can be repeatably reproduced, this is a bug in\n"
+      "  bzip2, and I would very much like to hear about it.  Please\n"
+      "  let me know, and, ideally, save a copy of the file causing the\n"
+      "  problem -- without which I will be unable to investigate it.\n"
+      "\n"
+   );
+   }
+
+   exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+   if (sizeof(int)   != 4) return 0;
+   if (sizeof(short) != 2) return 0;
+   if (sizeof(char)  != 1) return 0;
+   return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+   void* v = malloc ( items * size );
+   return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+   if (addr != NULL) free ( addr );
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+   Int32 i;
+   s->nblock = 0;
+   s->numZ = 0;
+   s->state_out_pos = 0;
+   BZ_INITIALISE_CRC ( s->blockCRC );
+   for (i = 0; i < 256; i++) s->inUse[i] = False;
+   s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+   s->state_in_ch  = 256;
+   s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+   if (s->state_in_ch < 256 && s->state_in_len > 0)
+      return False; else
+      return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit) 
+                    ( bz_stream* strm, 
+                     int        blockSize100k,
+                     int        verbosity,
+                     int        workFactor )
+{
+   Int32   n;
+   EState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL || 
+       blockSize100k < 1 || blockSize100k > 9 ||
+       workFactor < 0 || workFactor > 250)
+     return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(EState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm = strm;
+
+   s->arr1 = NULL;
+   s->arr2 = NULL;
+   s->ftab = NULL;
+
+   n       = 100000 * blockSize100k;
+   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
+   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
+
+   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+      if (s->arr1 != NULL) BZFREE(s->arr1);
+      if (s->arr2 != NULL) BZFREE(s->arr2);
+      if (s->ftab != NULL) BZFREE(s->ftab);
+      if (s       != NULL) BZFREE(s);
+      return BZ_MEM_ERROR;
+   }
+
+   s->blockNo           = 0;
+   s->state             = BZ_S_INPUT;
+   s->mode              = BZ_M_RUNNING;
+   s->combinedCRC       = 0;
+   s->blockSize100k     = blockSize100k;
+   s->nblockMAX         = 100000 * blockSize100k - 19;
+   s->verbosity         = verbosity;
+   s->workFactor        = workFactor;
+
+   s->block             = (UChar*)s->arr2;
+   s->mtfv              = (UInt16*)s->arr1;
+   s->zbits             = NULL;
+   s->ptr               = (UInt32*)s->arr1;
+
+   strm->state          = s;
+   strm->total_in_lo32  = 0;
+   strm->total_in_hi32  = 0;
+   strm->total_out_lo32 = 0;
+   strm->total_out_hi32 = 0;
+   init_RL ( s );
+   prepare_new_block ( s );
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+   Int32 i;
+   UChar ch = (UChar)(s->state_in_ch);
+   for (i = 0; i < s->state_in_len; i++) {
+      BZ_UPDATE_CRC( s->blockCRC, ch );
+   }
+   s->inUse[s->state_in_ch] = True;
+   switch (s->state_in_len) {
+      case 1:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 2:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 3:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      default:
+         s->inUse[s->state_in_len-4] = True;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+         s->nblock++;
+         break;
+   }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+   if (s->state_in_ch < 256) add_pair_to_block ( s );
+   init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
+{                                                 \
+   UInt32 zchh = (UInt32)(zchh0);                 \
+   /*-- fast track the common case --*/           \
+   if (zchh != zs->state_in_ch &&                 \
+       zs->state_in_len == 1) {                   \
+      UChar ch = (UChar)(zs->state_in_ch);        \
+      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
+      zs->inUse[zs->state_in_ch] = True;          \
+      zs->block[zs->nblock] = (UChar)ch;          \
+      zs->nblock++;                               \
+      zs->state_in_ch = zchh;                     \
+   }                                              \
+   else                                           \
+   /*-- general, uncommon cases --*/              \
+   if (zchh != zs->state_in_ch ||                 \
+      zs->state_in_len == 255) {                  \
+      if (zs->state_in_ch < 256)                  \
+         add_pair_to_block ( zs );                \
+      zs->state_in_ch = zchh;                     \
+      zs->state_in_len = 1;                       \
+   } else {                                       \
+      zs->state_in_len++;                         \
+   }                                              \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+   Bool progress_in = False;
+
+   if (s->mode == BZ_M_RUNNING) {
+
+      /*-- fast track the common case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+      }
+
+   } else {
+
+      /*-- general, uncommon case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         /*-- flush/finish end? --*/
+         if (s->avail_in_expect == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+         s->avail_in_expect--;
+      }
+   }
+   return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+   Bool progress_out = False;
+
+   while (True) {
+
+      /*-- no output space? --*/
+      if (s->strm->avail_out == 0) break;
+
+      /*-- block done? --*/
+      if (s->state_out_pos >= s->numZ) break;
+
+      progress_out = True;
+      *(s->strm->next_out) = s->zbits[s->state_out_pos];
+      s->state_out_pos++;
+      s->strm->avail_out--;
+      s->strm->next_out++;
+      s->strm->total_out_lo32++;
+      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+   }
+
+   return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+   Bool progress_in  = False;
+   Bool progress_out = False;
+   EState* s = strm->state;
+   
+   while (True) {
+
+      if (s->state == BZ_S_OUTPUT) {
+         progress_out |= copy_output_until_stop ( s );
+         if (s->state_out_pos < s->numZ) break;
+         if (s->mode == BZ_M_FINISHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+         prepare_new_block ( s );
+         s->state = BZ_S_INPUT;
+         if (s->mode == BZ_M_FLUSHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+      }
+
+      if (s->state == BZ_S_INPUT) {
+         progress_in |= copy_input_until_stop ( s );
+         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+            flush_RL ( s );
+            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->nblock >= s->nblockMAX) {
+            BZ2_compressBlock ( s, False );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->strm->avail_in == 0) {
+            break;
+         }
+      }
+
+   }
+
+   return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+   Bool progress;
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   preswitch:
+   switch (s->mode) {
+
+      case BZ_M_IDLE:
+         return BZ_SEQUENCE_ERROR;
+
+      case BZ_M_RUNNING:
+         if (action == BZ_RUN) {
+            progress = handle_compress ( strm );
+            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+         } 
+         else
+	 if (action == BZ_FLUSH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FLUSHING;
+            goto preswitch;
+         }
+         else
+         if (action == BZ_FINISH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FINISHING;
+            goto preswitch;
+         }
+         else 
+            return BZ_PARAM_ERROR;
+
+      case BZ_M_FLUSHING:
+         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+         s->mode = BZ_M_RUNNING;
+         return BZ_RUN_OK;
+
+      case BZ_M_FINISHING:
+         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (!progress) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+         s->mode = BZ_M_IDLE;
+         return BZ_STREAM_END;
+   }
+   return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+{
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->arr1 != NULL) BZFREE(s->arr1);
+   if (s->arr2 != NULL) BZFREE(s->arr2);
+   if (s->ftab != NULL) BZFREE(s->ftab);
+   BZFREE(strm->state);
+
+   strm->state = NULL;   
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit) 
+                     ( bz_stream* strm, 
+                       int        verbosity,
+                       int        small )
+{
+   DState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(DState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm                  = strm;
+   strm->state              = s;
+   s->state                 = BZ_X_MAGIC_1;
+   s->bsLive                = 0;
+   s->bsBuff                = 0;
+   s->calculatedCombinedCRC = 0;
+   strm->total_in_lo32      = 0;
+   strm->total_in_hi32      = 0;
+   strm->total_out_lo32     = 0;
+   strm->total_out_hi32     = 0;
+   s->smallDecompress       = (Bool)small;
+   s->ll4                   = NULL;
+   s->ll16                  = NULL;
+   s->tt                    = NULL;
+   s->currBlockNo           = 0;
+   s->verbosity             = verbosity;
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+               
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      /* restore */
+      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
+      UChar         c_state_out_ch       = s->state_out_ch;
+      Int32         c_state_out_len      = s->state_out_len;
+      Int32         c_nblock_used        = s->nblock_used;
+      Int32         c_k0                 = s->k0;
+      UInt32*       c_tt                 = s->tt;
+      UInt32        c_tPos               = s->tPos;
+      char*         cs_next_out          = s->strm->next_out;
+      unsigned int  cs_avail_out         = s->strm->avail_out;
+      Int32         ro_blockSize100k     = s->blockSize100k;
+      /* end restore */
+
+      UInt32       avail_out_INIT = cs_avail_out;
+      Int32        s_save_nblockPP = s->save_nblock+1;
+      unsigned int total_out_lo32_old;
+
+      while (True) {
+
+         /* try to finish existing run */
+         if (c_state_out_len > 0) {
+            while (True) {
+               if (cs_avail_out == 0) goto return_notr;
+               if (c_state_out_len == 1) break;
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               c_state_out_len--;
+               cs_next_out++;
+               cs_avail_out--;
+            }
+            s_state_out_len_eq_one:
+            {
+               if (cs_avail_out == 0) { 
+                  c_state_out_len = 1; goto return_notr;
+               };
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               cs_next_out++;
+               cs_avail_out--;
+            }
+         }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used > s_save_nblockPP)
+            return True;
+
+         /* can a new run be started? */
+         if (c_nblock_used == s_save_nblockPP) {
+            c_state_out_len = 0; goto return_notr;
+         };   
+         c_state_out_ch = c_k0;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (k1 != c_k0) { 
+            c_k0 = k1; goto s_state_out_len_eq_one; 
+         };
+         if (c_nblock_used == s_save_nblockPP) 
+            goto s_state_out_len_eq_one;
+   
+         c_state_out_len = 2;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         c_state_out_len = 3;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         c_state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST_C(c_k0); c_nblock_used++;
+      }
+
+      return_notr:
+      total_out_lo32_old = s->strm->total_out_lo32;
+      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+      if (s->strm->total_out_lo32 < total_out_lo32_old)
+         s->strm->total_out_hi32++;
+
+      /* save */
+      s->calculatedBlockCRC = c_calculatedBlockCRC;
+      s->state_out_ch       = c_state_out_ch;
+      s->state_out_len      = c_state_out_len;
+      s->nblock_used        = c_nblock_used;
+      s->k0                 = c_k0;
+      s->tt                 = c_tt;
+      s->tPos               = c_tPos;
+      s->strm->next_out     = cs_next_out;
+      s->strm->avail_out    = cs_avail_out;
+      /* end save */
+   }
+   return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+   Int32 nb, na, mid;
+   nb = 0;
+   na = 256;
+   do {
+      mid = (nb + na) >> 1;
+      if (indx >= cftab[mid]) nb = mid; else na = mid;
+   }
+   while (na - nb != 1);
+   return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); s->nblock_used++;
+      }
+
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+   Bool    corrupt;
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   while (True) {
+      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+      if (s->state == BZ_X_OUTPUT) {
+         if (s->smallDecompress)
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
+         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+            if (s->verbosity >= 3) 
+               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
+                          s->calculatedBlockCRC );
+            if (s->verbosity >= 2) VPrintf0 ( "]" );
+            if (s->calculatedBlockCRC != s->storedBlockCRC)
+               return BZ_DATA_ERROR;
+            s->calculatedCombinedCRC 
+               = (s->calculatedCombinedCRC << 1) | 
+                    (s->calculatedCombinedCRC >> 31);
+            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+            s->state = BZ_X_BLKHDR_1;
+         } else {
+            return BZ_OK;
+         }
+      }
+      if (s->state >= BZ_X_MAGIC_1) {
+         Int32 r = BZ2_decompress ( s );
+         if (r == BZ_STREAM_END) {
+            if (s->verbosity >= 3)
+               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
+                          s->storedCombinedCRC, s->calculatedCombinedCRC );
+            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+               return BZ_DATA_ERROR;
+            return r;
+         }
+         if (s->state != BZ_X_OUTPUT) return r;
+      }
+   }
+
+   AssertH ( 0, 6001 );
+
+   return 0;  /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+{
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->tt   != NULL) BZFREE(s->tt);
+   if (s->ll16 != NULL) BZFREE(s->ll16);
+   if (s->ll4  != NULL) BZFREE(s->ll4);
+
+   BZFREE(strm->state);
+   strm->state = NULL;
+
+   return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff                              ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee)                    \
+{                                         \
+   if (bzerror != NULL) *bzerror = eee;   \
+   if (bzf != NULL) bzf->lastErr = eee;   \
+}
+
+typedef 
+   struct {
+      FILE*     handle;
+      Char      buf[BZ_MAX_UNUSED];
+      Int32     bufN;
+      Bool      writing;
+      bz_stream strm;
+      Int32     lastErr;
+      Bool      initialisedOk;
+   }
+   bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen) 
+                    ( int*  bzerror,      
+                      FILE* f, 
+                      int   blockSize100k, 
+                      int   verbosity,
+                      int   workFactor )
+{
+   Int32   ret;
+   bzFile* bzf = NULL;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL ||
+       (blockSize100k < 1 || blockSize100k > 9) ||
+       (workFactor < 0 || workFactor > 250) ||
+       (verbosity < 0 || verbosity > 4))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+   bzf->initialisedOk = False;
+   bzf->bufN          = 0;
+   bzf->handle        = f;
+   bzf->writing       = True;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+
+   if (workFactor == 0) workFactor = 30;
+   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = 0;
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+             ( int*    bzerror, 
+               BZFILE* b, 
+               void*   buf, 
+               int     len )
+{
+   Int32 n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return; };
+
+   bzf->strm.avail_in = len;
+   bzf->strm.next_in  = buf;
+
+   while (True) {
+      bzf->strm.avail_out = BZ_MAX_UNUSED;
+      bzf->strm.next_out = bzf->buf;
+      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+      if (ret != BZ_RUN_OK)
+         { BZ_SETERR(ret); return; };
+
+      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                       n, bzf->handle );
+         if (n != n2 || ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return; };
+      }
+
+      if (bzf->strm.avail_in == 0)
+         { BZ_SETERR(BZ_OK); return; };
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in,
+                    unsigned int* nbytes_out )
+{
+   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
+                        nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in_lo32,
+                    unsigned int* nbytes_in_hi32,
+                    unsigned int* nbytes_out_lo32,
+                    unsigned int* nbytes_out_hi32 )
+{
+   Int32   n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+   if ((!abandon) && bzf->lastErr == BZ_OK) {
+      while (True) {
+         bzf->strm.avail_out = BZ_MAX_UNUSED;
+         bzf->strm.next_out = bzf->buf;
+         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+            { BZ_SETERR(ret); return; };
+
+         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                          n, bzf->handle );
+            if (n != n2 || ferror(bzf->handle))
+               { BZ_SETERR(BZ_IO_ERROR); return; };
+         }
+
+         if (ret == BZ_STREAM_END) break;
+      }
+   }
+
+   if ( !abandon && !ferror ( bzf->handle ) ) {
+      fflush ( bzf->handle );
+      if (ferror(bzf->handle))
+         { BZ_SETERR(BZ_IO_ERROR); return; };
+   }
+
+   if (nbytes_in_lo32 != NULL)
+      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+   if (nbytes_in_hi32 != NULL)
+      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+   if (nbytes_out_lo32 != NULL)
+      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+   if (nbytes_out_hi32 != NULL)
+      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+   BZ_SETERR(BZ_OK);
+   BZ2_bzCompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen) 
+                   ( int*  bzerror, 
+                     FILE* f, 
+                     int   verbosity,
+                     int   small,
+                     void* unused,
+                     int   nUnused )
+{
+   bzFile* bzf = NULL;
+   int     ret;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL || 
+       (small != 0 && small != 1) ||
+       (verbosity < 0 || verbosity > 4) ||
+       (unused == NULL && nUnused != 0) ||
+       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL) 
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+
+   bzf->initialisedOk = False;
+   bzf->handle        = f;
+   bzf->bufN          = 0;
+   bzf->writing       = False;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+   
+   while (nUnused > 0) {
+      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+      unused = ((void*)( 1 + ((UChar*)(unused))  ));
+      nUnused--;
+   }
+
+   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = bzf->bufN;
+   bzf->strm.next_in  = bzf->buf;
+
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+   if (bzf->initialisedOk)
+      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead) 
+           ( int*    bzerror, 
+             BZFILE* b, 
+             void*   buf, 
+             int     len )
+{
+   Int32   n, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return 0; };
+
+   bzf->strm.avail_out = len;
+   bzf->strm.next_out = buf;
+
+   while (True) {
+
+      if (ferror(bzf->handle)) 
+         { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+         n = fread ( bzf->buf, sizeof(UChar), 
+                     BZ_MAX_UNUSED, bzf->handle );
+         if (ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return 0; };
+         bzf->bufN = n;
+         bzf->strm.avail_in = bzf->bufN;
+         bzf->strm.next_in = bzf->buf;
+      }
+
+      ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+      if (ret != BZ_OK && ret != BZ_STREAM_END)
+         { BZ_SETERR(ret); return 0; };
+
+      if (ret == BZ_OK && myfeof(bzf->handle) && 
+          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+      if (ret == BZ_STREAM_END)
+         { BZ_SETERR(BZ_STREAM_END);
+           return len - bzf->strm.avail_out; };
+      if (bzf->strm.avail_out == 0)
+         { BZ_SETERR(BZ_OK); return len; };
+      
+   }
+
+   return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused) 
+                     ( int*    bzerror, 
+                       BZFILE* b, 
+                       void**  unused, 
+                       int*    nUnused )
+{
+   bzFile* bzf = (bzFile*)b;
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (bzf->lastErr != BZ_STREAM_END)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (unused == NULL || nUnused == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+   BZ_SETERR(BZ_OK);
+   *nUnused = bzf->strm.avail_in;
+   *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress) 
+                         ( char*         dest, 
+                           unsigned int* destLen,
+                           char*         source, 
+                           unsigned int  sourceLen,
+                           int           blockSize100k, 
+                           int           verbosity, 
+                           int           workFactor )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       blockSize100k < 1 || blockSize100k > 9 ||
+       verbosity < 0 || verbosity > 4 ||
+       workFactor < 0 || workFactor > 250) 
+      return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+   if (ret == BZ_FINISH_OK) goto output_overflow;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;   
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow:
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OUTBUFF_FULL;
+
+   errhandler:
+   BZ2_bzCompressEnd ( &strm );
+   return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress) 
+                           ( char*         dest, 
+                             unsigned int* destLen,
+                             char*         source, 
+                             unsigned int  sourceLen,
+                             int           small,
+                             int           verbosity )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       (small != 0 && small != 1) ||
+       verbosity < 0 || verbosity > 4) 
+          return BZ_PARAM_ERROR;
+
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzDecompress ( &strm );
+   if (ret == BZ_OK) goto output_overflow_or_eof;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;
+   BZ2_bzDecompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow_or_eof:
+   if (strm.avail_out > 0) {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_UNEXPECTED_EOF;
+   } else {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_OUTBUFF_FULL;
+   };      
+
+   errhandler:
+   BZ2_bzDecompressEnd ( &strm );
+   return ret; 
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+   return version like "0.9.5d, 4-Sept-1999".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+   return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#   include <fcntl.h>
+#   include <io.h>
+#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+               ( const char *path,   /* no use when bzdopen */
+                 int fd,             /* no use when bzdopen */
+                 const char *mode,
+                 int open_mode)      /* bzopen: 0, bzdopen:1 */
+{
+   int    bzerr;
+   char   unused[BZ_MAX_UNUSED];
+   int    blockSize100k = 9;
+   int    writing       = 0;
+   char   mode2[10]     = "";
+   FILE   *fp           = NULL;
+   BZFILE *bzfp         = NULL;
+   int    verbosity     = 0;
+   int    workFactor    = 30;
+   int    smallMode     = 0;
+   int    nUnused       = 0; 
+
+   if (mode == NULL) return NULL;
+   while (*mode) {
+      switch (*mode) {
+      case 'r':
+         writing = 0; break;
+      case 'w':
+         writing = 1; break;
+      case 's':
+         smallMode = 1; break;
+      default:
+         if (isdigit((int)(*mode))) {
+            blockSize100k = *mode-BZ_HDR_0;
+         }
+      }
+      mode++;
+   }
+   strcat(mode2, writing ? "w" : "r" );
+   strcat(mode2,"b");   /* binary mode */
+
+   if (open_mode==0) {
+      if (path==NULL || strcmp(path,"")==0) {
+        fp = (writing ? stdout : stdin);
+        SET_BINARY_MODE(fp);
+      } else {
+        fp = fopen(path,mode2);
+      }
+   } else {
+#ifdef BZ_STRICT_ANSI
+      fp = NULL;
+#else
+      fp = fdopen(fd,mode2);
+#endif
+   }
+   if (fp == NULL) return NULL;
+
+   if (writing) {
+      /* Guard against total chaos and anarchy -- JRS */
+      if (blockSize100k < 1) blockSize100k = 1;
+      if (blockSize100k > 9) blockSize100k = 9; 
+      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+                             verbosity,workFactor);
+   } else {
+      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+                            unused,nUnused);
+   }
+   if (bzfp == NULL) {
+      if (fp != stdin && fp != stdout) fclose(fp);
+      return NULL;
+   }
+   return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   open file for read or write.
+      ex) bzopen("file","w9")
+      case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+               ( const char *path,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+               ( int fd,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+   int bzerr, nread;
+   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+   nread = BZ2_bzRead(&bzerr,b,buf,len);
+   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+      return nread;
+   } else {
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+   int bzerr;
+
+   BZ2_bzWrite(&bzerr,b,buf,len);
+   if(bzerr == BZ_OK){
+      return len;
+   }else{
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+   /* do nothing now... */
+   return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+   int bzerr;
+   FILE *fp;
+   
+   if (b==NULL) {return;}
+   fp = ((bzFile *)b)->handle;
+   if(((bzFile*)b)->writing){
+      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+      if(bzerr != BZ_OK){
+         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+      }
+   }else{
+      BZ2_bzReadClose(&bzerr,b);
+   }
+   if(fp!=stdin && fp!=stdout){
+      fclose(fp);
+   }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   return last error code 
+--*/
+static const char *bzerrorstrings[] = {
+       "OK"
+      ,"SEQUENCE_ERROR"
+      ,"PARAM_ERROR"
+      ,"MEM_ERROR"
+      ,"DATA_ERROR"
+      ,"DATA_ERROR_MAGIC"
+      ,"IO_ERROR"
+      ,"UNEXPECTED_EOF"
+      ,"OUTBUFF_FULL"
+      ,"CONFIG_ERROR"
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+   int err = ((bzFile *)b)->lastErr;
+
+   if(err>0) err = 0;
+   *errnum = err;
+   return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/bzlib.h b/examples/C/hdf5plugins/bzlib.h
new file mode 100644
index 0000000..8277123
--- /dev/null
+++ b/examples/C/hdf5plugins/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef 
+   struct {
+      char *next_in;
+      unsigned int avail_in;
+      unsigned int total_in_lo32;
+      unsigned int total_in_hi32;
+
+      char *next_out;
+      unsigned int avail_out;
+      unsigned int total_out_lo32;
+      unsigned int total_out_hi32;
+
+      void *state;
+
+      void *(*bzalloc)(void *,int,int);
+      void (*bzfree)(void *,void *);
+      void *opaque;
+   } 
+   bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+#   include <windows.h>
+#   ifdef small
+      /* windows.h define small to char */
+#      undef small
+#   endif
+#   ifdef BZ_EXPORT
+#   define BZ_API(func) WINAPI func
+#   define BZ_EXTERN extern
+#   else
+   /* import windows dll dynamically */
+#   define BZ_API(func) (WINAPI * func)
+#   define BZ_EXTERN
+#   endif
+#else
+#   define BZ_API(func) func
+#   define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
+      bz_stream* strm, 
+      int        blockSize100k, 
+      int        verbosity, 
+      int        workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
+      bz_stream* strm, 
+      int action 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
+      bz_stream *strm, 
+      int       verbosity, 
+      int       small
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
+      bz_stream *strm 
+   );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
+      int*  bzerror,   
+      FILE* f, 
+      int   verbosity, 
+      int   small,
+      void* unused,    
+      int   nUnused 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
+      int*    bzerror, 
+      BZFILE* b 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void**  unused,  
+      int*    nUnused 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
+      int*  bzerror,      
+      FILE* f, 
+      int   blockSize100k, 
+      int   verbosity, 
+      int   workFactor 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in, 
+      unsigned int* nbytes_out 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in_lo32, 
+      unsigned int* nbytes_in_hi32, 
+      unsigned int* nbytes_out_lo32, 
+      unsigned int* nbytes_out_hi32
+   );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           blockSize100k, 
+      int           verbosity, 
+      int           workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           small, 
+      int           verbosity 
+   );
+
+
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+      void
+   );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+      const char *path,
+      const char *mode
+   );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+      int        fd,
+      const char *mode
+   );
+         
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+      BZFILE* b, 
+      void* buf, 
+      int len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+      BZFILE* b
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+      BZFILE* b
+   );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+      BZFILE *b, 
+      int    *errnum
+   );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/bzlib_private.h b/examples/C/hdf5plugins/bzlib_private.h
new file mode 100644
index 0000000..5d0217f
--- /dev/null
+++ b/examples/C/hdf5plugins/bzlib_private.h
@@ -0,0 +1,509 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include <stdlib.h>
+
+#ifndef BZ_NO_STDIO
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "bzlib.h"
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION  "1.0.6, 6-Sept-2010"
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__  /* */
+#endif 
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+   { if (!(cond)) {       \
+      fprintf ( stderr,   \
+        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+      exit(1); \
+   }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+   fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+   fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+   fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+   fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+   fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+   fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg)                do { } while (0)
+#define VPrintf0(zf)                     do { } while (0)
+#define VPrintf1(zf,za1)                 do { } while (0)
+#define VPrintf2(zf,za1,za2)             do { } while (0)
+#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+  
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS                          \
+   Int32 rNToGo;                               \
+   Int32 rTPos                                 \
+
+#define BZ_RAND_INIT_MASK                      \
+   s->rNToGo = 0;                              \
+   s->rTPos  = 0                               \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK                       \
+   if (s->rNToGo == 0) {                       \
+      s->rNToGo = BZ2_rNums[s->rTPos];         \
+      s->rTPos++;                              \
+      if (s->rTPos == 512) s->rTPos = 0;       \
+   }                                           \
+   s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar)              \
+{                                              \
+   crcVar = 0xffffffffL;                       \
+}
+
+#define BZ_FINALISE_CRC(crcVar)                \
+{                                              \
+   crcVar = ~(crcVar);                         \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha)              \
+{                                              \
+   crcVar = (crcVar << 8) ^                    \
+            BZ2_crc32Table[(crcVar >> 24) ^    \
+                           ((UChar)cha)];      \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* mode this stream is in, and whether inputting */
+      /* or outputting data */
+      Int32    mode;
+      Int32    state;
+
+      /* remembers avail_in when flush/finish requested */
+      UInt32   avail_in_expect;
+
+      /* for doing the block sorting */
+      UInt32*  arr1;
+      UInt32*  arr2;
+      UInt32*  ftab;
+      Int32    origPtr;
+
+      /* aliases for arr1 and arr2 */
+      UInt32*  ptr;
+      UChar*   block;
+      UInt16*  mtfv;
+      UChar*   zbits;
+
+      /* for deciding when to use the fallback sorting algorithm */
+      Int32    workFactor;
+
+      /* run-length-encoding of the input */
+      UInt32   state_in_ch;
+      Int32    state_in_len;
+      BZ_RAND_DECLS;
+
+      /* input and output limits and current posns */
+      Int32    nblock;
+      Int32    nblockMAX;
+      Int32    numZ;
+      Int32    state_out_pos;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      UChar    unseqToSeq[256];
+
+      /* the buffer for bit stream creation */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* block and combined CRCs */
+      UInt32   blockCRC;
+      UInt32   combinedCRC;
+
+      /* misc administratium */
+      Int32    verbosity;
+      Int32    blockNo;
+      Int32    blockSize100k;
+
+      /* stuff for coding the MTF values */
+      Int32    nMTF;
+      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+
+      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      /* second dimension: only 3 needed; 4 makes index calculations faster */
+      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+   }
+   EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void 
+BZ2_blockSort ( EState* );
+
+extern void 
+BZ2_compressBlock ( EState*, Bool );
+
+extern void 
+BZ2_bsInitWrite ( EState* );
+
+extern void 
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void 
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE        1
+#define BZ_X_OUTPUT      2
+
+#define BZ_X_MAGIC_1     10
+#define BZ_X_MAGIC_2     11
+#define BZ_X_MAGIC_3     12
+#define BZ_X_MAGIC_4     13
+#define BZ_X_BLKHDR_1    14
+#define BZ_X_BLKHDR_2    15
+#define BZ_X_BLKHDR_3    16
+#define BZ_X_BLKHDR_4    17
+#define BZ_X_BLKHDR_5    18
+#define BZ_X_BLKHDR_6    19
+#define BZ_X_BCRC_1      20
+#define BZ_X_BCRC_2      21
+#define BZ_X_BCRC_3      22
+#define BZ_X_BCRC_4      23
+#define BZ_X_RANDBIT     24
+#define BZ_X_ORIGPTR_1   25
+#define BZ_X_ORIGPTR_2   26
+#define BZ_X_ORIGPTR_3   27
+#define BZ_X_MAPPING_1   28
+#define BZ_X_MAPPING_2   29
+#define BZ_X_SELECTOR_1  30
+#define BZ_X_SELECTOR_2  31
+#define BZ_X_SELECTOR_3  32
+#define BZ_X_CODING_1    33
+#define BZ_X_CODING_2    34
+#define BZ_X_CODING_3    35
+#define BZ_X_MTF_1       36
+#define BZ_X_MTF_2       37
+#define BZ_X_MTF_3       38
+#define BZ_X_MTF_4       39
+#define BZ_X_MTF_5       40
+#define BZ_X_MTF_6       41
+#define BZ_X_ENDHDR_2    42
+#define BZ_X_ENDHDR_3    43
+#define BZ_X_ENDHDR_4    44
+#define BZ_X_ENDHDR_5    45
+#define BZ_X_ENDHDR_6    46
+#define BZ_X_CCRC_1      47
+#define BZ_X_CCRC_2      48
+#define BZ_X_CCRC_3      49
+#define BZ_X_CCRC_4      50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* state indicator for this stream */
+      Int32    state;
+
+      /* for doing the final run-length decoding */
+      UChar    state_out_ch;
+      Int32    state_out_len;
+      Bool     blockRandomised;
+      BZ_RAND_DECLS;
+
+      /* the buffer for bit stream reading */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* misc administratium */
+      Int32    blockSize100k;
+      Bool     smallDecompress;
+      Int32    currBlockNo;
+      Int32    verbosity;
+
+      /* for undoing the Burrows-Wheeler transform */
+      Int32    origPtr;
+      UInt32   tPos;
+      Int32    k0;
+      Int32    unzftab[256];
+      Int32    nblock_used;
+      Int32    cftab[257];
+      Int32    cftabCopy[257];
+
+      /* for undoing the Burrows-Wheeler transform (FAST) */
+      UInt32   *tt;
+
+      /* for undoing the Burrows-Wheeler transform (SMALL) */
+      UInt16   *ll16;
+      UChar    *ll4;
+
+      /* stored and calculated CRCs */
+      UInt32   storedBlockCRC;
+      UInt32   storedCombinedCRC;
+      UInt32   calculatedBlockCRC;
+      UInt32   calculatedCombinedCRC;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      Bool     inUse16[16];
+      UChar    seqToUnseq[256];
+
+      /* for decoding the MTF values */
+      UChar    mtfa   [MTFA_SIZE];
+      Int32    mtfbase[256 / MTFL_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    minLens[BZ_N_GROUPS];
+
+      /* save area for scalars in the main decompress code */
+      Int32    save_i;
+      Int32    save_j;
+      Int32    save_t;
+      Int32    save_alphaSize;
+      Int32    save_nGroups;
+      Int32    save_nSelectors;
+      Int32    save_EOB;
+      Int32    save_groupNo;
+      Int32    save_groupPos;
+      Int32    save_nextSym;
+      Int32    save_nblockMAX;
+      Int32    save_nblock;
+      Int32    save_es;
+      Int32    save_N;
+      Int32    save_curr;
+      Int32    save_zt;
+      Int32    save_zn; 
+      Int32    save_zvec;
+      Int32    save_zj;
+      Int32    save_gSel;
+      Int32    save_gMinlen;
+      Int32*   save_gLimit;
+      Int32*   save_gBase;
+      Int32*   save_gPerm;
+
+   }
+   DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc)                     \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    s->tPos = s->tt[s->tPos];                 \
+    cccc = (UChar)(s->tPos & 0xff);           \
+    s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc)                   \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+    c_tPos = c_tt[c_tPos];                    \
+    cccc = (UChar)(c_tPos & 0xff);            \
+    c_tPos >>= 8;
+
+#define SET_LL4(i,n)                                          \
+   { if (((i) & 0x1) == 0)                                    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
+   }
+
+#define GET_LL4(i)                             \
+   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n)                          \
+   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
+     SET_LL4(i, n >> 16);                    \
+   }
+
+#define GET_LL(i) \
+   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc)                            \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
+    s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32 
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32 
+BZ2_decompress ( DState* );
+
+extern void 
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+                           Int32,  Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/compress.c b/examples/C/hdf5plugins/compress.c
new file mode 100644
index 0000000..caf7696
--- /dev/null
+++ b/examples/C/hdf5plugins/compress.c
@@ -0,0 +1,672 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s->bsLive = 0;
+   s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s->bsLive > 0) {
+      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+      s->numZ++;
+      s->bsBuff <<= 8;
+      s->bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s->bsLive >= 8) {                   \
+      s->zbits[s->numZ]                       \
+         = (UChar)(s->bsBuff >> 24);          \
+      s->numZ++;                              \
+      s->bsBuff <<= 8;                        \
+      s->bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s->bsBuff |= (v << (32 - s->bsLive - n));
+   s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u >> 24) & 0xffL );
+   bsW ( s, 8, (u >> 16) & 0xffL );
+   bsW ( s, 8, (u >>  8) & 0xffL );
+   bsW ( s, 8,  u        & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->unseqToSeq[i] = s->nInUse;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s->ptr;
+   UChar* block  = s->block;
+   UInt16* mtfv  = s->mtfv;
+
+   makeMaps_e ( s );
+   EOB = s->nInUse+1;
+
+   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i < s->nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr <= i, "generateMTFValues(1)" );
+      j = ptr[i]-1; if (j < 0) j += s->nblock;
+      ll_i = s->unseqToSeq[block[j]];
+      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend > 0) {
+            zPend--;
+            while (True) {
+               if (zPend & 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s->mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s->mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend < 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &(yy[0]);
+            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend > 0) {
+      zPend--;
+      while (True) {
+         if (zPend & 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s->mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s->mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend < 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+   s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s->mtfv;
+
+   if (s->verbosity >= 3)
+      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
+                "%d+2 syms in use\n", 
+                s->nblock, s->nMTF, s->nInUse );
+
+   alphaSize = s->nInUse+2;
+   for (t = 0; t < BZ_N_GROUPS; t++)
+      for (v = 0; v < alphaSize; v++)
+         s->len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s->nMTF > 0, 3001 );
+   if (s->nMTF < 200)  nGroups = 2; else
+   if (s->nMTF < 600)  nGroups = 3; else
+   if (s->nMTF < 1200) nGroups = 4; else
+   if (s->nMTF < 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s->nMTF;
+      gs = 0;
+      while (nPart > 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq < tFreq && ge < alphaSize-1) {
+            ge++;
+            aFreq += s->mtfFreq[ge];
+         }
+
+         if (ge > gs 
+             && nPart != nGroups && nPart != 1 
+             && ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s->mtfFreq[ge];
+            ge--;
+         }
+
+         if (s->verbosity >= 3)
+            VPrintf5( "      initial group %d, [%d .. %d], "
+                      "has %d syms (%4.1f%%)\n",
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
+ 
+         for (v = 0; v < alphaSize; v++)
+            if (v >= gs && v <= ge) 
+               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s->len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+      for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t < nGroups; t++)
+         for (v = 0; v < alphaSize; v++)
+            s->rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v < alphaSize; v++) {
+            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start & end marks. --*/
+         if (gs >= s->nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge >= s->nMTF) ge = s->nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s->len_pack[icv][0]; \
+               cost23 += s->len_pack[icv][1]; \
+               cost45 += s->len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t < nGroups; t++)
+            if (cost[t] < bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s->selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++)
+               s->rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s->verbosity >= 3) {
+         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
+                   iter+1, totc/8 );
+         for (t = 0; t < nGroups; t++)
+            VPrintf1 ( "%d ", fave[t] );
+         VPrintf0 ( "\n" );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t < nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups < 8, 3002 );
+   AssertH( nSelectors < 32768 &&
+            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i < nGroups; i++) pos[i] = i;
+      for (i = 0; i < nSelectors; i++) {
+         ll_i = s->selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s->selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t < nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i < alphaSize; i++) {
+         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+         if (s->len[t][i] < minLen) minLen = s->len[t][i];
+      }
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen < 1),  3005 );
+      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i < 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j < 16; j++)
+             if (s->inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s->numZ;
+      for (i = 0; i < 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i < 16; i++)
+         if (inUse16[i])
+            for (j = 0; j < 16; j++) {
+               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s->verbosity >= 3) 
+         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s->numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i < nSelectors; i++) { 
+      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s->verbosity >= 3)
+      VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s->numZ;
+
+   for (t = 0; t < nGroups; t++) {
+      Int32 curr = s->len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i < alphaSize; i++) {
+         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s->verbosity >= 3)
+      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s->numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs >= s->nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge >= s->nMTF) ge = s->nMTF-1;
+      AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+      if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &(s->len[s->selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &(s->code[s->selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i <= ge; i++) {
+            bsW ( s, 
+                  s->len  [s->selector[selCtr]] [mtfv[i]],
+                  s->code [s->selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s->verbosity >= 3)
+      VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s->nblock > 0) {
+
+      BZ_FINALISE_CRC ( s->blockCRC );
+      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+      s->combinedCRC ^= s->blockCRC;
+      if (s->blockNo > 1) s->numZ = 0;
+
+      if (s->verbosity >= 2)
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
+                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s->blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+   }
+
+   if (s->nblock > 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s->blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s->origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s->combinedCRC );
+      if (s->verbosity >= 2)
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/crctable.c b/examples/C/hdf5plugins/crctable.c
new file mode 100644
index 0000000..1fea7e9
--- /dev/null
+++ b/examples/C/hdf5plugins/crctable.c
@@ -0,0 +1,104 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs                                  ---*/
+/*---                                            crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*--
+  I think this is an implementation of the AUTODIN-II,
+  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
+  from code by Rob Warnock, in Section 51 of the
+  comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+   /*-- Ugly, innit? --*/
+
+   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/decompress.c b/examples/C/hdf5plugins/decompress.c
new file mode 100644
index 0000000..311f566
--- /dev/null
+++ b/examples/C/hdf5plugins/decompress.c
@@ -0,0 +1,646 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery                               ---*/
+/*---                                          decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->seqToUnseq[s->nInUse] = i;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr)                               \
+   { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn)                     \
+   case lll: s->state = lll;                      \
+   while (True) {                                 \
+      if (s->bsLive >= nnn) {                     \
+         UInt32 v;                                \
+         v = (s->bsBuff >>                        \
+             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
+         s->bsLive -= nnn;                        \
+         vvv = v;                                 \
+         break;                                   \
+      }                                           \
+      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
+      s->bsBuff                                   \
+         = (s->bsBuff << 8) |                     \
+           ((UInt32)                              \
+              (*((UChar*)(s->strm->next_in))));   \
+      s->bsLive += 8;                             \
+      s->strm->next_in++;                         \
+      s->strm->avail_in--;                        \
+      s->strm->total_in_lo32++;                   \
+      if (s->strm->total_in_lo32 == 0)            \
+         s->strm->total_in_hi32++;                \
+   }
+
+#define GET_UCHAR(lll,uuu)                        \
+   GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu)                          \
+   GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval)           \
+{                                                 \
+   if (groupPos == 0) {                           \
+      groupNo++;                                  \
+      if (groupNo >= nSelectors)                  \
+         RETURN(BZ_DATA_ERROR);                   \
+      groupPos = BZ_G_SIZE;                       \
+      gSel = s->selector[groupNo];                \
+      gMinlen = s->minLens[gSel];                 \
+      gLimit = &(s->limit[gSel][0]);              \
+      gPerm = &(s->perm[gSel][0]);                \
+      gBase = &(s->base[gSel][0]);                \
+   }                                              \
+   groupPos--;                                    \
+   zn = gMinlen;                                  \
+   GET_BITS(label1, zvec, zn);                    \
+   while (1) {                                    \
+      if (zn > 20 /* the longest code */)         \
+         RETURN(BZ_DATA_ERROR);                   \
+      if (zvec <= gLimit[zn]) break;              \
+      zn++;                                       \
+      GET_BIT(label2, zj);                        \
+      zvec = (zvec << 1) | zj;                    \
+   };                                             \
+   if (zvec - gBase[zn] < 0                       \
+       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
+      RETURN(BZ_DATA_ERROR);                      \
+   lval = gPerm[zvec - gBase[zn]];                \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+   UChar      uc;
+   Int32      retVal;
+   Int32      minLen, maxLen;
+   bz_stream* strm = s->strm;
+
+   /* stuff that needs to be saved/restored */
+   Int32  i;
+   Int32  j;
+   Int32  t;
+   Int32  alphaSize;
+   Int32  nGroups;
+   Int32  nSelectors;
+   Int32  EOB;
+   Int32  groupNo;
+   Int32  groupPos;
+   Int32  nextSym;
+   Int32  nblockMAX;
+   Int32  nblock;
+   Int32  es;
+   Int32  N;
+   Int32  curr;
+   Int32  zt;
+   Int32  zn; 
+   Int32  zvec;
+   Int32  zj;
+   Int32  gSel;
+   Int32  gMinlen;
+   Int32* gLimit;
+   Int32* gBase;
+   Int32* gPerm;
+
+   if (s->state == BZ_X_MAGIC_1) {
+      /*initialise the save area*/
+      s->save_i           = 0;
+      s->save_j           = 0;
+      s->save_t           = 0;
+      s->save_alphaSize   = 0;
+      s->save_nGroups     = 0;
+      s->save_nSelectors  = 0;
+      s->save_EOB         = 0;
+      s->save_groupNo     = 0;
+      s->save_groupPos    = 0;
+      s->save_nextSym     = 0;
+      s->save_nblockMAX   = 0;
+      s->save_nblock      = 0;
+      s->save_es          = 0;
+      s->save_N           = 0;
+      s->save_curr        = 0;
+      s->save_zt          = 0;
+      s->save_zn          = 0;
+      s->save_zvec        = 0;
+      s->save_zj          = 0;
+      s->save_gSel        = 0;
+      s->save_gMinlen     = 0;
+      s->save_gLimit      = NULL;
+      s->save_gBase       = NULL;
+      s->save_gPerm       = NULL;
+   }
+
+   /*restore from the save area*/
+   i           = s->save_i;
+   j           = s->save_j;
+   t           = s->save_t;
+   alphaSize   = s->save_alphaSize;
+   nGroups     = s->save_nGroups;
+   nSelectors  = s->save_nSelectors;
+   EOB         = s->save_EOB;
+   groupNo     = s->save_groupNo;
+   groupPos    = s->save_groupPos;
+   nextSym     = s->save_nextSym;
+   nblockMAX   = s->save_nblockMAX;
+   nblock      = s->save_nblock;
+   es          = s->save_es;
+   N           = s->save_N;
+   curr        = s->save_curr;
+   zt          = s->save_zt;
+   zn          = s->save_zn; 
+   zvec        = s->save_zvec;
+   zj          = s->save_zj;
+   gSel        = s->save_gSel;
+   gMinlen     = s->save_gMinlen;
+   gLimit      = s->save_gLimit;
+   gBase       = s->save_gBase;
+   gPerm       = s->save_gPerm;
+
+   retVal = BZ_OK;
+
+   switch (s->state) {
+
+      GET_UCHAR(BZ_X_MAGIC_1, uc);
+      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_2, uc);
+      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_3, uc)
+      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
+          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+      s->blockSize100k -= BZ_HDR_0;
+
+      if (s->smallDecompress) {
+         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+         s->ll4  = BZALLOC( 
+                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
+                   );
+         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+      } else {
+         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+      }
+
+      GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+      if (uc == 0x17) goto endhdr_2;
+      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_2, uc);
+      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_3, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_4, uc);
+      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_5, uc);
+      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_6, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+      s->currBlockNo++;
+      if (s->verbosity >= 2)
+         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
+ 
+      s->storedBlockCRC = 0;
+      GET_UCHAR(BZ_X_BCRC_1, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_2, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_3, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_4, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+      s->origPtr = 0;
+      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+      if (s->origPtr < 0)
+         RETURN(BZ_DATA_ERROR);
+      if (s->origPtr > 10 + 100000*s->blockSize100k) 
+         RETURN(BZ_DATA_ERROR);
+
+      /*--- Receive the mapping table ---*/
+      for (i = 0; i < 16; i++) {
+         GET_BIT(BZ_X_MAPPING_1, uc);
+         if (uc == 1) 
+            s->inUse16[i] = True; else 
+            s->inUse16[i] = False;
+      }
+
+      for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+      for (i = 0; i < 16; i++)
+         if (s->inUse16[i])
+            for (j = 0; j < 16; j++) {
+               GET_BIT(BZ_X_MAPPING_2, uc);
+               if (uc == 1) s->inUse[i * 16 + j] = True;
+            }
+      makeMaps_d ( s );
+      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+      alphaSize = s->nInUse+2;
+
+      /*--- Now the selectors ---*/
+      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+      for (i = 0; i < nSelectors; i++) {
+         j = 0;
+         while (True) {
+            GET_BIT(BZ_X_SELECTOR_3, uc);
+            if (uc == 0) break;
+            j++;
+            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+         }
+         s->selectorMtf[i] = j;
+      }
+
+      /*--- Undo the MTF values for the selectors. ---*/
+      {
+         UChar pos[BZ_N_GROUPS], tmp, v;
+         for (v = 0; v < nGroups; v++) pos[v] = v;
+   
+         for (i = 0; i < nSelectors; i++) {
+            v = s->selectorMtf[i];
+            tmp = pos[v];
+            while (v > 0) { pos[v] = pos[v-1]; v--; }
+            pos[0] = tmp;
+            s->selector[i] = tmp;
+         }
+      }
+
+      /*--- Now the coding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         GET_BITS(BZ_X_CODING_1, curr, 5);
+         for (i = 0; i < alphaSize; i++) {
+            while (True) {
+               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+               GET_BIT(BZ_X_CODING_2, uc);
+               if (uc == 0) break;
+               GET_BIT(BZ_X_CODING_3, uc);
+               if (uc == 0) curr++; else curr--;
+            }
+            s->len[t][i] = curr;
+         }
+      }
+
+      /*--- Create the Huffman decoding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         minLen = 32;
+         maxLen = 0;
+         for (i = 0; i < alphaSize; i++) {
+            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+            if (s->len[t][i] < minLen) minLen = s->len[t][i];
+         }
+         BZ2_hbCreateDecodeTables ( 
+            &(s->limit[t][0]), 
+            &(s->base[t][0]), 
+            &(s->perm[t][0]), 
+            &(s->len[t][0]),
+            minLen, maxLen, alphaSize
+         );
+         s->minLens[t] = minLen;
+      }
+
+      /*--- Now the MTF values ---*/
+
+      EOB      = s->nInUse+1;
+      nblockMAX = 100000 * s->blockSize100k;
+      groupNo  = -1;
+      groupPos = 0;
+
+      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+      /*-- MTF init --*/
+      {
+         Int32 ii, jj, kk;
+         kk = MTFA_SIZE-1;
+         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+               kk--;
+            }
+            s->mtfbase[ii] = kk + 1;
+         }
+      }
+      /*-- end MTF init --*/
+
+      nblock = 0;
+      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+      while (True) {
+
+         if (nextSym == EOB) break;
+
+         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+            es = -1;
+            N = 1;
+            do {
+               /* Check that N doesn't get too big, so that es doesn't
+                  go negative.  The maximum value that can be
+                  RUNA/RUNB encoded is equal to the block size (post
+                  the initial RLE), viz, 900k, so bounding N at 2
+                  million should guard against overflow without
+                  rejecting any legitimate inputs. */
+               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
+               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+               N = N * 2;
+               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+            }
+               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+            es++;
+            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+            s->unzftab[uc] += es;
+
+            if (s->smallDecompress)
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->ll16[nblock] = (UInt16)uc;
+                  nblock++;
+                  es--;
+               }
+            else
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->tt[nblock] = (UInt32)uc;
+                  nblock++;
+                  es--;
+               };
+
+            continue;
+
+         } else {
+
+            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+            /*-- uc = MTF ( nextSym-1 ) --*/
+            {
+               Int32 ii, jj, kk, pp, lno, off;
+               UInt32 nn;
+               nn = (UInt32)(nextSym - 1);
+
+               if (nn < MTFL_SIZE) {
+                  /* avoid general-case expense */
+                  pp = s->mtfbase[0];
+                  uc = s->mtfa[pp+nn];
+                  while (nn > 3) {
+                     Int32 z = pp+nn;
+                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
+                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
+                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
+                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
+                     nn -= 4;
+                  }
+                  while (nn > 0) { 
+                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
+                  };
+                  s->mtfa[pp] = uc;
+               } else { 
+                  /* general case */
+                  lno = nn / MTFL_SIZE;
+                  off = nn % MTFL_SIZE;
+                  pp = s->mtfbase[lno] + off;
+                  uc = s->mtfa[pp];
+                  while (pp > s->mtfbase[lno]) { 
+                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
+                  };
+                  s->mtfbase[lno]++;
+                  while (lno > 0) {
+                     s->mtfbase[lno]--;
+                     s->mtfa[s->mtfbase[lno]] 
+                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s->mtfbase[0]--;
+                  s->mtfa[s->mtfbase[0]] = uc;
+                  if (s->mtfbase[0] == 0) {
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s->mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+            }
+            /*-- end uc = MTF ( nextSym-1 ) --*/
+
+            s->unzftab[s->seqToUnseq[uc]]++;
+            if (s->smallDecompress)
+               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
+            nblock++;
+
+            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+            continue;
+         }
+      }
+
+      /* Now we know what nblock is, we can do a better sanity
+         check on s->origPtr.
+      */
+      if (s->origPtr < 0 || s->origPtr >= nblock)
+         RETURN(BZ_DATA_ERROR);
+
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      /* Check: unzftab entries in range. */
+      for (i = 0; i <= 255; i++) {
+         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+            RETURN(BZ_DATA_ERROR);
+      }
+      /* Actually generate cftab. */
+      s->cftab[0] = 0;
+      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      /* Check: cftab entries in range. */
+      for (i = 0; i <= 256; i++) {
+         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+            /* s->cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+      /* Check: cftab entries non-descending. */
+      for (i = 1; i <= 256; i++) {
+         if (s->cftab[i-1] > s->cftab[i]) {
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
+      s->state_out_len = 0;
+      s->state_out_ch  = 0;
+      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+      s->state = BZ_X_OUTPUT;
+      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+      if (s->smallDecompress) {
+
+         /*-- Make a copy of cftab, used in generation of T --*/
+         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+         /*-- compute the T vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->ll16[i]);
+            SET_LL(i, s->cftabCopy[uc]);
+            s->cftabCopy[uc]++;
+         }
+
+         /*-- Compute T^(-1) by pointer reversal on T --*/
+         i = s->origPtr;
+         j = GET_LL(i);
+         do {
+            Int32 tmp = GET_LL(j);
+            SET_LL(j, i);
+            i = j;
+            j = tmp;
+         }
+            while (i != s->origPtr);
+
+         s->tPos = s->origPtr;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+         }
+
+      } else {
+
+         /*-- compute the T^(-1) vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->tt[i] & 0xff);
+            s->tt[s->cftab[uc]] |= (i << 8);
+            s->cftab[uc]++;
+         }
+
+         s->tPos = s->tt[s->origPtr] >> 8;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+         }
+
+      }
+
+      RETURN(BZ_OK);
+
+
+
+    endhdr_2:
+
+      GET_UCHAR(BZ_X_ENDHDR_2, uc);
+      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_3, uc);
+      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_4, uc);
+      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_5, uc);
+      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_6, uc);
+      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+      s->storedCombinedCRC = 0;
+      GET_UCHAR(BZ_X_CCRC_1, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_2, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_3, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_4, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+      s->state = BZ_X_IDLE;
+      RETURN(BZ_STREAM_END);
+
+      default: AssertH ( False, 4001 );
+   }
+
+   AssertH ( False, 4002 );
+
+   save_state_and_return:
+
+   s->save_i           = i;
+   s->save_j           = j;
+   s->save_t           = t;
+   s->save_alphaSize   = alphaSize;
+   s->save_nGroups     = nGroups;
+   s->save_nSelectors  = nSelectors;
+   s->save_EOB         = EOB;
+   s->save_groupNo     = groupNo;
+   s->save_groupPos    = groupPos;
+   s->save_nextSym     = nextSym;
+   s->save_nblockMAX   = nblockMAX;
+   s->save_nblock      = nblock;
+   s->save_es          = es;
+   s->save_N           = N;
+   s->save_curr        = curr;
+   s->save_zt          = zt;
+   s->save_zn          = zn;
+   s->save_zvec        = zvec;
+   s->save_zj          = zj;
+   s->save_gSel        = gSel;
+   s->save_gMinlen     = gMinlen;
+   s->save_gLimit      = gLimit;
+   s->save_gBase       = gBase;
+   s->save_gPerm       = gPerm;
+
+   return retVal;   
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                      decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/h5bzip2.h b/examples/C/hdf5plugins/h5bzip2.h
new file mode 100644
index 0000000..8a9a06c
--- /dev/null
+++ b/examples/C/hdf5plugins/h5bzip2.h
@@ -0,0 +1,30 @@
+#ifndef H5BZIP2_H
+#define H5BZIP2_H
+
+#include "bzlib.h"
+
+#ifdef _MSC_VER
+  #ifdef DLL_EXPORT /* define when building the library */
+    #define DECLSPEC __declspec(dllexport)
+  #else
+    #define DECLSPEC __declspec(dllimport)
+  #endif
+#else
+  #define DECLSPEC extern
+#endif
+
+/* use an integer greater than 256 to be id of the registered filter. */
+#define H5Z_FILTER_BZIP2 307
+
+/* declare the hdf5 interface */
+DECLSPEC H5PL_type_t H5PLget_plugin_type(void);
+DECLSPEC const void* H5PLget_plugin_info(void);
+DECLSPEC const H5Z_class2_t H5Z_BZIP2[1]; 
+
+/* Declare  filter specific functions */
+DECLSPEC htri_t H5Z_bzip2_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+DECLSPEC size_t H5Z_filter_bzip2(unsigned flags,size_t cd_nelmts,const unsigned cd_values[],
+                    size_t nbytes,size_t *buf_size,void**buf);
+
+#endif /*H5BZIP2_H*/
+
diff --git a/examples/C/hdf5plugins/huffman.c b/examples/C/hdf5plugins/huffman.c
new file mode 100644
index 0000000..2283fdb
--- /dev/null
+++ b/examples/C/hdf5plugins/huffman.c
@@ -0,0 +1,205 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2)                           \
+   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
+   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z)                                     \
+{                                                     \
+   Int32 zz, tmp;                                     \
+   zz = z; tmp = heap[zz];                            \
+   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
+      heap[zz] = heap[zz >> 1];                       \
+      zz >>= 1;                                       \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+#define DOWNHEAP(z)                                   \
+{                                                     \
+   Int32 zz, yy, tmp;                                 \
+   zz = z; tmp = heap[zz];                            \
+   while (True) {                                     \
+      yy = zz << 1;                                   \
+      if (yy > nHeap) break;                          \
+      if (yy < nHeap &&                               \
+          weight[heap[yy+1]] < weight[heap[yy]])      \
+         yy++;                                        \
+      if (weight[tmp] < weight[heap[yy]]) break;      \
+      heap[zz] = heap[yy];                            \
+      zz = yy;                                        \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len, 
+                             Int32 *freq,
+                             Int32 alphaSize,
+                             Int32 maxLen )
+{
+   /*--
+      Nodes and heap entries run from 1.  Entry 0
+      for both the heap and nodes is a sentinel.
+   --*/
+   Int32 nNodes, nHeap, n1, n2, i, j, k;
+   Bool  tooLong;
+
+   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
+   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+
+   for (i = 0; i < alphaSize; i++)
+      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+   while (True) {
+
+      nNodes = alphaSize;
+      nHeap = 0;
+
+      heap[0] = 0;
+      weight[0] = 0;
+      parent[0] = -2;
+
+      for (i = 1; i <= alphaSize; i++) {
+         parent[i] = -1;
+         nHeap++;
+         heap[nHeap] = i;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+   
+      while (nHeap > 1) {
+         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         nNodes++;
+         parent[n1] = parent[n2] = nNodes;
+         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+         parent[nNodes] = -1;
+         nHeap++;
+         heap[nHeap] = nNodes;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+      tooLong = False;
+      for (i = 1; i <= alphaSize; i++) {
+         j = 0;
+         k = i;
+         while (parent[k] >= 0) { k = parent[k]; j++; }
+         len[i-1] = j;
+         if (j > maxLen) tooLong = True;
+      }
+      
+      if (! tooLong) break;
+
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i < alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i <= alphaSize; i++) {
+         j = weight[i] >> 8;
+         j = 1 + (j / 2);
+         weight[i] = j << 8;
+      }
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+                         UChar *length,
+                         Int32 minLen,
+                         Int32 maxLen,
+                         Int32 alphaSize )
+{
+   Int32 n, vec, i;
+
+   vec = 0;
+   for (n = minLen; n <= maxLen; n++) {
+      for (i = 0; i < alphaSize; i++)
+         if (length[i] == n) { code[i] = vec; vec++; };
+      vec <<= 1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+                                Int32 *base,
+                                Int32 *perm,
+                                UChar *length,
+                                Int32 minLen,
+                                Int32 maxLen,
+                                Int32 alphaSize )
+{
+   Int32 pp, i, j, vec;
+
+   pp = 0;
+   for (i = minLen; i <= maxLen; i++)
+      for (j = 0; j < alphaSize; j++)
+         if (length[j] == i) { perm[pp] = j; pp++; };
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   vec = 0;
+
+   for (i = minLen; i <= maxLen; i++) {
+      vec += (base[i+1] - base[i]);
+      limit[i] = vec-1;
+      vec <<= 1;
+   }
+   for (i = minLen + 1; i <= maxLen; i++)
+      base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/hdf5plugins/randtable.c b/examples/C/hdf5plugins/randtable.c
new file mode 100644
index 0000000..6d62459
--- /dev/null
+++ b/examples/C/hdf5plugins/randtable.c
@@ -0,0 +1,84 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks               ---*/
+/*---                                           randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = { 
+   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
+   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
+   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
+   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
+   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
+   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
+   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
+   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
+   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
+   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
+   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
+   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
+   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
+   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
+   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
+   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
+   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
+   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
+   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
+   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
+   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
+   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
+   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
+   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
+   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
+   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
+   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
+   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
+   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
+   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
+   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
+   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
+   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
+   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
+   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
+   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
+   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
+   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
+   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
+   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
+   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
+   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
+   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
+   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
+   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
+   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
+   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
+   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
+   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
+   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
+   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
+   936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       randtable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/examples/C/run_examples.sh b/examples/C/run_examples.sh
new file mode 100755
index 0000000..655314b
--- /dev/null
+++ b/examples/C/run_examples.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+# This shell script runs the examples.
+# Ed Hartnett
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../../test_common.sh
+
+echo "*** Running examples."
+set -e
+
+echo "*** running simple_xy examples..."
+${execdir}/simple_xy_wr
+${execdir}/simple_xy_rd
+
+echo "*** running sfc_pres_temp examples..."
+${execdir}/sfc_pres_temp_wr
+${execdir}/sfc_pres_temp_rd
+
+echo "*** running pres_temp_4D examples..."
+${execdir}/pres_temp_4D_wr
+${execdir}/pres_temp_4D_rd
+
+echo "*** Examples successful!"
+exit 0
diff --git a/examples/C/run_examples4.sh b/examples/C/run_examples4.sh
new file mode 100755
index 0000000..f0fae09
--- /dev/null
+++ b/examples/C/run_examples4.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+# This shell script runs the examples for netCDF4.
+# Ed Hartnett
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../../test_common.sh
+
+echo "*** Running examples for netCDF-4."
+set -e
+
+echo "*** running simple_nc4 examples..."
+${execdir}/simple_nc4_wr
+${execdir}/simple_nc4_rd
+
+echo "*** running simple_xy_nc4 examples..."
+${execdir}/simple_xy_nc4_wr
+${execdir}/simple_xy_nc4_rd
+
+if test -f ${builddir}/findplugin.sh ; then
+echo "*** running test_filter example..."
+. ${builddir}/findplugin.sh
+
+# Locate the plugin path and the library names; argument order is critical
+# Find bzip2 and capture
+findplugin bzip2
+BZIP2PATH="${HDF5_PLUGIN_PATH}/${HDF5_PLUGIN_LIB}"
+# Verify
+if ! test -f ${BZIP2PATH} ; then echo "Unable to locate ${BZIP2PATH}"; exit 1; fi
+export HDF5_PLUGIN_PATH
+
+echo "*** running filter_example..."
+rm -f ./bzip2.nc
+${execdir}/filter_example
+#rm -f ./bzip2.nc
+
+fi # Filter enabled
+
+echo "*** Examples successful!"
+exit 0
diff --git a/examples/C/run_filter.sh b/examples/C/run_filter.sh
new file mode 100755
index 0000000..1a496c1
--- /dev/null
+++ b/examples/C/run_filter.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+# This shell script runs the examples for netCDF4.
+# Ed Hartnett
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../../test_common.sh
+
+set -e
+
+echo "*** Running test_filter example..."
+echo "ISCYGWIN=${ISCYGWIN}"
+if test "x$ISCYGWIN" != x ; then
+PLUGIN=cygbzip2.dll
+else
+PLUGIN=libbzip2.so
+fi
+
+HDF5_PLUGIN_PATH=`pwd`
+HDF5_PLUGIN_PATH="${HDF5_PLUGIN_PATH}/plugins"
+if test -f "${HDF5_PLUGIN_PATH}/.libs/${PLUGIN}" ; then
+HDF5_PLUGIN_PATH="${HDF5_PLUGIN_PATH}/.libs"
+fi
+export HDF5_PLUGIN_PATH
+rm -f ./bzip2.nc
+${execdir}/test_filter
+#rm -f ./bzip2.nc
+
+echo "*** Example successful!"
+exit 0
diff --git a/examples/CDL/CMakeLists.txt b/examples/CDL/CMakeLists.txt
index de80227..b0bff21 100644
--- a/examples/CDL/CMakeLists.txt
+++ b/examples/CDL/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(CDL_EXAMPLE_TESTS create_sample_files do_comps)
+SET(CDL_EXAMPLE_TESTS do_comps)
 
 FILE(GLOB COPY_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.sh ${CMAKE_CURRENT_SOURCE_DIR}/*.cdl)
 FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE)
@@ -7,12 +7,9 @@ FOREACH(F ${CDL_EXAMPLE_TESTS})
   add_sh_test(cdl ${F})
 ENDFOREACH()
 
-FILE(GLOB CUR_EXTRA_DIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.sh)
-SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} simple_xy.cdl sfc_pres_temp.cdl pres_temp_4D.cdl CMakeLists.txt Makefile.am create_sample_files.sh do_comps.sh)
-
-ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
-
+SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_tests_simple_xy_wr)
+SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_tests_sfc_pres_temp_wr)
+SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_test_pres_temp_4D_wr)
 
 SET(CLEANFILES simple_xy.nc sfc_pres_temp.nc pres_temp_4D.nc)
 SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}")
-
diff --git a/examples/CDL/Makefile.am b/examples/CDL/Makefile.am
index 0747616..0af9bd3 100644
--- a/examples/CDL/Makefile.am
+++ b/examples/CDL/Makefile.am
@@ -1,20 +1,18 @@
 ## This is a automake file, part of Unidata's netCDF package.
-# Copyright 2006, see the COPYRIGHT file for more information.  
-
+# Copyright 2006, see the COPYRIGHT file for more information.
 # This file builds CDL examples.
+# Ed Hartnett
 
-# $Id: Makefile.am,v 1.3 2009/05/19 11:56:50 ed Exp $
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
 
 # All we do is run two shell scripts, which create the sample files
 # and then compare them with the C versions of the examples.
-#if !BUILD_DLL
-TESTS = create_sample_files.sh do_comps.sh
-#endif
+TESTS = do_comps.sh
 
 # Ship the scripts needed to create the sample files and compare them.
-EXTRA_DIST = do_comps.sh create_sample_files.sh simple_xy.cdl	\
+EXTRA_DIST = do_comps.sh simple_xy.cdl	\
 sfc_pres_temp.cdl pres_temp_4D.cdl CMakeLists.txt
 
 # Clean up files created during the process.
-CLEANFILES = simple_xy.nc sfc_pres_temp.nc pres_temp_4D.nc
-
+CLEANFILES = *.nc
diff --git a/examples/CDL/Makefile.in b/examples/CDL/Makefile.in
index 477a24d..78cda8f 100644
--- a/examples/CDL/Makefile.in
+++ b/examples/CDL/Makefile.in
@@ -14,11 +14,9 @@
 
 @SET_MAKE@
 
-# Copyright 2006, see the COPYRIGHT file for more information.  
-
+# Copyright 2006, see the COPYRIGHT file for more information.
 # This file builds CDL examples.
-
-# $Id: Makefile.am,v 1.3 2009/05/19 11:56:50 ed Exp $
+# Ed Hartnett
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -312,9 +310,11 @@ am__set_TESTS_bases = \
 RECHECK_LOGS = $(TEST_LOGS)
 AM_RECURSIVE_TARGETS = check recheck
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
-LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
 am__set_b = \
   case '$@' in \
     */*) \
@@ -325,12 +325,6 @@ am__set_b = \
     *) \
       b='$*';; \
   esac
-am__test_logs1 = $(TESTS:=.log)
-am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -341,7 +335,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -364,12 +357,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -395,6 +390,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -409,6 +405,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -513,23 +510,24 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
+
 # All we do is run two shell scripts, which create the sample files
 # and then compare them with the C versions of the examples.
-#if !BUILD_DLL
-TESTS = create_sample_files.sh do_comps.sh
-#endif
+TESTS = do_comps.sh
 
 # Ship the scripts needed to create the sample files and compare them.
-EXTRA_DIST = do_comps.sh create_sample_files.sh simple_xy.cdl	\
+EXTRA_DIST = do_comps.sh simple_xy.cdl	\
 sfc_pres_temp.cdl pres_temp_4D.cdl CMakeLists.txt
 
 
 # Clean up files created during the process.
-CLEANFILES = simple_xy.nc sfc_pres_temp.nc pres_temp_4D.nc
+CLEANFILES = *.nc
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .log .test .test$(EXEEXT) .trs
+.SUFFIXES: .log .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -713,33 +711,19 @@ recheck: all
 	        am__force_recheck=am--force-recheck \
 	        TEST_LOGS="$$log_list"; \
 	exit $$?
-create_sample_files.sh.log: create_sample_files.sh
-	@p='create_sample_files.sh'; \
-	b='create_sample_files.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)
-do_comps.sh.log: do_comps.sh
-	@p='do_comps.sh'; \
-	b='do_comps.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
diff --git a/examples/CDL/create_sample_files.sh b/examples/CDL/create_sample_files.sh
deleted file mode 100755
index f2fa5a5..0000000
--- a/examples/CDL/create_sample_files.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-# This shell script creates the netCDF example files from CDL scipts.
-# $Id: create_sample_files.sh,v 1.2 2006/07/14 18:39:45 ed Exp $
-
-set -e
-echo ""
-echo "*** Creating example data files from CDL scripts."
-echo "*** creating simple_xy.nc..."
-../../ncgen/ncgen -b -o simple_xy.nc $srcdir/simple_xy.cdl
-
-echo "*** checking sfc_pres_temp.nc..."
-../../ncgen/ncgen -b -o sfc_pres_temp.nc $srcdir/sfc_pres_temp.cdl
-
-echo "*** checking pres_temp_4D.nc..."
-../../ncgen/ncgen -b -o pres_temp_4D.nc $srcdir/pres_temp_4D.cdl
-
-echo "*** All example creations worked!"
-exit 0
diff --git a/examples/CDL/do_comps.sh b/examples/CDL/do_comps.sh
index faaa6fa..88f80f9 100755
--- a/examples/CDL/do_comps.sh
+++ b/examples/CDL/do_comps.sh
@@ -3,6 +3,28 @@
 # $Id: do_comps.sh,v 1.1 2006/06/27 17:44:54 ed Exp $
 
 set -e
+
+##
+# This stanza was originally in create_sample_files.sh.
+# Moved here.
+##
+echo ""
+echo "*** Creating example data files from CDL scripts."
+echo "*** creating simple_xy.nc..."
+../../ncgen/ncgen -b -o simple_xy.nc $srcdir/simple_xy.cdl
+
+echo "*** checking sfc_pres_temp.nc..."
+../../ncgen/ncgen -b -o sfc_pres_temp.nc $srcdir/sfc_pres_temp.cdl
+
+echo "*** checking pres_temp_4D.nc..."
+../../ncgen/ncgen -b -o pres_temp_4D.nc $srcdir/pres_temp_4D.cdl
+
+echo "*** All example creations worked!"
+
+##
+# End create_sample_files.
+##
+
 echo ""
 echo "*** Testing that the CDL examples produced same files as C examples."
 echo "*** checking simple_xy.nc..."
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 6c6c7ba..5a253c2 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -3,8 +3,3 @@ ADD_SUBDIRECTORY(C)
 IF(BUILD_UTILITIES)
   ADD_SUBDIRECTORY(CDL)
 ENDIF()
-
-SET(CUR_EXTRA_DIST CMakeLists.txt Makefile.am)
-ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
-
-
diff --git a/examples/Makefile.in b/examples/Makefile.in
index 2652d3f..2806104 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -197,7 +197,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -220,12 +219,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -251,6 +252,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -265,6 +267,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/h5_test/CMakeLists.txt b/h5_test/CMakeLists.txt
index f27db47..5b51ddf 100644
--- a/h5_test/CMakeLists.txt
+++ b/h5_test/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(H5TESTS tst_h_files tst_h_files2 tst_h_files4 tst_h_atts tst_h_atts3 tst_h_atts4 tst_h_vars tst_h_vars2 tst_h_vars3 tst_h_grps tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_rd_cmp tst_h_vl tst_h_opaques tst_h_strings tst_h_strings1 tst_h_strings2 tst_h_ints tst_h_dimscales tst_h_dimscales1 tst_h_dimscales2 tst_h_dimscales3 tst_h_enums tst_h_dimscales4)
+SET(H5TESTS tst_h_files tst_h_files2 tst_h_files4 tst_h_atts tst_h_atts3 tst_h_atts4 tst_h_vars tst_h_vars2 tst_h_vars3 tst_h_grps tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_vl tst_h_opaques tst_h_strings tst_h_strings1 tst_h_strings2 tst_h_ints tst_h_dimscales tst_h_dimscales1 tst_h_dimscales2 tst_h_dimscales3 tst_h_enums tst_h_dimscales4)
 
 FILE(GLOB COPY_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h5 ${CMAKE_CURRENT_SOURCE_DIR}/*.nc)
 FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
@@ -12,9 +12,3 @@ FOREACH(CTEST ${H5TESTS})
     )
   ADD_TEST(${CTEST} ${EXECUTABLE_OUTPUT_PATH}/${CTEST})
 ENDFOREACH()
-
-
-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} ref_tst_h_compounds.h5 ref_tst_h_compounds2.h5 ref_tst_compounds.nc CMakeLists.txt Makefile.am)
-
-ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
diff --git a/h5_test/Makefile.am b/h5_test/Makefile.am
index a05b69c..18e168b 100644
--- a/h5_test/Makefile.am
+++ b/h5_test/Makefile.am
@@ -7,6 +7,7 @@
 # only use HDF5; these tests don't use netCDF at all.
 #
 # If one of these tests fails, then netCDF-4 will not work correctly.
+# Ed Hartnett, Ward Fisher
 
 # Set AM_CPPFLAGS and AM_LDFLAGS based on user choices.
 include $(top_srcdir)/lib_flags.am
@@ -15,10 +16,10 @@ include $(top_srcdir)/lib_flags.am
 # that netCDF-4 needs.
 H5TESTS = tst_h_files tst_h_files2 tst_h_files4 tst_h_atts		\
 tst_h_atts3 tst_h_atts4 tst_h_vars tst_h_vars2 tst_h_vars3 tst_h_grps	\
-tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_rd_cmp tst_h_vl	\
-tst_h_opaques tst_h_strings tst_h_strings1 tst_h_strings2 tst_h_ints	\
+tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_vl tst_h_opaques	\
+tst_h_strings tst_h_strings1 tst_h_strings2 tst_h_ints			\
 tst_h_dimscales tst_h_dimscales1 tst_h_dimscales2 tst_h_dimscales3	\
-tst_h_enums tst_h_dimscales4 #tst_h_filters
+tst_h_enums tst_h_dimscales4
 
 # If benchmarks were turned on, build and run a bunch more tests.
 if BUILD_BENCHMARKS
@@ -46,7 +47,8 @@ endif # USE_VALGRIND_TESTS
 # We must include these files in the distribution.
 EXTRA_DIST = run_par_tests.sh run_valgrind_tests.sh		\
 ref_tst_h_compounds.h5 ref_tst_h_compounds2.h5 run_par_tests.sh	\
-run_valgrind_tests.sh ref_tst_compounds.nc h5_err_macros.h CMakeLists.txt
+run_valgrind_tests.sh ref_tst_compounds.nc h5_err_macros.h	\
+CMakeLists.txt
 
 # Clean up test results.
 CLEANFILES = tst_h_*.h5
diff --git a/h5_test/Makefile.in b/h5_test/Makefile.in
index 2aac05e..aba2e6c 100644
--- a/h5_test/Makefile.in
+++ b/h5_test/Makefile.in
@@ -23,6 +23,7 @@
 # only use HDF5; these tests don't use netCDF at all.
 #
 # If one of these tests fails, then netCDF-4 will not work correctly.
+# Ed Hartnett, Ward Fisher
 
 # This is part of the netCDF package.
 # Copyright 2005 University Corporation for Atmospheric Research/Unidata
@@ -108,21 +109,18 @@ host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
 # If benchmarks were turned on, build and run a bunch more tests.
- at BUILD_BENCHMARKS_TRUE@am__append_3 = tst_h_mem
+ at BUILD_BENCHMARKS_TRUE@am__append_2 = tst_h_mem
 check_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3)
-TESTS = $(am__EXEEXT_2) $(am__append_5) $(am__append_6)
+TESTS = $(am__EXEEXT_2) $(am__append_4) $(am__append_5)
 
 # The parallel program is run from a script.
- at TEST_PARALLEL4_TRUE@am__append_4 = tst_h_par
- at TEST_PARALLEL4_TRUE@am__append_5 = run_par_tests.sh
+ at TEST_PARALLEL4_TRUE@am__append_3 = tst_h_par
+ at TEST_PARALLEL4_TRUE@am__append_4 = run_par_tests.sh
 
 # This will run a bunch of the test programs with valgrind, the memory
 # checking tool. (Valgrind must be present for this to work.)
- at USE_VALGRIND_TESTS_TRUE@am__append_6 = run_valgrind_tests.sh
+ at USE_VALGRIND_TESTS_TRUE@am__append_5 = run_valgrind_tests.sh
 subdir = h5_test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -142,7 +140,7 @@ am__EXEEXT_2 = tst_h_files$(EXEEXT) tst_h_files2$(EXEEXT) \
 	tst_h_atts4$(EXEEXT) tst_h_vars$(EXEEXT) tst_h_vars2$(EXEEXT) \
 	tst_h_vars3$(EXEEXT) tst_h_grps$(EXEEXT) \
 	tst_h_compounds$(EXEEXT) tst_h_compounds2$(EXEEXT) \
-	tst_h_wrt_cmp$(EXEEXT) tst_h_rd_cmp$(EXEEXT) tst_h_vl$(EXEEXT) \
+	tst_h_wrt_cmp$(EXEEXT) tst_h_vl$(EXEEXT) \
 	tst_h_opaques$(EXEEXT) tst_h_strings$(EXEEXT) \
 	tst_h_strings1$(EXEEXT) tst_h_strings2$(EXEEXT) \
 	tst_h_ints$(EXEEXT) tst_h_dimscales$(EXEEXT) \
@@ -211,9 +209,6 @@ tst_h_opaques_LDADD = $(LDADD)
 tst_h_par_SOURCES = tst_h_par.c
 tst_h_par_OBJECTS = tst_h_par.$(OBJEXT)
 tst_h_par_LDADD = $(LDADD)
-tst_h_rd_cmp_SOURCES = tst_h_rd_cmp.c
-tst_h_rd_cmp_OBJECTS = tst_h_rd_cmp.$(OBJEXT)
-tst_h_rd_cmp_LDADD = $(LDADD)
 tst_h_strings_SOURCES = tst_h_strings.c
 tst_h_strings_OBJECTS = tst_h_strings.$(OBJEXT)
 tst_h_strings_LDADD = $(LDADD)
@@ -277,17 +272,17 @@ SOURCES = tst_h_atts.c tst_h_atts3.c tst_h_atts4.c tst_h_compounds.c \
 	tst_h_dimscales2.c tst_h_dimscales3.c tst_h_dimscales4.c \
 	tst_h_enums.c tst_h_files.c tst_h_files2.c tst_h_files4.c \
 	tst_h_grps.c tst_h_ints.c tst_h_mem.c tst_h_opaques.c \
-	tst_h_par.c tst_h_rd_cmp.c tst_h_strings.c tst_h_strings1.c \
-	tst_h_strings2.c tst_h_vars.c tst_h_vars2.c tst_h_vars3.c \
-	tst_h_vl.c tst_h_wrt_cmp.c
+	tst_h_par.c tst_h_strings.c tst_h_strings1.c tst_h_strings2.c \
+	tst_h_vars.c tst_h_vars2.c tst_h_vars3.c tst_h_vl.c \
+	tst_h_wrt_cmp.c
 DIST_SOURCES = tst_h_atts.c tst_h_atts3.c tst_h_atts4.c \
 	tst_h_compounds.c tst_h_compounds2.c tst_h_dimscales.c \
 	tst_h_dimscales1.c tst_h_dimscales2.c tst_h_dimscales3.c \
 	tst_h_dimscales4.c tst_h_enums.c tst_h_files.c tst_h_files2.c \
 	tst_h_files4.c tst_h_grps.c tst_h_ints.c tst_h_mem.c \
-	tst_h_opaques.c tst_h_par.c tst_h_rd_cmp.c tst_h_strings.c \
-	tst_h_strings1.c tst_h_strings2.c tst_h_vars.c tst_h_vars2.c \
-	tst_h_vars3.c tst_h_vl.c tst_h_wrt_cmp.c
+	tst_h_opaques.c tst_h_par.c tst_h_strings.c tst_h_strings1.c \
+	tst_h_strings2.c tst_h_vars.c tst_h_vars2.c tst_h_vars3.c \
+	tst_h_vl.c tst_h_wrt_cmp.c
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -523,11 +518,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -550,12 +544,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -581,6 +577,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -595,6 +592,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -698,7 +696,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Set AM_CPPFLAGS and AM_LDFLAGS based on user choices.
 
@@ -706,16 +704,16 @@ AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=
 # that netCDF-4 needs.
 H5TESTS = tst_h_files tst_h_files2 tst_h_files4 tst_h_atts tst_h_atts3 \
 	tst_h_atts4 tst_h_vars tst_h_vars2 tst_h_vars3 tst_h_grps \
-	tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_rd_cmp \
-	tst_h_vl tst_h_opaques tst_h_strings tst_h_strings1 \
-	tst_h_strings2 tst_h_ints tst_h_dimscales tst_h_dimscales1 \
-	tst_h_dimscales2 tst_h_dimscales3 tst_h_enums tst_h_dimscales4 \
-	$(am__append_3)
+	tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_vl \
+	tst_h_opaques tst_h_strings tst_h_strings1 tst_h_strings2 \
+	tst_h_ints tst_h_dimscales tst_h_dimscales1 tst_h_dimscales2 \
+	tst_h_dimscales3 tst_h_enums tst_h_dimscales4 $(am__append_2)
 
 # We must include these files in the distribution.
 EXTRA_DIST = run_par_tests.sh run_valgrind_tests.sh		\
 ref_tst_h_compounds.h5 ref_tst_h_compounds2.h5 run_par_tests.sh	\
-run_valgrind_tests.sh ref_tst_compounds.nc h5_err_macros.h CMakeLists.txt
+run_valgrind_tests.sh ref_tst_compounds.nc h5_err_macros.h	\
+CMakeLists.txt
 
 
 # Clean up test results.
@@ -840,10 +838,6 @@ tst_h_par$(EXEEXT): $(tst_h_par_OBJECTS) $(tst_h_par_DEPENDENCIES) $(EXTRA_tst_h
 	@rm -f tst_h_par$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_h_par_OBJECTS) $(tst_h_par_LDADD) $(LIBS)
 
-tst_h_rd_cmp$(EXEEXT): $(tst_h_rd_cmp_OBJECTS) $(tst_h_rd_cmp_DEPENDENCIES) $(EXTRA_tst_h_rd_cmp_DEPENDENCIES) 
-	@rm -f tst_h_rd_cmp$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(tst_h_rd_cmp_OBJECTS) $(tst_h_rd_cmp_LDADD) $(LIBS)
-
 tst_h_strings$(EXEEXT): $(tst_h_strings_OBJECTS) $(tst_h_strings_DEPENDENCIES) $(EXTRA_tst_h_strings_DEPENDENCIES) 
 	@rm -f tst_h_strings$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_h_strings_OBJECTS) $(tst_h_strings_LDADD) $(LIBS)
@@ -901,7 +895,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_mem.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_opaques.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_par.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_rd_cmp.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_strings.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_strings1.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_strings2.Po at am__quote@
@@ -1225,13 +1218,6 @@ tst_h_wrt_cmp.log: tst_h_wrt_cmp$(EXEEXT)
 	--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_h_rd_cmp.log: tst_h_rd_cmp$(EXEEXT)
-	@p='tst_h_rd_cmp$(EXEEXT)'; \
-	b='tst_h_rd_cmp'; \
-	$(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_h_vl.log: tst_h_vl$(EXEEXT)
 	@p='tst_h_vl$(EXEEXT)'; \
 	b='tst_h_vl'; \
diff --git a/h5_test/tst_h_atts3.c b/h5_test/tst_h_atts3.c
index 2a4fe9a..d80f41e 100644
--- a/h5_test/tst_h_atts3.c
+++ b/h5_test/tst_h_atts3.c
@@ -35,7 +35,6 @@ int
 main()
 {
    printf("\n*** Checking HDF5 attribute functions some more.\n");
-#ifdef EXTRA_TESTS
    printf("*** Creating tst_xplatform2_3.nc with HDF only...");
    {
       hid_t fapl_id, fcpl_id;
@@ -308,6 +307,5 @@ main()
 	 free(vc_out[i].p);
    }
    SUMMARIZE_ERR;
-#endif /* EXTRA_TESTS */
    FINAL_RESULTS;
 }
diff --git a/h5_test/tst_h_atts4.c b/h5_test/tst_h_atts4.c
index eca0116..86a7b86 100644
--- a/h5_test/tst_h_atts4.c
+++ b/h5_test/tst_h_atts4.c
@@ -36,7 +36,6 @@ int
 main()
 {
    printf("\n*** Checking HDF5 attribute functions for memory leaks.\n");
-#ifdef EXTRA_TESTS
    printf("*** Checking vlen of compound file...");
    {
 #define NUM_OBJ_2 2
@@ -181,6 +180,5 @@ main()
       free(vc_out);
    }
    SUMMARIZE_ERR;
-#endif /* EXTRA_TESTS */
    FINAL_RESULTS;
 }
diff --git a/h5_test/tst_h_dimscales.c b/h5_test/tst_h_dimscales.c
index 73c817d..c6c4c0b 100644
--- a/h5_test/tst_h_dimscales.c
+++ b/h5_test/tst_h_dimscales.c
@@ -85,7 +85,7 @@ rec_scan_group(hid_t grpid)
 	    }
 	    else
 	    {
-	       int visitor_data = 0;
+		hid_t visitor_data = 0;
 
 	       /* Here's how to get the number of scales attached
 		* to the dataset's dimension 0. */
@@ -362,7 +362,6 @@ main()
    }
 
    SUMMARIZE_ERR;
-#ifdef EXTRA_TESTS
    printf("*** Checking that unlimited dimscale file can be read...");
 
    {
@@ -379,7 +378,7 @@ main()
       if ((grpid = H5Gopen(fileid, GRP_NAME)) < 0) ERR;
 
       /* Loop through datasets to find variables. */
-      if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
+      if (H5Gget_num_objs(grpid, (hsize_t *)&num_obj) < 0) ERR;
       for (i=0; i<num_obj; i++)
       {
 	 /* Get the type (i.e. group, dataset, etc.), and the name of
@@ -426,7 +425,7 @@ main()
 	       else
 	       {
 		  char label[STR_LEN+1];
-		  int visitor_data = 0;
+		  hid_t visitor_data = 0;
 
 		  /* Here's how to get the number of scales attached
 		   * to the dataset's dimension 0. */
@@ -617,7 +616,7 @@ main()
 	       else
 	       {
 		  char label[STR_LEN+1];
-		  int visitor_data = 0;
+		  hid_t visitor_data = 0;
 
 		  /* SHould have these dimensions... */
 		  if (dims[TIME_DIM] != 0 || dims[LAT_DIM] != LAT_LEN ||
@@ -780,6 +779,5 @@ main()
    }
 
    SUMMARIZE_ERR;
-#endif
    FINAL_RESULTS;
 }
diff --git a/h5_test/tst_h_dimscales1.c b/h5_test/tst_h_dimscales1.c
index da8b12c..6bc85f2 100644
--- a/h5_test/tst_h_dimscales1.c
+++ b/h5_test/tst_h_dimscales1.c
@@ -6,13 +6,13 @@
    but they use HDF5 the same way that netCDF-4 does, so if these
    tests don't work, than netCDF-4 won't work either.
 
-   $Id: tst_h_dimscales1.c,v 1.2 2010/06/01 15:34:51 ed Exp $
+   @author Ed Hartnett
 */
 #include "h5_err_macros.h"
 #include <hdf5.h>
 #include <H5DSpublic.h>
 
-#define FILE_NAME "tst_h_dimscales.h5"
+#define FILE_NAME "tst_h_dimscales1.h5"
 int
 main()
 {
@@ -36,35 +36,35 @@ main()
       hsize_t dimscale_dims[1] = {DIM1_LEN};
 
       /* Open file and create group. */
-      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, 
-			      H5P_DEFAULT)) < 0) ERR;
+      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
+                              H5P_DEFAULT)) < 0) ERR;
       if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR;
-      
+
       /* Create our dimension scale. Use the built-in NAME attribute
        * on the dimscale. */
-      if ((dimscale_spaceid = H5Screate_simple(1, dimscale_dims, 
-					       dimscale_dims)) < 0) ERR;
-      if ((dimscaleid = H5Dcreate(grpid, DIMSCALE_NAME, H5T_NATIVE_INT, 
-				  dimscale_spaceid, H5P_DEFAULT)) < 0) ERR;
+      if ((dimscale_spaceid = H5Screate_simple(1, dimscale_dims,
+                                               dimscale_dims)) < 0) ERR;
+      if ((dimscaleid = H5Dcreate(grpid, DIMSCALE_NAME, H5T_NATIVE_INT,
+                                  dimscale_spaceid, H5P_DEFAULT)) < 0) ERR;
       if (H5DSset_scale(dimscaleid, NAME_ATTRIBUTE) < 0) ERR;
 
       /* Create a 1D variable which uses the dimscale. Attach a label
        * to this scale. */
       if ((var1_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
-      if ((var1_datasetid = H5Dcreate(grpid, VAR1_NAME, H5T_NATIVE_INT, 
-				      var1_spaceid, H5P_DEFAULT)) < 0) ERR;
+      if ((var1_datasetid = H5Dcreate(grpid, VAR1_NAME, H5T_NATIVE_INT,
+                                      var1_spaceid, H5P_DEFAULT)) < 0) ERR;
       if (H5DSattach_scale(var1_datasetid, dimscaleid, 0) < 0) ERR;
       if (H5DSset_label(var1_datasetid, 0, FIFTIES_SONG) < 0) ERR;
 
       /* Create a 1D variabls that doesn't use the dimension scale. */
-      if ((var2_datasetid = H5Dcreate(grpid, VAR2_NAME, H5T_NATIVE_INT, 
-				      var1_spaceid, H5P_DEFAULT)) < 0) ERR;
+      if ((var2_datasetid = H5Dcreate(grpid, VAR2_NAME, H5T_NATIVE_INT,
+                                      var1_spaceid, H5P_DEFAULT)) < 0) ERR;
 
       /* Create a 2D dataset which uses the scale for one of its
        * dimensions. */
       if ((var3_spaceid = H5Screate_simple(2, dims, dims)) < 0) ERR;
-      if ((var3_datasetid = H5Dcreate(grpid, VAR3_NAME, H5T_NATIVE_INT, 
-				      var3_spaceid, H5P_DEFAULT)) < 0) ERR;
+      if ((var3_datasetid = H5Dcreate(grpid, VAR3_NAME, H5T_NATIVE_INT,
+                                      var3_spaceid, H5P_DEFAULT)) < 0) ERR;
       if (H5DSattach_scale(var3_datasetid, dimscaleid, 0) < 0) ERR;
 
       /* Detach the scale. */
@@ -72,16 +72,15 @@ main()
 
       /* Close up the shop. */
       if (H5Dclose(dimscaleid) < 0 ||
-	  H5Dclose(var1_datasetid) < 0 ||
-	  H5Dclose(var2_datasetid) < 0 ||
-	  H5Dclose(var3_datasetid) < 0 ||
-	  H5Sclose(var1_spaceid) < 0 ||
-	  H5Sclose(var3_spaceid) < 0 ||
-	  H5Sclose(dimscale_spaceid) < 0 ||
+          H5Dclose(var1_datasetid) < 0 ||
+          H5Dclose(var2_datasetid) < 0 ||
+          H5Dclose(var3_datasetid) < 0 ||
+          H5Sclose(var1_spaceid) < 0 ||
+          H5Sclose(var3_spaceid) < 0 ||
+          H5Sclose(dimscale_spaceid) < 0 ||
 	  H5Gclose(grpid) < 0 ||
-	  H5Fclose(fileid) < 0) ERR;
+          H5Fclose(fileid) < 0) ERR;
    }
    SUMMARIZE_ERR;
    FINAL_RESULTS;
 }
-
diff --git a/h5_test/tst_h_files.c b/h5_test/tst_h_files.c
index 92dff86..fa95b6c 100644
--- a/h5_test/tst_h_files.c
+++ b/h5_test/tst_h_files.c
@@ -32,7 +32,6 @@ main()
       int obj_class;
       char obj_name[STR_LEN + 1];
       H5T_class_t class;
-      size_t type_size;
       int j, k;
       hid_t tmp1;
 
@@ -237,7 +236,7 @@ main()
    printf("*** large file test for HDF5...");
    {
       hid_t fapl_id, fcpl_id, fileid, grpid, spaceid, datasetid;
-      hid_t dim1_dimscaleid, dim2_dimscaleid, plistid, datasetid2, file_spaceid;
+      hid_t dim1_dimscaleid, dim2_dimscaleid, plistid, file_spaceid;
       hid_t mem_spaceid, xfer_plistid, native_typeid;
       hsize_t *chunksize, dims[1], maxdims[1], *dimsize, *maxdimsize;
       hsize_t fdims[MAX_DIMS], fmaxdims[MAX_DIMS];
diff --git a/h5_test/tst_h_filters.c b/h5_test/tst_h_filters.c
deleted file mode 100644
index cccee44..0000000
--- a/h5_test/tst_h_filters.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#include "err_macros.h"
-#include <hdf5.h>
-#include <H5DSpublic.h>
-
-#define FILE_NAME "tst_h_filters.h5"
-#define DIM_LEN 10
-#define NDIMS 1
-#define VAR1_NAME "very_important_data"
-#define FILTER_NAME "ed_compress_2000"
-#define FILTER_ID (H5Z_FILTER_RESERVED + 1)
-#define NUM_FILTER_PARAM 2
-
-size_t 
-ed_compress_2000_filter(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], 
-			size_t nbytes, size_t *buf_size, void **buf) 
-{
-   char *new_buf;
-   char *old_buf = (char *)*buf;
-   int i;
-   
-/*   printf("ed_compress_2000_filter called: type 0x%x bits %d nbytes %d buf_size %d\n", 
-     cd_values[0], cd_values[1], nbytes, *buf_size);*/
-   if (flags & H5Z_FLAG_REVERSE)
-   {
-/*      printf("reading\n");*/
-      if (!(new_buf = malloc(*buf_size * 2))) ERR;
-      for (i = 0; i < *buf_size * 2; i++)
-	 new_buf[i] = old_buf[i/2];
-      free(*buf);
-      *buf = new_buf;
-      *buf_size *= 2;   
-   }
-   else
-   {
-/*      printf("writing\n");*/
-      if (!(new_buf = malloc(*buf_size/2))) ERR;
-      for (i = 0; i < *buf_size/2; i++)
-	 new_buf[i] = old_buf[i*2];
-      free(*buf);
-      *buf = new_buf;
-      *buf_size /= 2;
-   }
-   /* Return number of bytes in buf for success, 0 for failure. */
-   return *buf_size;
-}
-
-int
-main()
-{
-   printf("\n*** Checking HDF5 filter.\n");
-   printf("*** Checking EDPEG2000 compression filter...");
-   {
-      hid_t fileid, grpid, spaceid, var1_id, create_propid;
-      hsize_t dims[NDIMS] = {DIM_LEN}, chunksize = 1;
-      int data_out[DIM_LEN], data_in[DIM_LEN];
-      H5Z_class2_t fclass;
-      unsigned int filter_param[NUM_FILTER_PARAM] = {H5T_NATIVE_INT32, 12};
-      int i;
-
-      /* Initialize some data. */
-      for (i = 0; i < DIM_LEN; i++)
-	 data_out[i] = i;
-
-      /* Create file. */
-      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
-                              H5P_DEFAULT)) < 0) ERR;
-      if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
-
-      /* Register filter. */
-      fclass.version = H5Z_CLASS_T_VERS;
-      fclass.id = FILTER_ID;
-      fclass.encoder_present = 1;
-      fclass.decoder_present = 1;
-      fclass.can_apply = NULL;
-      fclass.set_local = NULL;
-      fclass.filter = &ed_compress_2000_filter;
-      if (H5Zregister(&fclass) < 0) ERR;
-
-      /* Create dataset. */
-      if ((spaceid = H5Screate_simple(NDIMS, dims, dims)) < 0) ERR;
-      if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
-      if (H5Pset_chunk(create_propid, NDIMS, &chunksize) < 0) ERR;
-      if (H5Pset_filter(create_propid, FILTER_ID, H5Z_FLAG_OPTIONAL, 
-			NUM_FILTER_PARAM, filter_param) < 0) ERR;
-      if ((var1_id = H5Dcreate2(grpid, VAR1_NAME, H5T_NATIVE_INT32, spaceid, 
-				H5P_DEFAULT, create_propid, H5P_DEFAULT)) < 0) ERR;
-      if (H5Dwrite(var1_id, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_out) < 0) ERR;
-      if (H5Sclose(spaceid) < 0) ERR;
-      if (H5Dclose(var1_id) < 0) ERR;
-      if (H5Gclose(grpid) < 0) ERR;
-      if (H5Fclose(fileid) < 0) ERR;
-
-      /* Read file. */
-      if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
-      if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
-      if ((var1_id = H5Dopen2(grpid, VAR1_NAME, H5P_DEFAULT)) < 0) ERR;
-      if (H5Dread(var1_id, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_in) < 0) ERR;
-      /*for (i = 0; i < DIM_LEN; i++) */
-	 /*printf("new data[%d]=%d\n", i, data_in[i]);*/
-
-      if (H5Dclose(var1_id) < 0) ERR;
-      if (H5Gclose(grpid) < 0) ERR;
-      if (H5Fclose(fileid) < 0) ERR;
-   }
-   SUMMARIZE_ERR;
-   FINAL_RESULTS;
-}
diff --git a/h5_test/tst_h_rd_cmp.c b/h5_test/tst_h_rd_cmp.c
deleted file mode 100644
index b46daff..0000000
--- a/h5_test/tst_h_rd_cmp.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This is part of the netCDF package.
-   Copyright 2007 University Corporation for Atmospheric Research/Unidata
-   See COPYRIGHT file for conditions of use.
-
-   Test HDF5 compound types. 
-*/
-
-#include "h5_err_macros.h"
-#include <hdf5.h>
-
-#define FILE_NAME "tst_h_wrt_cmp.h5"
-#define DIM1_LEN 3
-#define COMPOUND_NAME "cmp"
-#define VAR_NAME "var"
-
-int
-main()
-{
-   hid_t fileid, access_plist, spaceid, typeid;
-   hid_t datasetid;
-   struct s1 {
-	 unsigned char c1;
-	 double d;
-   } data[DIM1_LEN];
-   int i;
-
-   printf("\n*** Checking HDF5 compound types (we're almost there kids).\n");
-   printf("*** Checking packing of HDF5 compound types...");
-   
-   /* Open file. */
-   if ((access_plist = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
-   if (H5Pset_fclose_degree(access_plist, H5F_CLOSE_STRONG)) ERR;
-   if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, access_plist)) < 0) ERR;
-
-   /* Open dataset. */
-   if ((datasetid = H5Dopen1(fileid, VAR_NAME)) < 0) ERR;
-
-   /* Check space. */
-   if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
-   if (H5Sget_simple_extent_ndims(spaceid) != 1) ERR;
-   if (H5Sget_simple_extent_npoints(spaceid) != DIM1_LEN) ERR;
-
-   /* Get type. */
-   if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
-
-/*   if ((native_type = H5Tget_native_type(typeid, H5T_DIR_DEFAULT)) < 0) ERR;*/
-
-   /* Read the data. */
-   if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
-	       data) < 0) ERR;
-
-   /* Check the data. */
-   for (i=0; i<DIM1_LEN; i++)
-      if (data[i].c1 != 126 || data[i].d != -9999999) ERR;
-
-   /* Release all resources. */
-   if (H5Fclose(fileid) < 0) ERR;
-
-   SUMMARIZE_ERR;
-
-   FINAL_RESULTS;
-}
diff --git a/h5_test/tst_h_wrt_cmp.c b/h5_test/tst_h_wrt_cmp.c
index 11b0ef1..a9f139e 100644
--- a/h5_test/tst_h_wrt_cmp.c
+++ b/h5_test/tst_h_wrt_cmp.c
@@ -2,7 +2,8 @@
    Copyright 2007 University Corporation for Atmospheric Research/Unidata
    See COPYRIGHT file for conditions of use.
 
-   Test HDF5 compound types. 
+   Test HDF5 compound types.
+   Ed Hartnett
 */
 
 #include "h5_err_macros.h"
@@ -20,7 +21,7 @@ main()
    hid_t datasetid;
    hsize_t dims[1];
    char dummy[] = "                                 ";
-   struct s1 
+   struct s1
    {
       unsigned char c1;
       double d;
@@ -42,37 +43,97 @@ main()
 
    printf("\n*** Checking HDF5 compound types (even more so).\n");
    printf("*** Checking packing of HDF5 compound types...");
-   
-   /* Open file and create group. */
-   if ((access_plist = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
-   if (H5Pset_fclose_degree(access_plist, H5F_CLOSE_STRONG)) ERR;
-   if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, 
-			   access_plist)) < 0) ERR;
-
-   /* Create a simple compound type. */
-   if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
-   if (H5Tinsert(typeid, "c1", HOFFSET(struct s1, c1), H5T_NATIVE_UCHAR) < 0) ERR;
-   if (H5Tinsert(typeid, "d", HOFFSET(struct s1, d), H5T_NATIVE_DOUBLE) < 0) ERR;
-   if (H5Tcommit(fileid, COMPOUND_NAME, typeid) < 0) ERR;
-
-   /* Create a space. */
-   dims[0] = DIM1_LEN;
-   if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
-
-   /* Create a dataset of this compound type. */
-   if ((datasetid = H5Dcreate(fileid, VAR_NAME, typeid, spaceid, 
-			      H5P_DEFAULT)) < 0) ERR;
-
-   /* Write some data. */
-   if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
-		data) < 0) ERR;
-
-   /* Release all resources. */
-   if (H5Pclose(access_plist) < 0) ERR;
-   if (H5Tclose(typeid) < 0) ERR;
-   if (H5Sclose(spaceid) < 0) ERR;
-   if (H5Fclose(fileid) < 0) ERR;
+   {
+      /* Open file and create group. */
+      if ((access_plist = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
+      if (H5Pset_fclose_degree(access_plist, H5F_CLOSE_STRONG)) ERR;
+      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
+                              access_plist)) < 0) ERR;
+
+      /* Create a simple compound type. */
+      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
+      if (H5Tinsert(typeid, "c1", HOFFSET(struct s1, c1), H5T_NATIVE_UCHAR) < 0) ERR;
+      if (H5Tinsert(typeid, "d", HOFFSET(struct s1, d), H5T_NATIVE_DOUBLE) < 0) ERR;
+      if (H5Tcommit(fileid, COMPOUND_NAME, typeid) < 0) ERR;
+
+      /* Create a space. */
+      dims[0] = DIM1_LEN;
+      if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
+
+      /* Create a dataset of this compound type. */
+      if ((datasetid = H5Dcreate(fileid, VAR_NAME, typeid, spaceid,
+                                 H5P_DEFAULT)) < 0) ERR;
+
+      /* Write some data. */
+      if (H5Dwrite(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+                   data) < 0) ERR;
+
+      /* Release all resources. */
+      if (H5Pclose(access_plist) < 0) ERR;
+      if (H5Tclose(typeid) < 0) ERR;
+      if (H5Sclose(spaceid) < 0) ERR;
+      if (H5Fclose(fileid) < 0) ERR;
+   }
+   SUMMARIZE_ERR;
+   printf("*** Checking packing of HDF5 compound types...");
+   {
+      /* Open file. */
+      if ((access_plist = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
+      if (H5Pset_fclose_degree(access_plist, H5F_CLOSE_STRONG)) ERR;
+      if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, access_plist)) < 0) ERR;
+
+      /* Open dataset. */
+      if ((datasetid = H5Dopen1(fileid, VAR_NAME)) < 0) ERR;
+
+      /* Check space. */
+      if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
+      if (H5Sget_simple_extent_ndims(spaceid) != 1) ERR;
+      if (H5Sget_simple_extent_npoints(spaceid) != DIM1_LEN) ERR;
+
+      /* Get type. */
+      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
 
+      /* Read the data. */
+      if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+                  data) < 0) ERR;
+
+      /* Check the data. */
+      for (i=0; i<DIM1_LEN; i++)
+         if (data[i].c1 != 126 || data[i].d != -9999999) ERR;
+
+      /* Release all resources. */
+      if (H5Fclose(fileid) < 0) ERR;
+   }
+   SUMMARIZE_ERR;
+   printf("*** Checking packing of HDF5 compound types...");
+   {
+      /* Open file. */
+      if ((access_plist = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
+      if (H5Pset_fclose_degree(access_plist, H5F_CLOSE_STRONG)) ERR;
+      if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, access_plist)) < 0) ERR;
+
+      /* Open dataset. */
+      if ((datasetid = H5Dopen1(fileid, VAR_NAME)) < 0) ERR;
+
+      /* Check space. */
+      if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
+      if (H5Sget_simple_extent_ndims(spaceid) != 1) ERR;
+      if (H5Sget_simple_extent_npoints(spaceid) != DIM1_LEN) ERR;
+
+      /* Get type. */
+      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
+
+      /* Read the data. */
+      if (H5Dread(datasetid, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+                  data) < 0) ERR;
+
+      /* Check the data. */
+      for (i=0; i<DIM1_LEN; i++)
+         if (data[i].c1 != 126 || data[i].d != -9999999) ERR;
+
+      /* Release all resources. */
+      if (H5Fclose(fileid) < 0) ERR;
+   }
    SUMMARIZE_ERR;
    FINAL_RESULTS;
 }
diff --git a/include/Makefile.am b/include/Makefile.am
index b51d7e5..59c058a 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -18,8 +18,8 @@ noinst_HEADERS = nc_logging.h nc_tests.h fbits.h nc.h	\
 nclist.h ncuri.h ncutf8.h ncdispatch.h ncdimscale.h		\
 netcdf_f.h err_macros.h ncbytes.h nchashmap.h ceconstraints.h rnd.h	\
 nclog.h ncconfigure.h nc4internal.h nctime.h nc3internal.h \
-onstack.h nc_hashmap.h ncrc.h ncoffsets.h nctestserver.h \
-nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h
+onstack.h nc_hashmap.h ncrc.h ncauth.h ncoffsets.h nctestserver.h \
+nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h ncfilter.h
 
 if USE_DAP
 noinst_HEADERS += ncdap.h
diff --git a/include/Makefile.in b/include/Makefile.in
index 224794f..cdb6e5d 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -165,9 +165,9 @@ am__noinst_HEADERS_DIST = nc_logging.h nc_tests.h fbits.h nc.h \
 	nclist.h ncuri.h ncutf8.h ncdispatch.h ncdimscale.h netcdf_f.h \
 	err_macros.h ncbytes.h nchashmap.h ceconstraints.h rnd.h \
 	nclog.h ncconfigure.h nc4internal.h nctime.h nc3internal.h \
-	onstack.h nc_hashmap.h ncrc.h ncoffsets.h nctestserver.h \
-	nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h ncdap.h \
-	ncaux.h
+	onstack.h nc_hashmap.h ncrc.h ncauth.h ncoffsets.h \
+	nctestserver.h nc4dispatch.h nc3dispatch.h ncexternl.h \
+	ncwinpath.h ncfilter.h ncdap.h ncaux.h
 HEADERS = $(include_HEADERS) $(noinst_HEADERS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
@@ -198,7 +198,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -221,12 +220,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -252,6 +253,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -266,6 +268,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -375,9 +378,9 @@ noinst_HEADERS = nc_logging.h nc_tests.h fbits.h nc.h nclist.h ncuri.h \
 	ncutf8.h ncdispatch.h ncdimscale.h netcdf_f.h err_macros.h \
 	ncbytes.h nchashmap.h ceconstraints.h rnd.h nclog.h \
 	ncconfigure.h nc4internal.h nctime.h nc3internal.h onstack.h \
-	nc_hashmap.h ncrc.h ncoffsets.h nctestserver.h nc4dispatch.h \
-	nc3dispatch.h ncexternl.h ncwinpath.h $(am__append_3) \
-	$(am__append_4)
+	nc_hashmap.h ncrc.h ncauth.h ncoffsets.h nctestserver.h \
+	nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h ncfilter.h \
+	$(am__append_3) $(am__append_4)
 EXTRA_DIST = CMakeLists.txt XGetopt.h netcdf_meta.h.in
 all: all-am
 
diff --git a/include/err_macros.h b/include/err_macros.h
index 3c7ebe4..e87ace2 100644
--- a/include/err_macros.h
+++ b/include/err_macros.h
@@ -4,6 +4,8 @@
 
    Common includes, defines, etc., for test code in the libsrc4 and
    nc_test4 directories.
+
+   Ed Hartnett, Russ Rew, Dennis Heimbigner
 */
 
 #ifndef _ERR_MACROS_H
@@ -20,12 +22,6 @@
  * generally cosists of several sets of tests. */
 static int total_err = 0, err = 0;
 
-#if 0
-/* This is handy for print statements. */
-static char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4", 
-			      "netCDF-4 classic model"};
-#endif
-
 /* This macro prints an error message with line number and name of
  * test program. */
 #define ERR do { \
@@ -33,18 +29,12 @@ fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
 err++; \
 fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
 	__FILE__, __LINE__);				    \
+fflush(stderr);                                             \
 return 2;                                                   \
 } while (0)
 
-/* This macro prints an error message with line number and name of
- * test program, and then exits the program. */
-
-#define ERR_RET do { \
-fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
-fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
-	__FILE__, __LINE__);				    \
-return 2;                                                   \
-} while (0)
+/* Duplicate with different name. */
+#define ERR_RET ERR
 
 #define ERR_GOTO do { \
 fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
@@ -58,13 +48,12 @@ int ERR_report(int stat, const char* file, int line)
     fflush(stdout);
     fprintf(stderr, "Sorry! Unexpected result, %s, line: %d; status=%d\n",
 	file,line,stat);
-    fflush(stdout);
+    fflush(stderr);
     return 1;
 }
 
 #define ERRSTAT(stat) {err+=ERR_report(stat,__FILE__,__LINE__);}
 
-
 /* After a set of tests, report the number of errors, and increment
  * total_err. */
 #define SUMMARIZE_ERR do { \
@@ -78,12 +67,6 @@ int ERR_report(int stat, const char* file, int line)
       printf("ok.\n"); \
 } while (0)
 
-/* If extra memory debugging is not in use (as it usually isn't),
- * define away the nc_exit function, which may be in some tests. */
-#ifndef EXTRA_MEM_DEBUG
-#define nc_exit()
-#endif
-
 /* This macro prints out our total number of errors, if any, and exits
  * with a 0 if there are not, or a 2 if there were errors. Make will
  * stop if a non-zero value is returned from a test program. */
diff --git a/include/nc.h b/include/nc.h
index c4cddde..77259b4 100644
--- a/include/nc.h
+++ b/include/nc.h
@@ -27,6 +27,7 @@ typedef struct NC {
 	void* dispatchdata; /*per-'file' data; points to e.g. NC3_INFO data*/
 	char* path;
 	int   mode; /* as provided to nc_open/nc_create */
+        int   model; /* as determined by libdispatch/dfile.c */
 #ifdef USE_REFCOUNT
 	int   refcount; /* To enable multiple name-based opens */
 #endif
@@ -68,6 +69,8 @@ extern int nc__pseudofd(void);
 /* This function gets a current default create flag */
 extern int nc_get_default_format(void);
 
+extern int NC_check_file_type(const char *path, int flags, void *parameters, int* model, int* version);
+
 extern int add_to_NCList(NC*);
 extern void del_from_NCList(NC*);/* does not free object */
 extern NC* find_in_NCList(int ext_ncid);
@@ -78,7 +81,7 @@ extern int iterate_NCList(int i,NC**); /* Walk from 0 ...; ERANGE return => stop
 
 /* Defined in nc.c */
 extern void free_NC(NC*);
-extern int new_NC(struct NC_Dispatch*, const char*, int, NC**);
+extern int new_NC(struct NC_Dispatch*, const char*, int, int, NC**);
 
 /* Defined in nc.c */
 extern int ncdebug;
diff --git a/include/nc4dispatch.h b/include/nc4dispatch.h
index 2b6575c..b3827d5 100644
--- a/include/nc4dispatch.h
+++ b/include/nc4dispatch.h
@@ -126,7 +126,8 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp, 
                int *no_fill, void *fill_valuep, int *endiannessp, 
-	       int *options_maskp, int *pixels_per_blockp);
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+	       );
 
 extern int
 NC4_inq_varid(int ncid, const char *name, int *varidp);
@@ -250,6 +251,9 @@ extern int
 NC4_def_var_endian(int, int, int);
 
 extern int
+NC4_def_var_filter(int, int, unsigned int, size_t, const unsigned int*);
+
+extern int
 NC4_set_var_chunk_cache(int, int, size_t, size_t, float);
 
 extern int
diff --git a/include/nc4internal.h b/include/nc4internal.h
index aec7cb0..5337508 100644
--- a/include/nc4internal.h
+++ b/include/nc4internal.h
@@ -102,6 +102,12 @@ typedef enum {VAR, DIM, ATT} NC_OBJ_T;
  * as the netCDF dimid. */
 #define NC_DIMID_ATT_NAME "_Netcdf4Dimid"
 
+/** This is the name of the class HDF5 dimension scale attribute. */
+#define HDF5_DIMSCALE_CLASS_ATT_NAME "CLASS"
+
+/** This is the name of the name HDF5 dimension scale attribute. */
+#define HDF5_DIMSCALE_NAME_ATT_NAME "NAME"
+
 /* Boolean type, to make the code easier to read */
 typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t;
 
@@ -126,7 +132,7 @@ typedef struct NC_DIM_INFO
    nc_bool_t unlimited;         /* True if the dimension is unlimited */
    nc_bool_t extended;          /* True if the dimension needs to be extended */
    nc_bool_t too_long;          /* True if len is too big to fit in local size_t. */
-   hid_t hdf_dimscaleid;
+   hid_t hdf_dimscaleid;        /* Non-zero if a DIM_WITHOUT_VARIABLE dataset is in use (no coord var). */
    HDF5_OBJID_T hdf5_objid;
    struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */
 } NC_DIM_INFO_T;
@@ -179,9 +185,6 @@ typedef struct NC_VAR_INFO
    int deflate_level;
    nc_bool_t shuffle;           /* True if var has shuffle filter applied */
    nc_bool_t fletcher32;        /* True if var has fletcher32 filter applied */
-   nc_bool_t szip;              /* True if var has szip filter applied */
-   int options_mask;
-   int pixels_per_block;
    size_t chunk_cache_size, chunk_cache_nelems;
    float chunk_cache_preemption;
 #ifdef USE_HDF4
@@ -189,7 +192,11 @@ typedef struct NC_VAR_INFO
    int sdsid;
    int hdf4_data_type;
 #endif /* USE_HDF4 */
-   /* Stuff below for diskless data files. */
+   /* Stuff for arbitrary filters */
+   unsigned int filterid;
+   size_t nparams;
+   unsigned int* params;
+   /* Stuff for diskless data files. */
    void *diskless_data;
 } NC_VAR_INFO_T;
 
@@ -343,6 +350,7 @@ int nc4_convert_type(const void *src, void *dest,
 /* These functions do HDF5 things. */
 int rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
 int rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
+int delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim);
 int nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset);
 int nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
 		 const size_t *countp, nc_type xtype, int is_long, void *op);
diff --git a/include/nc_tests.h b/include/nc_tests.h
index efbc09b..d89b915 100644
--- a/include/nc_tests.h
+++ b/include/nc_tests.h
@@ -1,11 +1,12 @@
-/** \internal
-\file
-Common includes, defines, etc., for test code in the libsrc4 and
-nc_test4 directories.
-
-This is part of the netCDF package. Copyright 2005 University
-Corporation for Atmospheric Research/Unidata. See \ref copyright file
-for conditions of use.
+/* This is part of the netCDF package. Copyright 2005 University
+ * Corporation for Atmospheric Research/Unidata. See \ref copyright
+ * file for conditions of use. */
+/** @internal @file
+ *
+ * Common includes, defines, etc., for test code in the libsrc4 and
+ * nc_test4 directories.
+ *
+ * @author Ed Hartnett, Denis Heimbigner, Ward Fisher
 */
 
 #ifndef _NC_TESTS_H
@@ -22,8 +23,11 @@ for conditions of use.
 #include "netcdf.h"
 //#include "err_macros.h"
 
+/** NC_MAX_DIMS for tests.  Allows different NC_MAX_DIMS values
+ * without breaking this test with a heap or stack overflow. */
+#define NC_TESTS_MAX_DIMS 1024
 
-#define NC_TESTS_MAX_DIMS 1024 /**< NC_MAX_DIMS for tests.  Allows different NC_MAX_DIMS values without breaking this test with a heap or stack overflow. */
+#define MAX_NUM_FORMATS 5 /**< Max number of available binary formats. */
 
 /** Useful define for tests. */
 /** \{ */
@@ -35,6 +39,9 @@ for conditions of use.
 #define THIRTY_TWO_MEG (SIXTEEN_MEG * 2)
 #define SIXTY_FOUR_MEG (SIXTEEN_MEG * 4)
 #define ONE_TWENTY_EIGHT_MEG (SIXTEEN_MEG * 8)
+#define TEST_VAL_42 42
+#define BAD_NAME "dd//d/  "
+#define NUM_NETCDF_TYPES 12
 /** \} */
 
 #ifdef USE_PNETCDF
diff --git a/include/ncauth.h b/include/ncauth.h
new file mode 100644
index 0000000..a3087eb
--- /dev/null
+++ b/include/ncauth.h
@@ -0,0 +1,58 @@
+/*
+Copyright (c) 1998-2017 University Corporation for Atmospheric Research/Unidata
+See LICENSE.txt for license information.
+*/
+
+/*
+Common authorization tracking.
+Currently for DAP2 and DAP4 protocols.
+Every curl connection will need a copy of this.
+*/
+
+#ifndef NCAUTH_H
+#define NCAUTH_H
+
+/* Need these support includes */
+#include "ncrc.h"
+
+typedef struct NCauth {
+    struct curlflags {
+        int proto_https; /* is https: supported? */
+	int compress; /*CURLOPT_ENCODING*/
+	int verbose; /*CURLOPT_ENCODING*/
+	int timeout; /*CURLOPT_TIMEOUT*/
+	int maxredirs; /*CURLOPT_MAXREDIRS*/
+	char* useragent; /*CURLOPT_USERAGENT*/
+	int cookiejarcreated;
+	char* cookiejar; /*CURLOPT_COOKIEJAR,CURLOPT_COOKIEFILE*/
+	char* netrc; /*CURLOPT_NETRC,CURLOPT_NETRC_FILE*/
+    } curlflags;
+    struct ssl {
+	int   verifypeer; /* CURLOPT_SSL_VERIFYPEER;
+                             do not do this when cert might be self-signed
+                             or temporarily incorrect */
+	int   verifyhost; /* CURLOPT_SSL_VERIFYHOST; for client-side verification */
+        char* certificate; /*CURLOPT_SSLCERT*/
+	char* key; /*CURLOPT_SSLKEY*/
+	char* keypasswd; /*CURLOPT_SSLKEYPASSWD*/
+        char* cainfo; /* CURLOPT_CAINFO; certificate authority */
+	char* capath;  /*CURLOPT_CAPATH*/
+    } ssl;
+    struct proxy {
+	char *host; /*CURLOPT_PROXY*/
+	int port; /*CURLOPT_PROXYPORT*/
+	char* user; /*CURLOPT_PROXYUSERNAME*/
+	char* pwd; /*CURLOPT_PROXYPASSWORD*/
+    } proxy;
+    struct credentials {
+	char *user; /*CURLOPT_USERNAME*/
+	char *pwd; /*CURLOPT_PASSWORD*/
+    } creds;
+} NCauth;
+
+extern int NC_authsetup(NCauth*, NCURI*);
+extern void NC_authclear(NCauth*);
+extern char* NC_combinehostport(NCURI*);
+extern int NC_parsecredentials(const char* userpwd, char** userp, char** pwdp);
+
+#endif /*NCAUTH_H*/
diff --git a/include/ncconfigure.h b/include/ncconfigure.h
index d1ef846..0b20bb5 100644
--- a/include/ncconfigure.h
+++ b/include/ncconfigure.h
@@ -10,6 +10,10 @@
 #ifndef NCCONFIGURE_H
 #define NCCONFIGURE_H 1
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
 /*
 This is included in bottom
 of config.h. It is where,
@@ -42,6 +46,14 @@ char *nulldup(const char* s);
 #endif
 #endif
 
+#ifndef HAVE_STRLCAT
+#ifdef _MSC_VER
+/* Windows strlcat_s is equivalent to strlcat, but different arg order */
+#define strlcat(d,s,n) strcat_s((d),(n),(s))
+#else
+extern size_t strlcat(char* dst, const char* src, size_t dsize);
+#endif
+#endif
 
 #ifndef nulldup
 #define nulldup(s) ((s)==NULL?NULL:strdup(s))
diff --git a/include/ncdispatch.h b/include/ncdispatch.h
index 0e988d8..b9bb9c0 100644
--- a/include/ncdispatch.h
+++ b/include/ncdispatch.h
@@ -29,7 +29,8 @@
 #define X_INT_MAX	2147483647
 
 /* Given a filename, check its magic number */
-#define MAGIC_NUMBER_LEN 4
+/* Change magic number size from 4 to 8 to be more precise for HDF5 */
+#define MAGIC_NUMBER_LEN 8
 #define MAGIC_HDF5_FILE 1
 #define MAGIC_HDF4_FILE 2
 #define MAGIC_CDF1_FILE 1 /* std classic format */
@@ -245,7 +246,8 @@ int (*inq_var_all)(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp);
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+              );
 
 int (*var_par_access)(int, int, int);
 
@@ -289,6 +291,7 @@ int (*def_var_fletcher32)(int, int, int);
 int (*def_var_chunking)(int, int, int, const size_t*);
 int (*def_var_fill)(int, int, int, const void*);
 int (*def_var_endian)(int, int, int);
+int (*def_var_filter)(int, int, unsigned int, size_t, const unsigned int*);
 int (*set_var_chunk_cache)(int, int, size_t, size_t, float);
 int (*get_var_chunk_cache)(int ncid, int varid, size_t *sizep, size_t *nelemsp, float *preemptionp);
 #endif /*USE_NETCDF4*/
@@ -397,8 +400,8 @@ NCDISPATCH_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp);
-
+	       unsigned int* idp, size_t* nparamsp, unsigned int* paramsp
+               );
 extern int
 NCDISPATCH_get_att(int ncid, int varid, const char* name, void* value, nc_type t);
 
diff --git a/include/ncfilter.h b/include/ncfilter.h
new file mode 100644
index 0000000..17806e7
--- /dev/null
+++ b/include/ncfilter.h
@@ -0,0 +1,27 @@
+/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
+   See the COPYRIGHT file for more information. */
+
+#ifndef NCFILTER_H
+#define NCFILTER_H 1
+
+/* API for libdispatch/dfilter.c */
+
+/* Must match values in <H5Zpublic.h> */
+#ifndef H5Z_FILTER_SZIP
+#define H5Z_FILTER_SZIP 4
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Provide consistent filter spec parser */
+EXTERNL int NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
+
+EXTERNL void NC_byteswap8(unsigned char* mem);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* NCFILTER_H */
diff --git a/include/ncrc.h b/include/ncrc.h
index c881680..b6fb547 100644
--- a/include/ncrc.h
+++ b/include/ncrc.h
@@ -1,26 +1,59 @@
-/*********************************************************************
-  *   Copyright 2016, UCAR/Unidata
-  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
-  *********************************************************************/
+/*
+Copyright (c) 1998-2017 University Corporation for Atmospheric Research/Unidata
+See LICENSE.txt for license information.
+*/
+
+/*
+Common functionality for reading
+and accessing rc files (e.g. .daprc).
+*/
 
 #ifndef NCRC_H
 #define NCRC_H
 
+/* Need these support includes */
+#include "ncuri.h"
 #include "nclist.h"
+#include "ncbytes.h"
 
 typedef struct NCTriple {
-	char* tag;
+	char* host; /* combined host:port */
         char* key;
         char* value;
 } NCTriple;
 
-typedef struct NCTripleStore {
-    NClist* triples; /* list of NCTriple* */
-} NCTripleStore;
+/* collect all the relevant info around the rc file */
+typedef struct NCRCinfo {
+	int ignore; /* if 1, then do not use any rc file */
+	int loaded; /* 1 => already loaded */
+        NClist* triples; /* the rc file triple store fields*/
+        char* rcfile; /* specified rcfile; overrides anything else */
+} NCRCinfo;
+
+/* Collect global state info in one place */
+typedef struct NCRCglobalstate {
+    int initialized;
+    char* tempdir; /* track a usable temp dir */
+    char* home; /* track $HOME for use in creating $HOME/.oc dir */
+    NCRCinfo rcinfo; /* Currenly only one rc file per session */
+} NCRCglobalstate;
 
+extern NCRCglobalstate ncrc_globalstate; /* singleton instance */
+
+/* From drc.c */
 /* read and compile the rc file, if any */
-extern int ncrc_load(const char* filename);
-extern char* ncrc_lookup(NCTripleStore*, char* key, char* hostport);
-extern void ncrc_reset(NCTripleStore*);
+extern int NC_rcload(void);
+extern char* NC_rclookup(const char* key, const char* hostport);
+extern void NC_rcclear(NCRCinfo* info);
+extern int NC_set_rcfile(const char* rcfile);
+
+/* From dutil.c (Might later move to e.g. nc.h */
+extern int NC__testurl(const char* path, char** basenamep);
+extern int NC_isLittleEndian(void);
+extern char* NC_backslashEscape(const char* s);
+extern char* NC_backslashUnescape(const char* esc);
+extern char* NC_entityescape(const char* s);
+extern int NC_readfile(const char* filename, NCbytes* content);
+extern char* NC_mktmp(const char* base);
 
 #endif /*NCRC_H*/
diff --git a/include/netcdf.h b/include/netcdf.h
index cbdd185..6d9ca15 100644
--- a/include/netcdf.h
+++ b/include/netcdf.h
@@ -30,31 +30,32 @@ extern "C" {
 /*
  *  The netcdf external data types
  */
-#define	NC_NAT 	        0	/**< Not A Type */
-#define	NC_BYTE         1	/**< signed 1 byte integer */
-#define	NC_CHAR 	2	/**< ISO/ASCII character */
-#define	NC_SHORT 	3	/**< signed 2 byte integer */
-#define	NC_INT 	        4	/**< signed 4 byte integer */
+#define NC_NAT          0       /**< Not A Type */
+#define NC_BYTE         1       /**< signed 1 byte integer */
+#define NC_CHAR         2       /**< ISO/ASCII character */
+#define NC_SHORT        3       /**< signed 2 byte integer */
+#define NC_INT          4       /**< signed 4 byte integer */
 #define NC_LONG         NC_INT  /**< \deprecated required for backward compatibility. */
-#define	NC_FLOAT 	5	/**< single precision floating point number */
-#define	NC_DOUBLE 	6	/**< double precision floating point number */
-#define	NC_UBYTE 	7	/**< unsigned 1 byte int */
-#define	NC_USHORT 	8	/**< unsigned 2-byte int */
-#define	NC_UINT 	9	/**< unsigned 4-byte int */
-#define	NC_INT64 	10	/**< signed 8-byte int */
-#define	NC_UINT64 	11	/**< unsigned 8-byte int */
-#define	NC_STRING 	12	/**< string */
+#define NC_FLOAT        5       /**< single precision floating point number */
+#define NC_DOUBLE       6       /**< double precision floating point number */
+#define NC_UBYTE        7       /**< unsigned 1 byte int */
+#define NC_USHORT       8       /**< unsigned 2-byte int */
+#define NC_UINT         9       /**< unsigned 4-byte int */
+#define NC_INT64        10      /**< signed 8-byte int */
+#define NC_UINT64       11      /**< unsigned 8-byte int */
+#define NC_STRING       12      /**< string */
 
-#define NC_MAX_ATOMIC_TYPE NC_STRING
+#define NC_MAX_ATOMIC_TYPE NC_STRING /**< @internal Largest atomic type. */
 
 /* The following are use internally in support of user-defines
  * types. They are also the class returned by nc_inq_user_type. */
-#define	NC_VLEN 	13	/**< vlen (variable-length) types */
-#define	NC_OPAQUE 	14	/**< opaque types */
-#define	NC_ENUM 	15	/**< enum types */
-#define	NC_COMPOUND 	16	/**< compound types */
+#define NC_VLEN         13      /**< vlen (variable-length) types */
+#define NC_OPAQUE       14      /**< opaque types */
+#define NC_ENUM         15      /**< enum types */
+#define NC_COMPOUND     16      /**< compound types */
 
-/* Define the first user defined type id (leave some room) */
+/** @internal Define the first user defined type id (leave some
+ * room) */
 #define NC_FIRSTUSERTYPEID 32
 
 /** Default fill value. This is used unless _FillValue attribute
@@ -62,12 +63,12 @@ extern "C" {
  * appropriate.  The hope is that one might use these to notice that a
  * particular datum has not been set. */
 /**@{*/
-#define NC_FILL_BYTE	((signed char)-127)
-#define NC_FILL_CHAR	((char)0)
-#define NC_FILL_SHORT	((short)-32767)
-#define NC_FILL_INT	(-2147483647L)
-#define NC_FILL_FLOAT	(9.9692099683868690e+36f) /* near 15 * 2^119 */
-#define NC_FILL_DOUBLE	(9.9692099683868690e+36)
+#define NC_FILL_BYTE    ((signed char)-127)
+#define NC_FILL_CHAR    ((char)0)
+#define NC_FILL_SHORT   ((short)-32767)
+#define NC_FILL_INT     (-2147483647L)
+#define NC_FILL_FLOAT   (9.9692099683868690e+36f) /* near 15 * 2^119 */
+#define NC_FILL_DOUBLE  (9.9692099683868690e+36)
 #define NC_FILL_UBYTE   (255)
 #define NC_FILL_USHORT  (65535)
 #define NC_FILL_UINT    (4294967295U)
@@ -108,22 +109,22 @@ extern "C" {
  * the same type as the variable and this reserved name. The value you
  * give the attribute will be used as the fill value for that
  * variable. */
-#define _FillValue	"_FillValue"
-#define NC_FILL		0	/**< Argument to nc_set_fill() to clear NC_NOFILL */
-#define NC_NOFILL	0x100	/**< Argument to nc_set_fill() to turn off filling of data. */
+#define _FillValue      "_FillValue"
+#define NC_FILL         0       /**< Argument to nc_set_fill() to clear NC_NOFILL */
+#define NC_NOFILL       0x100   /**< Argument to nc_set_fill() to turn off filling of data. */
 
 /* Define the ioflags bits for nc_create and nc_open.
    currently unused:
         0x0002
-	0x0040
-	0x0080
+        0x0040
+        0x0080
    and the whole upper 16 bits
 */
 
-#define NC_NOWRITE	 0x0000	/**< Set read-only access for nc_open(). */
-#define NC_WRITE    	 0x0001	/**< Set read-write access for nc_open(). */
-#define NC_CLOBBER	 0x0000 /**< Destroy existing file. Mode flag for nc_create(). */
-#define NC_NOCLOBBER     0x0004	/**< Don't destroy existing file. Mode flag for nc_create(). */
+#define NC_NOWRITE       0x0000 /**< Set read-only access for nc_open(). */
+#define NC_WRITE         0x0001 /**< Set read-write access for nc_open(). */
+#define NC_CLOBBER       0x0000 /**< Destroy existing file. Mode flag for nc_create(). */
+#define NC_NOCLOBBER     0x0004 /**< Don't destroy existing file. Mode flag for nc_create(). */
 
 #define NC_DISKLESS      0x0008  /**< Use diskless file. Mode flag for nc_open() or nc_create(). */
 #define NC_MMAP          0x0010  /**< Use diskless file with mmap. Mode flag for nc_open() or nc_create(). */
@@ -253,13 +254,16 @@ These maximums are not used for netCDF-4/HDF5 files unless they were
 created with the ::NC_CLASSIC_MODEL flag.
 
 As a rule, NC_MAX_VAR_DIMS <= NC_MAX_DIMS.
+
+NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits 
+      are *not* enforced after version 4.5.0
 */
 /**@{*/
-#define NC_MAX_DIMS	1024
-#define NC_MAX_ATTRS	8192
-#define NC_MAX_VARS	8192
-#define NC_MAX_NAME	256
-#define NC_MAX_VAR_DIMS	1024 /**< max per variable dimensions */
+#define NC_MAX_DIMS     1024 /* not enforced after 4.5.0 */
+#define NC_MAX_ATTRS    8192 /* not enforced after 4.5.0 */
+#define NC_MAX_VARS     8192 /* not enforced after 4.5.0 */
+#define NC_MAX_NAME     256
+#define NC_MAX_VAR_DIMS 1024 /**< max per variable dimensions */
 /**@}*/
 
 /** This is the max size of an SD dataset name in HDF4 (from HDF4 documentation).*/
@@ -299,13 +303,16 @@ there. */
 #define NC_SHUFFLE   1
 /**@}*/
 
+#define NC_MIN_DEFLATE_LEVEL 0 /**< Minimum deflate level. */
+#define NC_MAX_DEFLATE_LEVEL 9 /**< Maximum deflate level. */
+
 /** The netcdf version 3 functions all return integer error status.
  * These are the possible values, in addition to certain values from
  * the system errno.h.
  */
-#define NC_ISSYSERR(err)	((err) > 0)
+#define NC_ISSYSERR(err)        ((err) > 0)
 
-#define	NC_NOERR	0   /**< No Error */
+#define NC_NOERR        0          /**< No Error */
 #define NC2_ERR         (-1)       /**< Returned for all errors in the v2 API. */
 
 /** Not a netcdf id.
@@ -342,11 +349,11 @@ larger than the corresponding dimension length will cause an error. */
 /** 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_EMAXDIMS	(-41) /* not enforced after 4.5.0 */
 
 #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 */
+#define	NC_EMAXATTS	(-44)	   /**< NC_MAX_ATTRS exceeded - not enforced after 4.5.0 */
 #define NC_EBADTYPE	(-45)	   /**< Not a netcdf data type */
 #define NC_EBADDIM	(-46)	   /**< Invalid dimension id or name */
 #define NC_EUNLIMPOS	(-47)	   /**< NC_UNLIMITED in the wrong index */
@@ -354,7 +361,7 @@ classic or 64-bit offset file, or an netCDF-4 file with
 /** NC_MAX_VARS exceeded. Max number of variables exceeded in a
 classic or 64-bit offset file, or an netCDF-4 file with
 ::NC_CLASSIC_MODEL on. */
-#define	NC_EMAXVARS	(-48)
+#define	NC_EMAXVARS	(-48) /* not enforced after 4.5.0 */
 
 /** Variable not found.
 
@@ -375,17 +382,17 @@ referenced data out of range for the rank of the specified
 variable. For example, an edge length that is larger than the
 corresponding dimension length minus the corner index will cause an
 error. */
-#define NC_EEDGE	(-57)
-#define NC_ESTRIDE	(-58)	   /**< Illegal stride */
-#define NC_EBADNAME	(-59)	   /**< Attribute or variable name contains illegal characters */
+#define NC_EEDGE        (-57)      /**< Start+count exceeds dimension bound. */
+#define NC_ESTRIDE      (-58)      /**< Illegal stride */
+#define NC_EBADNAME     (-59)      /**< Attribute or variable name contains illegal characters */
 /* N.B. following must match value in ncx.h */
 
 /** Math result not representable.
 
 One or more of the values are out of the range of values representable
 by the desired type. */
-#define NC_ERANGE	(-60)
-#define NC_ENOMEM	(-61)	   /**< Memory allocation (malloc) failure */
+#define NC_ERANGE       (-60)
+#define NC_ENOMEM       (-61)      /**< Memory allocation (malloc) failure */
 #define NC_EVARSIZE     (-62)      /**< One or more variable sizes violate format constraints */
 #define NC_EDIMSIZE     (-63)      /**< Invalid dimension size */
 #define NC_ETRUNC       (-64)      /**< File likely truncated or possibly corrupted */
@@ -397,12 +404,12 @@ by the desired type. */
 #define NC_EIO          (-68)      /**< Generic IO error */
 #define NC_ENODATA      (-69)      /**< Attempt to access variable with no data */
 #define NC_EDAPSVC      (-70)      /**< DAP server error */
-#define NC_EDAS		(-71)      /**< Malformed or inaccessible DAS */
-#define NC_EDDS		(-72)      /**< Malformed or inaccessible DDS */
+#define NC_EDAS         (-71)      /**< Malformed or inaccessible DAS */
+#define NC_EDDS         (-72)      /**< Malformed or inaccessible DDS */
 #define NC_EDMR         NC_EDDS    /**< Dap4 alias */
-#define NC_EDATADDS	(-73)      /**< Malformed or inaccessible DATADDS */
+#define NC_EDATADDS     (-73)      /**< Malformed or inaccessible DATADDS */
 #define NC_EDATADAP     NC_EDATADDS    /**< Dap4 alias */
-#define NC_EDAPURL	(-74)      /**< Malformed DAP URL */
+#define NC_EDAPURL      (-74)      /**< Malformed DAP URL */
 #define NC_EDAPCONSTRAINT (-75)    /**< Malformed DAP Constraint*/
 #define NC_ETRANSLATION (-76)      /**< Untranslatable construct */
 #define NC_EACCESS      (-77)      /**< Access Failure */
@@ -415,10 +422,8 @@ by the desired type. */
 /* The following was added in support of netcdf-4. Make all netcdf-4
    error codes < -100 so that errors can be added to netcdf-3 if
    needed. */
-#define NC4_FIRST_ERROR  (-100)
-
-/** Error at HDF5 layer. */
-#define NC_EHDFERR       (-101)
+#define NC4_FIRST_ERROR  (-100)    /**< @internal All HDF5 errors < this. */
+#define NC_EHDFERR       (-101)    /**< Error at HDF5 layer. */
 #define NC_ECANTREAD     (-102)    /**< Can't read. */
 #define NC_ECANTWRITE    (-103)    /**< Can't write. */
 #define NC_ECANTCREATE   (-104)    /**< Can't create. */
@@ -429,9 +434,7 @@ by the desired type. */
 #define NC_ENOCOMPOUND   (-109)    /**< Not a compound type. */
 #define NC_EATTEXISTS    (-110)    /**< Attribute already exists. */
 #define NC_ENOTNC4       (-111)    /**< Attempting netcdf-4 operation on netcdf-3 file. */
-
-/** Attempting netcdf-4 operation on strict nc3 netcdf-4 file. */
-#define NC_ESTRICTNC3    (-112)
+#define NC_ESTRICTNC3    (-112)    /**< Attempting netcdf-4 operation on strict nc3 netcdf-4 file. */
 #define NC_ENOTNC3       (-113)    /**< Attempting netcdf-3 operation on netcdf-4 file. */
 #define NC_ENOPAR        (-114)    /**< Parallel operation on file opened for non-parallel access. */
 #define NC_EPARINIT      (-115)    /**< Error initializing for parallel access. */
@@ -452,21 +455,23 @@ by the desired type. */
 #define NC_ECANTEXTEND   (-130)    /**< Attempt to extend dataset during ind. I/O operation. */
 #define NC_EMPI          (-131)    /**< MPI operation failed. */
 
-#define NC4_LAST_ERROR   (-131)
+#define NC_EFILTER       (-132)    /**< Filter operation failed. */
+#define NC_ERCFILE       (-133)    /**< RC file failure */
+#define NC_ENULLPAD      (-134)    /**< Header Bytes not Null-Byte padded */
+#define NC4_LAST_ERROR   (-135)    /**< @internal All netCDF errors > this. */
 
-/* This is used in netCDF-4 files for dimensions without coordinate
- * vars. */
+/** @internal This is used in netCDF-4 files for dimensions without
+ * coordinate vars. */
 #define DIM_WITHOUT_VARIABLE "This is a netCDF dimension but not a netCDF variable."
 
-/* This is here at the request of the NCO team to support our
- * mistake of having chunksizes be first ints, then size_t. Doh! */
+/** @internal This is here at the request of the NCO team to support
+ * our mistake of having chunksizes be first ints, then
+ * size_t. Doh! */
 #define NC_HAVE_NEW_CHUNKING_API 1
 
-
-/*Errors for all remote access methods(e.g. DAP and CDMREMOTE)*/
-#define NC_EURL		(NC_EDAPURL)   /* Malformed URL */
-#define NC_ECONSTRAINT  (NC_EDAPCONSTRAINT)   /* Malformed Constraint*/
-
+/* Errors for all remote access methods(e.g. DAP and CDMREMOTE)*/
+#define NC_EURL         (NC_EDAPURL)   /**< Malformed URL */
+#define NC_ECONSTRAINT  (NC_EDAPCONSTRAINT)   /**< Malformed Constraint*/
 
 /*
  * The Interface
@@ -481,10 +486,10 @@ by the desired type. */
 #  endif
 #  include <io.h>
 #else
-#  define MSC_EXTRA
-#endif	/* defined(DLL_NETCDF) */
+#define MSC_EXTRA  /**< Needed for DLL build. */
+#endif  /* defined(DLL_NETCDF) */
 
-# define EXTERNL MSC_EXTRA extern
+#define EXTERNL MSC_EXTRA extern /**< Needed for DLL build. */
 
 #if defined(DLL_NETCDF) /* define when library is a DLL */
 EXTERNL int ncerr;
@@ -499,14 +504,14 @@ nc_strerror(int ncerr);
 
 EXTERNL int
 nc__create(const char *path, int cmode, size_t initialsz,
-	 size_t *chunksizehintp, int *ncidp);
+         size_t *chunksizehintp, int *ncidp);
 
 EXTERNL int
 nc_create(const char *path, int cmode, int *ncidp);
 
 EXTERNL int
 nc__open(const char *path, int mode,
-	size_t *chunksizehintp, int *ncidp);
+        size_t *chunksizehintp, int *ncidp);
 
 EXTERNL int
 nc_open(const char *path, int mode, int *ncidp);
@@ -567,7 +572,7 @@ nc_inq_typeids(int ncid, int *ntypes, int *typeids);
 /* Are two types equal? */
 EXTERNL int
 nc_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
-		  nc_type typeid2, int *equal);
+                  nc_type typeid2, int *equal);
 
 /* Create a group. its ncid is returned in the new_ncid pointer. */
 EXTERNL int
@@ -586,13 +591,13 @@ nc_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp);
 /* Insert a named field into a compound type. */
 EXTERNL int
 nc_insert_compound(int ncid, nc_type xtype, const char *name,
-		   size_t offset, nc_type field_typeid);
+                   size_t offset, nc_type field_typeid);
 
 /* Insert a named array into a compound type. */
 EXTERNL int
 nc_insert_array_compound(int ncid, nc_type xtype, const char *name,
-			 size_t offset, nc_type field_typeid,
-			 int ndims, const int *dim_sizes);
+                         size_t offset, nc_type field_typeid,
+                         int ndims, const int *dim_sizes);
 
 /* Get the name and size of a type. */
 EXTERNL int
@@ -605,7 +610,7 @@ nc_inq_typeid(int ncid, const char *name, nc_type *typeidp);
 /* Get the name, size, and number of fields in a compound type. */
 EXTERNL int
 nc_inq_compound(int ncid, nc_type xtype, char *name, size_t *sizep,
-		size_t *nfieldsp);
+                size_t *nfieldsp);
 
 /* Get the name of a compound type. */
 EXTERNL int
@@ -622,40 +627,40 @@ nc_inq_compound_nfields(int ncid, nc_type xtype, size_t *nfieldsp);
 /* Given the xtype and the fieldid, get all info about it. */
 EXTERNL int
 nc_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name,
-		      size_t *offsetp, nc_type *field_typeidp, int *ndimsp,
-		      int *dim_sizesp);
+                      size_t *offsetp, nc_type *field_typeidp, int *ndimsp,
+                      int *dim_sizesp);
 
 /* Given the typeid and the fieldid, get the name. */
 EXTERNL int
 nc_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid,
-			  char *name);
+                          char *name);
 
 /* Given the xtype and the name, get the fieldid. */
 EXTERNL int
 nc_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name,
-			   int *fieldidp);
+                           int *fieldidp);
 
 /* Given the xtype and fieldid, get the offset. */
 EXTERNL int
 nc_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid,
-			    size_t *offsetp);
+                            size_t *offsetp);
 
 /* Given the xtype and the fieldid, get the type of that field. */
 EXTERNL int
 nc_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid,
-			  nc_type *field_typeidp);
+                          nc_type *field_typeidp);
 
 /* Given the xtype and the fieldid, get the number of dimensions for
  * that field (scalars are 0). */
 EXTERNL int
 nc_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid,
-			   int *ndimsp);
+                           int *ndimsp);
 
 /* Given the xtype and the fieldid, get the sizes of dimensions for
  * that field. User must have allocated storage for the dim_sizes. */
 EXTERNL int
 nc_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid,
-			       int *dim_sizes);
+                               int *dim_sizes);
 
 /** This is the type of arrays of vlens. */
 typedef struct {
@@ -676,7 +681,7 @@ nc_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep);
 /* Find out about a vlen. */
 EXTERNL int
 nc_inq_vlen(int ncid, nc_type xtype, char *name, size_t *datum_sizep,
-	    nc_type *base_nc_typep);
+            nc_type *base_nc_typep);
 
 /* When you read VLEN type the library will actually allocate the
  * storage space for the data. This storage space must be freed, so
@@ -691,11 +696,11 @@ nc_free_vlens(size_t len, nc_vlen_t vlens[]);
 /* Put or get one element in a vlen array. */
 EXTERNL int
 nc_put_vlen_element(int ncid, int typeid1, void *vlen_element,
-		    size_t len, const void *data);
+                    size_t len, const void *data);
 
 EXTERNL int
 nc_get_vlen_element(int ncid, int typeid1, const void *vlen_element,
-		    size_t *len, void *data);
+                    size_t *len, void *data);
 
 /* When you read the string type the library will allocate the storage
  * space for the data. This storage space must be freed, so pass the
@@ -707,12 +712,12 @@ nc_free_string(size_t len, char **data);
 /* Find out about a user defined type. */
 EXTERNL int
 nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size,
-		 nc_type *base_nc_typep, size_t *nfieldsp, int *classp);
+                 nc_type *base_nc_typep, size_t *nfieldsp, int *classp);
 
 /* Write an attribute of any type. */
 EXTERNL int
 nc_put_att(int ncid, int varid, const char *name, nc_type xtype,
-	   size_t len, const void *op);
+           size_t len, const void *op);
 
 /* Read an attribute of any type. */
 EXTERNL int
@@ -724,25 +729,25 @@ nc_get_att(int ncid, int varid, const char *name, void *ip);
  * only ints are accepted as base types. */
 EXTERNL int
 nc_def_enum(int ncid, nc_type base_typeid, const char *name,
-	    nc_type *typeidp);
+            nc_type *typeidp);
 
 /* Insert a named value into an enum type. The value must fit within
  * the size of the enum type, the name size must be <= NC_MAX_NAME. */
 EXTERNL int
 nc_insert_enum(int ncid, nc_type xtype, const char *name,
-	       const void *value);
+               const void *value);
 
 /* Get information about an enum type: its name, base type and the
  * number of members defined. */
 EXTERNL int
 nc_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep,
-	    size_t *base_sizep, size_t *num_membersp);
+            size_t *base_sizep, size_t *num_membersp);
 
 /* Get information about an enum member: a name and value. Name size
  * will be <= NC_MAX_NAME. */
 EXTERNL int
 nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name,
-		   void *value);
+                   void *value);
 
 
 /* Get enum name from enum value. Name size will be <= NC_MAX_NAME. */
@@ -770,7 +775,7 @@ nc_get_var(int ncid, int varid,  void *ip);
 /* Write one value. */
 EXTERNL int
 nc_put_var1(int ncid, int varid,  const size_t *indexp,
-	    const void *op);
+            const void *op);
 
 /* Read one value. */
 EXTERNL int
@@ -779,36 +784,36 @@ nc_get_var1(int ncid, int varid,  const size_t *indexp, void *ip);
 /* Write an array of values. */
 EXTERNL int
 nc_put_vara(int ncid, int varid,  const size_t *startp,
-	    const size_t *countp, const void *op);
+            const size_t *countp, const void *op);
 
 /* Read an array of values. */
 EXTERNL int
 nc_get_vara(int ncid, int varid,  const size_t *startp,
-	    const size_t *countp, void *ip);
+            const size_t *countp, void *ip);
 
 /* Write slices of an array of values. */
 EXTERNL int
 nc_put_vars(int ncid, int varid,  const size_t *startp,
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    const void *op);
+            const size_t *countp, const ptrdiff_t *stridep,
+            const void *op);
 
 /* Read slices of an array of values. */
 EXTERNL int
 nc_get_vars(int ncid, int varid,  const size_t *startp,
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    void *ip);
+            const size_t *countp, const ptrdiff_t *stridep,
+            void *ip);
 
 /* Write mapped slices of an array of values. */
 EXTERNL int
 nc_put_varm(int ncid, int varid,  const size_t *startp,
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    const ptrdiff_t *imapp, const void *op);
+            const size_t *countp, const ptrdiff_t *stridep,
+            const ptrdiff_t *imapp, const void *op);
 
 /* Read mapped slices of an array of values. */
 EXTERNL int
 nc_get_varm(int ncid, int varid,  const size_t *startp,
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    const ptrdiff_t *imapp, void *ip);
+            const size_t *countp, const ptrdiff_t *stridep,
+            const ptrdiff_t *imapp, void *ip);
 
 /* Extra netcdf-4 stuff. */
 
@@ -816,12 +821,12 @@ nc_get_varm(int ncid, int varid,  const size_t *startp,
  * better. Must be called after nc_def_var and before nc_enddef. */
 EXTERNL int
 nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
-		   int deflate_level);
+                   int deflate_level);
 
 /* Find out compression settings of a var. */
 EXTERNL int
 nc_inq_var_deflate(int ncid, int varid, int *shufflep,
-		   int *deflatep, int *deflate_levelp);
+                   int *deflatep, int *deflate_levelp);
 
 /* Find out szip settings of a var. */
 EXTERNL int
@@ -862,6 +867,14 @@ nc_def_var_endian(int ncid, int varid, int endian);
 EXTERNL int
 nc_inq_var_endian(int ncid, int varid, int *endianp);
 
+/* Define a filter for a variable */
+EXTERNL int
+nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
+
+/* Learn about the filter on a variable */
+EXTERNL int
+nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
+
 /* Set the fill mode (classic or 64-bit offset files only). */
 EXTERNL int
 nc_set_fill(int ncid, int fillmode, int *old_modep);
@@ -882,12 +895,12 @@ nc_get_chunk_cache(size_t *sizep, size_t *nelemsp, float *preemptionp);
 /* Set the per-variable cache size, nelems, and preemption policy. */
 EXTERNL int
 nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
-		       float preemption);
+                       float preemption);
 
 /* Get the per-variable cache size, nelems, and preemption policy. */
 EXTERNL int
 nc_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp,
-		       float *preemptionp);
+                       float *preemptionp);
 
 EXTERNL int
 nc_redef(int ncid);
@@ -895,7 +908,7 @@ nc_redef(int ncid);
 /* Is this ever used? Convert to parameter form */
 EXTERNL int
 nc__enddef(int ncid, size_t h_minfree, size_t v_align,
-	size_t v_minfree, size_t r_align);
+        size_t v_minfree, size_t r_align);
 
 EXTERNL int
 nc_enddef(int ncid);
@@ -961,7 +974,7 @@ nc_rename_dim(int ncid, int dimid, const char *name);
 
 EXTERNL int
 nc_inq_att(int ncid, int varid, const char *name,
-	   nc_type *xtypep, size_t *lenp);
+           nc_type *xtypep, size_t *lenp);
 
 EXTERNL int
 nc_inq_attid(int ncid, int varid, const char *name, int *idp);
@@ -988,95 +1001,95 @@ nc_del_att(int ncid, int varid, const char *name);
 /* Begin {put,get}_att */
 EXTERNL int
 nc_put_att_text(int ncid, int varid, const char *name,
-		size_t len, const char *op);
+                size_t len, const char *op);
 
 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);
+                  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);
+                 size_t len, const unsigned char *op);
 
 EXTERNL int
 nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *ip);
 
 EXTERNL int
 nc_put_att_schar(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const signed char *op);
+                 size_t len, const signed char *op);
 
 EXTERNL int
 nc_get_att_schar(int ncid, int varid, const char *name, signed char *ip);
 
 EXTERNL int
 nc_put_att_short(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const short *op);
+                 size_t len, const short *op);
 
 EXTERNL int
 nc_get_att_short(int ncid, int varid, const char *name, short *ip);
 
 EXTERNL int
 nc_put_att_int(int ncid, int varid, const char *name, nc_type xtype,
-	       size_t len, const int *op);
+               size_t len, const int *op);
 
 EXTERNL int
 nc_get_att_int(int ncid, int varid, const char *name, int *ip);
 
 EXTERNL int
 nc_put_att_long(int ncid, int varid, const char *name, nc_type xtype,
-		size_t len, const long *op);
+                size_t len, const long *op);
 
 EXTERNL int
 nc_get_att_long(int ncid, int varid, const char *name, long *ip);
 
 EXTERNL int
 nc_put_att_float(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const float *op);
+                 size_t len, const float *op);
 
 EXTERNL int
 nc_get_att_float(int ncid, int varid, const char *name, float *ip);
 
 EXTERNL int
 nc_put_att_double(int ncid, int varid, const char *name, nc_type xtype,
-		  size_t len, const double *op);
+                  size_t len, const double *op);
 
 EXTERNL int
 nc_get_att_double(int ncid, int varid, const char *name, double *ip);
 
 EXTERNL int
 nc_put_att_ushort(int ncid, int varid, const char *name, nc_type xtype,
-		  size_t len, const unsigned short *op);
+                  size_t len, const unsigned short *op);
 
 EXTERNL int
 nc_get_att_ushort(int ncid, int varid, const char *name, unsigned short *ip);
 
 EXTERNL int
 nc_put_att_uint(int ncid, int varid, const char *name, nc_type xtype,
-		size_t len, const unsigned int *op);
+                size_t len, const unsigned int *op);
 
 EXTERNL int
 nc_get_att_uint(int ncid, int varid, const char *name, unsigned int *ip);
 
 EXTERNL int
 nc_put_att_longlong(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const long long *op);
+                 size_t len, const long long *op);
 
 EXTERNL int
 nc_get_att_longlong(int ncid, int varid, const char *name, long long *ip);
 
 EXTERNL int
 nc_put_att_ulonglong(int ncid, int varid, const char *name, nc_type xtype,
-		     size_t len, const unsigned long long *op);
+                     size_t len, const unsigned long long *op);
 
 EXTERNL int
 nc_get_att_ulonglong(int ncid, int varid, const char *name,
-		     unsigned long long *ip);
+                     unsigned long long *ip);
 
 
 /* End {put,get}_att */
@@ -1084,11 +1097,11 @@ nc_get_att_ulonglong(int ncid, int varid, const char *name,
 
 EXTERNL int
 nc_def_var(int ncid, const char *name, nc_type xtype, int ndims,
-	   const int *dimidsp, int *varidp);
+           const int *dimidsp, int *varidp);
 
 EXTERNL int
 nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep,
-	   int *ndimsp, int *dimidsp, int *nattsp);
+           int *ndimsp, int *dimidsp, int *nattsp);
 
 EXTERNL int
 nc_inq_varid(int ncid, const char *name, int *varidp);
@@ -1130,27 +1143,27 @@ nc_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip);
 
 EXTERNL int
 nc_put_var1_uchar(int ncid, int varid, const size_t *indexp,
-		  const unsigned char *op);
+                  const unsigned char *op);
 
 EXTERNL int
 nc_get_var1_uchar(int ncid, int varid, const size_t *indexp,
-		  unsigned char *ip);
+                  unsigned char *ip);
 
 EXTERNL int
 nc_put_var1_schar(int ncid, int varid, const size_t *indexp,
-		  const signed char *op);
+                  const signed char *op);
 
 EXTERNL int
 nc_get_var1_schar(int ncid, int varid, const size_t *indexp,
-		  signed char *ip);
+                  signed char *ip);
 
 EXTERNL int
 nc_put_var1_short(int ncid, int varid, const size_t *indexp,
-		  const short *op);
+                  const short *op);
 
 EXTERNL int
 nc_get_var1_short(int ncid, int varid, const size_t *indexp,
-		  short *ip);
+                  short *ip);
 
 EXTERNL int
 nc_put_var1_int(int ncid, int varid, const size_t *indexp, const int *op);
@@ -1178,416 +1191,416 @@ nc_get_var1_double(int ncid, int varid, const size_t *indexp, double *ip);
 
 EXTERNL int
 nc_put_var1_ushort(int ncid, int varid, const size_t *indexp,
-		   const unsigned short *op);
+                   const unsigned short *op);
 
 EXTERNL int
 nc_get_var1_ushort(int ncid, int varid, const size_t *indexp,
-		   unsigned short *ip);
+                   unsigned short *ip);
 
 EXTERNL int
 nc_put_var1_uint(int ncid, int varid, const size_t *indexp,
-		 const unsigned int *op);
+                 const unsigned int *op);
 
 EXTERNL int
 nc_get_var1_uint(int ncid, int varid, const size_t *indexp,
-		 unsigned int *ip);
+                 unsigned int *ip);
 
 EXTERNL int
 nc_put_var1_longlong(int ncid, int varid, const size_t *indexp,
-		     const long long *op);
+                     const long long *op);
 
 EXTERNL int
 nc_get_var1_longlong(int ncid, int varid, const size_t *indexp,
-		  long long *ip);
+                  long long *ip);
 
 EXTERNL int
 nc_put_var1_ulonglong(int ncid, int varid, const size_t *indexp,
-		   const unsigned long long *op);
+                   const unsigned long long *op);
 
 EXTERNL int
 nc_get_var1_ulonglong(int ncid, int varid, const size_t *indexp,
-		   unsigned long long *ip);
+                   unsigned long long *ip);
 
 EXTERNL int
 nc_put_var1_string(int ncid, int varid, const size_t *indexp,
-		   const char **op);
+                   const char **op);
 
 EXTERNL int
 nc_get_var1_string(int ncid, int varid, const size_t *indexp,
-		   char **ip);
+                   char **ip);
 
 /* End {put,get}_var1 */
 /* Begin {put,get}_vara */
 
 EXTERNL int
 nc_put_vara_text(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const char *op);
+                 const size_t *countp, const char *op);
 
 EXTERNL int
 nc_get_vara_text(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, char *ip);
+                 const size_t *countp, char *ip);
 
 EXTERNL int
 nc_put_vara_uchar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const unsigned char *op);
+                  const size_t *countp, const unsigned char *op);
 
 EXTERNL int
 nc_get_vara_uchar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, unsigned char *ip);
+                  const size_t *countp, unsigned char *ip);
 
 EXTERNL int
 nc_put_vara_schar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const signed char *op);
+                  const size_t *countp, const signed char *op);
 
 EXTERNL int
 nc_get_vara_schar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, signed char *ip);
+                  const size_t *countp, signed char *ip);
 
 EXTERNL int
 nc_put_vara_short(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const short *op);
+                  const size_t *countp, const short *op);
 
 EXTERNL int
 nc_get_vara_short(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, short *ip);
+                  const size_t *countp, short *ip);
 
 EXTERNL int
 nc_put_vara_int(int ncid, int varid, const size_t *startp,
-		const size_t *countp, const int *op);
+                const size_t *countp, const int *op);
 
 EXTERNL int
 nc_get_vara_int(int ncid, int varid, const size_t *startp,
-		const size_t *countp, int *ip);
+                const size_t *countp, int *ip);
 
 EXTERNL int
 nc_put_vara_long(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const long *op);
+                 const size_t *countp, const long *op);
 
 EXTERNL int
 nc_get_vara_long(int ncid, int varid,
-	const size_t *startp, const size_t *countp, long *ip);
+        const size_t *startp, const size_t *countp, long *ip);
 
 EXTERNL int
 nc_put_vara_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const float *op);
+        const size_t *startp, const size_t *countp, const float *op);
 
 EXTERNL int
 nc_get_vara_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, float *ip);
+        const size_t *startp, const size_t *countp, float *ip);
 
 EXTERNL int
 nc_put_vara_double(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const double *op);
+                   const size_t *countp, const double *op);
 
 EXTERNL int
 nc_get_vara_double(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, double *ip);
+                   const size_t *countp, double *ip);
 
 EXTERNL int
 nc_put_vara_ushort(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const unsigned short *op);
+                   const size_t *countp, const unsigned short *op);
 
 EXTERNL int
 nc_get_vara_ushort(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, unsigned short *ip);
+                   const size_t *countp, unsigned short *ip);
 
 EXTERNL int
 nc_put_vara_uint(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const unsigned int *op);
+                 const size_t *countp, const unsigned int *op);
 
 EXTERNL int
 nc_get_vara_uint(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, unsigned int *ip);
+                 const size_t *countp, unsigned int *ip);
 
 EXTERNL int
 nc_put_vara_longlong(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const long long *op);
+                  const size_t *countp, const long long *op);
 
 EXTERNL int
 nc_get_vara_longlong(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, long long *ip);
+                  const size_t *countp, long long *ip);
 
 EXTERNL int
 nc_put_vara_ulonglong(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const unsigned long long *op);
+                   const size_t *countp, const unsigned long long *op);
 
 EXTERNL int
 nc_get_vara_ulonglong(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, unsigned long long *ip);
+                   const size_t *countp, unsigned long long *ip);
 
 EXTERNL int
 nc_put_vara_string(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const char **op);
+                   const size_t *countp, const char **op);
 
 EXTERNL int
 nc_get_vara_string(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, char **ip);
+                   const size_t *countp, char **ip);
 
 /* End {put,get}_vara */
 /* Begin {put,get}_vars */
 
 EXTERNL int
 nc_put_vars_text(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const char *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const char *op);
 
 EXTERNL int
 nc_get_vars_text(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	char *ip);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        char *ip);
 
 EXTERNL int
 nc_put_vars_uchar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const unsigned char *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const unsigned char *op);
 
 EXTERNL int
 nc_get_vars_uchar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	unsigned char *ip);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        unsigned char *ip);
 
 EXTERNL int
 nc_put_vars_schar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const signed char *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const signed char *op);
 
 EXTERNL int
 nc_get_vars_schar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	signed char *ip);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        signed char *ip);
 
 EXTERNL int
 nc_put_vars_short(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const short *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const short *op);
 
 EXTERNL int
 nc_get_vars_short(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  short *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  short *ip);
 
 EXTERNL int
 nc_put_vars_int(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const int *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const int *op);
 
 EXTERNL int
 nc_get_vars_int(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	int *ip);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        int *ip);
 
 EXTERNL int
 nc_put_vars_long(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const long *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const long *op);
 
 EXTERNL int
 nc_get_vars_long(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	long *ip);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        long *ip);
 
 EXTERNL int
 nc_put_vars_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const float *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const float *op);
 
 EXTERNL int
 nc_get_vars_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	float *ip);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        float *ip);
 
 EXTERNL int
 nc_put_vars_double(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const double *op);
+        const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
+        const double *op);
 
 EXTERNL int
-nc_get_vars_double(int ncid, int varid,	const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   double *ip);
+nc_get_vars_double(int ncid, int varid, const size_t *startp,
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   double *ip);
 
 EXTERNL int
 nc_put_vars_ushort(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const unsigned short *op);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const unsigned short *op);
 
 EXTERNL int
 nc_get_vars_ushort(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   unsigned short *ip);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   unsigned short *ip);
 
 EXTERNL int
 nc_put_vars_uint(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const unsigned int *op);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const unsigned int *op);
 
 EXTERNL int
 nc_get_vars_uint(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 unsigned int *ip);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 unsigned int *ip);
 
 EXTERNL int
 nc_put_vars_longlong(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const long long *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const long long *op);
 
 EXTERNL int
 nc_get_vars_longlong(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  long long *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  long long *ip);
 
 EXTERNL int
 nc_put_vars_ulonglong(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const unsigned long long *op);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const unsigned long long *op);
 
 EXTERNL int
 nc_get_vars_ulonglong(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   unsigned long long *ip);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   unsigned long long *ip);
 
 EXTERNL int
 nc_put_vars_string(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const char **op);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const char **op);
 
 EXTERNL int
 nc_get_vars_string(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   char **ip);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   char **ip);
 
 /* End {put,get}_vars */
 /* Begin {put,get}_varm */
 
 EXTERNL int
 nc_put_varm_text(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, const char *op);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const ptrdiff_t *imapp, const char *op);
 
 EXTERNL int
 nc_get_varm_text(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, char *ip);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const ptrdiff_t *imapp, char *ip);
 
 EXTERNL int
 nc_put_varm_uchar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const unsigned char *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, const unsigned char *op);
 
 EXTERNL int
 nc_get_varm_uchar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, unsigned char *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, unsigned char *ip);
 
 EXTERNL int
 nc_put_varm_schar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const signed char *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, const signed char *op);
 
 EXTERNL int
 nc_get_varm_schar(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, signed char *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, signed char *ip);
 
 EXTERNL int
 nc_put_varm_short(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const short *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, const short *op);
 
 EXTERNL int
 nc_get_varm_short(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, short *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, short *ip);
 
 EXTERNL int
 nc_put_varm_int(int ncid, int varid, const size_t *startp,
-		const size_t *countp, const ptrdiff_t *stridep,
-		const ptrdiff_t *imapp, const int *op);
+                const size_t *countp, const ptrdiff_t *stridep,
+                const ptrdiff_t *imapp, const int *op);
 
 EXTERNL int
 nc_get_varm_int(int ncid, int varid, const size_t *startp,
-		const size_t *countp, const ptrdiff_t *stridep,
-		const ptrdiff_t *imapp, int *ip);
+                const size_t *countp, const ptrdiff_t *stridep,
+                const ptrdiff_t *imapp, int *ip);
 
 EXTERNL int
 nc_put_varm_long(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, const long *op);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const ptrdiff_t *imapp, const long *op);
 
 EXTERNL int
 nc_get_varm_long(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, long *ip);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const ptrdiff_t *imapp, long *ip);
 
 EXTERNL int
 nc_put_varm_float(int ncid, int varid,const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const float *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, const float *op);
 
 EXTERNL int
 nc_get_varm_float(int ncid, int varid,const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, float *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t *imapp, float *ip);
 
 EXTERNL int
-nc_put_varm_double(int ncid, int varid,	const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t *imapp, const double *op);
+nc_put_varm_double(int ncid, int varid, const size_t *startp,
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t *imapp, const double *op);
 
 EXTERNL int
-nc_get_varm_double(int ncid, int varid,	const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, double *ip);
+nc_get_varm_double(int ncid, int varid, const size_t *startp,
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, double *ip);
 
 EXTERNL int
 nc_put_varm_ushort(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, const unsigned short *op);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, const unsigned short *op);
 
 EXTERNL int
 nc_get_varm_ushort(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, unsigned short *ip);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, unsigned short *ip);
 
 EXTERNL int
 nc_put_varm_uint(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t * imapp, const unsigned int *op);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const ptrdiff_t * imapp, const unsigned int *op);
 
 EXTERNL int
 nc_get_varm_uint(int ncid, int varid, const size_t *startp,
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t * imapp, unsigned int *ip);
+                 const size_t *countp, const ptrdiff_t *stridep,
+                 const ptrdiff_t * imapp, unsigned int *ip);
 
 EXTERNL int
 nc_put_varm_longlong(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t * imapp, const long long *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t * imapp, const long long *op);
 
 EXTERNL int
 nc_get_varm_longlong(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t * imapp, long long *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t * imapp, long long *ip);
 
 EXTERNL int
 nc_put_varm_ulonglong(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, const unsigned long long *op);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, const unsigned long long *op);
 
 EXTERNL int
 nc_get_varm_ulonglong(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, unsigned long long *ip);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, unsigned long long *ip);
 
 EXTERNL int
 nc_put_varm_string(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, const char **op);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, const char **op);
 
 EXTERNL int
 nc_get_varm_string(int ncid, int varid, const size_t *startp,
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, char **ip);
+                   const size_t *countp, const ptrdiff_t *stridep,
+                   const ptrdiff_t * imapp, char **ip);
 
 /* End {put,get}_varm */
 /* Begin {put,get}_var */
@@ -1673,38 +1686,38 @@ nc_get_var_string(int ncid, int varid, char **ip);
 /* Begin Deprecated, same as functions with "_ubyte" replaced by "_uchar" */
 EXTERNL int
 nc_put_att_ubyte(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const unsigned char *op);
+                 size_t len, const unsigned char *op);
 EXTERNL int
 nc_get_att_ubyte(int ncid, int varid, const char *name,
-		 unsigned char *ip);
+                 unsigned char *ip);
 EXTERNL int
 nc_put_var1_ubyte(int ncid, int varid, const size_t *indexp,
-		  const unsigned char *op);
+                  const unsigned char *op);
 EXTERNL int
 nc_get_var1_ubyte(int ncid, int varid, const size_t *indexp,
-		  unsigned char *ip);
+                  unsigned char *ip);
 EXTERNL int
 nc_put_vara_ubyte(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const unsigned char *op);
+                  const size_t *countp, const unsigned char *op);
 EXTERNL int
 nc_get_vara_ubyte(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, unsigned char *ip);
+                  const size_t *countp, unsigned char *ip);
 EXTERNL int
 nc_put_vars_ubyte(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const unsigned char *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const unsigned char *op);
 EXTERNL int
 nc_get_vars_ubyte(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  unsigned char *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  unsigned char *ip);
 EXTERNL int
 nc_put_varm_ubyte(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t * imapp, const unsigned char *op);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t * imapp, const unsigned char *op);
 EXTERNL int
 nc_get_varm_ubyte(int ncid, int varid, const size_t *startp,
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t * imapp, unsigned char *ip);
+                  const size_t *countp, const ptrdiff_t *stridep,
+                  const ptrdiff_t * imapp, unsigned char *ip);
 EXTERNL int
 nc_put_var_ubyte(int ncid, int varid, const unsigned char *op);
 EXTERNL int
@@ -1724,7 +1737,7 @@ nc_set_log_level(int new_level);
 
 #else /* not LOGGING */
 
-#define nc_set_log_level(e)
+#define nc_set_log_level(e) /**< Get rid of these calls. */
 
 #endif /* LOGGING */
 
@@ -1751,11 +1764,11 @@ nc_show_metadata(int ncid);
 
 EXTERNL int
 nc__create_mp(const char *path, int cmode, size_t initialsz, int basepe,
-	 size_t *chunksizehintp, int *ncidp);
+         size_t *chunksizehintp, int *ncidp);
 
 EXTERNL int
 nc__open_mp(const char *path, int mode, int basepe,
-	size_t *chunksizehintp, int *ncidp);
+        size_t *chunksizehintp, int *ncidp);
 
 EXTERNL int
 nc_delete(const char *path);
@@ -1784,18 +1797,18 @@ nctypelen(nc_type datatype);
 
 /** Backward compatible alias. */
 /**@{*/
-#define FILL_BYTE	NC_FILL_BYTE
-#define FILL_CHAR	NC_FILL_CHAR
-#define FILL_SHORT	NC_FILL_SHORT
-#define FILL_LONG	NC_FILL_INT
-#define FILL_FLOAT	NC_FILL_FLOAT
-#define FILL_DOUBLE	NC_FILL_DOUBLE
-
-#define MAX_NC_DIMS	NC_MAX_DIMS
-#define MAX_NC_ATTRS	NC_MAX_ATTRS
-#define MAX_NC_VARS	NC_MAX_VARS
-#define MAX_NC_NAME	NC_MAX_NAME
-#define MAX_VAR_DIMS	NC_MAX_VAR_DIMS
+#define FILL_BYTE       NC_FILL_BYTE
+#define FILL_CHAR       NC_FILL_CHAR
+#define FILL_SHORT      NC_FILL_SHORT
+#define FILL_LONG       NC_FILL_INT
+#define FILL_FLOAT      NC_FILL_FLOAT
+#define FILL_DOUBLE     NC_FILL_DOUBLE
+
+#define MAX_NC_DIMS     NC_MAX_DIMS
+#define MAX_NC_ATTRS    NC_MAX_ATTRS
+#define MAX_NC_VARS     NC_MAX_VARS
+#define MAX_NC_NAME     NC_MAX_NAME
+#define MAX_VAR_DIMS    NC_MAX_VAR_DIMS
 /**@}*/
 
 
@@ -1804,27 +1817,27 @@ nctypelen(nc_type datatype);
  */
 EXTERNL int ncerr;
 
-#define NC_ENTOOL       NC_EMAXNAME   /* Backward compatibility */
-#define	NC_EXDR		(-32)	/* */
-#define	NC_SYSERR	(-31)
+#define NC_ENTOOL       NC_EMAXNAME   /**< Backward compatibility */
+#define NC_EXDR         (-32)   /**< V2 API error. */
+#define NC_SYSERR       (-31)   /**< V2 API system error. */
 
 /*
  * Global options variable.
  * Used to determine behavior of error handler.
  */
-#define	NC_FATAL	1
-#define	NC_VERBOSE	2
+#define NC_FATAL        1  /**< For V2 API, exit on error. */
+#define NC_VERBOSE      2  /**< For V2 API, be verbose on error. */
 
-EXTERNL int ncopts;	/* default is (NC_FATAL | NC_VERBOSE) */
+/** V2 API error handling. Default is (NC_FATAL | NC_VERBOSE). */
+EXTERNL int ncopts;     
 
 EXTERNL void
 nc_advise(const char *cdf_routine_name, int err, const char *fmt,...);
 
-/*
- * C data type corresponding to a netCDF NC_LONG argument,
- * a signed 32 bit object.
- *
- * This is the only thing in this file which architecture dependent.
+/**
+ * C data type corresponding to a netCDF NC_LONG argument, a signed 32
+ * bit object. This is the only thing in this file which architecture
+ * dependent.
  */
 typedef int nclong;
 
@@ -1869,7 +1882,7 @@ ncdimrename(int ncid, int dimid, const char *name);
 
 EXTERNL int
 ncattput(int ncid, int varid, const char *name, nc_type xtype,
-	int len, const void *op);
+        int len, const void *op);
 
 EXTERNL int
 ncattinq(int ncid, int varid, const char *name, nc_type *xtypep, int *lenp);
@@ -1879,7 +1892,7 @@ ncattget(int ncid, int varid, const char *name, void *ip);
 
 EXTERNL int
 ncattcopy(int ncid_in, int varid_in, const char *name, int ncid_out,
-	int varid_out);
+        int varid_out);
 
 EXTERNL int
 ncattname(int ncid, int varid, int attnum, char *name);
@@ -1892,14 +1905,14 @@ ncattdel(int ncid, int varid, const char *name);
 
 EXTERNL int
 ncvardef(int ncid, const char *name, nc_type xtype,
-	int ndims, const int *dimidsp);
+        int ndims, const int *dimidsp);
 
 EXTERNL int
 ncvarid(int ncid, const char *name);
 
 EXTERNL int
 ncvarinq(int ncid, int varid, char *name, nc_type *xtypep,
-	int *ndimsp, int *dimidsp, int *nattsp);
+        int *ndimsp, int *dimidsp, int *nattsp);
 
 EXTERNL int
 ncvarput1(int ncid, int varid, const long *indexp, const void *op);
@@ -1909,27 +1922,27 @@ ncvarget1(int ncid, int varid, const long *indexp, void *ip);
 
 EXTERNL int
 ncvarput(int ncid, int varid, const long *startp, const long *countp,
-	const void *op);
+        const void *op);
 
 EXTERNL int
 ncvarget(int ncid, int varid, const long *startp, const long *countp,
-	void *ip);
+        void *ip);
 
 EXTERNL int
 ncvarputs(int ncid, int varid, const long *startp, const long *countp,
-	const long *stridep, const void *op);
+        const long *stridep, const void *op);
 
 EXTERNL int
 ncvargets(int ncid, int varid, const long *startp, const long *countp,
-	const long *stridep, void *ip);
+        const long *stridep, void *ip);
 
 EXTERNL int
 ncvarputg(int ncid, int varid, const long *startp, const long *countp,
-	const long *stridep, const long *imapp, const void *op);
+        const long *stridep, const long *imapp, const void *op);
 
 EXTERNL int
 ncvargetg(int ncid, int varid, const long *startp, const long *countp,
-	const long *stridep, const long *imapp, void *ip);
+        const long *stridep, const long *imapp, void *ip);
 
 EXTERNL int
 ncvarrename(int ncid, int varid, const char *name);
@@ -1943,7 +1956,8 @@ ncrecget(int ncid, long recnum, void **datap);
 EXTERNL int
 ncrecput(int ncid, long recnum, void *const *datap);
 
-EXTERNL int nc_finalize();
+EXTERNL int
+nc_finalize();
 
 /* End v2.4 backward compatibility */
 #endif /*!NO_NETCDF_2*/
@@ -1952,11 +1966,6 @@ EXTERNL int nc_finalize();
 }
 #endif
 
-/* Temporary hack to shut up warnings */
-#ifndef __MINGW32_VERSION
-#define END_OF_MAIN()
-#endif
-
 /* Define two hard-coded functionality-related
    macros, but this is not going to be
    standard practice. */
@@ -1968,6 +1977,4 @@ EXTERNL int nc_finalize();
 #define NC_HAVE_INQ_FORMAT_EXTENDED /*!< inq_format_extended() support. */
 #endif
 
-#define NC_HAVE_META_H
-
 #endif /* _NETCDF_ */
diff --git a/include/netcdf_par.h b/include/netcdf_par.h
index aa5142c..f35365b 100644
--- a/include/netcdf_par.h
+++ b/include/netcdf_par.h
@@ -7,8 +7,8 @@
  *
  * This header file is for the parallel I/O functions of netCDF.
  *
+ * \author Ed Hartnett
  */
-/* "$Id: netcdf_par.h,v 1.1 2010/06/01 15:46:49 ed Exp $" */
 
 #ifndef NETCDF_PAR_H
 #define NETCDF_PAR_H 1
@@ -19,8 +19,9 @@
 extern "C" {
 #endif
 
-/* Use these with nc_var_par_access(). */
+/** Use with nc_var_par_access() to set parallel access to independent. */
 #define NC_INDEPENDENT 0
+/** Use with nc_var_par_access() to set parallel access to collective. */
 #define NC_COLLECTIVE 1
 
 /* Create a file and enable parallel I/O. */
diff --git a/include/rnd.h b/include/rnd.h
index 4021a4d..90da7d2 100644
--- a/include/rnd.h
+++ b/include/rnd.h
@@ -1,9 +1,14 @@
-/*
- *	Copyright 1996, University Corporation for Atmospheric Research
- *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
+/* Copyright 1996-2018, University Corporation for Atmospheric
+ * Research See netcdf/COPYRIGHT file for copying and redistribution
+ * conditions.
+ *
+ * This header file contains some macros for rounding numbers.
+ *
+ * Glenn Davis, 1996
  */
-/* $Id: rnd.h,v 2.13 1996/12/11 05:46:54 davis Exp $ */
-#ifndef _RNDUP
+
+#ifndef _RND_H
+#define _RND_H
 
 /* useful for aligning memory */
 #define	_RNDUP(x, unit)  ((((x) + (unit) - 1) / (unit)) \
@@ -14,4 +19,4 @@
 #define	M_RNDUP(x) _RNDUP(x, M_RND_UNIT)
 #define	M_RNDDOWN(x)  __RNDDOWN(x, M_RND_UNIT)
 
-#endif
+#endif /* _RND_H */
diff --git a/lib_flags.am b/lib_flags.am
index 71b249d..58accdf 100644
--- a/lib_flags.am
+++ b/lib_flags.am
@@ -13,12 +13,7 @@ if USE_DAP
 AM_CPPFLAGS += -I${top_srcdir}/oc2
 endif
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
-if BUILD_DLL
-AM_CPPFLAGS += -DDLL_NETCDF
-endif
-
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 
 
diff --git a/libdap2/Makefile.in b/libdap2/Makefile.in
index a7d68d0..4d98cd5 100644
--- a/libdap2/Makefile.in
+++ b/libdap2/Makefile.in
@@ -104,12 +104,9 @@ host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
 #SRC += cdf4.c constraints4.c ncd4dispatch.c ncdap4.c getvara4.c
 #HDRS +=constraints4.h ncd4dispatch.h ncdap4.h
- at ENABLE_DAP_TRUE@@USE_NETCDF4_TRUE at am__append_3 = -I$(top_srcdir)/libsrc4
+ at ENABLE_DAP_TRUE@@USE_NETCDF4_TRUE at am__append_2 = -I$(top_srcdir)/libsrc4
 subdir = libdap2
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -215,12 +212,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
-	$(am__append_3)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -243,12 +238,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -274,6 +271,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -288,6 +286,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -391,7 +390,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 
diff --git a/libdap2/dapattr.c b/libdap2/dapattr.c
index 4bd39c2..f491cf9 100644
--- a/libdap2/dapattr.c
+++ b/libdap2/dapattr.c
@@ -151,368 +151,3 @@ buildattribute(char* name, nc_type ptype,
     return THROW(ncstat);
 }
 
-#if 0
-/*
-Given a das attribute walk it to see if it
-has at least 1 actual attribute (no recursion)
-*/
-static int
-hasattribute(OClink conn, OCdasnode dasnode)
-{
-    int i;
-    OCerror ocstat = OC_NOERR;
-    int tf = 0; /* assume false */
-    OCtype ocsubtype;
-    NClist* subnodes = nclistnew();
-
-    OCCHECK(oc_dds_octype(conn,dasnode,&ocsubtype));
-    if(ocsubtype == OC_Attribute) return 1; /* this is an attribute */
-    ASSERT((ocsubtype == OC_Attributeset));
-
-    OCCHECK(collect_subnodes(conn,dasnode,subnodes));
-    for(i=0;i<nclistlength(subnodes);i++) {
-        OCdasnode subnode = (OCdasnode)nclistget(subnodes,i);
-        OCCHECK(oc_dds_class(conn,subnode,&ocsubtype));
-	if(ocsubtype == OC_Attribute) {tf=1; break;}
-    }
-done:
-    nclistfree(subnodes);
-    return tf;
-}
-
-int
-dapmerge(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot)
-{
-    unsigned int i,j;
-    NCerror ncerr = NC_NOERR;
-    OCerror ocstat = OC_NOERR;
-    OClink conn = nccomm->oc.conn;
-    size_t nsubnodes;
-    NClist* dasglobals = nclistnew();
-    NClist* dasnodes = nclistnew();
-    NClist* dodsextra = nclistnew();
-    NClist* varnodes = nclistnew();
-    NClist* alldasnodes = nclistnew();    
-
-    if(ddsroot == NULL || dasroot == NULL) return NC_NOERR;
-
-    ocstat = collect_alldasnodes(conn,dasroot,alldasnodes);
-    
-    /* 1. collect all the relevant DAS nodes;
-          namely those that contain at least one
-          attribute value.
-          Simultaneously look for potential ambiguities
-          if found; complain but continue: result are indeterminate.
-          also collect globals and DODS_EXTRA separately.
-    */
-    for(i=0;i<nclistlength(alldasnodes);i++) {
-	OCddsnode das = (OCddsnode)nclistget(alldasnodes,i);
-	OCtype octype;
-        char* ocname = NULL;
-	int isglobal = 0;
-	int hasattributes = 0;
-
-        OCCHECK(oc_dds_class(conn,das,&octype));
-	if(octype == OC_Attribute) continue; /* ignore these for now*/
-
-        OCCHECK(oc_dds_name(conn,das,&ocname));
-	OCCHECK(oc_dds_nsubnodes(conn,das,&nsubnodes));
-
-	isglobal = (ocname == NULL ? 0 : isglobalname(ocname));
-
-	/* catch DODS_EXTRA */
-	if(isglobal && ocname != NULL && strcmp(ocname,"DODS_EXTRA")==0) {
-	    nclistpush(dodsextra,(void*)das);
-	    nullfree(ocname);
-	    continue;
-	}
-	if(ocname == NULL || isglobal) {
-            nclistpush(dasglobals,(void*)das);
-	    nullfree(ocname);
-	    continue;
-	}
-	hasattributes = hasattribute(conn,das);
-	if(hasattributes) {
-	    /* Look for previously collected nodes with same name*/
-            for(j=0;j<nclistlength(dasnodes);j++) {
-	        OCddsnode das2 = (OCddsnode)nclistget(dasnodes,j);
-		char* ocname2;
-	        OCCHECK(oc_dds_name(conn,das2,&ocname2));
-		if(ocname2 == NULL || ocname == NULL) goto loop;
-		if(strcmp(ocname2,"DODS")==0) goto loop;
-	        if(strcmp(ocname,ocname2)==0)
-		        nclog(NCLOGWARN,"nc_mergedas: potentially ambiguous DAS name: %s",ocname2);
-loop:
-		nullfree(ocname2);
-	    }
-	    nclistpush(dasnodes,(void*)das);
-	}
-	nullfree(ocname);
-    }
-
-    /* 2. collect all the leaf DDS nodes (of type NC_Atomic)*/
-    ocstat = collect_leaves(link,ddsroot,varnodes);
-
-    /* 3. For each das node, locate matching DDS node(s) and attach
-          attributes to the DDS node(s).
-          Match means:
-          1. DAS->fullname :: DDS->fullname
-          2. DAS->name :: DDS->fullname (support DAS names with embedded '.'
-          3. DAS->name :: DDS->name
-	  4. special case for DODS. Apply 1-3 on DODS parent.
-    */
-    for(i=0;i<nclistlength(dasnodes);i++) {
-	OCddsnode das = (OCddsnode)nclistget(dasnodes,i);
-	char* ocfullname = NULL;
-	char* ocbasename = NULL;
-
-	if(das == NULL) continue;
-	OCCHECK(oc_dds_name(conn,das,&ocbasename));
-	if(strcmp(ocbasename,"DODS")==0) {
-	    OCddsnode container;
-   	    OCCHECK(oc_dds_container(conn,das,&container));
-            ASSERT(container != NULL);
-	    ocfullname = makeocpathstring(conn,container,".");
-	} else {
-	    ocfullname = makeocpathstring(conn,das,".");
-	}
-        for(j=0;j<nclistlength(varnodes);j++) {
-	    CDFnode* dds = (CDFnode*)nclistget(varnodes,j);
-	    char* ddsfullname = makecdfpathstring(dds,".");
-	    if(strcmp(ocfullname,ddsfullname)==0
-	       || strcmp(ocbasename,ddsfullname)==0
-	       || strcmp(ocbasename,dds->ocname)==0) {
-		mergedas1(nccomm,conn,dds,das);
-		/* remove from dasnodes list*/
-		nclistset(dasnodes,i,(void*)NULL);
-	    }
-	    nullfree(ddsfullname);
-	}
-	nullfree(ocfullname);
-	nullfree(ocbasename);
-    }
-
-    /* 4. Assign globals */
-    for(i=0;i<nclistlength(dasglobals);i++) {
-	OCddsnode das = (OCddsnode)nclistget(dasglobals,i);
-	mergedas1(nccomm,conn,ddsroot,das);
-    }
-
-    /* 5. Assign DOD_EXTRA */
-    for(i=0;i<nclistlength(dodsextra);i++) {
-	OCddsnode das = (OCddsnode)nclistget(dodsextra,i);
-	mergedas1(nccomm,conn,ddsroot,das);
-    }
-
-done: /* cleanup*/
-    nclistfree(dasglobals);
-    nclistfree(dasnodes);
-    nclistfree(alldasnodes);
-    nclistfree(dodsextra);
-    nclistfree(varnodes);
-    if(ocstat != OC_NOERR)
-	ncerr = ocerrtoncerr(ocstat);
-    return THROW(ncerr);
-}
-
-static int
-mergedas1(NCDAPCOMMON* nccomm, OClink conn, CDFnode* dds, OCddsnode das)
-{
-    NCerror ncstat = NC_NOERR;
-    OCerror ocstat = OC_NOERR;
-    unsigned int i,j,k;
-    unsigned int nsubnodes;
-    OCobject* subnodes = NULL;
-    OCobject* dodsnodes = NULL;
-    unsigned int ndodsnodes;
-
-    if(dds == NULL || das == OCNULL) return NC_NOERR; /* nothing to do */
-    if(dds->attributes == NULL) dds->attributes = nclistnew();
-    /* assign the simple attributes in the das set to this dds node*/
-    OCCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes));
-    OCCHECK(oc_inq_subnodes(conn,das,&subnodes));
-    for(i=0;i<nsubnodes;i++) {
-	OCobject attnode = subnodes[i];
-	OCtype octype, ocetype;
-	char* ocname = NULL;
-	unsigned int ocnvalues;
-        OCCHECK(oc_inq_name(conn,attnode,&ocname));	
-        OCCHECK(oc_inq_class(conn,attnode,&octype));
-	if(octype == OC_Attribute) {
-	    NCattribute* att = NULL;
-	    NClist* stringvalues;
-            OCCHECK(oc_inq_primtype(conn,attnode,&ocetype));	
-	    OCCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues));
-	    stringvalues = nclistnew();
-	    for(j=0;j<ocnvalues;j++) {
-		char* stringval;
-	        OCCHECK(oc_inq_dasattr(conn,attnode,j,&ocetype,&stringval));
-	        nclistpush(stringvalues,(void*)stringval);
-	    }
-	    ncstat = buildattribute(ocname,
-				    octypetonc(ocetype),
-				    stringvalues,
-				    &att);				
-	    if(ncstat) goto done;
-            nclistpush(dds->attributes,(void*)att);
-	} else if(octype == OC_Attributeset
-		  && (strcmp(ocname,"DODS")==0
-		      || strcmp(ocname,"DODS_EXTRA")==0)) {
-	    /* Turn the DODS special attributes into into
-               special attributes for dds node */
-	    OCCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes));
-	    OCCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes));
-	    for(j=0;j<ndodsnodes;j++) {
-		char* dodsname = NULL;
-		char newname[4096];
-	        OCobject attnode = dodsnodes[j];
-	        NCattribute* att = NULL;
-	        NClist* stringvalues;
-	        OCCHECK(oc_inq_class(conn,attnode,&octype));
-		if(octype != OC_Attribute) continue;
-                OCCHECK(oc_inq_primtype(conn,attnode,&ocetype));	
-	        OCCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues));
-	        stringvalues = nclistnew();
-	        for(k=0;k<ocnvalues;k++) {
-		    char* stringval;
-	            OCCHECK(oc_inq_dasattr(conn,attnode,k,&ocetype,&stringval));
-	            nclistpush(stringvalues,(void*)stringval);
-		}
-	        OCCHECK(oc_inq_name(conn,attnode,&dodsname));
-		/* Compute new special name */
-		strcpy(newname,"_DODS_");
-		strcat(newname,dodsname);
-	        ncstat = buildattribute(newname,
-				        octypetonc(ocetype),
-				        stringvalues,
-				        &att);				
-		if(ncstat) goto done;
-		att->invisible = 1;
-            	nclistpush(dds->attributes,(void*)att);
-
-		/* Define extra semantics associated with DODS and DODS_EXTRA attribute */
-		if(strcmp(dodsname,"strlen")==0) {
-		    unsigned int maxstrlen = 0;
-		    if(nclistlength(stringvalues) > 0) {
-		        char* stringval = (char*)nclistget(stringvalues,0);
-			if(0==sscanf(stringval,"%u",&maxstrlen)) maxstrlen = 0;
-		    }
-		    dds->dodsspecial.maxstrlen = maxstrlen;
-#ifdef DEBUG
-fprintf(stderr,"%s.maxstrlen=%d\n",dds->ocname,(int)dds->dodsspecial.maxstrlen);
-#endif
-		} else if(strcmp(dodsname,"dimName")==0) {
-		    if(nclistlength(stringvalues) > 0) {
-		        char* stringval = (char*)nclistget(stringvalues,0);
-		        dds->dodsspecial.dimname = nulldup(stringval);
-#ifdef DEBUG
-fprintf(stderr,"%s.dimname=%s\n",dds->ocname,dds->dodsspecial.dimname);
-#endif
-		    } else dds->dodsspecial.dimname = NULL;
-		} else if(strcmp(dodsname,"Unlimited_Dimension")==0) {
-		    char* stringval = NULL;
-		    if(nclistlength(stringvalues) > 0)
-	                stringval = (char*)nclistget(stringvalues,0);
-		    if(stringval != NULL) {
-		        if(nccomm->cdf.recorddimname != NULL) {
-			   if(strcmp(stringval,nccomm->cdf.recorddimname) != 0)
-		            nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications");
-		        } else {
-			    nccomm->cdf.recorddimname = nulldup(stringval);
-#ifdef DEBUG
-fprintf(stderr,"%s.Unlimited_Dimension=%s\n",dds->ocname,nccomm->cdf.recorddimname);
-#endif
-		        }
-		    }
-		} /* else ignore */
-	        nullfree(dodsname);
-	    }
-	    nullfree(dodsnodes);
-	}
-        nullfree(ocname);
-    }
-
-done:
-    nullfree(subnodes);
-    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
-    return THROW(ncstat);
-}
-
-static int
-isglobalname(char* name)
-{
-    int len = strlen(name);
-    int glen = strlen("global");
-    char* p;
-    if(len < glen) return 0;
-    p = name + (len - glen);
-    if(strcasecmp(p,"global") != 0)
-	return 0;
-    return 1;
-}
-
-
-static OCerror
-collect_alldasnodes(OClink link, OCddsnode dasnode, NClist* alldasnodes)
-{
-    size_t nsubnodes,i;
-    OCerror ocstat = OC_NOERR;
-    nclistpush(alldasnodes,(void*)dasnode);
-    ocstat = oc_dds_nsubnodes(link,dasnode,&nsubnodes);
-    if(ocstat != OC_NOERR) goto done;
-    for(i=0;i<nsubnodes;i++) {
-	OCddsnode subnode;
-	ocstat = oc_dds_ithsubnode(link,dasnode,i,&subnode);
-        if(ocstat != OC_NOERR) goto done;
-	ocstat = collect_alldasnodes(link,subnode,alldasnodes);
-        if(ocstat != OC_NOERR) goto done;	
-    }
-    
-done:
-    return ocstat;
-}
-
-static OCerror
-collect_leaves(OClink link, OCddsnode ddsnode, NClist* leaves)
-{
-    size_t nsubnodes,i;
-    OCerror ocstat = OC_NOERR;
-    OCtype octype;
-    ocstat = oc_dds_octype(link,ddsnode,&octype);
-    if(ocstat != OC_NOERR) goto done;
-    if(octype == OC_Atomic) {
-        nclistpush(leaves,(void*)ddsnode);
-    } else {
-        ocstat = oc_dds_nsubnodes(link,ddsnode,&nsubnodes);
-        if(ocstat != OC_NOERR) goto done;
-        for(i=0;i<nsubnodes;i++) {
-	    OCddsnode subnode;
-	    ocstat = oc_dds_ithsubnode(link,ddsnode,i,&subnode);
-            if(ocstat != OC_NOERR) goto done;
-	    ocstat = collect_leaves(link,subnode,leaves);
-            if(ocstat != OC_NOERR) goto done;	
-	}
-    }
-    
-done:
-    return ocstat;
-}
-
-static OCerror
-collect_subnodes(OClink link, OCddsnode ddsnode, NClist* subnodes)
-{
-    size_t nsubnodes,i;
-    OCerror ocstat = OC_NOERR;
-    ocstat = oc_dds_nsubnodes(link,ddsnode,&nsubnodes);
-    if(ocstat != OC_NOERR) goto done;
-    for(i=0;i<nsubnodes;i++) {
-        OCddsnode subnode;
-	ocstat = oc_dds_ithsubnode(link,ddsnode,i,&subnode);
-        if(ocstat != OC_NOERR) goto done;
-	nclistpush(subnodes,(void*)subnode);
-    }
-    
-done:
-    return ocstat;
-}
-#endif /*0*/
diff --git a/libdap2/dapcvt.c b/libdap2/dapcvt.c
index 65cc692..7c76203 100644
--- a/libdap2/dapcvt.c
+++ b/libdap2/dapcvt.c
@@ -217,7 +217,8 @@ dapcvtattrval(nc_type etype, void* dst, NClist* src)
 #ifdef _MSC_VER
 	    _ASSERTE(_CrtCheckMemory());
 #endif
-	    if(ival < 0 || ival > NC_MAX_UBYTE) ok = 0;
+	    /* For back compatibility, we allow any value, but force conversion */
+	    ival = (ival & 0xFF);
 	    *p = (char)ival;
 	    } break;
 	case NC_CHAR: {
@@ -235,10 +236,22 @@ dapcvtattrval(nc_type etype, void* dst, NClist* src)
 	case NC_FLOAT: {
 	    float* p = (float*)dstmem;
 	    ok = sscanf(s,"%g%n",p,&nread);
+#if defined(_MSC_VER) && (_MSC_VER == 1500)
+	    if (!_strnicmp(s, "NaN", 3)) {
+	      ok = 1;
+	      nread = 3;
+	    }
+#endif
 	    } break;
 	case NC_DOUBLE: {
 	    double* p = (double*)dstmem;
 	    ok = sscanf(s,"%lg%n",p,&nread);
+#if defined(_MSC_VER) && (_MSC_VER == 1500)
+	    if (!_strnicmp(s, "NaN", 3)) {
+	      ok = 1;
+	      nread = 3;
+	    }
+#endif
 	    } break;
 	case NC_UBYTE: {
 	    unsigned char* p = (unsigned char*)dstmem;
@@ -246,7 +259,8 @@ dapcvtattrval(nc_type etype, void* dst, NClist* src)
 	    unsigned int uval;
 	    ok = sscanf(s,"%u%n",&uval,&nread);
 	    _ASSERTE(_CrtCheckMemory());
-	    if(uval > NC_MAX_UBYTE) ok = 0;
+	    /* For back compatibility, we allow any value, but force conversion */
+	    uval = (uval & 0xFF);
 	    *p = (unsigned char)uval;
 #else
 	    ok = sscanf(s,"%hhu%n",p,&nread);
diff --git a/libdap2/dapdump.c b/libdap2/dapdump.c
index b740424..51e5d9f 100644
--- a/libdap2/dapdump.c
+++ b/libdap2/dapdump.c
@@ -584,7 +584,7 @@ dumpslice(DCEslice* slice)
                 (unsigned long)slice->stride,
                 (unsigned long)slice->last);
     }
-    strcat(buf,tmp);
+    strlcat(buf,tmp,sizeof(buf));
     return strdup(tmp);
 }
 
diff --git a/libdap2/dapodom.c b/libdap2/dapodom.c
index 8df5756..965f335 100644
--- a/libdap2/dapodom.c
+++ b/libdap2/dapodom.c
@@ -79,14 +79,14 @@ dapodom_print(Dapodometer* odom)
     char tmp[64];
     line[0] = '\0';
     if(odom->rank == 0) {
-	strcat(line,"[]");
+	strlcat(line,"[]",sizeof(line));
     } else for(i=0;i<odom->rank;i++) {
 	sprintf(tmp,"[%lu/%lu:%lu:%lu]",
 		(size_t)odom->index[i],
 		(size_t)odom->start[i],
 		(size_t)odom->stride[i],
 		(size_t)odom->length[i]);
-	strcat(line,tmp);	
+	strlcat(line,tmp,sizeof(line));	
     }
     return line;
 }
diff --git a/libdap2/daputil.c b/libdap2/daputil.c
index 120a310..47d184c 100644
--- a/libdap2/daputil.c
+++ b/libdap2/daputil.c
@@ -442,13 +442,13 @@ simplepathstring(NClist* names,  char* separator)
 	len += strlen(name);
 	len += strlen(separator);
     }
-    len++; /* null terminator */
-    result = (char*)malloc(len);
+    len++; /* room for strlcat to null terminate */
+    result = (char*)malloc(len+1);
     result[0] = '\0';
     for(i=0;i<nclistlength(names);i++) {
 	char* segment = (char*)nclistget(names,i);
-	if(i > 0) strcat(result,separator);
-	strcat(result,segment);
+	if(i > 0) strlcat(result,separator,len);
+	strlcat(result,segment,len);
     }
     return result;
 }
@@ -776,10 +776,13 @@ repairname(const char* name, const char* badchars)
     const char *p;
     char *q;
     int c;
+    int nnlen = 0;
 
     if(name == NULL) return NULL;
-    newname = (char*)malloc(1+(3*strlen(name))); /* max needed */
-    newname[0] = '\0'; /* so we can use strcat */
+    nnlen = (3*strlen(name)); /* max needed */
+    nnlen++; /* room for strlcat to add nul */
+    newname = (char*)malloc(1+nnlen); /* max needed */
+    newname[0] = '\0'; /* so we can use strlcat */
     for(p=name,q=newname;(c=*p);p++) {
         if(strchr(badchars,c) != NULL) {
 	    int digit;
@@ -790,11 +793,11 @@ repairname(const char* name, const char* badchars)
             digit = (c & 0x0f);
 	    newchar[2] = hexdigits[digit];
 	    newchar[3] = '\0';
-            strcat(newname,newchar);
+            strlcat(newname,newchar,nnlen);
             q += 3; /*strlen(newchar)*/
         } else
             *q++ = c;
-	*q = '\0'; /* so we can always do strcat */
+	*q = '\0'; /* so we can always do strlcat */
     }
     *q = '\0'; /* ensure trailing null */
     return newname;
diff --git a/libdap2/ncd2dispatch.c b/libdap2/ncd2dispatch.c
index b6db0c8..eb8a2b7 100644
--- a/libdap2/ncd2dispatch.c
+++ b/libdap2/ncd2dispatch.c
@@ -5,6 +5,7 @@
 
 #include "dapincludes.h"
 #include "ncd2dispatch.h"
+#include "ncrc.h"
 #include "ncoffsets.h"
 #ifdef DEBUG2
 #include "dapdump.h"
@@ -14,8 +15,6 @@
 #include <crtdbg.h>
 #endif
 
-#define NCRCFILE "NCRCFILE"
-
 #ifdef HAVE_GETRLIMIT
 #  ifdef HAVE_SYS_RESOURCE_H
 #    include <sys/time.h>
@@ -175,6 +174,7 @@ NCD2_def_var_fletcher32,
 NCD2_def_var_chunking,
 NCD2_def_var_fill,
 NCD2_def_var_endian,
+NCD2_def_var_filter,
 NCD2_set_var_chunk_cache,
 NCD2_get_var_chunk_cache,
 
@@ -184,8 +184,6 @@ NCD2_get_var_chunk_cache,
 
 NC_Dispatch* NCD2_dispatch_table = NULL; /* moved here from ddispatch.c */
 
-static NC_Dispatch NCD2_dispatcher;
-
 int
 NCD2_initialize(void)
 {
@@ -197,12 +195,6 @@ NCD2_initialize(void)
     if(nclogopen(NULL))
         ncsetlogging(1); /* turn it on */
 #endif
-    /* Look at env vars for rc file location */
-    if(getenv(NCRCFILE) != NULL) {
-	const char* ncrcfile = getenv(NCRCFILE);
-	if(oc_set_rcfile(ncrcfile) != OC_NOERR)
-	    return NC_EAUTH;
-    }
     return NC_NOERR;
 }
 
@@ -322,10 +314,14 @@ NCD2_open(const char* path, int mode,
 #endif
 
 #ifdef OCCOMPILEBYDEFAULT
+    { int rullen = 0;
     /* set the compile flag by default */
-    dapcomm->oc.rawurltext = (char*)emalloc(strlen(path)+strlen("[compile]")+1);
-    strcpy(dapcomm->oc.rawurltext,"[compile]");
-    strcat(dapcomm->oc.rawurltext, path);
+    rullen = strlen(path)+strlen("[compile]");;
+    rullen++; /* strlcat nul */
+    dapcomm->oc.rawurltext = (char*)emalloc(rullen+1);
+    strncpy(dapcomm->oc.rawurltext,"[compile]",rullen);
+    strlcat(dapcomm->oc.rawurltext, path, rullen);
+    }
 #else
     dapcomm->oc.rawurltext = strdup(path);
 #endif
@@ -655,7 +651,6 @@ builddims(NCDAPCOMMON* dapcomm)
     NCerror ncstat = NC_NOERR;
     int dimid;
     NClist* dimset = NULL;
-    NC* drno = dapcomm->controller;
     NC* ncsub;
     char* definename;
 
@@ -740,7 +735,6 @@ buildvars(NCDAPCOMMON* dapcomm)
     NCerror ncstat = NC_NOERR;
     int varid;
     NClist* varnodes = dapcomm->cdf.ddsroot->tree->varnodes;
-    NC* drno = dapcomm->controller;
     char* definename;
 
     ASSERT((varnodes != NULL));
@@ -818,7 +812,6 @@ buildglobalattrs(NCDAPCOMMON* dapcomm, CDFnode* root)
     char *nltxt, *p;
     NCbytes* buf = NULL;
     NClist* cdfnodes;
-    NC* drno = dapcomm->controller;
 
     if(root->attributes != NULL) {
         for(i=0;i<nclistlength(root->attributes);i++) {
@@ -897,7 +890,6 @@ buildattribute(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int vari
     int i;
     NCerror ncstat = NC_NOERR;
     unsigned int nvalues = nclistlength(att->values);
-    NC* drno = dapcomm->controller;
 
     /* If the type of the attribute is string, then we need*/
     /* to convert to a single character string by concatenation.
@@ -911,15 +903,14 @@ buildattribute(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int vari
 	    char* s = (char*)nclistget(att->values,i);
 	    newlen += (1+strlen(s));
 	}
-    if(newlen > 0)
-      newstring = (char*)malloc(newlen);
-
-    MEMCHECK(newstring,NC_ENOMEM);
+	newlen++; /* for strlcat nul */
+        newstring = (char*)malloc(newlen+1);
+        MEMCHECK(newstring,NC_ENOMEM);
 	newstring[0] = '\0';
 	for(i=0;i<nvalues;i++) {
 	    char* s = (char*)nclistget(att->values,i);
-	    if(i > 0) strcat(newstring,"\n");
-	    strcat(newstring,s);
+	    if(i > 0) strlcat(newstring,"\n",newlen);
+	    strlcat(newstring,s,newlen);
 	}
         dapexpandescapes(newstring);
 	if(newstring[0]=='\0')
@@ -1143,11 +1134,14 @@ fprintf(stderr,"conflict: %s[%lu] %s[%lu]\n",
 	    nullfree(dim->ncbasename);
 	    if(dim->dim.index1 > 0) {/* need to fix conflicting names (see above) */
 	        char sindex[64];
+		size_t baselen;
 		snprintf(sindex,sizeof(sindex),"_%d",dim->dim.index1);
-		dim->ncbasename = (char*)malloc(strlen(sindex)+strlen(legalname)+1);
+		baselen = strlen(sindex)+strlen(legalname);
+		baselen++; /* for strlcat nul */
+		dim->ncbasename = (char*)malloc(baselen+1);
 		if(dim->ncbasename == NULL) {nullfree(legalname); return NC_ENOMEM;}
-		strcpy(dim->ncbasename,legalname);
-		strcat(dim->ncbasename,sindex);
+		strncpy(dim->ncbasename,legalname,baselen);
+		strlcat(dim->ncbasename,sindex,baselen);
 		nullfree(legalname);
 	    } else {/* standard case */
 	        dim->ncbasename = legalname;
@@ -1199,6 +1193,15 @@ constrainable(NCURI* durl)
    return 0;
 }
 
+static const char*
+paramlookup(NCDAPCOMMON* state, const char* key)
+{
+    const char* value = NULL;
+    if(state == NULL || key == NULL || state->oc.url == NULL) return NULL;
+    value = ncurilookup(state->oc.url,key);
+    return value;
+}
+
 /* Note: this routine only applies some common
    client parameters, other routines may apply
    specific ones.
@@ -1219,17 +1222,17 @@ applyclientparams(NCDAPCOMMON* nccomm)
     ASSERT(nccomm->oc.url != NULL);
 
     nccomm->cdf.cache->cachelimit = DFALTCACHELIMIT;
-    value = oc_clientparam_get(conn,"cachelimit");
+    value = paramlookup(nccomm,"cachelimit");
     limit = getlimitnumber(value);
     if(limit > 0) nccomm->cdf.cache->cachelimit = limit;
 
     nccomm->cdf.fetchlimit = DFALTFETCHLIMIT;
-    value = oc_clientparam_get(conn,"fetchlimit");
+    value = paramlookup(nccomm,"fetchlimit");
     limit = getlimitnumber(value);
     if(limit > 0) nccomm->cdf.fetchlimit = limit;
 
     nccomm->cdf.smallsizelimit = DFALTSMALLLIMIT;
-    value = oc_clientparam_get(conn,"smallsizelimit");
+    value = paramlookup(nccomm,"smallsizelimit");
     limit = getlimitnumber(value);
     if(limit > 0) nccomm->cdf.smallsizelimit = limit;
 
@@ -1241,23 +1244,23 @@ applyclientparams(NCDAPCOMMON* nccomm)
       }
     }
 #endif
-    value = oc_clientparam_get(conn,"cachecount");
+    value = paramlookup(nccomm,"cachecount");
     limit = getlimitnumber(value);
     if(limit > 0) nccomm->cdf.cache->cachecount = limit;
     /* Ignore limit if not caching */
     if(!FLAGSET(nccomm->controls,NCF_CACHE))
         nccomm->cdf.cache->cachecount = 0;
 
-    if(oc_clientparam_get(conn,"nolimit") != NULL)
+    if(paramlookup(nccomm,"nolimit") != NULL)
 	dfaltseqlim = 0;
-    value = oc_clientparam_get(conn,"limit");
+    value = paramlookup(nccomm,"limit");
     if(value != NULL && strlen(value) != 0) {
         if(sscanf(value,"%d",&len) && len > 0) dfaltseqlim = len;
     }
     nccomm->cdf.defaultsequencelimit = dfaltseqlim;
 
     /* allow embedded _ */
-    value = oc_clientparam_get(conn,"stringlength");
+    value = paramlookup(nccomm,"stringlength");
     if(value != NULL && strlen(value) != 0) {
         if(sscanf(value,"%d",&len) && len > 0) dfaltstrlen = len;
     }
@@ -1268,11 +1271,11 @@ applyclientparams(NCDAPCOMMON* nccomm)
 	CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.ddsroot->tree->varnodes,i);
 	/* Define the client param stringlength for this variable*/
 	var->maxstringlength = 0; /* => use global dfalt */
-	strcpy(tmpname,"stringlength_");
+	strncpy(tmpname,"stringlength_",sizeof(tmpname));
 	pathstr = makeocpathstring(conn,var->ocnode,".");
-	strncat(tmpname,pathstr,NC_MAX_NAME);
+	strlcat(tmpname,pathstr,sizeof(tmpname));
 	nullfree(pathstr);
-	value = oc_clientparam_get(conn,tmpname);
+	value = paramlookup(nccomm,tmpname);
         if(value != NULL && strlen(value) != 0) {
             if(sscanf(value,"%d",&len) && len > 0) var->maxstringlength = len;
 	}
@@ -1282,14 +1285,14 @@ applyclientparams(NCDAPCOMMON* nccomm)
 	CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.ddsroot->tree->nodes,i);
 	if(var->nctype != NC_Sequence) continue;
 	var->sequencelimit = dfaltseqlim;
-	strcpy(tmpname,"nolimit_");
+	strncpy(tmpname,"nolimit_",sizeof(tmpname));
 	pathstr = makeocpathstring(conn,var->ocnode,".");
-	strncat(tmpname,pathstr,NC_MAX_NAME);
-	if(oc_clientparam_get(conn,tmpname) != NULL)
+	strlcat(tmpname,pathstr,sizeof(tmpname));
+	if(paramlookup(nccomm,tmpname) != NULL)
 	    var->sequencelimit = 0;
-	strcpy(tmpname,"limit_");
-	strncat(tmpname,pathstr,NC_MAX_NAME);
-	value = oc_clientparam_get(conn,tmpname);
+	strncpy(tmpname,"limit_",sizeof(tmpname));
+	strlcat(tmpname,pathstr,sizeof(tmpname));
+	value = paramlookup(nccomm,tmpname);
         if(value != NULL && strlen(value) != 0) {
             if(sscanf(value,"%d",&len) && len > 0)
 		var->sequencelimit = len;
@@ -1298,7 +1301,7 @@ applyclientparams(NCDAPCOMMON* nccomm)
     }
 
     /* test for the appropriate fetch flags */
-    value = oc_clientparam_get(conn,"fetch");
+    value = paramlookup(nccomm,"fetch");
     if(value != NULL && strlen(value) > 0) {
 	if(value[0] == 'd' || value[0] == 'D') {
             SETFLAG(nccomm->controls,NCF_ONDISK);
@@ -1306,7 +1309,7 @@ applyclientparams(NCDAPCOMMON* nccomm)
     }
 
     /* test for the force-whole-var flag */
-    value = oc_clientparam_get(conn,"wholevar");
+    value = paramlookup(nccomm,"wholevar");
     if(value != NULL) {
         SETFLAG(nccomm->controls,NCF_WHOLEVAR);
     }
@@ -2389,7 +2392,8 @@ NCD2_inq_var_all(int ncid, int varid, char *name, nc_type* xtypep,
                int* shufflep, int* deflatep, int* deflate_levelp,
                int* fletcher32p, int* contiguousp, size_t* chunksizesp,
                int* no_fill, void* fill_valuep, int* endiannessp,
-	       int* options_maskp, int* pixels_per_blockp)
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               )
 {
     NC* drno;
     int ret;
@@ -2399,7 +2403,8 @@ NCD2_inq_var_all(int ncid, int varid, char *name, nc_type* xtypep,
                shufflep, deflatep, deflate_levelp,
                fletcher32p, contiguousp, chunksizesp,
                no_fill, fill_valuep, endiannessp,
-	       options_maskp, pixels_per_blockp);
+	       idp,nparamsp,params
+	       );
     return THROW(ret);
 }
 
@@ -2779,6 +2784,16 @@ NCD2_def_var_endian(int ncid, int p2, int p3)
 }
 
 int
+NCD2_def_var_filter(int ncid, int varid, unsigned int id, size_t n, const unsigned int* params)
+{
+    NC* drno;
+    int ret;
+    if((ret = NC_check_id(ncid, (NC**)&drno)) != NC_NOERR) return THROW(ret);
+    ret = nc_def_var_filter(getnc3id(drno), varid, id, n, params);
+    return THROW(ret);
+}
+
+int
 NCD2_set_var_chunk_cache(int ncid, int p2, size_t p3, size_t p4, float p5)
 {
     NC* drno;
diff --git a/libdap2/ncd2dispatch.h b/libdap2/ncd2dispatch.h
index 04df44f..ab132e3 100644
--- a/libdap2/ncd2dispatch.h
+++ b/libdap2/ncd2dispatch.h
@@ -135,7 +135,8 @@ NCD2_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp);
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               );
 
 extern int
 NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
@@ -143,7 +144,8 @@ NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp);
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               );
 
 extern int
 NCD2_inq_varid(int ncid, const char *name, int *varidp);
@@ -246,6 +248,9 @@ NCD2_var_par_access(int, int, int);
   NCD2_def_var_endian(int, int, int);
 
   extern int
+  NCD2_def_var_filter(int, int, unsigned int, size_t, const unsigned int*);
+
+  extern int
   NCD2_inq_unlimdims(int, int *, int *);
 
   extern int
diff --git a/libdap2/test_vara.c b/libdap2/test_vara.c
index c4bd0e0..c15cdbf 100644
--- a/libdap2/test_vara.c
+++ b/libdap2/test_vara.c
@@ -90,8 +90,8 @@ main()
 	exit(1);
     }
     printf("Using test server: %s\n",svc);
-    strcpy(URL,svc);
-    strcat(URL,DTSTEST);
+    strncpy(URL,svc,sizeof(URL));
+    strlcat(URL,DTSTEST,sizeof(URL));
 
     memset((void*)target,0,sizeof(target));
 
diff --git a/libdap4/CMakeLists.txt b/libdap4/CMakeLists.txt
index cbf6f5b..28cdb02 100644
--- a/libdap4/CMakeLists.txt
+++ b/libdap4/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(dap4_SOURCES d4crc32.c d4curlfunctions.c d4curlflags.c d4rc.c d4fix.c d4data.c d4file.c d4parser.c d4meta.c d4varx.c d4dump.c d4swap.c d4chunk.c d4printer.c d4read.c d4http.c d4util.c d4odom.c d4cvt.c d4debug.c ncd4dispatch.c ezxml_extra.c ezxml.c)
+SET(dap4_SOURCES d4crc32.c d4curlfunctions.c d4curlflags.c d4fix.c d4data.c d4file.c d4parser.c d4meta.c d4varx.c d4dump.c d4swap.c d4chunk.c d4printer.c d4read.c d4http.c d4util.c d4odom.c d4cvt.c d4debug.c ncd4dispatch.c ezxml_extra.c ezxml.c)
 
 add_library(dap4 OBJECT ${dap4_SOURCES})
 
diff --git a/libdap4/Makefile.am b/libdap4/Makefile.am
index 33223f7..5c1c9e5 100644
--- a/libdap4/Makefile.am
+++ b/libdap4/Makefile.am
@@ -19,7 +19,6 @@ SRC= \
 d4crc32.c \
 d4curlfunctions.c \
 d4curlflags.c \
-d4rc.c \
 d4fix.c \
 d4data.c \
 d4file.c \
diff --git a/libdap4/Makefile.in b/libdap4/Makefile.in
index 8453e4e..8b71e20 100644
--- a/libdap4/Makefile.in
+++ b/libdap4/Makefile.in
@@ -103,10 +103,7 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
- at ENABLE_DAP4_TRUE@@USE_NETCDF4_TRUE at am__append_3 = -I$(top_srcdir)/libsrc4
+ at ENABLE_DAP4_TRUE@@USE_NETCDF4_TRUE at am__append_2 = -I$(top_srcdir)/libsrc4
 subdir = libdap4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -123,16 +120,15 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libdap4_la_DEPENDENCIES =
 am__libdap4_la_SOURCES_DIST = d4crc32.c d4curlfunctions.c \
-	d4curlflags.c d4rc.c d4fix.c d4data.c d4file.c d4parser.c \
-	d4meta.c d4varx.c d4dump.c d4swap.c d4chunk.c d4printer.c \
-	d4read.c d4http.c d4util.c d4odom.c d4cvt.c d4debug.c \
-	ncd4dispatch.c ezxml_extra.c ezxml.c ncd4dispatch.h \
-	ncd4types.h ncd4.h d4chunk.h d4http.h d4read.h \
-	d4curlfunctions.h d4util.h d4debug.h d4odom.h d4bytes.h \
-	d4includes.h ezxml.h
+	d4curlflags.c d4fix.c d4data.c d4file.c d4parser.c d4meta.c \
+	d4varx.c d4dump.c d4swap.c d4chunk.c d4printer.c d4read.c \
+	d4http.c d4util.c d4odom.c d4cvt.c d4debug.c ncd4dispatch.c \
+	ezxml_extra.c ezxml.c ncd4dispatch.h ncd4types.h ncd4.h \
+	d4chunk.h d4http.h d4read.h d4curlfunctions.h d4util.h \
+	d4debug.h d4odom.h d4bytes.h d4includes.h ezxml.h
 am__objects_1 = libdap4_la-d4crc32.lo libdap4_la-d4curlfunctions.lo \
-	libdap4_la-d4curlflags.lo libdap4_la-d4rc.lo \
-	libdap4_la-d4fix.lo libdap4_la-d4data.lo libdap4_la-d4file.lo \
+	libdap4_la-d4curlflags.lo libdap4_la-d4fix.lo \
+	libdap4_la-d4data.lo libdap4_la-d4file.lo \
 	libdap4_la-d4parser.lo libdap4_la-d4meta.lo \
 	libdap4_la-d4varx.lo libdap4_la-d4dump.lo libdap4_la-d4swap.lo \
 	libdap4_la-d4chunk.lo libdap4_la-d4printer.lo \
@@ -216,12 +212,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
-	$(am__append_3)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -244,12 +238,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -275,6 +271,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -289,6 +286,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -392,7 +390,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 
@@ -406,7 +404,6 @@ SRC = \
 d4crc32.c \
 d4curlfunctions.c \
 d4curlflags.c \
-d4rc.c \
 d4fix.c \
 d4data.c \
 d4file.c \
@@ -523,7 +520,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4odom.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4parser.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4printer.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4rc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4read.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4swap.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap4_la-d4util.Plo at am__quote@
@@ -577,13 +573,6 @@ libdap4_la-d4curlflags.lo: d4curlflags.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) $(libdap4_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdap4_la-d4curlflags.lo `test -f 'd4curlflags.c' || echo '$(srcdir)/'`d4curlflags.c
 
-libdap4_la-d4rc.lo: d4rc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap4_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdap4_la-d4rc.lo -MD -MP -MF $(DEPDIR)/libdap4_la-d4rc.Tpo -c -o libdap4_la-d4rc.lo `test -f 'd4rc.c' || echo '$(srcdir)/'`d4rc.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdap4_la-d4rc.Tpo $(DEPDIR)/libdap4_la-d4rc.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='d4rc.c' object='libdap4_la-d4rc.lo' libtool=yes @AMDEPBACKSLASH@
- at 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) $(libdap4_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdap4_la-d4rc.lo `test -f 'd4rc.c' || echo '$(srcdir)/'`d4rc.c
-
 libdap4_la-d4fix.lo: d4fix.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap4_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdap4_la-d4fix.lo -MD -MP -MF $(DEPDIR)/libdap4_la-d4fix.Tpo -c -o libdap4_la-d4fix.lo `test -f 'd4fix.c' || echo '$(srcdir)/'`d4fix.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdap4_la-d4fix.Tpo $(DEPDIR)/libdap4_la-d4fix.Plo
diff --git a/libdap4/d4chunk.c b/libdap4/d4chunk.c
index b748879..8e159b7 100644
--- a/libdap4/d4chunk.c
+++ b/libdap4/d4chunk.c
@@ -65,7 +65,7 @@ NCD4_dechunk(NCD4meta* metadata)
 	/* setup as dmr only */
 	metadata->serial.dmr = (char*)metadata->serial.rawdata; /* temp */
 	metadata->serial.dmr[metadata->serial.rawsize-1] = '\0';
-	metadata->serial.dmr = strdup(q);
+	metadata->serial.dmr = strdup((char *)q);
 	if(metadata->serial.dmr == NULL)
 	    return THROW(NC_ENOMEM);
 	return THROW(NC_NOERR); 
diff --git a/libdap4/d4curlfunctions.c b/libdap4/d4curlfunctions.c
index df198d4..0c4f0bc 100644
--- a/libdap4/d4curlfunctions.c
+++ b/libdap4/d4curlfunctions.c
@@ -22,15 +22,15 @@
 #define CHECK(state,flag,value) {if(check(state,flag,(void*)value) != NC_NOERR) {goto done;}}
 
 /* forward */
-static int set_curlflag(NCD4INFO* state, int flag);
-static int set_curlopt(NCD4INFO* state, int flag, void* value);
-static int set_curl_options(NCD4INFO* state);
+static int set_curlflag(NCD4INFO*, int flag);
+static int set_curlopt(NCD4INFO*, int flag, void* value);
+static int set_curl_options(NCD4INFO*);
 static void* cvt(char* value, enum CURLFLAGTYPE type);
 
 static int
-check(NCD4INFO* state, int flag, void* value)
+check(NCD4INFO* info, int flag, void* value)
 {
-    int ret = set_curlopt(state,flag,value);
+    int ret = set_curlopt(info,flag,value);
     return THROW(ret);
 }
 
@@ -57,37 +57,37 @@ set_curlflag(NCD4INFO* state, int flag)
     int ret = NC_NOERR;
     switch (flag) {
     case CURLOPT_USERPWD: /* Do both user and pwd */
-        if(state->curl->creds.user != NULL
-           && state->curl->creds.pwd != NULL) {
-	    CHECK(state, CURLOPT_USERNAME, state->curl->creds.user);
-	    CHECK(state, CURLOPT_PASSWORD, state->curl->creds.pwd);
+        if(state->auth.creds.user != NULL
+           && state->auth.creds.pwd != NULL) {
+	    CHECK(state, CURLOPT_USERNAME, state->auth.creds.user);
+	    CHECK(state, CURLOPT_PASSWORD, state->auth.creds.pwd);
             CHECK(state, CURLOPT_HTTPAUTH, (OPTARG)CURLAUTH_ANY);
 	}
 	break;
     case CURLOPT_COOKIEJAR: case CURLOPT_COOKIEFILE:
-        if(state->curl->curlflags.cookiejar) {
+        if(state->auth.curlflags.cookiejar) {
 	    /* Assume we will read and write cookies to same place */
-	    CHECK(state, CURLOPT_COOKIEJAR, state->curl->curlflags.cookiejar);
-	    CHECK(state, CURLOPT_COOKIEFILE, state->curl->curlflags.cookiejar);
+	    CHECK(state, CURLOPT_COOKIEJAR, state->auth.curlflags.cookiejar);
+	    CHECK(state, CURLOPT_COOKIEFILE, state->auth.curlflags.cookiejar);
         }
 	break;
     case CURLOPT_NETRC: case CURLOPT_NETRC_FILE:
-	if(state->curl->curlflags.netrc) {
+	if(state->auth.curlflags.netrc) {
 	    CHECK(state, CURLOPT_NETRC, (OPTARG)CURL_NETRC_REQUIRED);
-	    CHECK(state, CURLOPT_NETRC_FILE, state->curl->curlflags.netrc);
+	    CHECK(state, CURLOPT_NETRC_FILE, state->auth.curlflags.netrc);
         }
 	break;
     case CURLOPT_VERBOSE:
-	if(state->curl->curlflags.verbose)
+	if(state->auth.curlflags.verbose)
 	    CHECK(state, CURLOPT_VERBOSE, (OPTARG)1L);
 	break;
     case CURLOPT_TIMEOUT:
-	if(state->curl->curlflags.timeout)
-	    CHECK(state, CURLOPT_TIMEOUT, (OPTARG)((long)state->curl->curlflags.timeout));
+	if(state->auth.curlflags.timeout)
+	    CHECK(state, CURLOPT_TIMEOUT, (OPTARG)((long)state->auth.curlflags.timeout));
 	break;
     case CURLOPT_USERAGENT:
-        if(state->curl->curlflags.useragent)
-	    CHECK(state, CURLOPT_USERAGENT, state->curl->curlflags.useragent);
+        if(state->auth.curlflags.useragent)
+	    CHECK(state, CURLOPT_USERAGENT, state->auth.curlflags.useragent);
 	break;
     case CURLOPT_FOLLOWLOCATION:
         CHECK(state, CURLOPT_FOLLOWLOCATION, (OPTARG)1L);
@@ -100,19 +100,19 @@ set_curlflag(NCD4INFO* state, int flag)
 	break;
     case CURLOPT_ENCODING:
 #ifdef CURLOPT_ENCODING
-	if(state->curl->curlflags.compress) {
+	if(state->auth.curlflags.compress) {
 	    CHECK(state, CURLOPT_ENCODING,"deflate, gzip");
         }
 #endif
 	break;
     case CURLOPT_PROXY:
-	if(state->curl->proxy.host != NULL) {
-	    CHECK(state, CURLOPT_PROXY, state->curl->proxy.host);
-	    CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->curl->proxy.port);
-	    if(state->curl->proxy.user != NULL
-	       && state->curl->proxy.pwd != NULL) {
-                CHECK(state, CURLOPT_PROXYUSERNAME, state->curl->proxy.user);
-                CHECK(state, CURLOPT_PROXYPASSWORD, state->curl->proxy.pwd);
+	if(state->auth.proxy.host != NULL) {
+	    CHECK(state, CURLOPT_PROXY, state->auth.proxy.host);
+	    CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->auth.proxy.port);
+	    if(state->auth.proxy.user != NULL
+	       && state->auth.proxy.pwd != NULL) {
+                CHECK(state, CURLOPT_PROXYUSERNAME, state->auth.proxy.user);
+                CHECK(state, CURLOPT_PROXYPASSWORD, state->auth.proxy.pwd);
 #ifdef CURLOPT_PROXYAUTH
 	        CHECK(state, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
 #endif
@@ -123,7 +123,7 @@ set_curlflag(NCD4INFO* state, int flag)
     case CURLOPT_SSLCERT: case CURLOPT_SSLKEY:
     case CURLOPT_SSL_VERIFYPEER: case CURLOPT_SSL_VERIFYHOST:
     {
-        struct ssl* ssl = &state->curl->ssl;
+        struct ssl* ssl = &state->auth.ssl;
         CHECK(state, CURLOPT_SSL_VERIFYPEER, (OPTARG)(ssl->verifypeer?1L:0L));
         CHECK(state, CURLOPT_SSL_VERIFYHOST, (OPTARG)(ssl->verifyhost?1L:0L));
         if(ssl->certificate)
@@ -191,20 +191,20 @@ set_curl_options(NCD4INFO* state)
     int ret = NC_NOERR;
     NClist* store = NULL;
     int i;
-    char hostport[NC_MAX_PATH];
+    char* hostport = NULL;
 
-    NCD4_hostport(state->uri,hostport,sizeof(hostport));
+    hostport = NC_combinehostport(state->uri);
 
-    store = NCD4_globalstate->rc.rc;
+    store = ncrc_globalstate.rcinfo.triples;
 
     for(i=0;i<nclistlength(store);i++) {
         struct CURLFLAG* flag;
-	NCD4triple* triple = (NCD4triple*)nclistget(store,i);
+	NCTriple* triple = (NCTriple*)nclistget(store,i);
         size_t hostlen = strlen(triple->host);
         const char* flagname;
         if(strncmp("CURL.",triple->key,5) != 0) continue; /* not a curl flag */
         /* do hostport prefix comparison */
-        if(hostport[0] != '\0') {
+        if(hostport != NULL) {
           int t = strncmp(hostport,triple->host,hostlen);
           if(t !=  0) continue;
         }
@@ -214,6 +214,7 @@ set_curl_options(NCD4INFO* state)
         ret = set_curlopt(state,flag->flag,cvt(triple->value,flag->type));
     }
  done:
+    nullfree(hostport);
     return THROW(ret);
 }
 
@@ -241,7 +242,7 @@ cvt(char* value, enum CURLFLAGTYPE type)
 void
 NCD4_curl_debug(NCD4INFO* state)
 {
-    state->curl->curlflags.verbose = 1;
+    state->auth.curlflags.verbose = 1;
     set_curlflag(state,CURLOPT_VERBOSE);
     set_curlflag(state,CURLOPT_ERRORBUFFER);
 }
@@ -252,18 +253,16 @@ NCD4_curl_debug(NCD4INFO* state)
        "file://..." &/or "https://..." urls.
 */
 void
-NCD4_curl_protocols(NCD4globalstate* state)
+NCD4_curl_protocols(NCD4INFO* state)
 {
     const char* const* proto; /*weird*/
     curl_version_info_data* curldata;
     curldata = curl_version_info(CURLVERSION_NOW);
     for(proto=curldata->protocols;*proto;proto++) {
-        if(strcmp("file",*proto)==0) {state->curl.proto_file=1;}
-        if(strcmp("http",*proto)==0) {state->curl.proto_https=1;}
+        if(strcmp("http",*proto)==0) {state->auth.curlflags.proto_https=1;}
     }
 #ifdef D4DEBUG	
-    nclog(NCLOGNOTE,"Curl file:// support = %d",state->curl.proto_file);
-    nclog(NCLOGNOTE,"Curl https:// support = %d",state->curl.proto_https);
+    nclog(NCLOGNOTE,"Curl https:// support = %d",state->auth.curlflags.proto_https);
 #endif
 }
 
@@ -280,26 +279,26 @@ NCD4_set_curlstate(NCD4INFO* state, int flag, void* value)
     int ret = NC_NOERR;
     switch (flag) {
     case CURLOPT_USERPWD:
-        if(state->curl->creds.userpwd != NULL) free(state->curl->creds.userpwd);
-	state->curl->creds.userpwd = strdup((char*)value);
+        if(info->creds.userpwd != NULL) free(info->creds.userpwd);
+	info->creds.userpwd = strdup((char*)value);
 	break;
     case CURLOPT_COOKIEJAR: case CURLOPT_COOKIEFILE:
-        if(state->curl->curlflags.cookiejar != NULL) free(state->curl->curlflags.cookiejar);
-	state->curl->curlflags.cookiejar = strdup((char*)value);
+        if(info->curlflags.cookiejar != NULL) free(info->curlflags.cookiejar);
+	info->curlflags.cookiejar = strdup((char*)value);
 	break;
     case CURLOPT_NETRC: case CURLOPT_NETRC_FILE:
-        if(state->curl->curlflags.netrc != NULL) free(state->curl->curlflags.netrc);
-	state->curl->curlflags.netrc = strdup((char*)value);
+        if(info->curlflags.netrc != NULL) free(info->curlflags.netrc);
+	info->curlflags.netrc = strdup((char*)value);
 	break;
     case CURLOPT_VERBOSE:
-	state->curl->curlflags.verbose = (long)value;
+	info->curlflags.verbose = (long)value;
 	break;
     case CURLOPT_TIMEOUT:
-	state->curl->curlflags.timeout = (long)value;
+	info->curlflags.timeout = (long)value;
 	break;
     case CURLOPT_USERAGENT:
-        if(state->curl->curlflags.useragent != NULL) free(state->curl->curlflags.useragent);
-        state->curl->curlflags.useragent = strdup((char*)value);
+        if(info->curlflags.useragent != NULL) free(info->curlflags.useragent);
+        info->curlflags.useragent = strdup((char*)value);
 	break;
     case CURLOPT_FOLLOWLOCATION:
 	/* no need to store; will always be set */
@@ -315,38 +314,38 @@ NCD4_set_curlstate(NCD4INFO* state, int flag, void* value)
 	break;
     case CURLOPT_PROXY:
 	/* We assume that the value is the proxy url */
-	if(state->curl->proxy.host != NULL) free(state->curl->proxy.host);
-	if(state->curl->proxy.userpwd != NULL) free(state->curl->proxy.userpwd);
-	state->curl->proxy.host = NULL;
-	state->curl->proxy.userpwd = NULL;
+	if(info->proxy.host != NULL) free(info->proxy.host);
+	if(info->proxy.userpwd != NULL) free(info->proxy.userpwd);
+	info->proxy.host = NULL;
+	info->proxy.userpwd = NULL;
 	if(!NCD4_parseproxy(state,(char*)value))
 		{ret = NC_EINVAL; goto done;}
 	break;
     case CURLOPT_SSLCERT:
-	if(state->curl->ssl.certificate != NULL) free(state->curl->ssl.certificate);
-	state->curl->ssl.certificate = strdup((char*)value);
+	if(info->ssl.certificate != NULL) free(info->ssl.certificate);
+	info->ssl.certificate = strdup((char*)value);
 	break;
     case CURLOPT_SSLKEY:
-	if(state->curl->ssl.key != NULL) free(state->curl->ssl.key);
-	state->curl->ssl.key = strdup((char*)value);
+	if(info->ssl.key != NULL) free(info->ssl.key);
+	info->ssl.key = strdup((char*)value);
 	break;
     case CURLOPT_KEYPASSWD:
-	if(state->curl->ssl.keypasswd!= NULL) free(state->curl->ssl.keypasswd);
-	state->curl->ssl.keypasswd = strdup((char*)value);
+	if(info->ssl.keypasswd!= NULL) free(info->ssl.keypasswd);
+	info->ssl.keypasswd = strdup((char*)value);
 	break;
     case CURLOPT_SSL_VERIFYPEER:
-      state->curl->ssl.verifypeer = (long)value;
+      info->ssl.verifypeer = (long)value;
       break;
     case CURLOPT_SSL_VERIFYHOST:
-      state->curl->ssl.verifyhost = (long)value;
+      info->ssl.verifyhost = (long)value;
       break;
     case CURLOPT_CAINFO:
-      if(state->curl->ssl.cainfo != NULL) free(state->curl->ssl.cainfo);
-      state->curl->ssl.cainfo = strdup((char*)value);
+      if(info->ssl.cainfo != NULL) free(info->ssl.cainfo);
+      info->ssl.cainfo = strdup((char*)value);
       break;
     case CURLOPT_CAPATH:
-	if(state->curl->ssl.capath != NULL) free(state->curl->ssl.capath);
-	state->curl->ssl.capath = strdup((char*)value);
+	if(info->ssl.capath != NULL) free(info->ssl.capath);
+	info->ssl.capath = strdup((char*)value);
 	break;
 
     default: break;
diff --git a/libdap4/d4curlfunctions.h b/libdap4/d4curlfunctions.h
index cadecf5..42c47fe 100644
--- a/libdap4/d4curlfunctions.h
+++ b/libdap4/d4curlfunctions.h
@@ -32,6 +32,6 @@ extern ncerror NCD4_set_curlflag(NCD4INFO*,int);
 extern void NCD4_curl_debug(NCD4INFO* state);
 
 extern struct CURLFLAG* NCD4_curlflagbyname(const char* name);
-extern void NCD4_curl_protocols(NCD4globalstate* state);
+extern void NCD4_curl_protocols(NCD4INFO*);
 
 #endif /*D4CURLFUNCTIONS_H*/
diff --git a/libdap4/d4data.c b/libdap4/d4data.c
index fa39d60..a60210b 100644
--- a/libdap4/d4data.c
+++ b/libdap4/d4data.c
@@ -180,7 +180,6 @@ fillstruct(NCD4meta* meta, NCD4node* type, void** offsetp, void** dstp, NClist*
  
 #ifdef CLEARSTRUCT
     /* Avoid random data within aligned structs */
-    d4size_t prevoffset = 0;    
     memset(dst,0,type->meta.memsize);
 #endif
 
diff --git a/libdap4/d4dump.c b/libdap4/d4dump.c
index 1d8126f..0384fa9 100644
--- a/libdap4/d4dump.c
+++ b/libdap4/d4dump.c
@@ -58,7 +58,7 @@ NCD4_dumpbytes(size_t size, const void* data0, int swap)
         if(v.s[0] == '\r') strcpy(v.s,"\\r");
         else if(v.s[0] == '\n') strcpy(v.s,"\\n");
         else if(v.s[0] < ' ' || v.s[0] >= 0x7f) v.s[0] = '?';
-        fprintf(stderr,"[%03lu] %02x %03u %4d", i, v.u8[0], v.u8[0], v.i8[0]);
+        fprintf(stderr,"[%03lu] %02x %03u %4d", (unsigned long)i, v.u8[0], v.u8[0], v.i8[0]);
         fprintf(stderr," 0x%08x %12u %13d", v.u32[0], v.u32[0], v.i32[0]);
         fprintf(stderr," 0x%04x %06u %7d", v.u16[0], v.u16[0], v.i16[0]);
         fprintf(stderr," '%s'\n",v.s);
diff --git a/libdap4/d4file.c b/libdap4/d4file.c
index 058648a..6574efe 100644
--- a/libdap4/d4file.c
+++ b/libdap4/d4file.c
@@ -29,7 +29,6 @@ static void freeInfo(NCD4INFO*);
 static int paramcheck(NCD4INFO*, const char* key, const char* subkey);
 static const char* getparam(NCD4INFO* info, const char* key);
 static int set_curl_properties(NCD4INFO*);
-static void d4removecookies(const char* path);
 
 /**************************************************/
 /* Constants */
@@ -66,6 +65,11 @@ NCD4_open(const char * path, int mode,
     if(ncuriparse(nc->path,&d4info->uri) != NCU_OK)
 	{ret = NC_EDAPURL; goto done;}
 
+    /* Load auth info from rc file */
+    if((ret = NC_authsetup(&d4info->auth, d4info->uri)))
+	goto done;
+    NCD4_curl_protocols(d4info);
+
     if(!constrainable(d4info->uri))
 	SETFLAG(d4info->controls.flags,NCF_UNCONSTRAINABLE);
 
@@ -308,6 +312,7 @@ freeInfo(NCD4INFO* d4info)
     }
     nullfree(d4info->substrate.filename); /* always reclaim */
     NCD4_reclaimMeta(d4info->substrate.metadata);
+    NC_authclear(&d4info->auth);
     free(d4info);    
 }
 
@@ -319,21 +324,6 @@ freeCurl(NCD4curl* curl)
     ncbytesfree(curl->packet);
     nullfree(curl->errdata.code);
     nullfree(curl->errdata.message);
-    nullfree(curl->curlflags.useragent);
-    nullfree(curl->curlflags.netrc);
-    nullfree(curl->ssl.certificate);
-    nullfree(curl->ssl.key);
-    nullfree(curl->ssl.keypasswd);
-    nullfree(curl->ssl.cainfo);
-    nullfree(curl->ssl.capath);
-    nullfree(curl->proxy.host);
-    nullfree(curl->proxy.user);
-    nullfree(curl->proxy.pwd);
-    nullfree(curl->creds.user);
-    nullfree(curl->creds.pwd);
-    if(curl->curlflags.createdflags & COOKIECREATED)
-        d4removecookies(curl->curlflags.cookiejar);
-    nullfree(curl->curlflags.cookiejar);
 }
 
 /* Define the set of protocols known to be constrainable */
@@ -358,61 +348,56 @@ set_curl_properties(NCD4INFO* d4info)
 {
     int ret = NC_NOERR;
 
-    /* defaults first */
-    NCD4_rcdefault(d4info);
-
-    /* extract the relevant triples into d4info */
-    NCD4_rcprocess(d4info);
-
-    if(d4info->curl->curlflags.useragent == NULL) {
-        size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1;
-	char* agent = (char*)malloc(len+1);
+    if(d4info->auth.curlflags.useragent == NULL) {
+	char* agent;
+        size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION);
+	len++; /*strlcat nul*/
+	agent = (char*)malloc(len+1);
 	strncpy(agent,DFALTUSERAGENT,len);
-	strncat(agent,VERSION,len);
-        d4info->curl->curlflags.useragent = agent;
+	strlcat(agent,VERSION,len);
+        d4info->auth.curlflags.useragent = agent;
     }
 
     /* Some servers (e.g. thredds and columbia) appear to require a place
        to put cookies in order for some security functions to work
     */
-    if(d4info->curl->curlflags.cookiejar != NULL
-       && strlen(d4info->curl->curlflags.cookiejar) == 0) {
-	free(d4info->curl->curlflags.cookiejar);
-	d4info->curl->curlflags.cookiejar = NULL;
+    if(d4info->auth.curlflags.cookiejar != NULL
+       && strlen(d4info->auth.curlflags.cookiejar) == 0) {
+	free(d4info->auth.curlflags.cookiejar);
+	d4info->auth.curlflags.cookiejar = NULL;
     }
 
-    if(d4info->curl->curlflags.cookiejar == NULL) {
+    if(d4info->auth.curlflags.cookiejar == NULL) {
 	/* If no cookie file was defined, define a default */
-        int ok;
         char* path = NULL;
-        char* name = NULL;
+        char* newpath = NULL;
         int len;
 	errno = 0;
 	/* Create the unique cookie file name */
         len =
-	  strlen(NCD4_globalstate->tempdir)
+	  strlen(ncrc_globalstate.tempdir)
 	  + 1 /* '/' */
 	  + strlen("ncd4cookies");
         path = (char*)malloc(len+1);
         if(path == NULL) return NC_ENOMEM;
-	snprintf(path,len,"%s/nc4cookies",NCD4_globalstate->tempdir);
+	snprintf(path,len,"%s/nc4cookies",ncrc_globalstate.tempdir);
 	/* Create the unique cookie file name */
-        ok = NCD4_mktmp(path,&name);
+        newpath = NC_mktmp(path);
         free(path);
-	if(ok != NC_NOERR && errno != EEXIST) {
+	if(newpath == NULL) {
 	    fprintf(stderr,"Cannot create cookie file\n");
 	    goto fail;
 	}
-	d4info->curl->curlflags.cookiejar = name;
-	d4info->curl->curlflags.createdflags |= COOKIECREATED;
+	d4info->auth.curlflags.cookiejar = newpath;
+	d4info->auth.curlflags.cookiejarcreated = 1;
 	errno = 0;
     }
-    assert(d4info->curl->curlflags.cookiejar != NULL);
+    assert(d4info->auth.curlflags.cookiejar != NULL);
 
     /* Make sure the cookie jar exists and can be read and written */
     {
 	FILE* f = NULL;
-	char* fname = d4info->curl->curlflags.cookiejar;
+	char* fname = d4info->auth.curlflags.cookiejar;
 	/* See if the file exists already */
         f = fopen(fname,"r");
 	if(f == NULL) {
@@ -442,7 +427,6 @@ fail:
 static void
 applyclientparamcontrols(NCD4INFO* info)
 {
-    NCD4meta* meta = info->substrate.metadata;
     const char* value;
 
     /* clear the flags */
@@ -516,12 +500,3 @@ getparam(NCD4INFO* info, const char* key)
     return value;
 }
 
-static void
-d4removecookies(const char* path)
-{
-#ifdef _MSC_VER
-    DeleteFile(path);
-#else
-    remove(path);
-#endif
-}
diff --git a/libdap4/d4http.c b/libdap4/d4http.c
index 2b260f3..03c5495 100644
--- a/libdap4/d4http.c
+++ b/libdap4/d4http.c
@@ -87,8 +87,7 @@ fail:
 }
 
 int
-NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime,
-           struct credentials* creds)
+NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime)
 {
     int ret = NC_NOERR;
     CURLcode cstat = CURLE_OK;
@@ -291,7 +290,7 @@ NCD4_ping(const char* url)
 
     /* Try to get the file */
     buf = ncbytesnew();
-    ret = NCD4_fetchurl(curl,url,buf,NULL,NULL);
+    ret = NCD4_fetchurl(curl,url,buf,NULL);
     if(ret == NC_NOERR) {
         /* Don't trust curl to return an error when request gets 404 */
         long http_code = 0;
diff --git a/libdap4/d4includes.h b/libdap4/d4includes.h
index dfcb152..6979e78 100644
--- a/libdap4/d4includes.h
+++ b/libdap4/d4includes.h
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <inttypes.h>
 #include <assert.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -32,6 +33,7 @@
 
 #include "netcdf.h"
 #include "nc.h"
+#include "ncrc.h"
 #include "ncbytes.h"
 #include "nclist.h"
 #include "ncuri.h"
diff --git a/libdap4/d4meta.c b/libdap4/d4meta.c
index a0c4c42..6d615e5 100644
--- a/libdap4/d4meta.c
+++ b/libdap4/d4meta.c
@@ -42,7 +42,7 @@ static int decodeEconst(NCD4meta* builder, NCD4node* enumtype, const char* nameo
 static int downConvert(union ATOMICS* converter, NCD4node* type);
 static void freeStringMemory(char** mem, int count);
 static size_t getDimrefs(NCD4node* var, int* dimids);
-static size_t getDimsizes(NCD4node* var, size_t* dimsizes);
+static size_t getDimsizes(NCD4node* var, int* dimsizes);
 static void reclaimNode(NCD4node* node);
 static d4size_t getpadding(d4size_t offset, size_t alignment);
 static int markdapsize(NCD4meta* meta);
@@ -523,7 +523,7 @@ buildCompound(NCD4meta* builder, NCD4node* cmpdtype, NCD4node* group, char* name
     /* Step 3: add the fields to type */
     for(i=0;i<nclistlength(cmpdtype->vars);i++) {  
 	int rank;
-	size_t dimsizes[NC_MAX_VAR_DIMS];
+	int dimsizes[NC_MAX_VAR_DIMS];
         NCD4node* field = (NCD4node*)nclistget(cmpdtype->vars,i);
 	rank = nclistlength(field->dims);
         if(rank == 0) { /* scalar */
@@ -531,11 +531,15 @@ buildCompound(NCD4meta* builder, NCD4node* cmpdtype, NCD4node* group, char* name
 					field->name, field->meta.offset,
 					field->basetype->meta.id)));
         } else if(rank > 0) { /* array  */
+  	    int idimsizes[NC_MAX_VAR_DIMS];
+	    int j;
 	    getDimsizes(field,dimsizes);
+	    /* nc_insert_array_compound: dimsizes arg is not size_t */
+	    for(j=0;j<rank;j++) idimsizes[j] = (int)dimsizes[j];
             NCCHECK((nc_insert_array_compound(group->meta.id, cmpdtype->meta.id,
 					      field->name, field->meta.offset,
 					      field->basetype->meta.id,
-					      rank, dimsizes)));
+					      rank, idimsizes)));
 	}
     }
 
@@ -681,13 +685,13 @@ getDimrefs(NCD4node* var, int* dimids)
 }
 
 static size_t
-getDimsizes(NCD4node* var, size_t* dimsizes)
+getDimsizes(NCD4node* var, int* dimsizes)
 {
     int i;
     int rank = nclistlength(var->dims);
     for(i=0;i<rank;i++) {
 	NCD4node* dim = (NCD4node*)nclistget(var->dims,i);
-	dimsizes[i] = dim->dim.size;
+	dimsizes[i] = (int)dim->dim.size;
     }
     return rank;
 }
@@ -729,7 +733,7 @@ compileAttrValues(NCD4meta* builder, NCD4node* basetype, NClist* values, void**
     if(!ISTYPE(truebase->sort) || (truebase->meta.id > NC_MAX_ATOMIC_TYPE))
         FAIL(NC_EBADTYPE,"Illegal attribute type: %s",basetype->name);
     size = NCD4_typesize(truebase->meta.id);
-    if((memory = (char*)d4alloc(count*size))==NULL)
+    if((memory = (unsigned char*)d4alloc(count*size))==NULL)
         return THROW(NC_ENOMEM);
     p = memory;
     for(i=0;i<count;i++) {
@@ -780,17 +784,17 @@ convertString(union ATOMICS* converter, NCD4node* type, const char* s)
     case NC_SHORT:
     case NC_INT:
     case NC_INT64:
-	if(sscanf(s,"%lld",&converter->i64) != 1) return THROW(NC_ERANGE);
+	if(sscanf(s,"%lld",&converter->i64[0]) != 1) return THROW(NC_ERANGE);
 	break;
     case NC_UBYTE:
     case NC_USHORT:
     case NC_UINT:
     case NC_UINT64:
-	if(sscanf(s,"%llu",&converter->u64) != 1) return THROW(NC_ERANGE);
+	if(sscanf(s,"%llu",&converter->u64[0]) != 1) return THROW(NC_ERANGE);
 	break;
     case NC_FLOAT:
     case NC_DOUBLE:
-	if(sscanf(s,"%lf",&converter->f64) != 1) return THROW(NC_ERANGE);
+	if(sscanf(s,"%lf",&converter->f64[0]) != 1) return THROW(NC_ERANGE);
 	break;
     case NC_CHAR:
 	converter->i8[0] = s[0];
diff --git a/libdap4/d4odom.c b/libdap4/d4odom.c
index 4975505..419bb41 100644
--- a/libdap4/d4odom.c
+++ b/libdap4/d4odom.c
@@ -76,14 +76,14 @@ d4odom_print(D4odometer* odom)
     char tmp[64];
     line[0] = '\0';
     if(odom->rank == 0) {
-	strcat(line,"[]");
+	strlcat(line,"[]",sizeof(line));
     } else for(i=0;i<odom->rank;i++) {
 	sprintf(tmp,"[%lu/%lu:%lu:%lu]",
 		(size_t)odom->index[i],
 		(size_t)odom->start[i],
 		(size_t)odom->stride[i],
 		(size_t)odom->length[i]);
-	strcat(line,tmp);	
+	strlcat(line,tmp,sizeof(line));	
     }
     return line;
 }
diff --git a/libdap4/d4parser.c b/libdap4/d4parser.c
index dc56568..2cbe430 100644
--- a/libdap4/d4parser.c
+++ b/libdap4/d4parser.c
@@ -525,7 +525,7 @@ parseSequence(NCD4parser* parser, NCD4node* container, ezxml_t xml, NCD4node** n
 	vlentype->basetype = var->basetype;
 	/* Use name <fqnname>_t */
 	strncpy(name,fqnname,sizeof(name));
-	strncat(name,"_t",sizeof(name)-strlen(name));
+	strlcat(name,"_t",sizeof(name));
         SETNAME(vlentype,name);
         /* Set the basetype */
         var->basetype = vlentype;
@@ -540,7 +540,7 @@ parseSequence(NCD4parser* parser, NCD4node* container, ezxml_t xml, NCD4node** n
         classify(group,structtype);
 	/* Use name <fqnname>_base */
 	strncpy(name,fqnname,sizeof(name));
-	strncat(name,"_base",sizeof(name)-strlen(name));
+	strlcat(name,"_base",sizeof(name));
         SETNAME(structtype,name);
         /* Parse Fields into type */
         if((ret = parseFields(parser,structtype,xml))) goto done;
@@ -549,7 +549,7 @@ parseSequence(NCD4parser* parser, NCD4node* container, ezxml_t xml, NCD4node** n
         classify(group,vlentype);
 	/* Use name <xname>_t */
 	strncpy(name,fqnname,sizeof(name));
-	strncat(name,"_t",sizeof(name)-strlen(name));
+	strlcat(name,"_t",sizeof(name));
         SETNAME(vlentype,name);
 	vlentype->basetype = structtype;
         /* Set the basetype */
@@ -1133,11 +1133,13 @@ keyword(const char* name)
     int n = sizeof(keywordmap)/sizeof(KEYWORDINFO);
     int L = 0;
     int R = (n - 1);
+    int m, cmp;
+    struct KEYWORDINFO* p;
     for(;;) {
 	if(L > R) break;
-        int m = (L + R) / 2;
-	struct KEYWORDINFO* p = &keywordmap[m];
-	int cmp = strcasecmp(p->tag,name);
+        m = (L + R) / 2;
+	p = &keywordmap[m];
+	cmp = strcasecmp(p->tag,name);
 	if(cmp == 0) return p;
 	if(cmp < 0)
 	    L = (m + 1);
@@ -1196,13 +1198,14 @@ lookupAtomictype(NCD4parser* parser, const char* name)
     int n = nclistlength(parser->atomictypes);
     int L = 0;
     int R = (n - 1);
+    int m, cmp;
     NCD4node* p;
 
     for(;;) {
 	if(L > R) break;
-        int m = (L + R) / 2;
+        m = (L + R) / 2;
 	p = (NCD4node*)nclistget(parser->atomictypes,m);
-	int cmp = strcasecmp(p->name,name);
+	cmp = strcasecmp(p->name,name);
 	if(cmp == 0) return p;
 	if(cmp < 0)
 	    L = (m + 1);
diff --git a/libdap4/d4rc.c b/libdap4/d4rc.c
deleted file mode 100644
index 4788099..0000000
--- a/libdap4/d4rc.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*********************************************************************
- *   Copyright 2016, UCAR/Unidata
- *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
- *********************************************************************/
-
-#include "d4includes.h"
-
-#define D4RCFILEENV "DAPRCFILE"
-
-#define RTAG ']'
-#define LTAG '['
-
-#define TRIMCHARS " \t\r\n"
-
-#undef MEMCHECK
-#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
-
-/* Forward */
-static int rccompile(const char* path);
-static struct NCD4triple* rclocate(char* key, char* hostport);
-static NClist* rcorder(NClist* rc);
-static char* rcreadline(char**);
-static int rcsearch(const char* prefix, const char* rcname, char** pathp);
-static void rctrim(char* text);
-static int rcsetinfocurlflag(NCD4INFO*, const char* flag, const char* value);
-static int parsecredentials(const char* userpwd, char** userp, char** pwdp);
-#ifdef D4DEBUG
-static void storedump(char* msg, NClist* triples);
-#endif
-
-/* Define default rc files and aliases, also defines search order*/
-static char* rcfilenames[] = {".daprc",".dodsrc",NULL};
-
-/* Define the curl flag defaults in envv style */
-static const char* RCDEFAULTFLAGS[] = {
-"HTTP.TIMEOUT","10", /*seconds */
-NULL
-};
-
-static char*
-rcreadline(char** nextlinep)
-{
-    char* line;
-    char* p;
-
-    line = (p = *nextlinep);
-    if(*p == '\0') return NULL; /*signal done*/
-    for(;*p;p++) {
-	if(*p == '\r' && p[1] == '\n') *p = '\0';
-	else if(*p == '\n') break;
-    }
-    *p++ = '\0'; /* null terminate line; overwrite newline */
-    *nextlinep = p;
-    return line;
-}
-
-/* Trim TRIMCHARS from both ends of text; */
-static void
-rctrim(char* text)
-{
-    char* p = text;
-    size_t len;
-    int i;
-
-    len = strlen(text);
-    /* locate first non-trimchar */
-    for(;*p;p++) {
-       if(strchr(TRIMCHARS,*p) == NULL) break; /* hit non-trim char */
-    }
-    d4memmove(text,p,strlen(p)+1);
-    len = strlen(text);
-    /* locate last non-trimchar */
-    if(len > 0) {
-        for(i=(len-1);i>=0;i--) {
-            if(strchr(TRIMCHARS,text[i]) == NULL) {
-                text[i+1] = '\0'; /* elide trailing trimchars */
-                break;
-            }
-        }
-    }
-}
-
-/* Order the triples: those with urls must be first,
-   but otherwise relative order does not matter.
-*/
-static NClist*
-rcorder(NClist* rc)
-{
-    int i,j;
-    int len = nclistlength(rc);
-    NClist* newrc = nclistnew();
-    if(rc == NULL || len == 0) return newrc;
-    /* Two passes: 1) pull triples with host */
-    for(i=0;i<len;i++) {
-        NCD4triple* ti = nclistget(rc,i);
-	if(ti->host == NULL) continue;
-	nclistpush(newrc,ti);
-    }
-    /* pass 2 pull triples without host*/
-    for(i=0;i<len;i++) {
-        NCD4triple* ti = nclistget(rc,i);
-	if(ti->host != NULL) continue;
-	nclistpush(newrc,ti);
-    }
-#ifdef D4DEBUG
-
-    storedump("reorder:",newrc);
-#endif
-    return newrc;
-
-}
-
-/* Create a triple store from a file */
-static int
-rccompile(const char* path)
-{
-    int ret = NC_NOERR;
-    NClist* rc = NCD4_globalstate->rc.rc;
-    char* contents = NULL;
-    NCbytes* tmp = ncbytesnew();
-    NCURI* uri = NULL;
-    char* nextline = NULL;
-
-    if((ret=NCD4_readfile(path,tmp))) {
-        nclog(NCLOGERR, "Could not open configuration file: %s",path);	
-	goto done;    
-    }
-    contents = ncbytesextract(tmp);
-    if(contents == NULL) contents = strdup("");
-    NCD4_rcfree(rc); /* clear out any old data */
-    rc = nclistnew();
-    nextline = contents;
-    for(;;) {
-	char* line;
-	char* key;
-        char* value;
-	size_t llen;
-        NCD4triple* triple;
-
-	line = rcreadline(&nextline);
-	if(line == NULL) break; /* done */
-        rctrim(line);  /* trim leading and trailing blanks */
-        if(line[0] == '#') continue; /* comment */
-	if((llen=strlen(line)) == 0) continue; /* empty line */
-	triple = (NCD4triple*)calloc(1,sizeof(NCD4triple));
-	if(triple == NULL) {ret = NC_ENOMEM; goto done;}
-        if(line[0] == LTAG) {
-            char* url = ++line;
-            char* rtag = strchr(line,RTAG);
-            if(rtag == NULL) {
-                nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
-                continue;
-            }
-            line = rtag + 1;
-            *rtag = '\0';
-            /* compile the url and pull out the host */
-	    if(uri) ncurifree(uri);
-	    if(ncuriparse(url,&uri) != NCU_OK) {
-                nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
-		continue;
-	    }
-	    ncbytesclear(tmp);
-	    ncbytescat(tmp,uri->host);
-	    if(uri->port != NULL) {
-		ncbytesappend(tmp,':');
-	        ncbytescat(tmp,uri->port);	
-	    }
-	    ncbytesnull(tmp);
-	    triple->host = ncbytesextract(tmp);
-        }
-        /* split off key and value */
-        key=line;
-        value = strchr(line, '=');
-        if(value == NULL)
-            value = line + strlen(line);
-        else {
-            *value = '\0';
-            value++;
-        }
-	triple->key = strdup(key);
-        triple->value = strdup(value);
-        rctrim(triple->key);
-        rctrim(triple->value);
-#ifdef D4DEBUG
-	fprintf(stderr,"rc: host=%s key=%s value=%s\n",
-		triple->host,triple->key,triple->valu);
-#endif
-	nclistpush(rc,triple);
-	triple = NULL;
-    }
-    rcorder(rc);
-
-done:
-    ncurifree(uri);
-    ncbytesfree(tmp);
-    return THROW(ret);
-}
-
-/* locate, read and compile the rc file, if any */
-int
-NCD4_rcload(void)
-{
-    int ret = NC_NOERR;
-    char* path = NULL;
-
-    if(NCD4_globalstate->rc.ignore) {
-        nclog(NCLOGDBG,"No runtime configuration file specified; continuing");
-	return THROW(NC_NOERR);
-    }
-    if(NCD4_globalstate->rc.loaded) return THROW(NC_NOERR);
-
-    /* locate the configuration files in the following order:
-       1. specified by NCD4_set_rcfile
-       2. set by DAPRCFILE env variable
-       3. '.'
-       4. $HOME
-    */
-    if(NCD4_globalstate->rc.rcfile != NULL) { /* always use this */
-	path = strdup(NCD4_globalstate->rc.rcfile);
-    } else if(getenv(RCFILEENV) != NULL && strlen(getenv(RCFILEENV)) > 0) {
-        path = strdup(getenv(RCFILEENV));
-    } else {
-	char** rcname;
-	int found = 0;
-	for(rcname=rcfilenames;!found && *rcname;rcname++) {
-	    ret = rcsearch(".",*rcname,&path);
-    	    if(ret == NC_NOERR && path == NULL)  /* try $HOME */
-	        ret = rcsearch(NCD4_globalstate->home,*rcname,&path);
-	    if(ret != NC_NOERR)
-		goto done;
-	    if(path != NULL)
-		found = 1;
-	}
-    }
-    if(path == NULL) {
-        nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
-    } else {
-#ifdef D4DEBUG
-        fprintf(stderr, "RC file: %s\n", path);
-#endif
-        if((ret=rccompile(path))) {
-	    nclog(NCLOGERR, "Error parsing %s\n",path);
-	    goto done;
-	}
-    }
-done:
-    NCD4_globalstate->rc.loaded = 1; /* even if not exists */
-    nullfree(path);
-    return THROW(ret);
-}
-
-static int
-rcsetinfocurlflag(NCD4INFO* info, const char* flag, const char* value)
-{
-    int ret = NC_NOERR;
-    if(value == NULL) goto done;
-    if(strcmp(flag,"HTTP.DEFLATE")==0) {
-        if(atoi(value)) info->curl->curlflags.compress = 1;
-#ifdef D4DEBUG
-        nclog(NCLOGNOTE,"HTTP.DEFLATE: %ld", info->curlflags.compress);
-#endif
-    }
-    if(strcmp(flag,"HTTP.VERBOSE")==0) {
-        if(atoi(value)) info->curl->curlflags.verbose = 1;
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.VERBOSE: %ld", info->curl->curlflags.verbose);
-#endif
-    }
-    if(strcmp(flag,"HTTP.TIMEOUT")==0) {
-        if(atoi(value)) info->curl->curlflags.timeout = atoi(value);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.TIMEOUT: %ld", info->curl->curlflags.timeout);
-#endif
-    }
-    if(strcmp(flag,"HTTP.USERAGENT")==0) {
-        if(atoi(value)) info->curl->curlflags.useragent = strdup(value);
-        MEMCHECK(info->curl->curlflags.useragent);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.USERAGENT: %s", info->curl->curlflags.useragent);
-#endif
-    }
-    if(
-	strcmp(flag,"HTTP.COOKIEFILE")==0
-        || strcmp(flag,"HTTP.COOKIE_FILE")==0
-        || strcmp(flag,"HTTP.COOKIEJAR")==0
-        || strcmp(flag,"HTTP.COOKIE_JAR")==0
-      ) {
-	nullfree(info->curl->curlflags.cookiejar);
-        info->curl->curlflags.cookiejar = strdup(value);
-        MEMCHECK(info->curl->curlflags.cookiejar);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.COOKIEJAR: %s", info->curl->curlflags.cookiejar);
-#endif
-    }
-    if(strcmp(flag,"HTTP.PROXY_SERVER")==0) {
-        ret = NCD4_parseproxy(info,value);
-        if(ret != NC_NOERR) goto done;
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.PROXY_SERVER: %s", value);
-#endif
-    }
-    if(strcmp(flag,"HTTP.SSL.VALIDATE")==0) {
-        if(atoi(value)) {
-	    info->curl->ssl.verifypeer = 1;
-	    info->curl->ssl.verifyhost = 1;
-#ifdef D4DEBUG
-                nclog(NCLOGNOTE,"HTTP.SSL.VALIDATE: %ld", 1);
-#endif
-	}
-    }
-
-    if(strcmp(flag,"HTTP.SSL.CERTIFICATE")==0) {
-	nullfree(info->curl->ssl.certificate);
-        info->curl->ssl.certificate = strdup(value);
-        MEMCHECK(info->curl->ssl.certificate);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.SSL.CERTIFICATE: %s", info->curl->ssl.certificate);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.SSL.KEY")==0) {
-	nullfree(info->curl->ssl.key);
-        info->curl->ssl.key = strdup(value);
-        MEMCHECK(info->curl->ssl.key);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.SSL.KEY: %s", info->curl->ssl.key);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.SSL.KEYPASSWORD")==0) {
-	nullfree(info->curl->ssl.keypasswd) ;
-        info->curl->ssl.keypasswd = strdup(value);
-        MEMCHECK(info->curl->ssl.keypasswd);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.SSL.KEYPASSWORD: %s", info->curl->ssl.keypasswd);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.SSL.CAINFO")==0) {
-	nullfree(info->curl->ssl.cainfo) ;
-        info->curl->ssl.cainfo = strdup(value);
-        MEMCHECK(info->curl->ssl.cainfo);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.SSL.CAINFO: %s", info->curl->ssl.cainfo);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.SSL.CAPATH")==0) {
-	nullfree(info->curl->ssl.capath) ;
-        info->curl->ssl.capath = strdup(value);
-        MEMCHECK(info->curl->ssl.capath);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.SSL.CAPATH: %s", info->curl->ssl.capath);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.SSL.VERIFYPEER")==0) {
-        const char* s = value;
-        int tf = 0;
-        if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0)
-            tf = 0;
-        else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0)
-            tf = 1;
-        else
-            tf = 1; /* default if not null */
-        info->curl->ssl.verifypeer = tf;
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", info->curl->ssl.verifypeer);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.NETRC")==0) {
-        nullfree(info->curl->curlflags.netrc);
-        info->curl->curlflags.netrc = strdup(value);
-        MEMCHECK(info->curl->curlflags.netrc);
-#ifdef D4DEBUG
-            nclog(NCLOGNOTE,"HTTP.NETRC: %s", info->curl->curlflags.netrc);
-#endif
-    }
-
-    if(strcmp(flag,"HTTP.CREDENTIALS.USERNAME")==0) {
-        nullfree(info->curl->creds.user);
-        info->curl->creds.user = strdup(value);
-        MEMCHECK(info->curl->creds.user);
-    }
-    if(strcmp(flag,"HTTP.CREDENTIALS.PASSWORD")==0) {
-        nullfree(info->curl->creds.pwd);
-        info->curl->creds.pwd = strdup(value);
-        MEMCHECK(info->curl->creds.pwd);
-    }
-
-done:
-    return THROW(ret);
-
-nomem:
-    return THROW(NC_ENOMEM);
-}
-
-int
-NCD4_rcprocess(NCD4INFO* info)
-{
-    int ret = NC_NOERR;
-    char hostport[NC_MAX_PATH];
-    char* url_hostport = hostport; /* WATCH OUT: points to previous variable */
-    NCURI* uri = info->uri;
-
-    assert (NCD4_globalstate != NULL);
-
-    if(!NCD4_globalstate->rc.loaded)
-	NCD4_rcload();
-
-    /* Note, we still must do this function even if
-       NCD4_globalstate->rc.ignore is set in order
-       to getinfo e.g. host+port  from url
-    */
-
-    url_hostport = NULL;
-    if(uri != NULL) {
-        NCD4_hostport(uri,url_hostport,sizeof(hostport));
-    }
-
-    rcsetinfocurlflag(info,"HTTP.DEFLATE",
-		      NCD4_rclookup("HTTP.DEFLATE",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.VERBOSE",
-			NCD4_rclookup("HTTP.VERBOSE",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.TIMEOUT",
-			NCD4_rclookup("HTTP.TIMEOUT",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.USERAGENT",
-			NCD4_rclookup("HTTP.USERAGENT",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.COOKIEFILE",
-			NCD4_rclookup("HTTP.COOKIEFILE",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.COOKIE_FILE",
-			NCD4_rclookup("HTTP.COOKIE_FILE",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.COOKIEJAR",
-			NCD4_rclookup("HTTP.COOKIEJAR",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.COOKIE_JAR",
-			NCD4_rclookup("HTTP.COOKIE_JAR",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.PROXY_SERVER",
-			NCD4_rclookup("HTTP.PROXY_SERVER",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.VALIDATE",
-			NCD4_rclookup("HTTP.SSL.VALIDATE",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.CERTIFICATE",
-			NCD4_rclookup("HTTP.SSL.CERTIFICATE",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.KEY",
-			NCD4_rclookup("HTTP.SSL.KEY",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.KEYPASSWORD",
-			NCD4_rclookup("HTTP.SSL.KEYPASSWORD",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.CAINFO",
-			NCD4_rclookup("HTTP.SSL.CAINFO",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.CAPATH",
-			NCD4_rclookup("HTTP.SSL.CAPATH",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.SSL.VERIFYPEER",
-			NCD4_rclookup("HTTP.SSL.VERIFYPEER",url_hostport));
-    rcsetinfocurlflag(info,"HTTP.NETRC",
-			NCD4_rclookup("HTTP.NETRC",url_hostport));
-    { /* Handle various cases for user + password */
-	/* First, see if the user+pwd was in the original url */
-	char* user = NULL;
-	char* pwd = NULL;
-	if(uri->user != NULL && uri->password != NULL) {
-	    user = uri->user;
-	    pwd = uri->password;
-	} else {
-   	    user = NCD4_rclookup("HTTP.CREDENTIALS.USER",url_hostport);
-	    pwd = NCD4_rclookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
-	}
-	if(user != NULL && pwd != NULL) {
-            user = strdup(user); /* so we can consistently reclaim */
-            pwd = strdup(pwd);
-	} else {
-	    /* Could not get user and pwd, so try USERPASSWORD */
-	    const char* userpwd = NCD4_rclookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
-	    if(userpwd != NULL) {
-		ret = parsecredentials(userpwd,&user,&pwd);
-		if(ret) return ret;
-	    }
-        }
-        rcsetinfocurlflag(info,"HTTP.USERNAME",user);
-        rcsetinfocurlflag(info,"HTTP.PASSWORD",pwd);
-	nullfree(user);
-	nullfree(pwd);
-    }
-    return THROW(ret);
-}
-
-/**
- * (Internal) Locate a triple by property key and host+port (may be null or "").
- * If duplicate keys, first takes precedence.
- */
-static struct NCD4triple*
-rclocate(char* key, char* hostport)
-{
-    int i,found;
-    NClist* rc = NCD4_globalstate->rc.rc;
-    NCD4triple* triple = NULL;
-
-    if(NCD4_globalstate->rc.ignore)
-	return NULL;
-    if(!NCD4_globalstate->rc.loaded)
-	NCD4_rcload();
-
-    if(key == NULL || rc == NULL) return NULL;
-    if(hostport == NULL) hostport = "";
-
-    for(found=0,i=0;i<nclistlength(rc);i++) {
-	triple = (NCD4triple*)nclistget(rc,i);
-        size_t hplen = strlen(triple->host);
-        int t;
-        if(strcmp(key,triple->key) != 0) continue; /* keys do not match */
-        /* If the triple entry has no url, then use it
-           (because we have checked all other cases)*/
-        if(hplen == 0) {found=1;break;}
-        /* do hostport match */
-        t = strcmp(hostport,triple->host);
-        if(t ==  0) {found=1; break;}
-    }
-    return (found?triple:NULL);
-}
-
-/**
- * Locate a triple by property key and host+port (may be null|"")
- * If duplicate keys, first takes precedence.
- */
-char*
-NCD4_rclookup(char* key, char* hostport)
-{
-    struct NCD4triple* triple = rclocate(key,hostport);
-    return (triple == NULL ? NULL : triple->value);
-}
-
-#ifdef D4DEBUG
-static void
-storedump(char* msg, NClist* triples)
-{
-    int i;
-
-    if(msg != NULL) fprintf(stderr,"%s\n",msg);
-    if(triples == NULL || nclistlength(triples)==0) {
-        fprintf(stderr,"<EMPTY>\n");
-        return;
-    }
-    for(i=0;i<nclistlength(triples);i++) {
-	NCD4triple* t = (NCD4triple*)nclistget(triples,i);
-        fprintf(stderr,"\t%s\t%s\t%s\n",
-
-                ((t->host == NULL || strlen(t->host)==0)?"--":t->host),t->key,t->value);
-
-    }
-    fflush(stderr);
-}
-#endif
-
-/**
- * Locate rc file by searching in directory prefix.
- * Prefix must end in '/'
- */
-static
-int
-rcsearch(const char* prefix, const char* rcname, char** pathp)
-{
-    char* path = NULL;
-    FILE* f = NULL;
-    int plen = strlen(prefix);
-    int rclen = strlen(rcname);
-    int ret = NC_NOERR;
-
-    size_t pathlen = plen+rclen+1; /*+1 for '/' */
-    path = (char*)malloc(pathlen+1); /* +1 for nul*/
-    if(path == NULL) {ret = NC_ENOMEM;	goto done;}
-    strncpy(path,prefix,pathlen);
-    strncat(path,"/",pathlen);
-    strncat(path,rcname,pathlen);
-    /* see if file is readable */
-    f = fopen(path,"r");
-    if(f != NULL)
-        nclog(NCLOGDBG, "Found rc file=%s",path);
-done:
-    if(f == NULL || ret != NC_NOERR) {
-	nullfree(path);
-	path = NULL;
-    }
-    if(f != NULL)
-      fclose(f);
-    if(pathp != NULL)
-      *pathp = path;
-    else {
-      nullfree(path);
-      path = NULL;
-    }
-    return THROW(ret);
-}
-
-void
-NCD4_rcfree(NClist* rc)
-{
-    int i;
-    for(i=0;i<nclistlength(rc);i++) {
-	NCD4triple* t = (NCD4triple*)nclistget(rc,i);
-	nullfree(t->host);
-	nullfree(t->key);
-	nullfree(t->value);
-	free(t);
-    }
-    nclistfree(rc);
-}
-
-int
-NCD4_parseproxy(NCD4INFO* info, const char* surl)
-{
-    int ret = NC_NOERR;
-    NCURI* uri = NULL;
-    if(surl == NULL || strlen(surl) == 0)
-	return THROW(NC_NOERR); /* nothing there*/
-    if(ncuriparse(surl,&uri) != NCU_OK)
-	return THROW(NC_EURL);
-    info->curl->proxy.user = uri->user;
-    info->curl->proxy.pwd = uri->password;
-    info->curl->proxy.host = strdup(uri->host);
-    if(uri->port != NULL)
-        info->curl->proxy.port = atoi(uri->port);
-    else
-        info->curl->proxy.port = 80;
-    return THROW(ret);
-}
-
-/*
-Given form user:pwd, parse into user and pwd
-and do %xx unescaping
-*/
-static int
-parsecredentials(const char* userpwd, char** userp, char** pwdp)
-{
-    char* user = NULL;
-    char* pwd = NULL;
-
-    if(userpwd == NULL)
-	return NC_EINVAL;
-    user = strdup(userpwd);
-    if(user == NULL)
-	return NC_ENOMEM;
-    pwd = strchr(user,':');
-    if(pwd == NULL)
-	return NC_EINVAL;
-    *pwd = '\0';
-    pwd++;
-    if(userp)
-	*userp = ncuridecode(user);
-    if(pwdp)
-	*pwdp = ncuridecode(pwd);
-    free(user);
-    return NC_NOERR;
-}
-
-int
-NCD4_rcdefault(NCD4INFO* info)
-{
-    int ret = NC_NOERR;
-    const char** p;
-    for(p=RCDEFAULTFLAGS;*p;p+=2) {
-	ret = rcsetinfocurlflag(info,p[0],p[1]);
-	if(ret) {
-            nclog(NCLOGERR, "RC file defaulting failed for: %s=%s",p[0],p[1]);
-	}
-    }
-    return THROW(ret);
-}
diff --git a/libdap4/d4read.c b/libdap4/d4read.c
index 51f21a4..b3d87b5 100644
--- a/libdap4/d4read.c
+++ b/libdap4/d4read.c
@@ -37,7 +37,7 @@ NCD4_readDAP(NCD4INFO* state, int flags)
     } else { /*((flags & NCF_ONDISK) != 0) */
         NCURI* url = state->uri;
         int fileprotocol = (strcmp(url->protocol,"file")==0);
-        if(fileprotocol && !state->curl->curlflags.proto_file) {
+        if(fileprotocol) {
             stat = readfiletofile(url, ".dap", state->data.ondiskfile, &state->data.datasize);
         } else {
 	    char* readurl = NULL;
@@ -86,7 +86,7 @@ readpacket(NCD4INFO* state, NCURI* url, NCbytes* packet, NCD4mode dxx, long* las
 
     fileprotocol = (strcmp(url->protocol,"file")==0);
 
-    if(fileprotocol && !state->curl->curlflags.proto_file) {
+    if(fileprotocol) {
 	/* Short circuit file://... urls*/
 	/* We do this because the test code always needs to read files*/
 	stat = readfile(url,suffix,packet);
@@ -99,7 +99,7 @@ readpacket(NCD4INFO* state, NCURI* url, NCbytes* packet, NCD4mode dxx, long* las
 	MEMCHECK(fetchurl);
 	if(state->debug > 0)
             {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);}
-        stat = NCD4_fetchurl(curl,fetchurl,packet,lastmodified,&state->curl->creds);
+        stat = NCD4_fetchurl(curl,fetchurl,packet,lastmodified);
         nullfree(fetchurl);
 	if(stat) goto fail;
 	if(state->debug > 0)
@@ -150,11 +150,6 @@ static int
 readfile(const NCURI* uri, const char* suffix, NCbytes* packet)
 {
     int stat = NC_NOERR;
-    char buf[1024];
-    int fd = -1;
-    int flags = 0;
-    d4size_t filesize = 0;
-    d4size_t totalread = 0;
     NCbytes* tmp = ncbytesnew();
     char* filename = NULL;
 
@@ -163,53 +158,7 @@ readfile(const NCURI* uri, const char* suffix, NCbytes* packet)
     ncbytesnull(tmp);
     filename = ncbytesextract(tmp);
     ncbytesfree(tmp);
-    flags = O_RDONLY;
-#ifdef O_BINARY
-    flags |= O_BINARY;
-#endif
-
-    fd = NCopen2(filename,flags);
-    if(fd < 0) {
-	nclog(NCLOGERR,"open failed:%s",filename);
-	fprintf(stderr,"XXX: open failed: flags=0x%x file=%s\n",flags,filename);
-        fflush(stderr);
-	stat = NC_ENOTFOUND;
-	goto done;
-    }
-    /* Get the file size */
-    filesize = lseek(fd,(d4size_t)0,SEEK_END);
-    if(filesize < 0) {
-	stat = NC_EIO;
-	nclog(NCLOGERR,"lseek failed: %s",filename);
-	goto done;
-    }
-    /* Move file pointer back to the beginning of the file */
-    (void)lseek(fd,(d4size_t)0,SEEK_SET);
-    stat = NC_NOERR;
-    for(totalread=0;;) {
-	d4size_t count = (d4size_t)read(fd,buf,sizeof(buf));
-	if(count == 0)
-	    break; /*eof*/
-	else if(count <  0) {
-	    stat = NC_EIO;
-	    nclog(NCLOGERR,"read failed: %s",filename);
-	    goto done;
-	}
-	ncbytesappendn(packet,buf,(unsigned long)count);
-	totalread += count;
-    }
-    if(totalread < filesize) {
-	stat = NC_EIO;
-	nclog(NCLOGERR,"short read: |%s|=%lu read=%lu\n",
-		filename,(unsigned long)filesize,(unsigned long)totalread);
-        goto done;
-    }
 
-done:
-#ifdef D4DEBUG
-fprintf(stderr,"readfile: filesize=%lu totalread=%lu\n",
-		(unsigned long)filesize,(unsigned long)totalread);
-#endif
-    if(fd >= 0) close(fd);
+    stat = NC_readfile(filename,packet);
     return THROW(stat);
 }
diff --git a/libdap4/d4swap.c b/libdap4/d4swap.c
index daed375..2278d73 100644
--- a/libdap4/d4swap.c
+++ b/libdap4/d4swap.c
@@ -235,7 +235,7 @@ walkSeq(NCD4meta* compiler, NCD4node* topvar, NCD4node* vlentype, void** offsetp
         swapinline64(&recordcount);
 
     basetype = vlentype->basetype; /* This may be of any type potentially */
-    assert(basetype->sort = NCD4_TYPE);
+    assert(basetype->sort == NCD4_TYPE);
 
     for(i=0;i<recordcount;i++) {
         switch(basetype->subsort) {
diff --git a/libdap4/d4util.c b/libdap4/d4util.c
index 59e6c65..c5a2b54 100644
--- a/libdap4/d4util.c
+++ b/libdap4/d4util.c
@@ -102,6 +102,7 @@ char*
 NCD4_makeFQN(NCD4node* node)
 {
     char* fqn = NULL;
+    char* escaped;
     int i;
     NCD4node* g = node;
     NClist* path = nclistnew();
@@ -112,19 +113,20 @@ NCD4_makeFQN(NCD4node* node)
 	nclistinsert(path,0,g);
     }
     estimate = (estimate*2) + 2*nclistlength(path);
-    /* start at 1 to avoid dataset */
+    estimate++; /*strlcat nul*/
     fqn = (char*)malloc(estimate+1);
     if(fqn == NULL) goto done;
     fqn[0] = '\0';
     /* Create the group-based fqn prefix */
+    /* start at 1 to avoid dataset */
     for(i=1;i<nclistlength(path);i++) {
 	NCD4node* elem = (NCD4node*)nclistget(path,i);
 	if(elem->sort != NCD4_GROUP) break;
 	/* Add in the group name */
-	char* escaped = backslashEscape(elem->name);
+	escaped = backslashEscape(elem->name);
 	if(escaped == NULL) {free(fqn); fqn = NULL; goto done;}
-	strcat(fqn,"/");
-	strcat(fqn,escaped);
+	strlcat(fqn,"/",estimate);
+	strlcat(fqn,escaped,estimate);
 	free(escaped);
     }
     /* Add in the final name part (if not group) */
@@ -132,8 +134,8 @@ NCD4_makeFQN(NCD4node* node)
 	int last = nclistlength(path)-1;
 	NCD4node* n = (NCD4node*)nclistget(path,last);
 	char* name = NCD4_makeName(n,".");
-	strcat(fqn,"/");
-	strcat(fqn,name);
+	strlcat(fqn,"/",estimate);
+	strlcat(fqn,name,estimate);
 	nullfree(name);
     }
 
@@ -160,7 +162,7 @@ NCD4_makeName(NCD4node* elem, const char* sep)
 	nclistinsert(path,0,n);
 	estimate += (1+(2*strlen(n->name)));
     }
-
+    estimate++; /*strlcat nul*/
     fqn = (char*)malloc(estimate+1);
     if(fqn == NULL) goto done;
     fqn[0] = '\0';
@@ -170,8 +172,8 @@ NCD4_makeName(NCD4node* elem, const char* sep)
 	char* escaped = backslashEscape(elem->name);
 	if(escaped == NULL) {free(fqn); fqn = NULL; goto done;}
 	if(i > 0)
-	    strcat(fqn,sep);
-	strcat(fqn,escaped);
+	    strlcat(fqn,sep,estimate);
+	strlcat(fqn,escaped,estimate);
 	free(escaped);
     }
 done:
@@ -326,103 +328,6 @@ NCD4_entityescape(const char* s)
     return escaped;
 }
 
-int
-NCD4_readfile(const char* filename, NCbytes* content)
-{
-    int ret = NC_NOERR;
-    FILE* stream = NULL;
-    char part[1024];
-
-    stream = fopen(filename,"r");
-    if(stream == NULL) {ret=errno; goto done;}
-    for(;;) {
-	size_t count = fread(part, 1, sizeof(part), stream);
-	if(count <= 0) break;
-	ncbytesappendn(content,part,count);
-	if(ferror(stream)) {ret = NC_EIO; goto done;}
-	if(feof(stream)) break;
-    }
-    ncbytesnull(content);
-done:
-    if(stream) fclose(stream);
-    return ret;
-}
-
-/**
-Wrap mktmp and return the generated name
-*/
-
-int
-NCD4_mktmp(const char* base, char** tmpnamep)
-{
-    int fd;
-    char tmp[NC_MAX_PATH];
-#ifdef HAVE_MKSTEMP
-    mode_t mask;
-#endif
-
-    strncpy(tmp,base,sizeof(tmp));
-#ifdef HAVE_MKSTEMP
-    strncat(tmp,"XXXXXX",sizeof(tmp)-strlen(tmp));
-    /* Note Potential problem: old versions of this function
-       leave the file in mode 0666 instead of 0600 */
-    mask=umask(0077);
-    fd = mkstemp(tmp);
-    (void)umask(mask);
-#else /* !HAVE_MKSTEMP */
-    /* Need to simulate by using some kind of pseudo-random number */
-    {
-	int rno = rand();
-	char spid[7];
-	if(rno < 0) rno = -rno;
-        snprintf(spid,sizeof(spid),"%06d",rno);
-        strncat(tmp,spid,sizeof(tmp));
-#if defined(_WIN32) || defined(_WIN64)
-        fd=open(tmp,O_RDWR|O_BINARY|O_CREAT, _S_IREAD|_S_IWRITE);
-#  else
-        fd=open(tmp,O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
-#  endif
-    }
-#endif /* !HAVE_MKSTEMP */
-    if(fd < 0) {
-       nclog(NCLOGERR, "Could not create temp file: %s",tmp);
-       return THROW(NC_EPERM);
-    } else
-	close(fd);
-    if(tmpnamep) *tmpnamep = strdup(tmp);
-    return THROW(NC_NOERR);
-}
-
-void
-NCD4_hostport(NCURI* uri, char* space, size_t len)
-{
-    if(space != NULL && len >  0) {
-	space[0] = '\0'; /* so we can use strncat */
-        if(uri->host != NULL) {
-	    strncat(space,uri->host,len);
-            if(uri->port != NULL) {
-	        strncat(space,":",len);
-	        strncat(space,uri->port,len);
-	    }
-	}
-    }
-}
-
-#if 0
-void
-NCD4_userpwd(NCURI* uri, char* space, size_t len)
-{
-    if(space != NULL && len > 0) {
-	space[0] = '\0'; /* so we can use strncat */
-        if(uri->user != NULL && uri->password != NULL) {
-            strncat(space,uri->user,len);
-            strncat(space,":",len);
-            strncat(space,uri->password,len);
-	}
-    }
-}
-#endif
-
 #ifdef BLOB
 void
 NCD4_saveblob(NCD4meta* meta, void* mem)
@@ -439,8 +344,8 @@ NCD4_saveblob(NCD4meta* meta, void* mem)
 int
 NCD4_error(int code, const int line, const char* file, const char* fmt, ...)
 {
-    fprintf(stderr,"(%s:%d) ",file,line);
     va_list argv;
+    fprintf(stderr,"(%s:%d) ",file,line);
     va_start(argv,fmt);
     vfprintf(stderr,fmt,argv);
     fprintf(stderr,"\n");
diff --git a/libdap4/d4varx.c b/libdap4/d4varx.c
index d944f7d..2bbd28b 100644
--- a/libdap4/d4varx.c
+++ b/libdap4/d4varx.c
@@ -21,7 +21,7 @@ NCD4_get_vara(int ncid, int varid,
 {
     int ret;
     /* TODO: optimize since we know stride is 1 */
-    ret = NCD4_get_vars(ncid,varid,start,edges,nc_sizevector1,value,memtype);
+    ret = NCD4_get_vars(ncid,varid,start,edges,(ptrdiff_t *)nc_sizevector1,value,memtype);
     return ret;
 }
 
diff --git a/libdap4/ncd4.h b/libdap4/ncd4.h
index 2c47e55..2995edd 100644
--- a/libdap4/ncd4.h
+++ b/libdap4/ncd4.h
@@ -84,7 +84,7 @@ extern NCerror NCD4_getvarx(int ncid, int varid,
 /* From d4http.c */
 extern long NCD4_fetchhttpcode(CURL* curl);
 extern int NCD4_fetchurl_file(CURL* curl, const char* url, FILE* stream, d4size_t* sizep, long* filetime);
-extern int NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime, struct credentials* creds);
+extern int NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime);
 extern int NCD4_curlopen(CURL** curlp);
 extern void NCD4_curlclose(CURL* curl);
 extern int NCD4_fetchlastmodified(CURL* curl, char* url, long* filetime);
@@ -128,16 +128,13 @@ extern int NCD4_getToplevelVars(NCD4meta* meta, NCD4node* group, NClist* topleve
 
 /* From d4util.c */
 extern d4size_t NCD4_dimproduct(NCD4node* node);
-extern void NCD4_hostport(NCURI* uri, char* space, size_t len);
 extern size_t NCD4_typesize(nc_type tid);
 extern int NCD4_isLittleEndian(void);/* Return 1 if this machine is little endian */
 extern int NCD4_errorNC(int code, const int line, const char* file);
 extern int NCD4_error(int code, const int line, const char* file, const char* fmt, ...);
 extern char* NCD4_makeFQN(NCD4node* node);
 extern char* NCD4_makeName(NCD4node*,const char* sep);
-extern int NCD4_mktmp(const char* base, char** tmpnamep);
 extern int NCD4_parseFQN(const char* fqn0, NClist* pieces);
-extern int NCD4_readfile(const char* filename, NCbytes* content);
 extern char* NCD4_deescape(const char* esc);
 extern char* NCD4_entityescape(const char* s);
 
diff --git a/libdap4/ncd4dispatch.c b/libdap4/ncd4dispatch.c
index df66fa5..b374af2 100644
--- a/libdap4/ncd4dispatch.c
+++ b/libdap4/ncd4dispatch.c
@@ -56,21 +56,13 @@ NCD4_initialize(void)
     /* Init global state */
     globalinit();
     /* Load rc file */
-    NCD4_rcload();    
+    NC_rcload();    
     return THROW(NC_NOERR);
 }
 
 int
 NCD4_finalize(void)
 {
-    if(NCD4_globalstate != NULL) {
-        nullfree(NCD4_globalstate->tempdir);
-        nullfree(NCD4_globalstate->home);
-	nclistfree(NCD4_globalstate->rc.rc);
-	nullfree(NCD4_globalstate->rc.rcfile);
-	free(NCD4_globalstate);
-	NCD4_globalstate = NULL;
-    }
     return THROW(NC_NOERR);
 }
 
@@ -247,6 +239,12 @@ NCD4_def_var_endian(int ncid, int p2, int p3)
 }
 
 static int
+NCD4_def_var_filter(int ncid, int varid, unsigned int id, size_t n, const unsigned int* parms)
+{
+    return (NC_EPERM);
+}
+
+static int
 NCD4_set_var_chunk_cache(int ncid, int p2, size_t p3, size_t p4, float p5)
 {
     return (NC_EPERM);
@@ -421,7 +419,8 @@ NCD4_inq_var_all(int ncid, int varid, char *name, nc_type* xtypep,
                int* shufflep, int* deflatep, int* deflate_levelp,
                int* fletcher32p, int* contiguousp, size_t* chunksizesp,
                int* no_fill, void* fill_valuep, int* endiannessp,
-	       int* options_maskp, int* pixels_per_blockp)
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               )
 {
     NC* ncp;
     int ret;
@@ -433,7 +432,7 @@ NCD4_inq_var_all(int ncid, int varid, char *name, nc_type* xtypep,
                shufflep, deflatep, deflate_levelp,
                fletcher32p, contiguousp, chunksizesp,
                no_fill, fill_valuep, endiannessp,
-	       options_maskp, pixels_per_blockp);
+               idp, nparamsp, params);
     return (ret);
 }
 
@@ -796,82 +795,11 @@ static int
 globalinit(void)
 {
     int stat = NC_NOERR;
-    if(NCD4_globalstate != NULL) return stat;
-    NCD4_globalstate = (NCD4globalstate*)calloc(1,sizeof(NCD4globalstate));
-    if(NCD4_globalstate == NULL) {
-	nclog(NCLOGERR, "Out of memory");
-	return stat;
-    }
-
-    /* Capture temp dir*/
-    {
-	char* tempdir;
-	char* p;
-	char* q;
-	char cwd[NC_MAX_PATH];
-#if defined(_WIN32) || defined(_WIN64)
-        tempdir = getenv("TEMP");
-#else
-	tempdir = "/tmp";
-#endif
-        if(tempdir == NULL) {
-	    fprintf(stderr,"Cannot find a temp dir; using ./\n");
-#if defined(_WIN32) || defined(_WIN64)
-	    tempdir = getcwd(cwd,sizeof(cwd));
-#else
-	    tempdir = getcwd(cwd,sizeof(cwd));
-#endif
-	    if(tempdir == NULL || *tempdir == '\0') tempdir = ".";
-	}
-        NCD4_globalstate->tempdir= (char*)malloc(strlen(tempdir) + 1);
-	for(p=tempdir,q=NCD4_globalstate->tempdir;*p;p++,q++) {
-	    if((*p == '/' && *(p+1) == '/')
-	       || (*p == '\\' && *(p+1) == '\\')) {p++;}
-	    *q = *p;
-	}
-	*q = '\0';
-#if defined(_WIN32) || defined(_WIN64)
-#else
-        /* Canonicalize */
-	for(p=NCD4_globalstate->tempdir;*p;p++) {
-	    if(*p == '\\') {*p = '/'; };
-	}
-	*q = '\0';
-#endif
-    }
-
-    /* Capture $HOME */
-    {
-	char* p;
-	char* q;
-        char* home = getenv("HOME");
-
-        if(home == NULL) {
-	    /* use tempdir */
-	    home = NCD4_globalstate->tempdir;
-	}
-        NCD4_globalstate->home = (char*)malloc(strlen(home) + 1);
-	for(p=home,q=NCD4_globalstate->home;*p;p++,q++) {
-	    if((*p == '/' && *(p+1) == '/')
-	       || (*p == '\\' && *(p+1) == '\\')) {p++;}
-	    *q = *p;
-	}
-	*q = '\0';
-#if defined(_WIN32) || defined(_WIN64)
-#else
-        /* Canonicalize */
-	for(p=home;*p;p++) {
-	    if(*p == '\\') {*p = '/'; };
-	}
-#endif
-    }
-
     {
 	CURLcode cstat = curl_global_init(CURL_GLOBAL_DEFAULT);
 	if(cstat != CURLE_OK)
 	    fprintf(stderr,"curl_global_init failed!\n");
     }
-    NCD4_curl_protocols(NCD4_globalstate); /* see what protocols are supported */
     return stat;
 }
 
@@ -962,6 +890,7 @@ NCD4_def_var_fletcher32,
 NCD4_def_var_chunking,
 NCD4_def_var_fill,
 NCD4_def_var_endian,
+NCD4_def_var_filter,
 NCD4_set_var_chunk_cache,
 NCD4_get_var_chunk_cache,
 
diff --git a/libdap4/ncd4types.h b/libdap4/ncd4types.h
index 1043758..993faff 100644
--- a/libdap4/ncd4types.h
+++ b/libdap4/ncd4types.h
@@ -13,6 +13,9 @@ are defined here.
 
 #undef COMPILEBYDEFAULT
 
+#include "ncrc.h"
+#include "ncauth.h"
+
 /*
 Control if struct fields can be map targets.
 Currently turned off because semantics are unclear.
@@ -261,31 +264,6 @@ typedef struct NCD4parser {
 
 /**************************************************/
 
-typedef struct NCD4triple {
-        char* host; /* includes port if specified */
-        char* key;
-        char* value;
-} NCD4triple;
-
-
-/**************************************************/
-
-/* Collect global state info in one place */
-struct NCD4globalstate {
-    struct {
-        int proto_file;
-        int proto_https;
-    } curl;
-    char* tempdir; /* track a usable temp dir */
-    char* home; /* track $HOME for use in creating $HOME/.oc dir */
-    struct {
-	int ignore; /* if 1, then do not use any rc file */
-	int loaded;
-        NClist* rc; /*NClist<NCD4triple>; the rc file triple store fields*/
-        char* rcfile; /* specified rcfile; overrides anything else */
-    } rc;
-};
-
 /* Curl info */
 struct NCD4curl {
     CURL* curl; /* curl handle*/
@@ -296,42 +274,6 @@ struct NCD4curl {
 	long  httpcode;
 	char  errorbuf[CURL_ERROR_SIZE]; /* CURLOPT_ERRORBUFFER*/
     } errdata;
-    struct curlflags {
-        int proto_file; /* Is file: supported? */
-        int proto_https; /* is https: supported? */
-	int compress; /*CURLOPT_ENCODING*/
-	int verbose; /*CURLOPT_ENCODING*/
-	int timeout; /*CURLOPT_TIMEOUT*/
-	int maxredirs; /*CURLOPT_MAXREDIRS*/
-	char* useragent; /*CURLOPT_USERAGENT*/
-	/* track which of these are created by oc */
-#define COOKIECREATED 1
-#define NETRCCREATED 2
-	int createdflags;
-	char* cookiejar; /*CURLOPT_COOKIEJAR,CURLOPT_COOKIEFILE*/
-	char* netrc; /*CURLOPT_NETRC,CURLOPT_NETRC_FILE*/
-    } curlflags;
-    struct ssl {
-	int   verifypeer; /* CURLOPT_SSL_VERIFYPEER;
-                             do not do this when cert might be self-signed
-                             or temporarily incorrect */
-	int   verifyhost; /* CURLOPT_SSL_VERIFYHOST; for client-side verification */
-        char* certificate; /*CURLOPT_SSLCERT*/
-	char* key; /*CURLOPT_SSLKEY*/
-	char* keypasswd; /*CURLOPT_SSLKEYPASSWD*/
-        char* cainfo; /* CURLOPT_CAINFO; certificate authority */
-	char* capath;  /*CURLOPT_CAPATH*/
-    } ssl;
-    struct proxy {
-	char *host; /*CURLOPT_PROXY*/
-	int port; /*CURLOPT_PROXYPORT*/
-	char* user; /*CURLOPT_PROXYUSERNAME*/
-	char* pwd; /*CURLOPT_PROXYPASSWORD*/
-    } proxy;
-    struct credentials {
-	char *user; /*CURLOPT_USERNAME*/
-	char *pwd; /*CURLOPT_PASSWORD*/
-    } creds;
 };
 
 /**************************************************/
@@ -365,6 +307,7 @@ struct NCD4INFO {
 	NCD4translation translation;
 	char substratename[NC_MAX_NAME];
     } controls;
+    NCauth auth;
 };
 
 #endif /*D4TYPES_H*/
diff --git a/libdispatch/CMakeLists.txt b/libdispatch/CMakeLists.txt
index 4a2536e..2613b82 100644
--- a/libdispatch/CMakeLists.txt
+++ b/libdispatch/CMakeLists.txt
@@ -1,7 +1,7 @@
-SET(libdispatch_SOURCES dparallel.c dcopy.c dfile.c ddim.c datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c dvarinq.c ddispatch.c nclog.c dstring.c dutf8.c dinternal.c doffsets.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c utf8proc.h utf8proc.c dwinpath.c)
+SET(libdispatch_SOURCES dparallel.c dcopy.c dfile.c ddim.c datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c dvarinq.c ddispatch.c nclog.c dstring.c dutf8.c dinternal.c doffsets.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c utf8proc.h utf8proc.c dwinpath.c dutil.c drc.c dauth.c)
 
 IF(USE_NETCDF4)
-  SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c)
+  SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c dfilter.c)
 ENDIF(USE_NETCDF4)
 
 IF(BUILD_V2)
diff --git a/libdispatch/Makefile.am b/libdispatch/Makefile.am
index 42d868c..a1e9008 100644
--- a/libdispatch/Makefile.am
+++ b/libdispatch/Makefile.am
@@ -20,7 +20,7 @@ dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c	\
 dvarinq.c dinternal.c ddispatch.c dutf8.c                               \
 nclog.c dstring.c                           \
 ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c                        \
-nc.c nclistmgr.c drc.c doffsets.c dwinpath.c
+nc.c nclistmgr.c drc.c dauth.c doffsets.c dwinpath.c dutil.c
 
 # Add the utf8 codebase
 libdispatch_la_SOURCES += utf8proc.c utf8proc.h
@@ -28,17 +28,12 @@ libdispatch_la_SOURCES += utf8proc.c utf8proc.h
 # Add functions only found in netCDF-4.
 if USE_NETCDF4
 libdispatch_la_SOURCES += dgroup.c dvlen.c dcompound.c dtype.c denum.c	\
-dopaque.c ncaux.c
+dopaque.c dfilter.c ncaux.c
 endif # USE_NETCDF4
 
-# Turn on pre-processor flag when building a DLL for windows.
-if BUILD_DLL
-libdispatch_la_CPPFLAGS += -DDLL_EXPORT
-endif # BUILD_DLL
-
 # Add V2 API convenience library if needed.
 if BUILD_V2
-noinst_LTLIBRARIES += libnetcdf2.la 
+noinst_LTLIBRARIES += libnetcdf2.la
 libnetcdf2_la_SOURCES = dv2i.c
 libnetcdf2_la_CPPFLAGS = ${AM_CPPFLAGS} -DDLL_EXPORT
 endif # BUILD_V2
@@ -70,4 +65,3 @@ test_ncuri_SOURCES = test_ncuri.c ncuri.c ncbytes.c nclist.c
 test_pathcvt_SOURCES = test_pathcvt.c dwinpath.c
 check_PROGRAMS = test_ncuri test_pathcvt
 TESTS = test_ncuri test_pathcvt
-
diff --git a/libdispatch/Makefile.in b/libdispatch/Makefile.in
index 5a1bc52..f0441bf 100644
--- a/libdispatch/Makefile.in
+++ b/libdispatch/Makefile.in
@@ -107,19 +107,13 @@ host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
 # Add functions only found in netCDF-4.
- at USE_NETCDF4_TRUE@am__append_3 = dgroup.c dvlen.c dcompound.c dtype.c denum.c	\
- at USE_NETCDF4_TRUE@dopaque.c ncaux.c
-
+ at USE_NETCDF4_TRUE@am__append_2 = dgroup.c dvlen.c dcompound.c dtype.c denum.c	\
+ at USE_NETCDF4_TRUE@dopaque.c dfilter.c ncaux.c
 
-# Turn on pre-processor flag when building a DLL for windows.
- at BUILD_DLL_TRUE@am__append_4 = -DDLL_EXPORT
 
 # Add V2 API convenience library if needed.
- at BUILD_V2_TRUE@am__append_5 = libnetcdf2.la 
+ at BUILD_V2_TRUE@am__append_3 = libnetcdf2.la
 check_PROGRAMS = test_ncuri$(EXEEXT) test_pathcvt$(EXEEXT)
 TESTS = test_ncuri$(EXEEXT) test_pathcvt$(EXEEXT)
 subdir = libdispatch
@@ -141,14 +135,16 @@ am__libdispatch_la_SOURCES_DIST = dparallel.c dcopy.c dfile.c ddim.c \
 	datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c \
 	dvarput.c dvarinq.c dinternal.c ddispatch.c dutf8.c nclog.c \
 	dstring.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c \
-	nclistmgr.c drc.c doffsets.c dwinpath.c utf8proc.c utf8proc.h \
-	dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c
+	nclistmgr.c drc.c dauth.c doffsets.c dwinpath.c dutil.c \
+	utf8proc.c utf8proc.h dgroup.c dvlen.c dcompound.c dtype.c \
+	denum.c dopaque.c dfilter.c ncaux.c
 @USE_NETCDF4_TRUE at am__objects_1 = libdispatch_la-dgroup.lo \
 @USE_NETCDF4_TRUE@	libdispatch_la-dvlen.lo \
 @USE_NETCDF4_TRUE@	libdispatch_la-dcompound.lo \
 @USE_NETCDF4_TRUE@	libdispatch_la-dtype.lo \
 @USE_NETCDF4_TRUE@	libdispatch_la-denum.lo \
 @USE_NETCDF4_TRUE@	libdispatch_la-dopaque.lo \
+ at USE_NETCDF4_TRUE@	libdispatch_la-dfilter.lo \
 @USE_NETCDF4_TRUE@	libdispatch_la-ncaux.lo
 am_libdispatch_la_OBJECTS = libdispatch_la-dparallel.lo \
 	libdispatch_la-dcopy.lo libdispatch_la-dfile.lo \
@@ -163,8 +159,9 @@ am_libdispatch_la_OBJECTS = libdispatch_la-dparallel.lo \
 	libdispatch_la-nclist.lo libdispatch_la-ncbytes.lo \
 	libdispatch_la-nchashmap.lo libdispatch_la-nctime.lo \
 	libdispatch_la-nc.lo libdispatch_la-nclistmgr.lo \
-	libdispatch_la-drc.lo libdispatch_la-doffsets.lo \
-	libdispatch_la-dwinpath.lo libdispatch_la-utf8proc.lo \
+	libdispatch_la-drc.lo libdispatch_la-dauth.lo \
+	libdispatch_la-doffsets.lo libdispatch_la-dwinpath.lo \
+	libdispatch_la-dutil.lo libdispatch_la-utf8proc.lo \
 	$(am__objects_1)
 libdispatch_la_OBJECTS = $(am_libdispatch_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
@@ -457,11 +454,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -484,12 +480,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -515,6 +513,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -529,6 +528,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -632,13 +632,13 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 
 # This is our output, the dispatch convenience library.
-noinst_LTLIBRARIES = libdispatch.la $(am__append_5)
-libdispatch_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_4)
+noinst_LTLIBRARIES = libdispatch.la $(am__append_3)
+libdispatch_la_CPPFLAGS = ${AM_CPPFLAGS}
 
 # The source files.
 
@@ -647,8 +647,8 @@ libdispatch_la_SOURCES = dparallel.c dcopy.c dfile.c ddim.c datt.c \
 	dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c \
 	dvarput.c dvarinq.c dinternal.c ddispatch.c dutf8.c nclog.c \
 	dstring.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c \
-	nclistmgr.c drc.c doffsets.c dwinpath.c utf8proc.c utf8proc.h \
-	$(am__append_3)
+	nclistmgr.c drc.c dauth.c doffsets.c dwinpath.c dutil.c \
+	utf8proc.c utf8proc.h $(am__append_2)
 @BUILD_V2_TRUE at libnetcdf2_la_SOURCES = dv2i.c
 @BUILD_V2_TRUE at libnetcdf2_la_CPPFLAGS = ${AM_CPPFLAGS} -DDLL_EXPORT
 EXTRA_DIST = CMakeLists.txt ncsettings.hdr utf8proc_data.c
@@ -736,6 +736,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dattget.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dattinq.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dattput.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dauth.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dcompound.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dcopy.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-ddim.Plo at am__quote@
@@ -743,6 +744,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-denum.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-derror.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dfile.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dfilter.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dgroup.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dinternal.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-doffsets.Plo at am__quote@
@@ -752,6 +754,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dstring.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dtype.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dutf8.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dutil.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dvar.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dvarget.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdispatch_la-dvarinq.Plo at am__quote@
@@ -981,6 +984,13 @@ libdispatch_la-drc.lo: drc.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) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdispatch_la-drc.lo `test -f 'drc.c' || echo '$(srcdir)/'`drc.c
 
+libdispatch_la-dauth.lo: dauth.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdispatch_la-dauth.lo -MD -MP -MF $(DEPDIR)/libdispatch_la-dauth.Tpo -c -o libdispatch_la-dauth.lo `test -f 'dauth.c' || echo '$(srcdir)/'`dauth.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdispatch_la-dauth.Tpo $(DEPDIR)/libdispatch_la-dauth.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='dauth.c' object='libdispatch_la-dauth.lo' libtool=yes @AMDEPBACKSLASH@
+ at 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) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdispatch_la-dauth.lo `test -f 'dauth.c' || echo '$(srcdir)/'`dauth.c
+
 libdispatch_la-doffsets.lo: doffsets.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdispatch_la-doffsets.lo -MD -MP -MF $(DEPDIR)/libdispatch_la-doffsets.Tpo -c -o libdispatch_la-doffsets.lo `test -f 'doffsets.c' || echo '$(srcdir)/'`doffsets.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdispatch_la-doffsets.Tpo $(DEPDIR)/libdispatch_la-doffsets.Plo
@@ -995,6 +1005,13 @@ libdispatch_la-dwinpath.lo: dwinpath.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) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdispatch_la-dwinpath.lo `test -f 'dwinpath.c' || echo '$(srcdir)/'`dwinpath.c
 
+libdispatch_la-dutil.lo: dutil.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdispatch_la-dutil.lo -MD -MP -MF $(DEPDIR)/libdispatch_la-dutil.Tpo -c -o libdispatch_la-dutil.lo `test -f 'dutil.c' || echo '$(srcdir)/'`dutil.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdispatch_la-dutil.Tpo $(DEPDIR)/libdispatch_la-dutil.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='dutil.c' object='libdispatch_la-dutil.lo' libtool=yes @AMDEPBACKSLASH@
+ at 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) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdispatch_la-dutil.lo `test -f 'dutil.c' || echo '$(srcdir)/'`dutil.c
+
 libdispatch_la-utf8proc.lo: utf8proc.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdispatch_la-utf8proc.lo -MD -MP -MF $(DEPDIR)/libdispatch_la-utf8proc.Tpo -c -o libdispatch_la-utf8proc.lo `test -f 'utf8proc.c' || echo '$(srcdir)/'`utf8proc.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdispatch_la-utf8proc.Tpo $(DEPDIR)/libdispatch_la-utf8proc.Plo
@@ -1044,6 +1061,13 @@ libdispatch_la-dopaque.lo: dopaque.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) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdispatch_la-dopaque.lo `test -f 'dopaque.c' || echo '$(srcdir)/'`dopaque.c
 
+libdispatch_la-dfilter.lo: dfilter.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdispatch_la-dfilter.lo -MD -MP -MF $(DEPDIR)/libdispatch_la-dfilter.Tpo -c -o libdispatch_la-dfilter.lo `test -f 'dfilter.c' || echo '$(srcdir)/'`dfilter.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdispatch_la-dfilter.Tpo $(DEPDIR)/libdispatch_la-dfilter.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='dfilter.c' object='libdispatch_la-dfilter.lo' libtool=yes @AMDEPBACKSLASH@
+ at 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) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdispatch_la-dfilter.lo `test -f 'dfilter.c' || echo '$(srcdir)/'`dfilter.c
+
 libdispatch_la-ncaux.lo: ncaux.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdispatch_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdispatch_la-ncaux.lo -MD -MP -MF $(DEPDIR)/libdispatch_la-ncaux.Tpo -c -o libdispatch_la-ncaux.lo `test -f 'ncaux.c' || echo '$(srcdir)/'`ncaux.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdispatch_la-ncaux.Tpo $(DEPDIR)/libdispatch_la-ncaux.Plo
diff --git a/libdispatch/datt.c b/libdispatch/datt.c
index 0b0a064..9a9df35 100644
--- a/libdispatch/datt.c
+++ b/libdispatch/datt.c
@@ -1,10 +1,9 @@
 /** \file
-Attribute functions
+Copyright 2010 University Corporation for Atmospheric
+Research/Unidata. See \ref copyright file for more info.  
 
 These functions read and write attributes.
-
-Copyright 2010 University Corporation for Atmospheric
-Research/Unidata. See \ref copyright file for more info.  */
+*/
 
 #include "ncdispatch.h"
 
@@ -16,11 +15,11 @@ Attributes hold metadata about data and files.
 
 Attributes may be associated with a netCDF variable to specify such
 properties as units, special values, maximum and minimum valid values,
-scaling factors, and offsets. 
+scaling factors, and offsets.
 
 Attributes for a netCDF dataset are defined when the dataset is first
 created, while the netCDF dataset is in define mode. Additional
-attributes may be added later by reentering define mode. 
+attributes may be added later by reentering define mode.
 
 A netCDF attribute has a netCDF variable to which it is assigned, a
 name, a type, a length, and a sequence of one or more values. 
@@ -38,9 +37,10 @@ more space than the attribute as originally defined.
 
 It is also possible to have attributes that are not associated with
 any variable. These are called global attributes and are identified by
-using ::NC_GLOBAL as a variable pseudo-ID. Global attributes are usually
-related to the netCDF dataset as a whole and may be used for purposes
-such as providing a title or processing history for a netCDF dataset.
+using ::NC_GLOBAL as a variable pseudo-ID. Global attributes are
+usually related to the netCDF dataset as a whole and may be used for
+purposes such as providing a title or processing history for a netCDF
+dataset.
 
 Operations supported on attributes are:
 - Create an attribute, given its variable ID, name, data type, length,
@@ -102,6 +102,20 @@ dataset named foo.nc:
      status = nc_rename_att(ncid, rh_id, "units", "Units");
      if (status != NC_NOERR) handle_error(status);
 \endcode
+
+\returns NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Bad varid.
+\returns ::NC_EBADNAME Bad name.
+\returns ::NC_EMAXNAME New name too long.
+\returns ::NC_EINVAL Name or new name not provided.
+\returns ::NC_ENAMEINUSE Name already in use.
+\returns ::NC_EPERM File was opened read only.
+\returns ::NC_ENOTINDEFINE File is not in define mode.
+\returns ::NC_ENOTATT Attribute not found.
+\returns ::NC_EHDFERR Failure at HDF5 layer.
+\returns ::NC_ENOMEM Out of memory.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
  */
 int
 nc_rename_att(int ncid, int varid, const char *name, const char *newname)
@@ -153,6 +167,17 @@ Units for a variable rh in an existing netCDF dataset named foo.nc:
      status = nc_enddef(ncid);
      if (status != NC_NOERR) handle_error(status);
 \endcode
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Bad varid.
+\returns ::NC_EBADNAME Bad name.
+\returns ::NC_EINVAL Name not provided.
+\returns ::NC_EPERM File was opened read only.
+\returns ::NC_ENOTINDEFINE File is not in define mode.
+\returns ::NC_ENOTATT Attribute not found.
+\returns ::NC_EATTMETA Failure at HDF5 layer.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
  */
 int
 nc_del_att(int ncid, int varid, const char *name)
diff --git a/libdispatch/dattget.c b/libdispatch/dattget.c
index 2fbc11f..3f71679 100644
--- a/libdispatch/dattget.c
+++ b/libdispatch/dattget.c
@@ -20,7 +20,7 @@ Get an attribute of any type.
 
 The nc_get_att() functions works for any type of attribute, and must
 be used to get attributes of user-defined type. We recommend that they
-type safe versions of this function be used where possible.
+type safe versions of this function be used for atomic data types.
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
 nc_create(), nc_def_grp(), or associated inquiry functions such as
@@ -29,7 +29,7 @@ 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 name Attribute name.
 
 \param value Pointer to location for returned attribute value(s). All
 elements of the vector of attribute values are returned, so you must
@@ -37,8 +37,47 @@ 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.
+\note See documentation for nc_get_att_string() regarding a special
+case where memory must be explicitly released.
 
+\returns ::NC_NOERR for success.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Bad varid.
+\returns ::NC_EBADNAME Bad name. See \ref object_name.
+\returns ::NC_EINVAL Invalid parameters.
+\returns ::NC_ENOTATT Can't find attribute.
+\returns ::NC_ECHAR Can't convert to or from NC_CHAR.
+\returns ::NC_ENOMEM Out of memory.
+\returns ::NC_ERANGE Data convertion went out of range.
+
+<h1>Example</h1>
+
+Here is an example using nc_get_att() from nc_test4/tst_vl.c creates a
+VLEN attribute, then uses nc_get_att() to read it.
+
+ at code
+#define FILE_NAME "tst_vl.nc"
+#define VLEN_NAME "vlen_name"
+#define ATT_NAME "att_name"
+
+      int ncid, typeid;
+      nc_vlen_t data[DIM_LEN], data_in[DIM_LEN];
+      ...
+
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_vlen(ncid, VLEN_NAME, NC_INT, &typeid)) ERR;
+      ...
+      if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, typeid, DIM_LEN, data)) ERR;
+      if (nc_close(ncid)) ERR;
+
+      ...
+      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
+      if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR;
+      ...
+      if (nc_close(ncid)) ERR;
+ at endcode
+
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_get_att(int ncid, int varid, const char *name, void *value)
@@ -77,7 +116,7 @@ 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 name Attribute name.
 
 \param value Pointer to location for returned attribute value(s). All
 elements of the vector of attribute values are returned, so you must
@@ -85,6 +124,16 @@ 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.
 
+\returns ::NC_NOERR for success.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Bad varid.
+\returns ::NC_EBADNAME Bad name. See \ref object_name.
+\returns ::NC_EINVAL Invalid parameters.
+\returns ::NC_ENOTATT Can't find attribute.
+\returns ::NC_ECHAR Can't convert to or from NC_CHAR.
+\returns ::NC_ENOMEM Out of memory.
+\returns ::NC_ERANGE Data convertion went out of range.
+
 <h1>Example</h1>
 
 Here is an example using nc_get_att_double() to determine the values
@@ -130,6 +179,7 @@ the length of the attributes.
      title[t_len] = '\0';
         ...
 \endcode
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 /*! \{ */
 
@@ -268,9 +318,17 @@ nc_get_att_ulonglong(int ncid, int varid, const char *name, unsigned long long *
 \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.
+This function gets an attribute from netCDF file. The 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().
+\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
@@ -279,7 +337,7 @@ 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 name Attribute name.
 
 \param value Pointer to location for returned attribute value(s). All
 elements of the vector of attribute values are returned, so you must
@@ -287,6 +345,16 @@ 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.
 
+\returns ::NC_NOERR for success.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Bad varid.
+\returns ::NC_EBADNAME Bad name. See \ref object_name.
+\returns ::NC_EINVAL Invalid parameters.
+\returns ::NC_ENOTATT Can't find attribute.
+\returns ::NC_ECHAR Can't convert to or from NC_CHAR.
+\returns ::NC_ENOMEM Out of memory.
+\returns ::NC_ERANGE Data convertion went out of range.
+
 \section nc_get_att_string_example Example
 
 \code{.c}
@@ -333,8 +401,7 @@ int main(int argc, char ** argv) {
   return 0;
 }
 \endcode
-
-
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 
 int
diff --git a/libdispatch/dattinq.c b/libdispatch/dattinq.c
index 4bc99d7..e5acab0 100644
--- a/libdispatch/dattinq.c
+++ b/libdispatch/dattinq.c
@@ -67,6 +67,17 @@ foo.nc:
      status = nc_inq_att (ncid, NC_GLOBAL, "title", &t_type, &t_len);
      if (status != NC_NOERR) handle_error(status);
 \endcode
+
+\returns ::NC_NOERR no error.
+\returns ::NC_EBADID bad ncid.
+\returns ::NC_ENOTVAR bad varid.
+\returns ::NC_EBADGRPID bad group ID.
+\returns ::NC_EBADNAME bad name.
+\returns ::NC_ENOTATT attribute not found.
+\returns ::NC_ECHAR illegal conversion to or from NC_CHAR.
+\returns ::NC_ENOMEM out of memory.
+\returns ::NC_ERANGE range error when converting data.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, 
@@ -96,6 +107,55 @@ specifies which attribute this is for this variable (or which global
 attribute). If you already know the attribute name, knowing its number
 is not very useful, because accessing information about an attribute
 requires its name.
+
+\section nc_inq_attid_example Example
+
+Here is an example using nc_inq_attid() from nc_test4/tst_vars2.c. In
+this example three attributes are created in a file. Then it is
+re-opened, and their IDs are checked. They will be 0, 1, and 2, in
+the order that the attributes were written to the file.
+
+
+\code
+     #include <netcdf.h>
+     ...
+     printf("**** testing fill value with three other attributes...");
+     {
+#define NUM_LEADERS 3
+         char leader[NUM_LEADERS][NC_MAX_NAME + 1] = {"hair_length_of_strategoi",
+                                                      "hair_length_of_Miltiades",
+                                                      "hair_length_of_Darius_I"};
+         short hair_length[NUM_LEADERS] = {3, 11, 4};
+         short short_in;
+         int a;
+
+         if (nc_create(FILE_NAME, cmode, &ncid)) ERR;
+         if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
+         if (nc_def_var(ncid, VAR_NAME, NC_BYTE, NUM_DIMS, dimids, &varid)) ERR;
+         for (a = 0; a < NUM_LEADERS; a++)
+            if (nc_put_att_short(ncid, varid, leader[a], NC_SHORT, 1, &hair_length[a])) ERR;
+         if (nc_put_att_schar(ncid, varid, _FillValue, NC_BYTE, 1, &fill_value)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
+         for (a = 0; a < NUM_LEADERS; a++)
+         {
+            ...
+            if (nc_inq_attid(ncid, 0, leader[a], &attnum_in)) ERR;
+            if (attnum_in != a) ERR;
+         }
+
+         if (nc_close(ncid)) ERR;
+\endcode
+
+\returns ::NC_NOERR no error.
+\returns ::NC_EBADID bad ncid.
+\returns ::NC_ENOTVAR bad varid.
+\returns ::NC_EBADGRPID bad group ID.
+\returns ::NC_EBADNAME bad name.
+\returns ::NC_ENOTATT attribute not found.
+\returns ::NC_ENOMEM out of memory.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_inq_attid(int ncid, int varid, const char *name, int *idp)
@@ -124,6 +184,70 @@ nc_inq_varnatts().
 
 \param name Pointer to the location for the returned attribute \ref
 object_name.  
+
+\section nc_inq_attname_example Example
+
+Here is an example from nc_test4/tst_atts3.c a variable of every type
+is added to a file, with names from the 'names' array. Then the file
+is re-opened, and the names of the attributes are checked in a for
+loop.
+
+
+\code
+     #include <netcdf.h>
+     ...
+#define NUM_ATTS 8
+#define ATT_MAX_NAME 25
+int
+tst_att_ordering(int cmode)
+{
+   int ncid;
+   char name[NUM_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf",
+					    "Gd", "Gatt-name-dashes", "Gatt.name.dots"};
+   int len[NUM_ATTS] = {0, 2, 3, 3, 3, 3, 1, 1};
+   signed char b[2] = {-128, 127};
+   short s[3] = {-32768, 0, 32767};
+   int i[3] = {42, 0, -42};
+   float f[3] = {42.0, -42.0, 42.0};
+   double d[3] = {420.0, -420.0, 420.0};
+   int att_name_dashes = -1, att_name_dots = -2;
+   char name_in[NC_MAX_NAME];
+   int j;
+
+   if (nc_create(FILE_NAME, cmode, &ncid)) ERR;
+   ...
+   if (nc_put_att_text(ncid, NC_GLOBAL, name[0], len[0], NULL)) ERR;
+   if (nc_put_att_schar(ncid, NC_GLOBAL, name[1], NC_BYTE, len[1], b)) ERR;
+   if (nc_put_att_short(ncid, NC_GLOBAL, name[2], NC_SHORT, len[2], s)) ERR;
+   if (nc_put_att_int(ncid, NC_GLOBAL, name[3], NC_INT, len[3], i)) ERR;
+   if (nc_put_att_float(ncid, NC_GLOBAL, name[4], NC_FLOAT, len[4], f)) ERR;
+   if (nc_put_att_double(ncid, NC_GLOBAL, name[5], NC_DOUBLE, len[5], d)) ERR;
+   if (nc_put_att_int(ncid, NC_GLOBAL, name[6], NC_INT, len[6], &att_name_dashes)) ERR;
+   if (nc_put_att_int(ncid, NC_GLOBAL, name[7], NC_INT, len[7], &att_name_dots)) ERR;
+   if (nc_close(ncid)) ERR;
+
+   ...
+   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
+   for (j = 0; j < NUM_ATTS; j++)
+   {
+      if (nc_inq_attname(ncid, NC_GLOBAL, j, name_in)) ERR;
+      if (strcmp(name_in, name[j])) ERR;
+   }
+
+   if (nc_close(ncid)) ERR;
+
+\endcode
+
+\returns ::NC_NOERR no error.
+\returns ::NC_EBADID bad ncid.
+\returns ::NC_ENOTVAR bad varid.
+\returns ::NC_EBADGRPID bad group ID.
+\returns ::NC_EBADNAME bad name.
+\returns ::NC_ENOTATT attribute not found.
+\returns ::NC_ECHAR illegal conversion to or from NC_CHAR.
+\returns ::NC_ENOMEM out of memory.
+\returns ::NC_ERANGE range error when converting data.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_inq_attname(int ncid, int varid, int attnum, char *name)
@@ -144,6 +268,33 @@ nc_inq_ncid().
 
 \param nattsp Pointer where number of global or group attributes will be
 written. \ref ignored_if_null.
+
+\section nc_inq_natts_example Example
+
+Here is an example from 
+
+
+\code
+     #include <netcdf.h>
+     ...
+int
+check_4D_example(char *file_name, int expected_format)
+{
+   int ncid;
+   int format, ndims_in, nvars_in, natts_in;
+   ...
+
+   if (nc_open(file_name, 0, &ncid)) ERR;
+   ...
+   if (nc_inq_natts(ncid, &natts_in)) ERR;
+   if (natts_in != 0) ERR;
+
+\endcode
+
+\returns ::NC_NOERR no error.
+\returns ::NC_EBADID bad ncid.
+\returns ::NC_EBADGRPID bad group ID.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_inq_natts(int ncid, int *nattsp)
@@ -169,6 +320,39 @@ for a global or group attribute.
 \param name Attribute \ref object_name. 
 
 \param xtypep Pointer to location for returned attribute \ref data_type.
+
+\section nc_inq_atttype_example Example
+
+Here is an example from nc_test4/tst_h_refs.c. In this example, a file
+with an integer attribute is open. It's type is confirmed to be
+NC_INT.
+
+
+\code
+     #include <netcdf.h>
+     ...
+    printf("*** Checking accessing file through netCDF-4 API...");
+    {
+	int ncid, varid, attid;
+	nc_type type;
+
+	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
+        ...
+	if (nc_inq_atttype(ncid, NC_GLOBAL, INT_ATT_NAME, &type)) ERR;
+	if (type != NC_INT) ERR;
+
+\endcode
+
+\returns ::NC_NOERR no error.
+\returns ::NC_EBADID bad ncid.
+\returns ::NC_ENOTVAR bad varid.
+\returns ::NC_EBADGRPID bad group ID.
+\returns ::NC_EBADNAME bad name.
+\returns ::NC_ENOTATT attribute not found.
+\returns ::NC_ECHAR illegal conversion to or from NC_CHAR.
+\returns ::NC_ENOMEM out of memory.
+\returns ::NC_ERANGE range error when converting data.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep)
@@ -195,6 +379,47 @@ for a global or group attribute.
 \param lenp Pointer to location for returned number of values
 currently stored in the attribute. Before using the value as a C
 string, make sure it is null-terminated. \ref ignored_if_null.  
+
+\section nc_inq_attlen_example Example
+
+Here is an example from nc_test4/tst_h_scalar.c which checks the
+attributes of an already-open netCDF file. In this code, the length of
+two attributes are checked, and found to be 1.
+
+
+\code
+     #include <netcdf.h>
+     ...
+int
+check_attrs(int ncid, int obj)
+{
+    int attid;
+    int natts = 0;
+    size_t len;
+    nc_type type;
+    char *vlstr;
+    char fixstr[10];
+    int x;
+
+    ...
+    if (nc_inq_attlen(ncid, obj, VSTR_ATT1_NAME, &len)) ERR_GOTO;
+    if (len != 1) ERR_GOTO;
+    ...
+    if (nc_inq_attlen(ncid, obj, VSTR_ATT2_NAME, &len)) ERR_GOTO;
+    if (len != 1) ERR_GOTO;
+
+\endcode
+
+\returns ::NC_NOERR no error.
+\returns ::NC_EBADID bad ncid.
+\returns ::NC_ENOTVAR bad varid.
+\returns ::NC_EBADGRPID bad group ID.
+\returns ::NC_EBADNAME bad name.
+\returns ::NC_ENOTATT attribute not found.
+\returns ::NC_ECHAR illegal conversion to or from NC_CHAR.
+\returns ::NC_ENOMEM out of memory.
+\returns ::NC_ERANGE range error when converting data.
+\author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_inq_attlen(int ncid, int varid, const char *name, size_t *lenp)
diff --git a/libdispatch/dauth.c b/libdispatch/dauth.c
new file mode 100644
index 0000000..484c87d
--- /dev/null
+++ b/libdispatch/dauth.c
@@ -0,0 +1,383 @@
+/*
+Copyright (c) 1998-2017 University Corporation for Atmospheric Research/Unidata
+See LICENSE.txt for license information.
+*/
+
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#include "netcdf.h"
+#include "ncbytes.h"
+#include "ncuri.h"
+#include "ncauth.h"
+#include "nclog.h"
+#include "ncwinpath.h"
+
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+
+#undef MEMCHECK
+#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
+
+/* Define the curl flag defaults in envv style */
+static const char* AUTHDEFAULTS[] = {
+"HTTP.TIMEOUT","10", /*seconds */
+NULL
+};
+
+/* Forward */
+static int setauthfield(NCauth* auth, const char* flag, const char* value);
+static void setdefaults(NCauth*);
+
+/**************************************************/
+/* External Entry Points */
+
+int
+NC_parseproxy(NCauth* auth, const char* surl)
+{
+    int ret = NC_NOERR;
+    NCURI* uri = NULL;
+    if(surl == NULL || strlen(surl) == 0)
+	return (NC_NOERR); /* nothing there*/
+    if(ncuriparse(surl,&uri) != NCU_OK)
+	return (NC_EURL);
+    auth->proxy.user = uri->user;
+    auth->proxy.pwd = uri->password;
+    auth->proxy.host = strdup(uri->host);
+    if(uri->port != NULL)
+        auth->proxy.port = atoi(uri->port);
+    else
+        auth->proxy.port = 80;
+    return (ret);
+}
+
+char*
+NC_combinehostport(NCURI* uri)
+{
+    size_t len;
+    char* host = NULL;
+    char* port = NULL;
+    char* hp = NULL;
+    if(uri == NULL) return NULL;
+    host = uri->host;
+    port = uri->port;
+    if(uri == NULL || host == NULL) return NULL;
+    if(port != NULL && strlen(port) == 0) port = NULL;
+    len = strlen(host);
+    if(port != NULL) len += (1+strlen(port));
+    hp = (char*)malloc(len+1);
+    if(hp == NULL) return NULL;
+    strncpy(hp,host,len);
+    if(port != NULL) {
+	strncat(hp,":",len);
+	strncat(hp,port,len);
+    }
+    return hp;
+}
+
+int
+NC_authsetup(NCauth* auth, NCURI* uri)
+{
+    int ret = NC_NOERR;
+    char* uri_hostport = NULL;
+
+    if(uri != NULL)
+	uri_hostport = NC_combinehostport(uri);    
+
+    setdefaults(auth);
+
+    /* Note, we still must do this function even if
+       ncrc_globalstate.rc.ignore is set in order
+       to getinfo e.g. host+port  from url
+    */
+
+    setauthfield(auth,"HTTP.DEFLATE",
+		      NC_rclookup("HTTP.DEFLATE",uri_hostport));
+    setauthfield(auth,"HTTP.VERBOSE",
+			NC_rclookup("HTTP.VERBOSE",uri_hostport));
+    setauthfield(auth,"HTTP.TIMEOUT",
+			NC_rclookup("HTTP.TIMEOUT",uri_hostport));
+    setauthfield(auth,"HTTP.USERAGENT",
+			NC_rclookup("HTTP.USERAGENT",uri_hostport));
+    setauthfield(auth,"HTTP.COOKIEFILE",
+			NC_rclookup("HTTP.COOKIEFILE",uri_hostport));
+    setauthfield(auth,"HTTP.COOKIE_FILE",
+			NC_rclookup("HTTP.COOKIE_FILE",uri_hostport));
+    setauthfield(auth,"HTTP.COOKIEJAR",
+			NC_rclookup("HTTP.COOKIEJAR",uri_hostport));
+    setauthfield(auth,"HTTP.COOKIE_JAR",
+			NC_rclookup("HTTP.COOKIE_JAR",uri_hostport));
+    setauthfield(auth,"HTTP.PROXY.SERVER",
+			NC_rclookup("HTTP.PROXY.SERVER",uri_hostport));
+    setauthfield(auth,"HTTP.PROXY_SERVER",
+			NC_rclookup("HTTP.PROXY_SERVER",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.VALIDATE",
+			NC_rclookup("HTTP.SSL.VALIDATE",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.CERTIFICATE",
+			NC_rclookup("HTTP.SSL.CERTIFICATE",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.KEY",
+			NC_rclookup("HTTP.SSL.KEY",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.KEYPASSWORD",
+			NC_rclookup("HTTP.SSL.KEYPASSWORD",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.CAINFO",
+			NC_rclookup("HTTP.SSL.CAINFO",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.CAPATH",
+			NC_rclookup("HTTP.SSL.CAPATH",uri_hostport));
+    setauthfield(auth,"HTTP.SSL.VERIFYPEER",
+			NC_rclookup("HTTP.SSL.VERIFYPEER",uri_hostport));
+    setauthfield(auth,"HTTP.NETRC",
+			NC_rclookup("HTTP.NETRC",uri_hostport));
+    { /* Handle various cases for user + password */
+	/* First, see if the user+pwd was in the original url */
+	char* user = NULL;
+	char* pwd = NULL;
+	if(uri->user != NULL && uri->password != NULL) {
+	    user = uri->user;
+	    pwd = uri->password;
+	} else {
+   	    user = NC_rclookup("HTTP.CREDENTIALS.USER",uri_hostport);
+	    pwd = NC_rclookup("HTTP.CREDENTIALS.PASSWORD",uri_hostport);
+	}
+	if(user != NULL && pwd != NULL) {
+            user = strdup(user); /* so we can consistently reclaim */
+            pwd = strdup(pwd);
+	} else {
+	    /* Could not get user and pwd, so try USERPASSWORD */
+	    const char* userpwd = NC_rclookup("HTTP.CREDENTIALS.USERPASSWORD",uri_hostport);
+	    if(userpwd != NULL) {
+		ret = NC_parsecredentials(userpwd,&user,&pwd);
+		if(ret) return ret;
+	    }
+        }
+        setauthfield(auth,"HTTP.USERNAME",user);
+        setauthfield(auth,"HTTP.PASSWORD",pwd);
+	nullfree(user);
+	nullfree(pwd);
+    }
+    return (ret);
+}
+
+void
+NC_authclear(NCauth* auth)
+{
+    if(auth->curlflags.cookiejarcreated) {
+#ifdef _MSC_VER
+        DeleteFile(auth->curlflags.cookiejar);
+#else
+        remove(auth->curlflags.cookiejar);
+#endif
+    }
+    nullfree(auth->curlflags.useragent);
+    nullfree(auth->curlflags.cookiejar);
+    nullfree(auth->curlflags.netrc);
+    nullfree(auth->ssl.certificate);
+    nullfree(auth->ssl.key);
+    nullfree(auth->ssl.keypasswd);
+    nullfree(auth->ssl.cainfo);
+    nullfree(auth->ssl.capath);
+    nullfree(auth->proxy.host);
+    nullfree(auth->proxy.user);
+    nullfree(auth->proxy.pwd);
+    nullfree(auth->creds.user);
+    nullfree(auth->creds.pwd);
+}
+
+/**************************************************/
+
+static int
+setauthfield(NCauth* auth, const char* flag, const char* value)
+{
+    int ret = NC_NOERR;
+    if(value == NULL) goto done;
+    if(strcmp(flag,"HTTP.DEFLATE")==0) {
+        if(atoi(value)) auth->curlflags.compress = 1;
+#ifdef D4DEBUG
+        nclog(NCLOGNOTE,"HTTP.DEFLATE: %ld", infoflags.compress);
+#endif
+    }
+    if(strcmp(flag,"HTTP.VERBOSE")==0) {
+        if(atoi(value)) auth->curlflags.verbose = 1;
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.VERBOSE: %ld", auth->curlflags.verbose);
+#endif
+    }
+    if(strcmp(flag,"HTTP.TIMEOUT")==0) {
+        if(atoi(value)) auth->curlflags.timeout = atoi(value);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.TIMEOUT: %ld", auth->curlflags.timeout);
+#endif
+    }
+    if(strcmp(flag,"HTTP.USERAGENT")==0) {
+        if(atoi(value)) auth->curlflags.useragent = strdup(value);
+        MEMCHECK(auth->curlflags.useragent);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.USERAGENT: %s", auth->curlflags.useragent);
+#endif
+    }
+    if(
+	strcmp(flag,"HTTP.COOKIEFILE")==0
+        || strcmp(flag,"HTTP.COOKIE_FILE")==0
+        || strcmp(flag,"HTTP.COOKIEJAR")==0
+        || strcmp(flag,"HTTP.COOKIE_JAR")==0
+      ) {
+	nullfree(auth->curlflags.cookiejar);
+        auth->curlflags.cookiejar = strdup(value);
+        MEMCHECK(auth->curlflags.cookiejar);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.COOKIEJAR: %s", auth->curlflags.cookiejar);
+#endif
+    }
+    if(strcmp(flag,"HTTP.PROXY.SERVER")==0 || strcmp(flag,"HTTP.PROXY_SERVER")==0) {
+        ret = NC_parseproxy(auth,value);
+        if(ret != NC_NOERR) goto done;
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.PROXY.SERVER: %s", value);
+#endif
+    }
+    if(strcmp(flag,"HTTP.SSL.VALIDATE")==0) {
+        if(atoi(value)) {
+	    auth->ssl.verifypeer = 1;
+	    auth->ssl.verifyhost = 1;
+#ifdef D4DEBUG
+                nclog(NCLOGNOTE,"HTTP.SSL.VALIDATE: %ld", 1);
+#endif
+	}
+    }
+
+    if(strcmp(flag,"HTTP.SSL.CERTIFICATE")==0) {
+	nullfree(auth->ssl.certificate);
+        auth->ssl.certificate = strdup(value);
+        MEMCHECK(auth->ssl.certificate);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.SSL.CERTIFICATE: %s", auth->ssl.certificate);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.SSL.KEY")==0) {
+	nullfree(auth->ssl.key);
+        auth->ssl.key = strdup(value);
+        MEMCHECK(auth->ssl.key);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.SSL.KEY: %s", auth->ssl.key);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.SSL.KEYPASSWORD")==0) {
+	nullfree(auth->ssl.keypasswd) ;
+        auth->ssl.keypasswd = strdup(value);
+        MEMCHECK(auth->ssl.keypasswd);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.SSL.KEYPASSWORD: %s", auth->ssl.keypasswd);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.SSL.CAINFO")==0) {
+	nullfree(auth->ssl.cainfo) ;
+        auth->ssl.cainfo = strdup(value);
+        MEMCHECK(auth->ssl.cainfo);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.SSL.CAINFO: %s", auth->ssl.cainfo);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.SSL.CAPATH")==0) {
+	nullfree(auth->ssl.capath) ;
+        auth->ssl.capath = strdup(value);
+        MEMCHECK(auth->ssl.capath);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.SSL.CAPATH: %s", auth->ssl.capath);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.SSL.VERIFYPEER")==0) {
+        const char* s = value;
+        int tf = 0;
+        if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0)
+            tf = 0;
+        else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0)
+            tf = 1;
+        else
+            tf = 1; /* default if not null */
+        auth->ssl.verifypeer = tf;
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", auth->ssl.verifypeer);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.NETRC")==0) {
+        nullfree(auth->curlflags.netrc);
+        auth->curlflags.netrc = strdup(value);
+        MEMCHECK(auth->curlflags.netrc);
+#ifdef D4DEBUG
+            nclog(NCLOGNOTE,"HTTP.NETRC: %s", auth->curlflags.netrc);
+#endif
+    }
+
+    if(strcmp(flag,"HTTP.CREDENTIALS.USERNAME")==0) {
+        nullfree(auth->creds.user);
+        auth->creds.user = strdup(value);
+        MEMCHECK(auth->creds.user);
+    }
+    if(strcmp(flag,"HTTP.CREDENTIALS.PASSWORD")==0) {
+        nullfree(auth->creds.pwd);
+        auth->creds.pwd = strdup(value);
+        MEMCHECK(auth->creds.pwd);
+    }
+
+done:
+    return (ret);
+
+nomem:
+    return (NC_ENOMEM);
+}
+
+/*
+Given form user:pwd, parse into user and pwd
+and do %xx unescaping
+*/
+int
+NC_parsecredentials(const char* userpwd, char** userp, char** pwdp)
+{
+    char* user = NULL;
+    char* pwd = NULL;
+
+    if(userpwd == NULL)
+	return NC_EINVAL;
+    user = strdup(userpwd);
+    if(user == NULL)
+	return NC_ENOMEM;
+    pwd = strchr(user,':');
+    if(pwd == NULL)
+	return NC_EINVAL;
+    *pwd = '\0';
+    pwd++;
+    if(userp)
+	*userp = ncuridecode(user);
+    if(pwdp)
+	*pwdp = ncuridecode(pwd);
+    free(user);
+    return NC_NOERR;
+}
+
+static void
+setdefaults(NCauth* auth)
+{
+    int ret = NC_NOERR;
+    const char** p;
+    for(p=AUTHDEFAULTS;*p;p+=2) {
+	ret = setauthfield(auth,p[0],p[1]);
+	if(ret) {
+            nclog(NCLOGERR, "RC file defaulting failed for: %s=%s",p[0],p[1]);
+	}
+    }
+}
+
diff --git a/libdispatch/dcopy.c b/libdispatch/dcopy.c
index ebf32fd..0c73c40 100644
--- a/libdispatch/dcopy.c
+++ b/libdispatch/dcopy.c
@@ -1,17 +1,30 @@
-/* Copyright 2010 University Corporation for Atmospheric
-   Research/Unidata. See COPYRIGHT file for more info.
-
-   This file has the var and att copy functions.
-
-   "$Id: copy.c,v 1.1 2010/06/01 15:46:49 ed Exp $"
+/**
+ * @file
+ * Copyright 2010 University Corporation for Atmospheric
+ * Research/Unidata. See COPYRIGHT file for more info.
+ *
+ * This file has the var and att copy functions.
+ *
+ * @author Dennis Heimbigner
 */
-
 #include "ncdispatch.h"
 #include "nc_logging.h"
 
 #ifdef USE_NETCDF4
-/* Compare two netcdf types for equality. Must have the ncids as well,
-   to find user-defined types. */
+/**
+ * @internal Compare two netcdf types for equality. Must have the
+ * ncids as well, to find user-defined types. 
+ *
+ * @param ncid1 File ID.
+ * @param typeid1 Type ID.
+ * @param ncid2 File ID.
+ * @param typeid2 Type ID.
+ * @param equalp Pointer that gets 1 of the types are equal, 0
+ * otherwise.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int
 NC_compare_nc_types(int ncid1, int typeid1, int ncid2, int typeid2,
 		    int *equalp)
@@ -137,8 +150,18 @@ NC_compare_nc_types(int ncid1, int typeid1, int ncid2, int typeid2,
    return ret;
 }
 
-/* Recursively hunt for a netCDF type id. (Code from nc4internal.c);
-   Return matching typeid or 0 if not found. */
+/**
+ * @internal Recursively hunt for a netCDF type id. (Code from
+ * nc4internal.c); Return matching typeid or 0 if not found. 
+ *
+ * @param ncid1 File ID.
+ * @param tid1 Type ID.
+ * @param ncid2 File ID.
+ * @param tid2 Pointer that gets type ID of equal type.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int
 NC_rec_find_nc_type(int ncid1, nc_type tid1, int ncid2, nc_type* tid2)
 {
@@ -201,8 +224,18 @@ NC_rec_find_nc_type(int ncid1, nc_type tid1, int ncid2, nc_type* tid2)
    return NC_EBADTYPE; /* not found */
 }
 
-/* Given a type in one file, find its equal (if any) in another
- * file. It sounds so simple, but it's a real pain! */
+/**
+ * @internal Given a type in one file, find its equal (if any) in
+ * another file. It sounds so simple, but it's a real pain! 
+ *
+ * @param ncid1 File ID.
+ * @param xtype1 Type ID.
+ * @param ncid2 File ID.
+ * @param xtype2 Pointer that gets type ID of equal type.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int
 NC_find_equal_type(int ncid1, nc_type xtype1, int ncid2, nc_type *xtype2)
 {
@@ -229,25 +262,33 @@ NC_find_equal_type(int ncid1, nc_type xtype1, int ncid2, nc_type *xtype2)
 
 #endif /* USE_NETCDF4 */
 
-/* This will copy a variable that is an array of primitive type and
-   its attributes from one file to another, assuming dimensions in the
-   output file are already defined and have same dimension IDs and
-   length.  However it doesn't work for copying netCDF-4 variables of
-   type string or a user-defined type.
-
-   This function works even if the files are different formats,
-   (for example, one netcdf classic, the other netcdf-4).
-
-   If you're copying into a classic-model file, from a netcdf-4 file,
-   you must be copying a variable of one of the six classic-model
-   types, and similarly for the attributes.
-
-   For large netCDF-3 files, this can be a very inefficient way to
-   copy data from one file to another, because adding a new variable
-   to the target file may require more space in the header and thus
-   result in moving data for other variables in the target file. This
-   is not a problem for netCDF-4 files, which support efficient
-   addition of variables without moving data for other variables.
+/**
+ * This will copy a variable that is an array of primitive type and
+ * its attributes from one file to another, assuming dimensions in the
+ * output file are already defined and have same dimension IDs and
+ * length.  However it doesn't work for copying netCDF-4 variables of
+ * type string or a user-defined type.
+ *
+ * This function works even if the files are different formats,
+ * (for example, one netcdf classic, the other netcdf-4).
+ *
+ * If you're copying into a classic-model file, from a netcdf-4 file,
+ * you must be copying a variable of one of the six classic-model
+ * types, and similarly for the attributes.
+ *
+ * For large netCDF-3 files, this can be a very inefficient way to
+ * copy data from one file to another, because adding a new variable
+ * to the target file may require more space in the header and thus
+ * result in moving data for other variables in the target file. This
+ * is not a problem for netCDF-4 files, which support efficient
+ * addition of variables without moving data for other variables.
+ *
+ * @param ncid_in File ID to copy from.
+ * @param varid_in Variable ID to copy.
+ * @param ncid_out File ID to copy to.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_copy_var(int ncid_in, int varid_in, int ncid_out)
@@ -477,6 +518,19 @@ nc_copy_var(int ncid_in, int varid_in, int ncid_out)
    return retval;
 }
 
+/**
+ * Copy an attribute from one open file to another. This is called by
+ * nc_copy_att().
+ *
+ * @param ncid_in File ID to copy from.
+ * @param varid_in Variable ID to copy from.
+ * @param name Name of attribute to copy.
+ * @param ncid_out File ID to copy to.
+ * @param varid_out Variable ID to copy to.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
+*/
 static int
 NC_copy_att(int ncid_in, int varid_in, const char *name,
 	    int ncid_out, int varid_out)
@@ -576,16 +630,26 @@ NC_copy_att(int ncid_in, int varid_in, const char *name,
    return res;
 }
 
-/* Copy an attribute from one open file to another.
-
-   Special programming challenge: this function must work even if one
-   of the other of the files is a netcdf version 1.0 file (i.e. not
-   HDF5). So only use top level netcdf api functions.
-
-   From the netcdf-3 docs: The output netCDF dataset should be in
-   define mode if the attribute to be copied does not already exist
-   for the target variable, or if it would cause an existing target
-   attribute to grow.
+/**
+ * Copy an attribute from one open file to another.
+ *
+ * Special programming challenge: this function must work even if one
+ * of the other of the files is a netcdf version 1.0 file (i.e. not
+ * HDF5). So only use top level netcdf api functions.
+ *
+ * From the netcdf-3 docs: The output netCDF dataset should be in
+ * define mode if the attribute to be copied does not already exist
+ * for the target variable, or if it would cause an existing target
+ * attribute to grow.
+ *
+ * @param ncid_in File ID to copy from.
+ * @param varid_in Variable ID to copy from.
+ * @param name Name of attribute to copy.
+ * @param ncid_out File ID to copy to.
+ * @param varid_out Variable ID to copy to.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_copy_att(int ncid_in, int varid_in, const char *name,
diff --git a/libdispatch/ddim.c b/libdispatch/ddim.c
index 9b0b500..1ead3ef 100644
--- a/libdispatch/ddim.c
+++ b/libdispatch/ddim.c
@@ -94,7 +94,7 @@ unlimited dimensions.
 \returns ::NC_ENOTINDEFINE Not in define mode.
 \returns ::NC_EDIMSIZE Invalid dimension size.
 \returns ::NC_EUNLIMIT NC_UNLIMITED size already in use
-\returns ::NC_EMAXDIMS NC_MAX_DIMS exceeded
+\returns ::NC_EMAXDIMS NC_MAX_DIMS exceeded [not enforced after 4.5.0]
 \returns ::NC_ENAMEINUSE String match to name in use
 \returns ::NC_ENOMEM Memory allocation (malloc) failure
 \returns ::NC_EPERM Write to read only
diff --git a/libdispatch/ddispatch.c b/libdispatch/ddispatch.c
index e089479..a93a086 100644
--- a/libdispatch/ddispatch.c
+++ b/libdispatch/ddispatch.c
@@ -1,5 +1,26 @@
+/*
+Copyright (c) 1998-2017 University Corporation for Atmospheric Research/Unidata
+See LICENSE.txt for license information.
+*/
+
+#include "config.h"
 #include "ncdispatch.h"
 #include "ncuri.h"
+#include "nclog.h"
+#include "ncbytes.h"
+#include "ncrc.h"
+
+/* Required for getcwd, other functions. */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* Required for getcwd, other functions. */
+#ifdef _MSC_VER
+#include <direct.h>
+#define getcwd _getcwd
+#endif
+
 
 /* Define vectors of zeros and ones for use with various nc_get_varX function*/
 size_t nc_sizevector0[NC_MAX_VAR_DIMS];
@@ -24,6 +45,8 @@ static struct NCPROTOCOLLIST {
     {NULL,NULL,0} /* Terminate search */
 };
 
+NCRCglobalstate ncrc_globalstate;
+
 /*
 static nc_type longtype = (sizeof(long) == sizeof(int)?NC_INT:NC_INT64);
 static nc_type ulongtype = (sizeof(unsigned long) == sizeof(unsigned int)?NC_UINT:NC_UINT64);
@@ -35,6 +58,9 @@ NCDISPATCH_initialize(void)
 {
     int status = NC_NOERR;
     int i;
+
+    memset(&ncrc_globalstate,0,sizeof(NCRCglobalstate));
+
     for(i=0;i<NC_MAX_VAR_DIMS;i++) {
 	nc_sizevector0[i] = 0;
         nc_sizevector1[i] = 1;
@@ -44,6 +70,70 @@ NCDISPATCH_initialize(void)
 	NC_coord_one[i] = 1;
 	NC_coord_zero[i] = 0;
     }
+
+    /* Capture temp dir*/
+    {
+	char* tempdir;
+	char* p;
+	char* q;
+	char cwd[4096];
+#ifdef _MSC_VER
+        tempdir = getenv("TEMP");
+#else
+	tempdir = "/tmp";
+#endif
+        if(tempdir == NULL) {
+	    fprintf(stderr,"Cannot find a temp dir; using ./\n");
+	    tempdir = getcwd(cwd,sizeof(cwd));
+	    if(tempdir == NULL || *tempdir == '\0') tempdir = ".";
+	}
+        ncrc_globalstate.tempdir= (char*)malloc(strlen(tempdir) + 1);
+	for(p=tempdir,q=ncrc_globalstate.tempdir;*p;p++,q++) {
+	    if((*p == '/' && *(p+1) == '/')
+	       || (*p == '\\' && *(p+1) == '\\')) {p++;}
+	    *q = *p;
+	}
+	*q = '\0';
+#ifdef _MSC_VER
+#else
+        /* Canonicalize */
+	for(p=ncrc_globalstate.tempdir;*p;p++) {
+	    if(*p == '\\') {*p = '/'; };
+	}
+	*q = '\0';
+#endif
+    }
+
+    /* Capture $HOME */
+    {
+	char* p;
+	char* q;
+        char* home = getenv("HOME");
+
+        if(home == NULL) {
+	    /* use tempdir */
+	    home = ncrc_globalstate.tempdir;
+	}
+        ncrc_globalstate.home = (char*)malloc(strlen(home) + 1);
+	for(p=home,q=ncrc_globalstate.home;*p;p++,q++) {
+	    if((*p == '/' && *(p+1) == '/')
+	       || (*p == '\\' && *(p+1) == '\\')) {p++;}
+	    *q = *p;
+	}
+	*q = '\0';
+#ifdef _MSC_VER
+#else
+        /* Canonicalize */
+	for(p=home;*p;p++) {
+	    if(*p == '\\') {*p = '/'; };
+	}
+#endif
+    }
+
+    /* Now load RC File */
+    status = NC_rcload();
+    ncloginit();
+
     return status;
 }
 
@@ -51,6 +141,10 @@ int
 NCDISPATCH_finalize(void)
 {
     int status = NC_NOERR;
+    nullfree(ncrc_globalstate.tempdir);
+    nullfree(ncrc_globalstate.home);
+    NC_rcclear(&ncrc_globalstate.rcinfo);
+    memset(&ncrc_globalstate,0,sizeof(NCRCglobalstate));
     return status;
 }
 
@@ -167,7 +261,6 @@ fail:
 int
 nc__testurl(const char* path, char** basenamep)
 {
-    int stat = NC_NOERR;
     NCURI* uri;
     int ok = 0;
     if(ncuriparse(path,&uri) == NCU_OK) {
diff --git a/libdispatch/derror.c b/libdispatch/derror.c
index 39338ac..68cede3 100644
--- a/libdispatch/derror.c
+++ b/libdispatch/derror.c
@@ -12,16 +12,14 @@ Research/Unidata. See COPYRIGHT file for more info.
 #include <pnetcdf.h>  /* for ncmpi_strerror() */
 #endif
 
-/* Tell the user the version of netCDF. */
+/** @internal The version string for the library, used by
+ * nc_inq_libvers(). */
 static const char nc_libvers[] = PACKAGE_VERSION " of "__DATE__" "__TIME__" $";
 
 /**
-\defgroup lib_version Library Version
-  Functions related to querying the library version.
+Return the library version.
 
-  Return the library version.
-
-  \returns short string that contains the version information for the
+\returns short string that contains the version information for the
 library.
  */
 const char *
@@ -118,20 +116,20 @@ const char *nc_strerror(int ncerr1)
       case NC_EINVALCOORDS:
 	 return "NetCDF: Index exceeds dimension bound";
       case NC_EMAXDIMS:
-	 return "NetCDF: NC_MAX_DIMS exceeded";
+	 return "NetCDF: NC_MAX_DIMS exceeded"; /* not enforced after 4.5.0 */
       case NC_ENAMEINUSE:
 	 return "NetCDF: String match to name in use";
       case NC_ENOTATT:
 	 return "NetCDF: Attribute not found";
       case NC_EMAXATTS:
-	 return "NetCDF: NC_MAX_ATTRS exceeded";
+	 return "NetCDF: NC_MAX_ATTRS exceeded"; /* not enforced after 4.5.0 */
       case NC_EBADTYPE:
 	 return "NetCDF: Not a valid data type or _FillValue type mismatch";
       case NC_EBADDIM:
 	 return "NetCDF: Invalid dimension ID or name";
       case NC_EUNLIMPOS:
 	 return "NetCDF: NC_UNLIMITED in the wrong index";
-      case NC_EMAXVARS:	 return "NetCDF: NC_MAX_VARS exceeded";
+      case NC_EMAXVARS:	 return "NetCDF: NC_MAX_VARS exceeded"; /* not enforced after 4.5.0 */
       case NC_ENOTVAR:
 	 return "NetCDF: Variable not found";
       case NC_EGLOBAL:
@@ -194,8 +192,6 @@ const char *nc_strerror(int ncerr1)
 	 return "NetCDF: Authorization failure";
       case NC_ENOTFOUND:
 	 return "NetCDF: file not found";
-      case NC_ECANTEXTEND:
-	return "NetCDF: Attempt to extend dataset during NC_INDEPENDENT I/O operation. Use nc_var_par_access to set mode NC_COLLECTIVE before extending variable.";
       case NC_ECANTREMOVE:
 	 return "NetCDF: cannot delete file";
       case NC_EHDFERR:
@@ -257,6 +253,15 @@ const char *nc_strerror(int ncerr1)
 	    "when netCDF was built.";
       case NC_EDISKLESS:
 	 return "NetCDF: Error in using diskless access";
+      case NC_EFILTER:
+	 return "NetCDF: Filter error: bad id or parameters or filter library non-existent";
+      case NC_ECANTEXTEND:
+	return "NetCDF: Attempt to extend dataset during NC_INDEPENDENT I/O operation. Use nc_var_par_access to set mode NC_COLLECTIVE before extending variable.";
+      case NC_EMPI: return "NetCDF: MPI operation failed.";
+      case NC_ERCFILE:
+	return "NetCDF: RC File Failure.";
+   case NC_ENULLPAD:
+     return "NetCDF: File fails strict Null-Byte Header check.";
       default:
 #ifdef USE_PNETCDF
         /* The behavior of ncmpi_strerror here is to return
diff --git a/libdispatch/dfile.c b/libdispatch/dfile.c
index 09ac557..416bc8e 100644
--- a/libdispatch/dfile.c
+++ b/libdispatch/dfile.c
@@ -1,12 +1,13 @@
-/** \file dfile.c
-
-File create and open functions
-
-These functions end up calling functions in one of the dispatch layers
-(netCDF-4, dap server, etc).
-
-Copyright 2010 University Corporation for Atmospheric
-Research/Unidata. See COPYRIGHT file for more info.
+/**
+ * @file
+ *
+ * File create and open functions
+ *
+ * These functions end up calling functions in one of the dispatch
+ * layers (netCDF-4, dap server, etc).
+ *
+ * Copyright 2010 University Corporation for Atmospheric
+ * Research/Unidata. See COPYRIGHT file for more info.
 */
 
 #include "config.h"
@@ -24,8 +25,39 @@ Research/Unidata. See COPYRIGHT file for more info.
 #include "netcdf_mem.h"
 #include "ncwinpath.h"
 
-extern int NC_initialized;
-extern int NC_finalized;
+/* If Defined, then use only stdio for all magic number io;
+   otherwise use stdio or mpio as required.
+ */
+#undef DEBUG
+
+/**
+Sort info for open/read/close of
+file when searching for magic numbers
+*/
+struct MagicFile {
+    const char* path;
+    long long filelen;
+    int use_parallel;
+    int inmemory;
+    void* parameters;
+    FILE* fp;
+#ifdef USE_PARALLEL
+    MPI_File fh;
+#endif
+};
+
+static int openmagic(struct MagicFile* file);
+static int readmagic(struct MagicFile* file, long pos, char* magic);
+static int closemagic(struct MagicFile* file);
+#ifdef DEBUG
+static void printmagic(const char* tag, char* magic,struct MagicFile*);
+#endif
+
+extern int NC_initialized; /**< True when dispatch table is initialized. */
+
+/** @internal Magic number for HDF5 files. To be consistent with
+ * H5Fis_hdf5, use the complete HDF5 magic number */
+static char HDF5_SIGNATURE[MAGIC_NUMBER_LEN] = "\211HDF\r\n\032\n";
 
 /** \defgroup datasets NetCDF File and Data I/O
 
@@ -63,172 +95,155 @@ interfaces, the rest of this chapter presents a detailed description
 of the interfaces for these operations.
 */
 
-
 /*!
   Interpret the magic number found in the header of a netCDF file.
-
   This function interprets the magic number/string contained in the header of a netCDF file and sets the appropriate NC_FORMATX flags.
 
   @param[in] magic Pointer to a character array with the magic number block.
   @param[out] model Pointer to an integer to hold the corresponding netCDF type.
   @param[out] version Pointer to an integer to hold the corresponding netCDF version.
-  @param[in] use_parallel 1 if using parallel, 0 if not.
-  @return Returns an error code or 0 on success.
+  @returns NC_NOERR if a legitimate file type found
+  @returns NC_ENOTNC otherwise
 
 \internal
 \ingroup datasets
 
 */
 static int
-NC_interpret_magic_number(char* magic, int* model, int* version, int use_parallel)
+NC_interpret_magic_number(char* magic, int* model, int* version)
 {
     int status = NC_NOERR;
     /* Look at the magic number */
-    /* Ignore the first byte for HDF */
+    *model = 0;
+    *version = 0;
 #ifdef USE_NETCDF4
-    if(magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') {
+    /* Use the complete magic number string for HDF5 */
+    if(memcmp(magic,HDF5_SIGNATURE,sizeof(HDF5_SIGNATURE))==0) {
 	*model = NC_FORMATX_NC4;
-	*version = 5;
-#ifdef USE_HDF4
-    } else if(magic[0] == '\016' && magic[1] == '\003'
-              && magic[2] == '\023' && magic[3] == '\001') {
-	*model = NC_FORMATX_NC4;
-	*version = 4;
+	*version = 5; /* redundant */
+	goto done;
+    }
 #endif
-    } else
+#if defined(USE_NETCDF4) && defined(USE_HDF4)
+    if(magic[0] == '\016' && magic[1] == '\003'
+              && magic[2] == '\023' && magic[3] == '\001') {
+	*model = NC_FORMATX_NC_HDF4;
+	*version = 4; /* redundant */
+	goto done;
+    }
 #endif
     if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') {
         if(magic[3] == '\001') {
             *version = 1; /* netcdf classic version 1 */
 	    *model = NC_FORMATX_NC3;
-         } else if(magic[3] == '\002') {
+	    goto done;	    
+	}
+        if(magic[3] == '\002') {
             *version = 2; /* netcdf classic version 2 */
 	    *model = NC_FORMATX_NC3;
+	    goto done;
+        }
 #ifdef USE_CDF5
-        } else if(magic[3] == '\005') {
+        if(magic[3] == '\005') {
           *version = 5; /* cdf5 (including pnetcdf) file */
-	    *model = NC_FORMATX_NC3;
+	  *model = NC_FORMATX_NC3;
+	  goto done;
+	}
 #endif
-     } else
-	    {status = NC_ENOTNC; goto done;}
-     } else
-        {status = NC_ENOTNC; goto done;}
+     }
+     /* No match  */
+     status = NC_ENOTNC;
+     goto done;
+
 done:
      return status;
 }
 
-/*!
-Given an existing file, figure out its format
-and return that format value (NC_FORMATX_XXX)
-in model arg. Assume any path conversion was
-already performed at a higher level.
+/**
+ * @internal Given an existing file, figure out its format and return
+ * that format value (NC_FORMATX_XXX) in model arg. Assume any path
+ * conversion was already performed at a higher level.
+ *
+ * @param path File name.
+ * @param flags
+ * @param parameters
+ * @param model Pointer that gets the model to use for the dispatch
+ * table.
+ * @param version Pointer that gets version of the file.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
 */
-static int
+int
 NC_check_file_type(const char *path, int flags, void *parameters,
 		   int* model, int* version)
 {
-   char magic[MAGIC_NUMBER_LEN];
-   int status = NC_NOERR;
-   int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
-   int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
-   int inmemory = (diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
-
-   *model = 0;
-
-    if(inmemory)  {
-	NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
-	if(meminfo == NULL || meminfo->size < MAGIC_NUMBER_LEN)
-	    {status = NC_EDISKLESS; goto done;}
-	memcpy(magic,meminfo->memory,MAGIC_NUMBER_LEN);
-    } else {/* presumably a real file */
-       /* Get the 4-byte magic from the beginning of the file. Don't use posix
-        * for parallel, use the MPI functions instead. */
+    char magic[MAGIC_NUMBER_LEN];
+    int status = NC_NOERR;
 
+    int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
 #ifdef USE_PARALLEL
-	if (use_parallel) {
-	    MPI_File fh;
-	    MPI_Status mstatus;
-	    int retval;
-	    MPI_Comm comm = MPI_COMM_WORLD;
-	    MPI_Info info = MPI_INFO_NULL;
-
-	    if(parameters != NULL) {
-	        comm = ((NC_MPI_INFO*)parameters)->comm;
-		info = ((NC_MPI_INFO*)parameters)->info;
-	    }
-	    if((retval = MPI_File_open(comm,(char*)path,MPI_MODE_RDONLY,info,
-				       &fh)) != MPI_SUCCESS)
-		{status = NC_EPARINIT; goto done;}
-	    if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
-				 &mstatus)) != MPI_SUCCESS)
-		{status = NC_EPARINIT; goto done;}
-	    if((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
-		{status = NC_EPARINIT; goto done;}
-	} else
+    int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
 #endif /* USE_PARALLEL */
-	{
-	    FILE *fp;
-	    size_t i;
-#ifdef HAVE_FILE_LENGTH_I64
-          __int64 file_len = 0;
-#else
-          struct stat st;
-#endif
-          if(path == NULL || strlen(path)==0)
-		{status = NC_EINVAL; goto done;}
-
-	  if (!(fp = fopen(path, "r")))
-		{status = errno; goto done;}
-
-#ifdef HAVE_SYS_STAT_H
-	  /* The file must be at least MAGIC_NUMBER_LEN in size,
-	       or otherwise the following fread will exhibit unexpected
-  	       behavior. */
-
-          /* Windows and fstat have some issues, this will work around that. */
-#ifdef HAVE_FILE_LENGTH_I64
-          if((file_len = _filelengthi64(fileno(fp))) < 0) {
-            fclose(fp);
-            status = errno;
-            goto done;
-          }
-
-          if(file_len < MAGIC_NUMBER_LEN) {
-            fclose(fp);
-            status = NC_ENOTNC;
-            goto done;
-          }
-#else
-	  { int fno = fileno(fp);
-	    if(!(fstat(fno,&st) == 0)) {
-	        fclose(fp);
-	        status = errno;
-	        goto done;
-	    }
-	    if(st.st_size < MAGIC_NUMBER_LEN) {
-              fclose(fp);
-              status = NC_ENOTNC;
-              goto done;
-	    }
-	  }
-#endif //HAVE_FILE_LENGTH_I64
+    int inmemory = (diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
+    struct MagicFile file;
 
-#endif //HAVE_SYS_STAT_H
-
-	    i = fread(magic, MAGIC_NUMBER_LEN, 1, fp);
-	    fclose(fp);
-	    if(i == 0)
-		{status = NC_ENOTNC; goto done;}
-	    if(i != 1)
-		{status = errno; goto done;}
-	}
-    } /* !inmemory */
+   *model = 0;
+   *version = 0;
+
+    memset((void*)&file,0,sizeof(file));   
+    file.path = path; /* do not free */
+    file.parameters = parameters;
+    if(inmemory && parameters == NULL)
+	{status = NC_EDISKLESS; goto done;}
+    if(inmemory) {
+        file.inmemory = inmemory;
+	goto next;
+    }
+    /* presumably a real file */
+#ifdef USE_PARALLEL
+    /* for parallel, use the MPI functions instead (why?) */
+    if (use_parallel) {
+	file.use_parallel = use_parallel;
+	goto next;
+    }
+#endif /* USE_PARALLEL */
 
+next:
+    status = openmagic(&file);
+    if(status != NC_NOERR) {goto done;}
+    /* Verify we have a large enough file */
+    if(file.filelen < MAGIC_NUMBER_LEN)
+	{status = NC_ENOTNC; goto done;}
+    if((status = readmagic(&file,0L,magic)) != NC_NOERR) {
+	status = NC_ENOTNC;
+	*model = 0;
+	*version = 0;
+	goto done;
+    }
     /* Look at the magic number */
-    status = NC_interpret_magic_number(magic,model,version,use_parallel);
+    if(NC_interpret_magic_number(magic,model,version) == NC_NOERR
+       && *model != 0)
+        goto done; /* found something */
 
+    /* Remaining case is to search forward at starting at 512
+       and doubling to see if we have HDF5 magic number */
+    {
+	long pos = 512L;
+        for(;;) {
+	    if((pos+MAGIC_NUMBER_LEN) > file.filelen)
+		{status = NC_ENOTNC; goto done;}
+            if((status = readmagic(&file,pos,magic)) != NC_NOERR)
+	        {status = NC_ENOTNC; goto done; }
+            NC_interpret_magic_number(magic,model,version);
+            if(*model == NC_FORMATX_NC4) break;
+	    /* double and try again */
+	    pos = 2*pos;
+        }
+    }    
 done:
-   return status;
+    closemagic(&file);
+    return status;
 }
 
 /**  \ingroup datasets
@@ -335,14 +350,10 @@ Note that nc_create(path,cmode,ncidp) is equivalent to the invocation of
 nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp).
 
 \returns ::NC_NOERR No error.
-
 \returns ::NC_ENOMEM System out of memory.
-
 \returns ::NC_EHDFERR HDF5 error (netCDF-4 files only).
-
 \returns ::NC_EFILEMETA Error writing netCDF-4 file-level metadata in
 HDF5 file. (netCDF-4 files only).
-
 \returns ::NC_EDISKLESS if there was an error in creating the
 in-memory file.
 
@@ -444,55 +455,57 @@ nc_create(const char *path, int cmode, int *ncidp)
    return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
 }
 
-/*!
-Create a netCDF file with some extra parameters controlling classic
-file cacheing.
-
-Like nc_create(), this function creates a netCDF file.
-
-\param path The file name of the new netCDF dataset.
-
-\param cmode The creation mode flag, the same as in nc_create().
-
-\param initialsz On some systems, and with custom I/O layers, it may
-be advantageous to set the size of the output file at creation
-time. This parameter sets the initial size of the file at creation
-time. This only applies to classic and 64-bit offset files.
-The special value NC_SIZEHINT_DEFAULT (which is the value 0),
-lets the netcdf library choose a suitable initial size.
-
-\param chunksizehintp A pointer to the chunk size hint,
-which controls a space versus time tradeoff, memory
-allocated in the netcdf library versus number of system
-calls. Because of internal requirements, the value may not
-be set to exactly the value requested. The actual value
-chosen is returned by reference. Using a NULL pointer or
-having the pointer point to the value NC_SIZEHINT_DEFAULT
-causes the library to choose a default. How the system
-chooses the default depends on the system. On many systems,
-the "preferred I/O block size" is available from the stat()
-system call, struct stat member st_blksize. If this is
-available it is used. Lacking that, twice the system
-pagesize is used. Lacking a call to discover the system
-pagesize, we just set default bufrsize to 8192. The bufrsize
-is a property of a given open netcdf descriptor ncid, it is
-not a persistent property of the netcdf dataset. This only
-applies to classic and 64-bit offset files.
-
-\param ncidp Pointer to location where returned netCDF ID is to be
-stored.
-
-\note This function uses the same return codes as the nc_create()
-function.
-
-<h1>Examples</h1>
-
-In this example we create a netCDF dataset named foo_large.nc; we want
-the dataset to be created in the current directory only if a dataset
-with that name does not already exist. We also specify that bufrsize
-and initial size for the file.
-
-\code
+/**
+ * Create a netCDF file with some extra parameters controlling classic
+ * file cacheing.
+ *
+ * Like nc_create(), this function creates a netCDF file.
+ *
+ * @param path The file name of the new netCDF dataset.
+ * @param cmode The creation mode flag, the same as in nc_create().
+ * @param initialsz On some systems, and with custom I/O layers, it
+ * may be advantageous to set the size of the output file at creation
+ * time. This parameter sets the initial size of the file at creation
+ * time. This only applies to classic and 64-bit offset files.  The
+ * special value NC_SIZEHINT_DEFAULT (which is the value 0), lets the
+ * netcdf library choose a suitable initial size.
+ * @param chunksizehintp A pointer to the chunk size hint, which
+ * controls a space versus time tradeoff, memory allocated in the
+ * netcdf library versus number of system calls. Because of internal
+ * requirements, the value may not be set to exactly the value
+ * requested. The actual value chosen is returned by reference. Using
+ * a NULL pointer or having the pointer point to the value
+ * NC_SIZEHINT_DEFAULT causes the library to choose a default. How the
+ * system chooses the default depends on the system. On many systems,
+ * the "preferred I/O block size" is available from the stat() system
+ * call, struct stat member st_blksize. If this is available it is
+ * used. Lacking that, twice the system pagesize is used. Lacking a
+ * call to discover the system pagesize, we just set default bufrsize
+ * to 8192. The bufrsize is a property of a given open netcdf
+ * descriptor ncid, it is not a persistent property of the netcdf
+ * dataset. This only applies to classic and 64-bit offset files.
+ * @param ncidp Pointer to location where returned netCDF ID is to be
+ * stored.
+ *
+ * @note This function uses the same return codes as the nc_create()
+ * function.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_ENOMEM System out of memory.
+ * @returns ::NC_EHDFERR HDF5 error (netCDF-4 files only).
+ * @returns ::NC_EFILEMETA Error writing netCDF-4 file-level metadata in
+ * HDF5 file. (netCDF-4 files only).
+ * @returns ::NC_EDISKLESS if there was an error in creating the
+ * in-memory file.
+ *
+ * <h1>Examples</h1>
+ *
+ * In this example we create a netCDF dataset named foo_large.nc; we
+ * want the dataset to be created in the current directory only if a
+ * dataset with that name does not already exist. We also specify that
+ * bufrsize and initial size for the file.
+ *
+ * @code
 #include <netcdf.h>
         ...
      int status = NC_NOERR;
@@ -503,10 +516,10 @@ and initial size for the file.
      *bufrsize = 1024;
      status = nc__create("foo.nc", NC_NOCLOBBER, initialsz, bufrsize, &ncid);
      if (status != NC_NOERR) handle_error(status);
-\endcode
-
-\ingroup datasets
-
+ at endcode
+ *
+ * @ingroup datasets
+ * @author Glenn Davis
 */
 int
 nc__create(const char *path, int cmode, size_t initialsz,
@@ -517,12 +530,23 @@ nc__create(const char *path, int cmode, size_t initialsz,
 
 }
 /**
-\internal
-
-\deprecated This function was used in the old days with the Cray at
-NCAR. The Cray is long gone, and this call is supported only for
-backward compatibility.
-
+ * @internal Create a file with special (deprecated) Cray settings.
+ * 
+ * @deprecated This function was used in the old days with the Cray at
+ * NCAR. The Cray is long gone, and this call is supported only for
+ * backward compatibility. Use nc_create() instead.
+ *
+ * @param path File name.
+ * @param cmode Create mode.
+ * @param initialsz Initial size of metadata region for classic files,
+ * ignored for other files.
+ * @param basepe Deprecated parameter from the Cray days.
+ * @param chunksizehintp A pointer to the chunk size hint. This only
+ * applies to classic and 64-bit offset files.
+ * @param ncidp Pointer that gets ncid.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Glenn Davis
  */
 int
 nc__create_mp(const char *path, int cmode, size_t initialsz,
@@ -532,119 +556,116 @@ nc__create_mp(const char *path, int cmode, size_t initialsz,
 		    chunksizehintp, 0, NULL, ncidp);
 }
 
-/** \ingroup datasets
-Open an existing netCDF file.
-
-This function opens an existing netCDF dataset for access. It
-determines the underlying file format automatically. Use the same call
-to open a netCDF classic, 64-bit offset, or netCDF-4 file.
-
-\param path File name for netCDF dataset to be opened. When DAP
-support is enabled, then the path may be an OPeNDAP URL rather than a
-file path.
-
-\param mode The mode flag may include NC_WRITE (for read/write
-access) and NC_SHARE (see below) and NC_DISKLESS (see below).
-
-\param ncidp Pointer to location where returned netCDF ID is to be
-stored.
-
-<h2>Open Mode</h2>
-
-A zero value (or ::NC_NOWRITE) specifies the default behavior: open the
-dataset with read-only access, buffering and caching accesses for
-efficiency.
-
-Otherwise, the open mode is ::NC_WRITE, ::NC_SHARE, or
-::NC_WRITE|::NC_SHARE. Setting the ::NC_WRITE flag opens the dataset with
-read-write access. ("Writing" means any kind of change to the dataset,
-including appending or changing data, adding or renaming dimensions,
-variables, and attributes, or deleting attributes.)
-
-The NC_SHARE flag is only used for netCDF classic and 64-bit offset
-files. It is appropriate when one process may be writing the dataset
-and one or more other processes reading the dataset concurrently; it
-means that dataset accesses are not buffered and caching is
-limited. Since the buffering scheme is optimized for sequential
-access, programs that do not access data sequentially may see some
-performance improvement by setting the NC_SHARE flag.
-
-This procedure may also be invoked with the NC_DISKLESS flag
-set in the mode argument if the file to be opened is a
-classic format file.  For nc_open(), this flag applies only
-to files in classic format.  If the file is of type
-NC_NETCDF4, then the NC_DISKLESS flag will be ignored.
-
-If NC_DISKLESS is specified, then the whole file is read completely into
-memory. In effect this creates an in-memory cache of the file.
-If the mode flag also specifies NC_WRITE, then the in-memory cache
-will be re-written to the disk file when nc_close() is called.
-For some kinds of manipulations, having the in-memory cache can
-speed up file processing. But in simple cases, non-cached
-processing may actually be faster than using cached processing.
-You will need to experiment to determine if the in-memory caching
-is worthwhile for your application.
-
-Normally, NC_DISKLESS allocates space in the heap for
-storing the in-memory file. If, however, the ./configure
-flags --enable-mmap is used, and the additional mode flag
-NC_MMAP is specified, then the file will be opened using
-the operating system MMAP facility.
-This flag only applies to files in classic format. Extended
-format (netcdf-4) files will ignore the NC_MMAP flag.
-
-In most cases, using MMAP provides no advantage
-for just NC_DISKLESS. The one case where using MMAP is an
-advantage is when a file is to be opened and only a small portion
-of its data is to be read and/or written.
-In this scenario, MMAP will cause only the accessed data to be
-retrieved from disk. Without MMAP, NC_DISKLESS will read the whole
-file into memory on nc_open. Thus, MMAP will provide some performance
-improvement in this case.
-
-It is not necessary to pass any information about the format of the
-file being opened. The file type will be detected automatically by the
-netCDF library.
-
-If a the path is a DAP URL, then the open mode is read-only.
-Setting NC_WRITE will be ignored.
-
-As of version 4.3.1.2, multiple calls to nc_open with the same
-path will return the same ncid value.
-
-\note When opening a netCDF-4 file HDF5 error reporting is turned off,
-if it is on. This doesn't stop the HDF5 error stack from recording the
-errors, it simply stops their display to the user through stderr.
-
-nc_open()returns the value NC_NOERR if no errors occurred. Otherwise,
-the returned status indicates an error. Possible causes of errors
-include:
-
-Note that nc_open(path,cmode,ncidp) is equivalent to the invocation of
-nc__open(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp).
-
-\returns ::NC_NOERR No error.
-
-\returns ::NC_ENOMEM Out of memory.
-
-\returns ::NC_EHDFERR HDF5 error. (NetCDF-4 files only.)
-
-\returns ::NC_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4 files only.)
-
-<h1>Examples</h1>
-
-Here is an example using nc_open()to open an existing netCDF dataset
-named foo.nc for read-only, non-shared access:
-
- at code
-#include <netcdf.h>
-   ...
-int status = NC_NOERR;
-int ncid;
-   ...
-status = nc_open("foo.nc", 0, &ncid);
-if (status != NC_NOERR) handle_error(status);
- at endcode
+/**
+ * Open an existing netCDF file.
+ *
+ * This function opens an existing netCDF dataset for access. It
+ * determines the underlying file format automatically. Use the same
+ * call to open a netCDF classic, 64-bit offset, or netCDF-4 file.
+ *
+ * @param path File name for netCDF dataset to be opened. When DAP
+ * support is enabled, then the path may be an OPeNDAP URL rather than
+ * a file path.
+ * @param mode The mode flag may include NC_WRITE (for read/write
+ * access) and NC_SHARE (see below) and NC_DISKLESS (see below).
+ * @param ncidp Pointer to location where returned netCDF ID is to be
+ * stored.
+ *
+ * <h2>Open Mode</h2>
+ *
+ * A zero value (or ::NC_NOWRITE) specifies the default behavior: open
+ * the dataset with read-only access, buffering and caching accesses
+ * for efficiency.
+ *
+ * Otherwise, the open mode is ::NC_WRITE, ::NC_SHARE, or
+ * ::NC_WRITE|::NC_SHARE. Setting the ::NC_WRITE flag opens the
+ * dataset with read-write access. ("Writing" means any kind of change
+ * to the dataset, including appending or changing data, adding or
+ * renaming dimensions, variables, and attributes, or deleting
+ * attributes.)
+ * 
+ * The NC_SHARE flag is only used for netCDF classic and 64-bit offset
+ * files. It is appropriate when one process may be writing the
+ * dataset and one or more other processes reading the dataset
+ * concurrently; it means that dataset accesses are not buffered and
+ * caching is limited. Since the buffering scheme is optimized for
+ * sequential access, programs that do not access data sequentially
+ * may see some performance improvement by setting the NC_SHARE flag.
+ *
+ * This procedure may also be invoked with the NC_DISKLESS flag set in
+ * the mode argument if the file to be opened is a classic format
+ * file.  For nc_open(), this flag applies only to files in classic
+ * format.  If the file is of type NC_NETCDF4, then the NC_DISKLESS
+ * flag will be ignored.
+ *
+ * If NC_DISKLESS is specified, then the whole file is read completely
+ * into memory. In effect this creates an in-memory cache of the file.
+ * If the mode flag also specifies NC_WRITE, then the in-memory cache
+ * will be re-written to the disk file when nc_close() is called.  For
+ * some kinds of manipulations, having the in-memory cache can speed
+ * up file processing. But in simple cases, non-cached processing may
+ * actually be faster than using cached processing.  You will need to
+ * experiment to determine if the in-memory caching is worthwhile for
+ * your application.
+ *
+ * Normally, NC_DISKLESS allocates space in the heap for storing the
+ * in-memory file. If, however, the ./configure flags --enable-mmap is
+ * used, and the additional mode flag NC_MMAP is specified, then the
+ * file will be opened using the operating system MMAP facility.  This
+ * flag only applies to files in classic format. Extended format
+ * (netcdf-4) files will ignore the NC_MMAP flag.
+ *
+ * In most cases, using MMAP provides no advantage for just
+ * NC_DISKLESS. The one case where using MMAP is an advantage is when
+ * a file is to be opened and only a small portion of its data is to
+ * be read and/or written.  In this scenario, MMAP will cause only the
+ * accessed data to be retrieved from disk. Without MMAP, NC_DISKLESS
+ * will read the whole file into memory on nc_open. Thus, MMAP will
+ * provide some performance improvement in this case.
+ * 
+ * It is not necessary to pass any information about the format of the
+ * file being opened. The file type will be detected automatically by
+ * the netCDF library.
+ *
+ * If a the path is a DAP URL, then the open mode is read-only.
+ * Setting NC_WRITE will be ignored.
+ * 
+ * As of version 4.3.1.2, multiple calls to nc_open with the same
+ * path will return the same ncid value.
+ *
+ * @note When opening a netCDF-4 file HDF5 error reporting is turned
+ * off, if it is on. This doesn't stop the HDF5 error stack from
+ * recording the errors, it simply stops their display to the user
+ * through stderr.
+ *
+ * nc_open()returns the value NC_NOERR if no errors
+ * occurred. Otherwise, the returned status indicates an
+ * error. Possible causes of errors include:
+ *
+ * Note that nc_open(path,cmode,ncidp) is equivalent to the invocation
+ * of nc__open(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp).
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @returns ::NC_EHDFERR HDF5 error. (NetCDF-4 files only.)
+ * @returns ::NC_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4 files only.)
+ *
+ * <h1>Examples</h1>
+ * 
+ * Here is an example using nc_open()to open an existing netCDF dataset
+ * named foo.nc for read-only, non-shared access:
+ * 
+ * @code
+ * #include <netcdf.h>
+ *   ...
+ * int status = NC_NOERR;
+ * int ncid;
+ *   ...
+ * status = nc_open("foo.nc", 0, &ncid);
+ * if (status != NC_NOERR) handle_error(status);
+ * @endcode
+ * @ingroup datasets
+ * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
 */
 int
 nc_open(const char *path, int mode, int *ncidp)
@@ -781,12 +802,22 @@ nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp)
 }
 
 /**
-\internal
-
-\deprecated This function was used in the old days with the Cray at
-NCAR. The Cray is long gone, and this call is supported only for
-backward compatibility.
-
+ * @internal Open a netCDF file with extra parameters for Cray.
+ *
+ * @deprecated This function was used in the old days with the Cray at
+ * NCAR. The Cray is long gone, and this call is supported only for
+ * backward compatibility. Use nc_open() instead.
+ *
+ * @param path The file name of the new netCDF dataset.
+ * @param mode Open mode.
+ * @param basepe Deprecated parameter from the Cray days.
+ * @param chunksizehintp A pointer to the chunk size hint. This only
+ * applies to classic and 64-bit offset files.
+ * @param ncidp Pointer to location where returned netCDF ID is to be
+ * stored.
+ *
+ * @return ::NC_NOERR
+ * @author Glenn Davis
  */
 int
 nc__open_mp(const char *path, int mode, int basepe,
@@ -1234,10 +1265,13 @@ nc_close(int ncid)
 #endif
    {
 
-	   stat = ncp->dispatch->close(ncid);
+       stat = ncp->dispatch->close(ncid);
        /* Remove from the nc list */
-       del_from_NCList(ncp);
-       free_NC(ncp);
+       if (!stat)
+       {
+	   del_from_NCList(ncp);
+	   free_NC(ncp);
+       }
    }
    return stat;
 }
@@ -1350,15 +1384,18 @@ nc_set_fill(int ncid, int fillmode, int *old_modep)
 }
 
 /**
-\internal
-
-\deprecated This function was used in the old days with the Cray at
-NCAR. The Cray is long gone, and this call is supported only for
-backward compatibility.
-
-\returns ::NC_NOERR No error.
-
-\returns ::NC_EBADID Invalid ncid passed.
+ * @internal Learn base PE.
+ *
+ * @deprecated This function was used in the old days with the Cray at
+ * NCAR. The Cray is long gone, and this call is supported only for
+ * backward compatibility.
+ *
+ * @param ncid File and group ID.
+ * @param pe Pointer for base PE.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Invalid ncid passed.
+ * @author Glenn Davis
  */
 int
 nc_inq_base_pe(int ncid, int *pe)
@@ -1370,15 +1407,18 @@ nc_inq_base_pe(int ncid, int *pe)
 }
 
 /**
-\internal
-
-\deprecated This function was used in the old days with the Cray at
-NCAR. The Cray is long gone, and this call is supported only for
-backward compatibility.
-
-\returns ::NC_NOERR No error.
-
-\returns ::NC_EBADID Invalid ncid passed.
+ * @internal Sets base processing element (ignored).
+ *
+ * @deprecated This function was used in the old days with the Cray at
+ * NCAR. The Cray is long gone, and this call is supported only for
+ * backward compatibility.
+ *
+ * @param ncid File ID.
+ * @param pe Base PE.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Invalid ncid passed.
+ * @author Glenn Davis
  */
 int
 nc_set_base_pe(int ncid, int pe)
@@ -1504,6 +1544,16 @@ nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
    return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
 }
 
+/**
+ * Learn the number of variables in a file or group.
+ *
+ * @param ncid File and group ID.
+ * @param nvarsp Pointer that gets number of variables. Ignored if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Glenn Davis, Ed Hartnett, Dennis Heimbigner
+ */
 int
 nc_inq_nvars(int ncid, int *nvarsp)
 {
@@ -1603,37 +1653,95 @@ nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
 }
 
 /**
-\internal
-\ingroup dispatch
-
-Create a file, calling the appropriate dispatch create call.
-
-For create, we have the following pieces of information to use to
-determine the dispatch table:
-- path
-- cmode
-
-\param path0 The file name of the new netCDF dataset.
+Check the create mode parameter for sanity.
 
-\param cmode The creation mode flag, the same as in nc_create().
+Some create flags cannot be used if corresponding library features are
+enabled during the build. This function does a pre-check of the mode
+flag before calling the dispatch layer nc_create functions.
 
-\param initialsz This parameter sets the initial size of the file at creation
-time. This only applies to classic and 64-bit offset files.
+\param mode The creation mode flag.
 
-\param basepe Deprecated parameter from the Cray days.
-
-\param chunksizehintp A pointer to the chunk size hint. This only
-applies to classic and 64-bit offset files.
-
-\param useparallel Non-zero if parallel I/O is to be used on this
-file.
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOTBUILT Requested feature not built into library
+\returns ::NC_EINVAL Invalid combination of modes.
+\internal
+\ingroup dispatch
+\author Ed Hartnett
+*/
+static int
+check_create_mode(int mode)
+{
+    int mode_format;
+
+    /* This is a clever check to see if more than one format bit is
+     * set. */
+    mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
+       (mode & NC_CDF5);
+    if (mode_format && (mode_format & (mode_format - 1)))
+       return NC_EINVAL;
+    
+    /* Can't use both NC_MPIIO and NC_MPIPOSIX. Make up your damn
+     * mind! */
+    if (mode & NC_MPIIO && mode & NC_MPIPOSIX)
+       return NC_EINVAL;
+    
+    /* Can't use both parallel and diskless. */
+    if ((mode & NC_MPIIO && mode & NC_DISKLESS) ||
+	(mode & NC_MPIPOSIX && mode & NC_DISKLESS))
+	return NC_EINVAL;
 
-\param parameters Pointer to MPI comm and info.
+#ifndef USE_DISKLESS
+   /* If diskless is requested, but not built, return error. */
+   if (mode & NC_DISKLESS)
+       return NC_ENOTBUILT;       
+   if (mode & NC_INMEMORY)
+       return NC_ENOTBUILT;       
+#endif
+   
+#ifndef USE_NETCDF4
+   /* If the user asks for a netCDF-4 file, and the library was built
+    * without netCDF-4, then return an error.*/
+   if (mode & NC_NETCDF4)
+       return NC_ENOTBUILT;
+#endif /* USE_NETCDF4 undefined */
+
+#ifndef USE_PARALLEL
+   /* If parallel support is not included, these mode flags won't
+    * work. */
+   if (mode & NC_PNETCDF || mode & NC_MPIPOSIX)
+       return NC_ENOTBUILT;
+#endif /* USE_PARALLEL */
 
-\param ncidp Pointer to location where returned netCDF ID is to be
-stored.
+   /* Well I guess there is some sanity in the world after all. */
+   return NC_NOERR;
+}
 
-\returns ::NC_NOERR No error.
+/**
+ * @internal Create a file, calling the appropriate dispatch create
+ * call.
+ *
+ * For create, we have the following pieces of information to use to
+ * determine the dispatch table:
+ * - path
+ * - cmode
+ *
+ * @param path0 The file name of the new netCDF dataset.
+ * @param cmode The creation mode flag, the same as in nc_create().
+ * @param initialsz This parameter sets the initial size of the file
+ * at creation time. This only applies to classic and 64-bit offset
+ * files.
+ * @param basepe Deprecated parameter from the Cray days.
+ * @param chunksizehintp A pointer to the chunk size hint. This only
+ * applies to classic and 64-bit offset files.
+ * @param useparallel Non-zero if parallel I/O is to be used on this
+ * file.
+ * @param parameters Pointer to MPI comm and info.
+ * @param ncidp Pointer to location where returned netCDF ID is to be
+ * stored.
+ *
+ * @returns ::NC_NOERR No error.
+ * @ingroup dispatch
+ * @author Dennis Heimbigner, Ed Hartnett, Ward Fisher
 */
 int
 NC_create(const char *path0, int cmode, size_t initialsz,
@@ -1652,6 +1760,11 @@ NC_create(const char *path0, int cmode, size_t initialsz,
    TRACE(nc_create);
    if(path0 == NULL)
 	return NC_EINVAL;
+
+   /* Check mode flag for sanity. */
+   if ((stat = check_create_mode(cmode)))
+      return stat;
+   
    /* Initialize the dispatch table. The function pointers in the
     * dispatch table will depend on how netCDF was built
     * (with/without netCDF-4, DAP, CDMREMOTE). */
@@ -1668,7 +1781,6 @@ NC_create(const char *path0, int cmode, size_t initialsz,
 #ifdef WINPATH
    /* Need to do path conversion */
    path = NCpathcvt(path0);
-fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
 #else
    path = nulldup(path0);
 #endif
@@ -1748,7 +1860,10 @@ fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
 	cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/
 
    if((cmode & NC_MPIIO) && (cmode & NC_MPIPOSIX))
-      return  NC_EINVAL;
+   {
+       nullfree(path);       
+       return  NC_EINVAL;
+   }
 
    if (dispatcher == NULL)
    {
@@ -1767,11 +1882,14 @@ fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
       if(model == (NC_FORMATX_NC3))
  	dispatcher = NC3_dispatch_table;
       else
-	 return NC_ENOTNC;
+      {
+	  nullfree(path);
+	  return NC_ENOTNC;
+      }
    }
 
    /* Create the NC* instance and insert its dispatcher */
-   stat = new_NC(dispatcher,path,cmode,&ncp);
+   stat = new_NC(dispatcher,path,cmode,model,&ncp);
    nullfree(path); path = NULL; /* no longer needed */
 
    if(stat) return stat;
@@ -1796,25 +1914,31 @@ fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
 }
 
 /**
-\internal
-\ingroup dispatch
-
-Open a netCDF file (or remote dataset) calling the appropriate
-dispatch function.
-
-For open, we have the following pieces of information to use to determine the dispatch table.
-- table specified by override
-- path
-- cmode
-- the contents of the file (if it exists), basically checking its magic number.
-
-\returns ::NC_NOERR No error.
+ * @internal Open a netCDF file (or remote dataset) calling the
+ * appropriate dispatch function.
+ *
+ * For open, we have the following pieces of information to use to
+ * determine the dispatch table.
+ * - table specified by override
+ * - path
+ * - cmode
+ * - the contents of the file (if it exists), basically checking its magic number.
+ *
+ * @param path0 Path to the file to open.
+ * @param cmode Open mode.
+ * @param basepe Base processing element (ignored).
+ * @param chunksizehintp Size hint for classic files.
+ * @param useparallel If true use parallel I/O.
+ * @param parameters Extra parameters for the open.
+ * @param ncidp Pointer that gets ncid.
+ *
+ * @returns ::NC_NOERR No error.
+ * @ingroup dispatch
+ * @author Dennis Heimbigner
 */
 int
-NC_open(const char *path0, int cmode,
-	int basepe, size_t *chunksizehintp,
-        int useparallel, void* parameters,
-        int *ncidp)
+NC_open(const char *path0, int cmode, int basepe, size_t *chunksizehintp,
+        int useparallel, void* parameters, int *ncidp)
 {
    int stat = NC_NOERR;
    NC* ncp = NULL;
@@ -1883,10 +2007,15 @@ NC_open(const char *path0, int cmode,
 	if(diskless) flags |= NC_DISKLESS;
 	stat = NC_check_file_type(path,flags,parameters,&model,&version);
         if(stat == NC_NOERR) {
-   	if(model == 0)
-	    return NC_ENOTNC;
-	} else /* presumably not a netcdf file */
+	    if(model == 0) {
+		nullfree(path);       		
+		return NC_ENOTNC;
+	    }
+	} else {
+	    /* presumably not a netcdf file */
+	    nullfree(path);       			    
 	    return stat;
+	}
     }
 
    if(model == 0) {
@@ -1895,7 +2024,7 @@ NC_open(const char *path0, int cmode,
    }
 
    /* Force flag consistentcy */
-   if(model == NC_FORMATX_NC4 || model == NC_FORMATX_DAP4)
+   if(model == NC_FORMATX_NC4 || model == NC_FORMATX_NC_HDF4 || model == NC_FORMATX_DAP4)
       cmode |= NC_NETCDF4;
    else if(model == NC_FORMATX_DAP2) {
       cmode &= ~NC_NETCDF4;
@@ -1926,8 +2055,12 @@ NC_open(const char *path0, int cmode,
      cmode |= NC_64BIT_DATA;
    }
 
-   if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX))
-     return  NC_EINVAL;
+   /* Invalid to use both NC_MPIIO and NC_MPIPOSIX. Make up your damn
+    * mind! */
+   if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX)) {
+       nullfree(path);       
+       return NC_EINVAL;
+   }
 
    /* override any other table choice */
    if(dispatcher != NULL) goto havetable;
@@ -1949,22 +2082,26 @@ NC_open(const char *path0, int cmode,
    else
 #endif
 #if defined(USE_NETCDF4)
-   if(model == (NC_FORMATX_NC4))
+   if(model == (NC_FORMATX_NC4) || model == (NC_FORMATX_NC_HDF4))
 	dispatcher = NC4_dispatch_table;
    else
 #endif
    if(model == (NC_FORMATX_NC3))
 	dispatcher = NC3_dispatch_table;
-   else
-      return  NC_ENOTNC;
+   else {
+       nullfree(path);              
+       return  NC_ENOTNC;
+   }
 
 havetable:
 
-   if(dispatcher == NULL)
-	return NC_ENOTNC;
+   if(dispatcher == NULL) {
+       nullfree(path);              
+       return NC_ENOTNC;
+   }
 
    /* Create the NC* instance and insert its dispatcher */
-   stat = new_NC(dispatcher,path,cmode,&ncp);
+   stat = new_NC(dispatcher,path,cmode,model,&ncp);
    nullfree(path); path = NULL; /* no longer need path */
    if(stat) return stat;
 
@@ -1992,11 +2129,15 @@ havetable:
   for systems that are not file based (e.g. dap, memio).
 */
 
-/* Static counter for pseudo file descriptors (incremented) */
+/** @internal Static counter for pseudo file descriptors (incremented) */
 static int pseudofd = 0;
 
-/* Create a pseudo file descriptor that does not
-   overlap real file descriptors
+/**
+ * @internal Create a pseudo file descriptor that does not
+ * overlap real file descriptors
+ *
+ * @return pseudo file number
+ * @author Dennis Heimbigner
 */
 int
 nc__pseudofd(void)
@@ -2016,3 +2157,176 @@ nc__pseudofd(void)
     }
     return pseudofd++;
 }
+
+/**
+\internal
+\ingroup datasets
+Provide open, read and close for use when searching for magic numbers
+*/
+static int
+openmagic(struct MagicFile* file)
+{
+    int status = NC_NOERR;
+    if(file->inmemory) {
+	/* Get its length */
+	NC_MEM_INFO* meminfo = (NC_MEM_INFO*)file->parameters;
+	file->filelen = (long long)meminfo->size;
+	goto done;
+    }
+#ifdef USE_PARALLEL
+    if (file->use_parallel) {
+	MPI_Status mstatus;
+	int retval;
+	MPI_Offset size;
+	MPI_Comm comm = MPI_COMM_WORLD;
+	MPI_Info info = MPI_INFO_NULL;
+        if(file->parameters != NULL) {
+	    comm = ((NC_MPI_INFO*)file->parameters)->comm;
+	    info = ((NC_MPI_INFO*)file->parameters)->info;
+	}
+	if((retval = MPI_File_open(comm,(char*)file->path,MPI_MODE_RDONLY,info,
+				       &file->fh)) != MPI_SUCCESS)
+	    {status = NC_EPARINIT; goto done;}
+	/* Get its length */
+	if((retval=MPI_File_get_size(file->fh, &size)) != MPI_SUCCESS)
+	    {status = NC_EPARINIT; goto done;}
+	file->filelen = (long long)size;
+	goto done;
+    }
+#endif /* USE_PARALLEL */
+    {
+        if(file->path == NULL || strlen(file->path)==0)
+	    {status = NC_EINVAL; goto done;}
+#ifdef _MSC_VER
+        file->fp = fopen(file->path, "rb");
+#else
+        file->fp = fopen(file->path, "r");
+#endif
+	if(file->fp == NULL)
+	    {status = errno; goto done;}
+	/* Get its length */
+	{
+#ifdef _MSC_VER
+	int fd = fileno(file->fp);
+	__int64 len64 = _filelengthi64(fd);
+	if(len64 < 0)
+            {status = errno; goto done;}
+	file->filelen = (long long)len64;
+#else
+	long size;
+	if((status = fseek(file->fp, 0L, SEEK_END)) < 0)
+	    {status = errno; goto done;}
+	size = ftell(file->fp);
+	file->filelen = (long long)size;
+#endif
+	rewind(file->fp);
+	}
+	goto done;
+    }
+
+done:
+    return status;
+}
+
+static int
+readmagic(struct MagicFile* file, long pos, char* magic)
+{
+    int status = NC_NOERR;
+    memset(magic,0,MAGIC_NUMBER_LEN);
+    if(file->inmemory) {
+	char* mempos;
+	NC_MEM_INFO* meminfo = (NC_MEM_INFO*)file->parameters;
+	if((pos + MAGIC_NUMBER_LEN) > meminfo->size)
+	    {status = NC_EDISKLESS; goto done;}
+	mempos = ((char*)meminfo->memory) + pos;
+	memcpy((void*)magic,mempos,MAGIC_NUMBER_LEN);
+#ifdef DEBUG
+	printmagic("XXX: readmagic",magic,file);
+#endif
+	goto done;
+    }
+#ifdef USE_PARALLEL
+    if (file->use_parallel) {
+	MPI_Status mstatus;
+	int retval;
+	MPI_Offset offset;
+	offset = pos;
+	if((retval = MPI_File_seek(file->fh, offset, MPI_SEEK_SET)) != MPI_SUCCESS)
+	    {status = NC_EPARINIT; goto done;}	
+	if((retval = MPI_File_read(file->fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
+				 &mstatus)) != MPI_SUCCESS)
+	    {status = NC_EPARINIT; goto done;}
+	goto done;
+    }
+#endif /* USE_PARALLEL */
+    {
+	size_t count;
+	int i = fseek(file->fp,pos,SEEK_SET);
+	if(i < 0)
+	    {status = errno; goto done;}
+	for(i=0;i<MAGIC_NUMBER_LEN;) {/* make sure to read proper # of bytes */
+	    count=fread(&magic[i],1,(MAGIC_NUMBER_LEN-i),file->fp);
+	    if(count == 0 || ferror(file->fp))
+		{status = errno; goto done;}
+	    i += count;
+	}
+	goto done;
+    }
+done:
+    if(file && file->fp) clearerr(file->fp);
+    return status;
+}
+
+/** 
+ * Close the file opened to check for magic number. 
+ * 
+ * @param file pointer to the MagicFile struct for this open file.
+ * @returns NC_NOERR for success
+ * @returns NC_EPARINIT if there was a problem closing file with MPI
+ * (parallel builds only).
+ * @author Dennis Heimbigner
+ */
+static int
+closemagic(struct MagicFile* file)
+{
+    int status = NC_NOERR;
+    if(file->inmemory) goto done; /* noop*/
+#ifdef USE_PARALLEL
+    if (file->use_parallel) {
+	MPI_Status mstatus;
+	int retval;
+	if((retval = MPI_File_close(&file->fh)) != MPI_SUCCESS)
+		{status = NC_EPARINIT; goto done;}
+	goto done;
+    }
+#endif
+    {
+	if(file->fp) fclose(file->fp);
+	goto done;
+    }
+done:
+    return status;
+}
+
+#ifdef DEBUG
+static void
+printmagic(const char* tag, char* magic, struct MagicFile* f)
+{
+    int i;
+    fprintf(stderr,"%s: inmem=%d ispar=%d magic=",tag,f->inmemory,f->use_parallel);
+    for(i=0;i<MAGIC_NUMBER_LEN;i++) {
+        unsigned int c = (unsigned int)magic[i];
+	c = c & 0x000000FF;
+	if(c == '\n')
+	    fprintf(stderr," 0x%0x/'\\n'",c);
+	else if(c == '\r')
+	    fprintf(stderr," 0x%0x/'\\r'",c);
+	else if(c < ' ')
+	    fprintf(stderr," 0x%0x/'?'",c);
+	else
+	    fprintf(stderr," 0x%0x/'%c'",c,c);
+    }
+    fprintf(stderr,"\n");
+    fflush(stderr);
+}
+#endif
diff --git a/libdispatch/dfilter.c b/libdispatch/dfilter.c
new file mode 100644
index 0000000..e4f9aea
--- /dev/null
+++ b/libdispatch/dfilter.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright 1996, University Corporation for Atmospheric Research
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef _MSC_VER
+#include <io.h>
+#endif
+
+#include "netcdf.h"
+
+/*
+Common utilities related to filters.
+*/
+
+
+/* Forward */
+static int gettype(const int q0, const int q1, int* unsignedp);
+
+/**************************************************/
+/*
+Parse a filter spec string into a filter id + a vector
+of unsigned ints.
+
+ at param spec0 - a string containing the spec as a sequence of
+              constants separated by commas.
+ at param idp - store the parsed filter id here
+ at param nparamsp - store number of parsed filter params here
+ at param paramsp - store the vector of parsed filter params here
+ at return 1 if parse succeeded, 0 otherwise.
+*/
+
+EXTERNL int
+NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp)
+{
+    int stat = NC_NOERR;
+    int sstat; /* for scanf */
+    char* p;
+    char* sdata = NULL;
+    unsigned int id;
+    size_t count; /* no. of comma delimited params */
+    size_t nparams; /* final no. of unsigned ints */
+    size_t len;
+    int i;
+    unsigned int* ulist = NULL;
+    unsigned char mem[8]; /* to convert to network byte order */
+
+    if(spec == NULL || strlen(spec) == 0) goto fail;
+    sdata = strdup(spec);
+
+    /* Count number of parameters + id and delimit */
+    p=sdata;
+    for(count=0;;count++) {
+        char* q = strchr(p,',');
+	if(q == NULL) break;
+	*q++ = '\0';
+	p = q;
+    }
+    count++; /* for final piece */
+
+    if(count == 0)
+	goto fail; /* no id and no parameters */
+
+    /* Extract the filter id */
+    p = sdata;
+    sstat = sscanf(p,"%u",&id);
+    if(sstat != 1) goto fail;
+    /* skip past the filter id */
+    p = p + strlen(p) + 1;
+    count--;
+
+    /* Allocate the max needed space; *2 in case the params are all doubles */
+    ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count)*2);
+    if(ulist == NULL) goto fail;
+
+    /* walk and convert */
+    nparams = 0; /* actual count */
+    for(i=0;i<count;i++) { /* step thru param strings */
+	unsigned long long val64u;
+	unsigned int val32u;
+	double vald;
+	float valf;
+	unsigned int *vector;
+	int isunsigned = 0;
+	int isnegative = 0;
+	int type = 0;
+	char* q;
+
+	len = strlen(p);
+	/* skip leading white space */
+	while(strchr(" 	",*p) != NULL) {p++; len--;}
+	/* Get leading sign character, if any */
+	if(*p == '-') isnegative = 1;
+        /* Get trailing type tag characters */
+	switch (len) {
+	case 0:
+	    goto fail; /* empty parameter */
+	case 1:
+	case 2:
+	    q = (p + len) - 1; /* point to last char */
+	    type = gettype(*q,'\0',&isunsigned);
+	    break;
+	default: /* > 2 => we might have a two letter tag */
+	    q = (p + len) - 2;
+	    type = gettype(*q,*(q+1),&isunsigned);
+	    break;
+	}
+
+	/* Now parse */
+	switch (type) {
+	case 'b':
+	case 's':
+	case 'i':
+ 	    /* special case for a positive integer;for back compatibility.*/
+	    if(!isnegative)
+	        sstat = sscanf(p,"%u",&val32u);
+	    else
+                sstat = sscanf(p,"%d",(int*)&val32u);
+	    if(sstat != 1) goto fail;
+	    switch(type) {
+	    case 'b': val32u = (val32u & 0xFF); break;
+	    case 's': val32u = (val32u & 0xFFFF); break;
+	    }
+	    ulist[nparams++] = val32u;
+	    break;
+
+	case 'f':
+	    sstat = sscanf(p,"%lf",&vald);
+	    if(sstat != 1) goto fail;
+	    valf = (float)vald;
+	    ulist[nparams++] = *(unsigned int*)&valf;
+	    break;
+
+	case 'd':
+	    sstat = sscanf(p,"%lf",&vald);
+	    if(sstat != 1) goto fail;
+	    /* convert to network byte order */
+	    memcpy(mem,&vald,sizeof(mem));
+#ifdef WORDS_BIGENDIAN
+	    NC_byteswap8(mem);  /* convert big endian to little endian */
+#endif
+	    vector = (unsigned int*)mem;
+	    ulist[nparams++] = vector[0];
+	    ulist[nparams++] = vector[1];
+	    break;
+	case 'l': /* long long */
+	    if(isunsigned)
+	        sstat = sscanf(p,"%llu",&val64u);
+	    else
+                sstat = sscanf(p,"%lld",(long long*)&val64u);
+	    if(sstat != 1) goto fail;
+	    /* convert to network byte order */
+	    memcpy(mem,&val64u,sizeof(mem));
+#ifdef WORDS_BIGENDIAN	    
+	    byteswap8(mem);  /* convert big endian to little endian */
+#endif
+	    vector = (unsigned int*)mem;
+	    ulist[nparams++] = vector[0];
+	    ulist[nparams++] = vector[1];
+	    break;
+	default:
+	    goto fail;
+	}
+        p = p + strlen(p) + 1; /* move to next param */
+    }
+    /* Now return results */
+    if(idp) *idp = id;
+    if(nparamsp) *nparamsp = nparams;
+    if(paramsp) {
+       *paramsp = ulist;
+       ulist = NULL; /* avoid duplicate free */
+    }
+done:
+    if(sdata) free(sdata);
+    if(ulist) free(ulist);
+    return stat;
+fail:
+    stat = NC_EFILTER;
+    goto done;
+}
+
+/* Look at q0 and q1) to determine type */
+static int
+gettype(const int q0, const int q1, int* isunsignedp)
+{
+    int type = 0;
+    int isunsigned = 0;
+    char typechar;
+    
+    isunsigned = (q0 == 'u' || q0 == 'U');
+    if(q1 == '\0')
+	typechar = q0; /* we were given only a single char */
+    else if(isunsigned)
+	typechar = q1; /* we have something like Ux as the tag */
+    else
+	typechar = q1; /* look at last char for tag */
+    switch (typechar) {
+    case 'f': case 'F': case '.': type = 'f'; break; /* float */
+    case 'd': case 'D': type = 'd'; break; /* double */
+    case 'b': case 'B': type = 'b'; break; /* byte */
+    case 's': case 'S': type = 's'; break; /* short */
+    case 'l': case 'L': type = 'l'; break; /* long long */
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9': type = 'i'; break;
+    case 'u': case 'U': type = 'i'; isunsigned = 1; break; /* unsigned int */
+    case '\0': type = 'i'; break;
+    default: break;
+    }
+    if(isunsignedp) *isunsignedp = isunsigned;
+    return type;
+}
+
+#ifdef WORDS_BIGENDIAN
+/* Byte swap an 8-byte integer in place */
+EXTERNL
+void
+NC_byteswap8(unsigned char* mem)
+{
+    unsigned char c;
+    c = mem[0];
+    mem[0] = mem[7];
+    mem[7] = c;
+    c = mem[1];
+    mem[1] = mem[6];
+    mem[6] = c;
+    c = mem[2];
+    mem[2] = mem[5];
+    mem[5] = c;
+    c = mem[3];
+    mem[3] = mem[4];
+    mem[4] = c;
+}
+#endif
diff --git a/libdispatch/dinternal.c b/libdispatch/dinternal.c
index 5451a4b..4783042 100644
--- a/libdispatch/dinternal.c
+++ b/libdispatch/dinternal.c
@@ -20,7 +20,8 @@ NCDISPATCH_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp)
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               )
 {
    NC* ncp;
    int stat = NC_check_id(ncid,&ncp);
@@ -32,8 +33,7 @@ NCDISPATCH_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
       contiguousp, chunksizesp,
       no_fill, fill_valuep,
       endiannessp,
-      options_maskp, 
-      pixels_per_blockp);
+      idp, nparamsp, params);
 }
 
 int
diff --git a/libdispatch/dparallel.c b/libdispatch/dparallel.c
index 652053b..d420281 100644
--- a/libdispatch/dparallel.c
+++ b/libdispatch/dparallel.c
@@ -1,17 +1,89 @@
-/** \file dparallel.c
-This file has the parallel I/O functions which correspond to the serial I/O functions.
+/** \file
+
+This file has the parallel I/O functions which correspond to the
+serial I/O functions.
 
 Copyright 2010 University Corporation for Atmospheric
 Research/Unidata. See COPYRIGHT file for more info.
 */
-
 #include "config.h"
 #include "ncdispatch.h"
 
 /**
+Create a netCDF file for parallel I/O.
+
+This function creates a new netCDF file for parallel I/O access.
+
+Parallel I/O access is only available in library build which support
+parallel I/O. To support parallel I/O, netCDF must be built with
+netCDF-4 enabled, and with a HDF5 library that supports parallel I/O,
+or with support for the parallel-netcdf library via the
+enable-pnetcdf option.
+
+See nc_create() for a fuller discussion of file creation.
+
+\note When opening a netCDF-4 file HDF5 error reporting is turned off,
+if it is on. This doesn't stop the HDF5 error stack from recording the
+errors, it simply stops their display to the user through stderr.
+
+\param path The file name of the new netCDF dataset.
+
+\param cmode The creation mode flag. The following flags are available:
+  NC_NOCLOBBER (do not overwrite existing file),
+  NC_NETCDF4 (create netCDF-4/HDF5 file),
+  NC_CLASSIC_MODEL (enforce netCDF classic mode on netCDF-4/HDF5 files),
+  NC_PNETCDF.
+
+\param comm the MPI communicator to be used.
+
+\param info MPI info or MPI_INFO_NULL.
+
+\param ncidp Pointer to location where returned netCDF ID is to be
+stored.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOPAR Library was not built with parallel I/O features.
+\returns ::NC_EINVAL Invalid input parameters.
+\returns ::NC_ENOMEM System out of memory.
+\returns ::NC_ENOTNC Binary format could not be determined.
+\returns ::NC_EHDFERR HDF5 error (netCDF-4 files only).
+\returns ::NC_EFILEMETA Error writing netCDF-4 file-level metadata in
+HDF5 file. (netCDF-4 files only).
+
+<h1>Example</h1>
+
+In this example from nc_test4/tst_parallel.c, a file is create for
+parallel I/O.
+
+\code
+    int mpi_size, mpi_rank;
+    MPI_Comm comm = MPI_COMM_WORLD;
+    MPI_Info info = MPI_INFO_NULL;
+    int ncid, v1id, dimids[NDIMS];
+    char file_name[NC_MAX_NAME + 1];
+
+    MPI_Init(&argc,&argv);
+    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
+    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
 
- This function creates a file for use with parallel I/O.
+    sprintf(file_name, "%s/%s", TEMP_LARGE, FILE);
+    if ((res = nc_create_par(file_name, NC_NETCDF4|NC_MPIIO, comm,
+			     info, &ncid))) ERR;
 
+    if (nc_def_dim(ncid, "d1", DIMSIZE, dimids)) ERR;
+    if (nc_def_dim(ncid, "d2", DIMSIZE, &dimids[1])) ERR;
+    if (nc_def_dim(ncid, "d3", NUM_SLABS, &dimids[2])) ERR;
+
+    if ((res = nc_def_var(ncid, "v1", NC_INT, NDIMS, dimids, &v1id))) ERR;
+
+    if ((res = nc_enddef(ncid))) ERR;
+
+    ...
+
+    if ((res = nc_close(ncid)))	ERR;
+\endcode
+\author Ed Hartnett, Dennis Heimbigner
+\ingroup datasets
 */
 int nc_create_par(const char *path, int cmode, MPI_Comm comm,
 	      MPI_Info info, int *ncidp)
@@ -33,10 +105,74 @@ int nc_create_par(const char *path, int cmode, MPI_Comm comm,
 #endif /* USE_PARALLEL */
 }
 
-/*! \ingroup datasets
+/**
+Open an existing netCDF file for parallel I/O.
+
+This function opens an existing netCDF dataset for parallel I/O
+access. It determines the underlying file format automatically. Use
+the same call to open a netCDF classic, 64-bit offset, or netCDF-4
+file.
+
+Parallel I/O access is only available in library build which support
+parallel I/O. To support parallel I/O, netCDF must be built with
+netCDF-4 enabled, and with a HDF5 library that supports parallel I/O,
+or with support for the parallel-netcdf library via the
+enable-pnetcdf option.
+
+It is not necessary to pass any information about the format of the
+file being opened. The file type will be detected automatically by the
+netCDF library.
+
+As of version 4.3.1.2, multiple calls to nc_open_par() with the same
+path will return the same ncid value.
+
+\note When opening a netCDF-4 file HDF5 error reporting is turned off,
+if it is on. This doesn't stop the HDF5 error stack from recording the
+errors, it simply stops their display to the user through stderr.
+
+\param path File name for netCDF dataset to be opened.
+
+\param mode The mode flag may include NC_WRITE (for read/write
+access), NC_MPIIO or NC_MPIPOSIX (not both) for parallel netCDF-4 I/O,
+or NC_PNETCDF for parallel-netcdf parallel I/O access for a netCDF
+classic or CDF5 file.
+
+\param comm the MPI communicator to be used.
+
+\param info MPI info or MPI_INFO_NULL.
+
+\param ncidp Pointer to location where returned netCDF ID is to be
+stored.
 
-  This function opens a file for parallel I/O.
+nc_open_par() returns the value NC_NOERR if no errors
+occurred. Otherwise, the returned status indicates an error. Possible
+causes of errors include:
 
+\returns ::NC_NOERR No error.
+\returns ::NC_EINVAL Invalid parameters.
+\returns ::NC_ENOTNC Not a netCDF file.
+\returns ::NC_ENOMEM Out of memory.
+\returns ::NC_EHDFERR HDF5 error. (NetCDF-4 files only.)
+\returns ::NC_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4
+files only.)
+
+<h1>Examples</h1>
+
+Here is an example using nc_open_par() from examples/C/parallel_vara.c.
+
+\code
+#include <mpi.h>
+#include <netcdf.h>
+#include <netcdf_par.h>
+   ...
+    int ncid, omode;
+    char filename[128];
+   ...
+    omode = NC_PNETCDF | NC_NOWRITE;
+    err = nc_open_par(filename, omode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); FATAL_ERR
+\endcode
+\author Ed Hartnett, Dennis Heimbigner
+\ingroup datasets
 */
 int
 nc_open_par(const char *path, int mode, MPI_Comm comm,
@@ -63,10 +199,39 @@ nc_open_par(const char *path, int mode, MPI_Comm comm,
 #endif /* USE_PARALLEL */
 }
 
-/*! \ingroup datasets
+/**
+This is the same as nc_open_par(), but accepts the MPI comm/info as
+integers.
+
+\param path File name for netCDF dataset to be opened.
+
+\param mode The mode flag may include NC_WRITE (for read/write
+access), NC_MPIIO or NC_MPIPOSIX (not both) for parallel netCDF-4 I/O,
+or NC_PNETCDF for parallel-netcdf parallel I/O access for a netCDF
+classic or CDF5 file.
+
+\param comm the MPI communicator to be used.
+
+\param info MPI info or MPI_INFO_NULL.
 
- Fortran needs to pass MPI comm/info as integers.
+\param ncidp Pointer to location where returned netCDF ID is to be
+stored.
 
+nc_open_par() returns the value NC_NOERR if no errors
+occurred. Otherwise, the returned status indicates an error. Possible
+causes of errors include:
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EINVAL Invalid parameters.
+\returns ::NC_ENOTNC Not a netCDF file.
+\returns ::NC_ENOMEM Out of memory.
+\returns ::NC_EHDFERR HDF5 error. (NetCDF-4 files only.)
+\returns ::NC_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4
+files only.)
+
+\author Ed Hartnett
+\ingroup datasets
+\internal
 */
 int
 nc_open_par_fortran(const char *path, int mode, int comm,
@@ -92,8 +257,67 @@ nc_open_par_fortran(const char *path, int mode, int comm,
 #endif
 }
 
-/* This function will change the parallel access of a variable from
- * independent to collective. */
+/**\ingroup datasets
+
+This function will change the parallel access of a variable from
+independent to collective.
+
+\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
+
+\param par_access NC_COLLECTIVE or NC_INDEPENDENT.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Invalid ncid passed.
+\returns ::NC_ENOTVAR Invalid varid passed.
+\returns ::NC_ENOPAR LFile was not opened with nc_open_par/nc_create_var.
+\returns ::NC_EINVAL Invalid par_access specified.
+
+<h1>Example</h1>
+
+Here is an example from examples/C/parallel_vara.c which changes the
+parallel access of a variable and then writes to it.
+
+\code
+#define NY 10
+#define NX 4
+
+    #include <mpi.h>
+    #include <netcdf.h>
+    #include <netcdf_par.h>
+        ...
+    char filename[128];
+    int err, ncid, cmode, varid, dimid, dimid[2], buf[NY][NX];
+    size_t global_ny, global_nx, start[2], count[2];
+        ...
+    global_ny = NY;
+    global_nx = NX * nprocs;
+        ...
+    cmode = NC_CLOBBER | NC_PNETCDF;
+    err = nc_create_par(filename, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); FATAL_ERR
+        ...
+    err = nc_def_dim(ncid, "Y", global_ny, &dimid[0]); ERR
+    err = nc_def_dim(ncid, "X", global_nx, &dimid[1]); ERR
+    err = nc_def_var(ncid, "var", NC_INT, 2, dimid, &varid); ERR
+        ...
+    err = nc_enddef(ncid); ERR
+        ...
+    err = nc_var_par_access(ncid, varid, NC_COLLECTIVE); ERR
+        ...
+    start[0] = 0;
+    start[1] = NX * rank;
+    count[0] = NY;
+    count[1] = NX;
+
+    err = nc_put_vara_int(ncid, varid, start, count, &buf[0][0]); ERR
+
+\endcode
+\author Ed Hartnett, Dennis Heimbigner
+\ingroup datasets
+ */
 int
 nc_var_par_access(int ncid, int varid, int par_access)
 {
@@ -111,7 +335,40 @@ nc_var_par_access(int ncid, int varid, int par_access)
 #endif
 }
 
-/* when calling from fortran: convert MPI_Comm and MPI_Info to C */
+/**
+Create a netCDF file for parallel access from the Fortran API.
+
+This function calls nc_create_par() after converting the MPI comm and
+info from Fortran to C, if necessary.
+
+\param path The file name of the new netCDF dataset.
+
+\param cmode The creation mode flag. The following flags are available:
+  NC_NOCLOBBER (do not overwrite existing file),
+  NC_NETCDF4 (create netCDF-4/HDF5 file),
+  NC_CLASSIC_MODEL (enforce netCDF classic mode on netCDF-4/HDF5 files),
+  NC_PNETCDF.
+
+\param comm the MPI communicator to be used.
+
+\param info MPI info or MPI_INFO_NULL.
+
+\param ncidp Pointer to location where returned netCDF ID is to be
+stored.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOPAR Library was not built with parallel I/O features.
+\returns ::NC_EINVAL Invalid input parameters.
+\returns ::NC_ENOMEM System out of memory.
+\returns ::NC_ENOTNC Binary format could not be determined.
+\returns ::NC_EHDFERR HDF5 error (netCDF-4 files only).
+\returns ::NC_EFILEMETA Error writing netCDF-4 file-level metadata in
+HDF5 file. (netCDF-4 files only).
+
+\author Ed Hartnett, Dennis Heimbigner
+\ingroup datasets
+\internal
+*/
 int
 nc_create_par_fortran(const char *path, int cmode, int comm,
 		      int info, int *ncidp)
diff --git a/libdispatch/drc.c b/libdispatch/drc.c
index b953042..374ffcd 100644
--- a/libdispatch/drc.c
+++ b/libdispatch/drc.c
@@ -13,290 +13,298 @@ See LICENSE.txt for license information.
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "nc.h"
-#include "nclog.h"
+#include "netcdf.h"
 #include "ncbytes.h"
+#include "ncuri.h"
 #include "ncrc.h"
+#include "nclog.h"
+#include "ncwinpath.h"
+
+#define RCFILEENV "DAPRCFILE"
 
 #define RTAG ']'
 #define LTAG '['
 
 #define TRIMCHARS " \t\r\n"
 
-static char* ENVRCLIST[] = {"DAPRCFILE","NETCDFRCFILE",NULL};
-static char* RCFILELIST[] = {".netcdfrc",".daprc", ".dodsrc",NULL};
+#undef MEMCHECK
+#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
+
+/* Forward */
+static char* rcreadline(char** nextlinep);
+static void rctrim(char* text);
+static NClist* rcorder(NClist* rc);
+static int rccompile(const char* path);
+static struct NCTriple* rclocate(const char* key, const char* hostport);
+static int rcsearch(const char* prefix, const char* rcname, char** pathp);
+static void rcfreetriples(NClist* rc);
+#ifdef D4DEBUG
+static void storedump(char* msg, NClist* triples);
+#endif
 
-/*Forward*/
-static int rcreadline(FILE* f, NCbytes*);
-static void rctrim(NCbytes* text);
-static void storedump(char* msg, NCTripleStore*);
-static int rc_compile(const char* path);
-static const NCTriple* rc_locate(NCTripleStore* rc, char* key, char* tag);
-static int rc_search(const char* prefix, const char* rcfile, char** pathp);
-static int copycat(char* dst, size_t size, size_t n, ...);
+/* Define default rc files and aliases, also defines search order*/
+static char* rcfilenames[] = {".daprc",".dodsrc",NULL};
 
 /**************************************************/
+/* External Entry Points */
 
-static int ncrc_ignore = 0;
-static int ncrc_loaded = 0;
-static char* ncrc_home = NULL;
-static NCTripleStore ncrc_store;
 
-/**************************************************/
-
-/* read and compile the rc file, if any */
+/* locate, read and compile the rc file, if any */
 int
-ncrc_load(const char* filename)
+NC_rcload(void)
 {
-    int stat = NC_NOERR;
+    int ret = NC_NOERR;
     char* path = NULL;
 
-    if(ncrc_ignore) {
+    if(ncrc_globalstate.rcinfo.ignore) {
         nclog(NCLOGDBG,"No runtime configuration file specified; continuing");
-	goto done;
+	return (NC_NOERR);
     }
-    if(ncrc_loaded) return NC_NOERR;
+    if(ncrc_globalstate.rcinfo.loaded) return (NC_NOERR);
 
     /* locate the configuration files in the following order:
-       1. specified by argument
-       2. set by any ENVRCLIST env variable
-       3. '.'
-       4. $HOME
+       1. specified by NC_set_rcfile
+       2. set by DAPRCFILE env variable
+       3. ./<rcfile> (current directory)
+       4. $HOME/<rcfile>
     */
-    if(filename != NULL) /* always use this */
-	path = strdup(filename);
-    if(path == NULL) {
-	char** p;
-	for(p=ENVRCLIST;*p;p++) {
-	    const char* value = getenv(*p);
-            if(value != NULL && strlen(value) > 0) {
-		path = strdup(value);
-		break;
-	    }
-	}
-    }
-    if(path == NULL) {
+    if(ncrc_globalstate.rcinfo.rcfile != NULL) { /* always use this */
+	path = strdup(ncrc_globalstate.rcinfo.rcfile);
+    } else if(getenv(RCFILEENV) != NULL && strlen(getenv(RCFILEENV)) > 0) {
+        path = strdup(getenv(RCFILEENV));
+    } else {
 	char** rcname;
-	for(rcname=RCFILELIST;*rcname;rcname++) {
-	    stat = rc_search(".",*rcname,&path);
-    	    if(stat != NC_NOERR || path != NULL) break;
-	    stat = rc_search(ncrc_home,*rcname,&path);
-    	    if(stat != NC_NOERR || path != NULL) break;
+	int found = 0;
+	for(rcname=rcfilenames;!found && *rcname;rcname++) {
+	    ret = rcsearch(".",*rcname,&path);
+    	    if(ret == NC_NOERR && path == NULL)  /* try $HOME */
+	        ret = rcsearch(ncrc_globalstate.home,*rcname,&path);
+	    if(ret != NC_NOERR)
+		goto done;
+	    if(path != NULL)
+		found = 1;
 	}
-	if(stat != NC_NOERR) goto done;
     }
     if(path == NULL) {
         nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
-	goto done;
-    }
-    nclog(NCLOGDBG,"RC files: %s\n", path);
-    if(rc_compile(path) == 0) {
-	nclog(NCLOGERR, "Error parsing %s\n",path);
-	stat = NC_NOERR;
+    } else {
+#ifdef D4DEBUG
+        fprintf(stderr, "RC file: %s\n", path);
+#endif
+        if((ret=rccompile(path))) {
+	    nclog(NCLOGERR, "Error parsing %s\n",path);
+	    goto done;
+	}
     }
 done:
-    ncrc_loaded = 1; /* even if not exists */
-    if(path != NULL)
-	free(path);
-    return stat;
+    ncrc_globalstate.rcinfo.loaded = 1; /* even if not exists */
+    nullfree(path);
+    return (ret);
 }
 
-void
-ncrc_reset(NCTripleStore* store)
+/**
+ * Locate a triple by property key and host+port (may be null|"")
+ * If duplicate keys, first takes precedence.
+ */
+char*
+NC_rclookup(const char* key, const char* hostport)
 {
-    int i;
-    if(store->triples == NULL) return;
-    for(i=0;i<nclistlength(store->triples);i++) {
-	NCTriple* triple = (NCTriple*)nclistget(store->triples,i);
-	if(triple == NULL) continue;
-	if(triple->tag != NULL) free(triple->tag);
-	if(triple->key != NULL) free(triple->key);
-	if(triple->value != NULL) free(triple->value);
-	free(triple);
-    }
-    nclistfree(store->triples);
-    store->triples = NULL;
+    struct NCTriple* triple = rclocate(key,hostport);
+    return (triple == NULL ? NULL : triple->value);
 }
 
-char*
-ncrc_lookup(NCTripleStore* store, char* key, char* tag)
+/*!
+Set the absolute path to use for the rc file.
+WARNING: this MUST be called before any other
+call in order for this to take effect.
+
+\param[in] rcfile The path to use. If NULL, or "",
+                  then do not use any rcfile.
+
+\retval OC_NOERR if the request succeeded.
+\retval OC_ERCFILE if the file failed to load
+*/
+
+int
+NC_set_rcfile(const char* rcfile)
 {
-    const NCTriple* triple = rc_locate(store, key, tag);
-    if(triple != NULL && ncdebug > 2) {
-	fprintf(stderr,"lookup %s: [%s]%s = %s\n",tag,triple->tag,triple->key,triple->value);
+    int stat = NC_NOERR;
+    FILE* f = NULL;
+
+    if(rcfile != NULL && strlen(rcfile) == 0)
+	rcfile = NULL;
+    f = NCfopen(rcfile,"r");
+    if(f == NULL) {
+	stat = NC_ERCFILE;
+        goto done;
     }
-    return (triple == NULL ? NULL : triple->value);
+    fclose(f);
+    nullfree(ncrc_globalstate.rcinfo.rcfile);
+    ncrc_globalstate.rcinfo.rcfile = strdup(rcfile);
+    /* Clear ncrc_globalstate.rcinfo */
+    NC_rcclear(&ncrc_globalstate.rcinfo);    
+    /* (re) load the rcfile and esp the triplestore*/
+    stat = NC_rcload();
+done:
+    return stat;
 }
 
-static const NCTriple*
-rc_locate(NCTripleStore* rc, char* key, char* tag)
+void
+NC_rcclear(NCRCinfo* info)
 {
-    int i,found;
-
-    if(ncrc_ignore || !ncrc_loaded || rc->triples == NULL)
-	return NULL;
-    if(key == NULL || rc == NULL) return NULL;
+    if(info == NULL) return;
+    nullfree(info->rcfile);
+    rcfreetriples(info->triples);
+}
 
-    if(tag == NULL) tag = "";
-    /* Assume that the triple store has been properly sorted */
-    for(found=0,i=0;i<nclistlength(rc->triples);i++) {
-	NCTriple* triple = (NCTriple*)nclistget(rc->triples,i);
-        size_t taglen = strlen(triple->tag);
-        int t;
-        if(strcmp(key,triple->key) != 0) continue; /* keys do not match */
-        /* If the triple entry has no tag, then use it
-           (because we have checked all other cases)*/
-        if(taglen == 0) {found=1;break;}
-        /* do tag match */
-        t = strcmp(tag,triple->tag);
-        if(t ==  0) return triple;
+void
+rcfreetriples(NClist* rc)
+{
+    int i;
+    for(i=0;i<nclistlength(rc);i++) {
+	NCTriple* t = (NCTriple*)nclistget(rc,i);
+	nullfree(t->host);
+	nullfree(t->key);
+	nullfree(t->value);
+	free(t);
     }
-    return NULL;
+    nclistfree(rc);
 }
 
-static int
-rcreadline(FILE* f, NCbytes* buf)
+/**************************************************/
+/* RC processing functions */
+
+static char*
+rcreadline(char** nextlinep)
 {
-    int c;
-    ncbytesclear(buf);
-    for(;;) {
-        c = getc(f);
-        if(c < 0) break; /* eof */
-        if(c == '\n') break; /* eol */
-	ncbytesappend(buf,c);
+    char* line;
+    char* p;
+
+    line = (p = *nextlinep);
+    if(*p == '\0') return NULL; /*signal done*/
+    for(;*p;p++) {
+	if(*p == '\r' && p[1] == '\n') *p = '\0';
+	else if(*p == '\n') break;
     }
-    ncbytesnull(buf);
-    return 1;
+    *p++ = '\0'; /* null terminate line; overwrite newline */
+    *nextlinep = p;
+    return line;
 }
 
 /* Trim TRIMCHARS from both ends of text; */
 static void
-rctrim(NCbytes* buf)
+rctrim(char* text)
 {
-    if(nclistlength(buf) == 0) return;
-    for(;;) {
-	int c = ncbytesget(buf,0);
-        if(strchr(TRIMCHARS,c) == NULL) break; /* hit non-trim char */
-	ncbytesremove(buf,0);
+    char* p = text;
+    size_t len;
+    int i;
+
+    len = strlen(text);
+    /* locate first non-trimchar */
+    for(;*p;p++) {
+       if(strchr(TRIMCHARS,*p) == NULL) break; /* hit non-trim char */
     }
-    int pos = ncbyteslength(buf) - 1;
-    while(pos >= 0) {
-	int c = ncbytesget(buf,pos);
-        if(strchr(TRIMCHARS,c) == NULL) break; /* hit non-trim char */
-	ncbytesremove(buf,pos);
-	pos--;
+    memmove(text,p,strlen(p)+1);
+    len = strlen(text);
+    /* locate last non-trimchar */
+    if(len > 0) {
+        for(i=(len-1);i>=0;i--) {
+            if(strchr(TRIMCHARS,text[i]) == NULL) {
+                text[i+1] = '\0'; /* elide trailing trimchars */
+                break;
+            }
+        }
     }
 }
 
-/* insertion sort the triplestore based on tag */
-static void
-sorttriplestore(NCTripleStore* store)
+/* Order the triples: those with urls must be first,
+   but otherwise relative order does not matter.
+*/
+static NClist*
+rcorder(NClist* rc)
 {
-    int i, nsorted, len;
-    NCTriple** content = NULL;
-
-    if(store == NULL) return; /* nothing to sort */
-    len = nclistlength(store->triples);
-    if(len <= 1) return; /* nothing to sort */
-    if(ncdebug > 2)
-        storedump("initial:",store);
-    content = (NCTriple**)nclistdup(store->triples);
-    nclistclear(store->triples);
-    nsorted = 0;
-    while(nsorted < len) {
-        int largest;
-        /* locate first non killed entry */
-        for(largest=0;largest<len;largest++) {
-            if(content[largest]->key[0] != '\0') break;
-        }
-        for(i=0;i<len;i++) {
-            if(content[i]->key[0] != '\0') { /* avoid empty slots */
-                int lexorder = strcmp(content[i]->tag,content[largest]->tag);
-                int leni = strlen(content[i]->tag);
-                int lenlarge = strlen(content[largest]->tag);
-                /* this defines the ordering */
-                if(leni == 0 && lenlarge == 0)
-		    continue; /* if no tags, then leave in order */
-                if(leni != 0 && lenlarge == 0)
-		    largest = i;
-                else if(lexorder > 0)
-		    largest = i;
-            }
-        }
-        /* Move the largest entry */
-	nclistpush(store->triples,content[largest]);
-        content[largest]->key[0] = '\0'; /* kill entry */
-        nsorted++;
-        if(ncdebug > 2)
-	    storedump("pass:",store);
+    int i;
+    int len = nclistlength(rc);
+    NClist* newrc = nclistnew();
+    if(rc == NULL || len == 0) return newrc;
+    /* Two passes: 1) pull triples with host */
+    for(i=0;i<len;i++) {
+        NCTriple* ti = nclistget(rc,i);
+	if(ti->host == NULL) continue;
+	nclistpush(newrc,ti);
+    }
+    /* pass 2 pull triples without host*/
+    for(i=0;i<len;i++) {
+        NCTriple* ti = nclistget(rc,i);
+	if(ti->host != NULL) continue;
+	nclistpush(newrc,ti);
     }
-    free(content);
-    if(ncdebug > 1)
-        storedump("final .rc order:",store);
+#ifdef D4DEBUG
+    storedump("reorder:",newrc);
+#endif
+    return newrc;
 }
 
 /* Create a triple store from a file */
 static int
-rc_compile(const char* path)
+rccompile(const char* path)
 {
-    FILE *in_file = NULL;
-    int linecount = 0;
-    NCbytes* buf;
-    NCTripleStore* rc;
-
-    rc = &ncrc_store;
-    memset(rc,0,sizeof(NCTripleStore));
-    rc->triples = nclistnew();
-
-    in_file = fopen(path, "r"); /* Open the file to read it */
-    if (in_file == NULL) {
-        nclog(NCLOGERR, "Could not open configuration file: %s",path);
-        return NC_EPERM;
+    int ret = NC_NOERR;
+    NClist* rc = ncrc_globalstate.rcinfo.triples;
+    char* contents = NULL;
+    NCbytes* tmp = ncbytesnew();
+    NCURI* uri = NULL;
+    char* nextline = NULL;
+
+    if((ret=NC_readfile(path,tmp))) {
+        nclog(NCLOGERR, "Could not open configuration file: %s",path);	
+	goto done;    
     }
-
-    buf =  ncbytesnew();
+    contents = ncbytesextract(tmp);
+    if(contents == NULL) contents = strdup("");
+    rcfreetriples(rc); /* clear out any old data */
+    rc = nclistnew();
+    nextline = contents;
     for(;;) {
-        int c;
-	int pos;
 	char* line;
-	size_t len,count;
-	char* value;
-
-        if(!rcreadline(in_file,buf)) break;
-        linecount++;
-        rctrim(buf);  /* trim leading and trailing blanks */
-        len = ncbyteslength(buf);
-	line = ncbytescontents(buf);
-
-	if(len == 0) continue;
-        if(line[0] == '#') continue; /* check for comment */
-
-        /* setup */
-	NCTriple* triple = (NCTriple*)calloc(1,sizeof(NCTriple));
-	if(triple == NULL) {
-            nclog(NCLOGERR, "Out of memory reading rc file: %s",path);
-	    goto done;
-	}	
-        nclistpush(rc->triples,triple);
-	c = line[0];
-        if(c == LTAG) {
-	    int i;
-	    for(i=0;i<len;i++) {
-		if(line[i] != RTAG) break;
-	    }
-	    if(i == len) {/* RTAG is missing */
-		nclog(NCLOGERR, "Line has missing %c: %s",RTAG,line);
-	        goto done;
+	char* key;
+        char* value;
+	size_t llen;
+        NCTriple* triple;
+
+	line = rcreadline(&nextline);
+	if(line == NULL) break; /* done */
+        rctrim(line);  /* trim leading and trailing blanks */
+        if(line[0] == '#') continue; /* comment */
+	if((llen=strlen(line)) == 0) continue; /* empty line */
+	triple = (NCTriple*)calloc(1,sizeof(NCTriple));
+	if(triple == NULL) {ret = NC_ENOMEM; goto done;}
+        if(line[0] == LTAG) {
+            char* url = ++line;
+            char* rtag = strchr(line,RTAG);
+            if(rtag == NULL) {
+                nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
+                continue;
+            }
+            line = rtag + 1;
+            *rtag = '\0';
+            /* compile the url and pull out the host */
+	    if(uri) ncurifree(uri);
+	    if(ncuriparse(url,&uri) != NCU_OK) {
+                nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
+		continue;
 	    }
-	    count = (i - 1);
-	    if(count > 0) {
-		triple->tag = (char*)malloc(count+1);
-		if(triple->tag == NULL) {goto done;}
-		memcpy(triple->tag,&line[1],count);
+	    ncbytesclear(tmp);
+	    ncbytescat(tmp,uri->host);
+	    if(uri->port != NULL) {
+		ncbytesappend(tmp,':');
+	        ncbytescat(tmp,uri->port);	
 	    }
-	    memmove(line,&line[count]+1,count+2); /* remove [...] */
-	}
+	    ncbytesnull(tmp);
+	    triple->host = ncbytesextract(tmp);
+        }
         /* split off key and value */
+        key=line;
         value = strchr(line, '=');
         if(value == NULL)
             value = line + strlen(line);
@@ -304,121 +312,114 @@ rc_compile(const char* path)
             *value = '\0';
             value++;
         }
-	triple->key = strdup(line);
-	if(*value == '\0')
-	    triple->value = strdup("1");	    
-	else
-	    triple->value = strdup(value);
+	triple->key = strdup(key);
+        triple->value = strdup(value);
+        rctrim(triple->key);
+        rctrim(triple->value);
+#ifdef D4DEBUG
+	fprintf(stderr,"rc: host=%s key=%s value=%s\n",
+		triple->host,triple->key,triple->valu);
+#endif
+	nclistpush(rc,triple);
+	triple = NULL;
     }
+    rcorder(rc);
+
 done:
-    fclose(in_file);
-    sorttriplestore(rc);
-    return 1;
+    ncurifree(uri);
+    ncbytesfree(tmp);
+    return (ret);
 }
 
+/**
+ * (Internal) Locate a triple by property key and host+port (may be null or "").
+ * If duplicate keys, first takes precedence.
+ */
+static struct NCTriple*
+rclocate(const char* key, const char* hostport)
+{
+    int i, found, t;
+    size_t hplen;
+    NClist* rc = ncrc_globalstate.rcinfo.triples;
+    NCTriple* triple = NULL;
 
+    if(ncrc_globalstate.rcinfo.ignore)
+	return NULL;
 
-static void
-storedump(char* msg, NCTripleStore* rc)
-{
-    int i;
+    if(key == NULL || rc == NULL) return NULL;
+    if(hostport == NULL) hostport = "";
 
-    if(msg != NULL) fprintf(stderr,"%s\n",msg);
-    if(rc == NULL || nclistlength(rc->triples) == 0) {
-        fprintf(stderr,"<EMPTY>\n");
-        return;
-    }
-    for(i=0;i<nclistlength(rc->triples);i++) {
-	NCTriple* triple = (NCTriple*)nclistget(rc->triples,i);
-	if(triple->tag == NULL)
-	    fprintf(stderr,"[%s]",triple->tag);
-        fprintf(stderr,"%s=%s\n",triple->key,triple->value);
+    for(found=0,i=0;i<nclistlength(rc);i++) {
+	triple = (NCTriple*)nclistget(rc,i);
+        hplen = strlen(triple->host);
+        if(strcmp(key,triple->key) != 0) continue; /* keys do not match */
+        /* If the triple entry has no url, then use it
+           (because we have checked all other cases)*/
+        if(hplen == 0) {found=1;break;}
+        /* do hostport match */
+        t = strcmp(hostport,triple->host);
+        if(t ==  0) {found=1; break;}
     }
-    fflush(stderr);
+    return (found?triple:NULL);
 }
 
-static int
-rc_search(const char* prefix, const char* rcname, char** pathp)
+/**
+ * Locate rc file by searching in directory prefix.
+ * Prefix must end in '/'
+ */
+static
+int
+rcsearch(const char* prefix, const char* rcname, char** pathp)
 {
     char* path = NULL;
     FILE* f = NULL;
     int plen = strlen(prefix);
     int rclen = strlen(rcname);
-    int stat = NC_NOERR;
-
-    size_t pathlen = plen+rclen+1+1; /*+1 for '/' +1 for nul*/
-    path = (char*)malloc(pathlen);
-    if(path == NULL) {
-	stat = NC_ENOMEM;
-	goto done;
-    }
-    if(!copycat(path,pathlen,3,prefix,"/",rcname)) {
-        stat = NC_ENOMEM;
-	goto done;
-    }
+    int ret = NC_NOERR;
+
+    size_t pathlen = plen+rclen+1; /*+1 for '/' */
+    path = (char*)malloc(pathlen+1); /* +1 for nul*/
+    if(path == NULL) {ret = NC_ENOMEM;	goto done;}
+    strncpy(path,prefix,pathlen);
+    strncat(path,"/",pathlen);
+    strncat(path,rcname,pathlen);
     /* see if file is readable */
     f = fopen(path,"r");
     if(f != NULL)
         nclog(NCLOGDBG, "Found rc file=%s",path);
 done:
-    if(f == NULL || stat != NC_NOERR) {
-	if(path != NULL)
-	    free(path);
+    if(f == NULL || ret != NC_NOERR) {
+	nullfree(path);
 	path = NULL;
     }
     if(f != NULL)
-	fclose(f);
+      fclose(f);
     if(pathp != NULL)
-	*pathp = path;
-    return stat;
+      *pathp = path;
+    else {
+      nullfree(path);
+      path = NULL;
+    }
+    return (ret);
 }
 
-/*
-Instead of using snprintf to concatenate
-multiple strings into a given target,
-provide a direct concatenator.
-So, this function concats the n argument strings
-and overwrites the contents of dst.
-Care is taken to never overrun the available
-space (the size parameter).
-Note that size is assumed to include the null
-terminator and that in the event of overrun,
-the string will have a null at dst[size-1].
-Return 0 if overrun, 1 otherwise.
-*/
-static int
-copycat(char* dst, size_t size, size_t n, ...)
+#ifdef D4DEBUG
+static void
+storedump(char* msg, NClist* triples)
 {
-    va_list args;
-    size_t avail = size - 1;
-    int i; 
-    int status = 1; /* assume ok */
-    char* p = dst;
-
-    if(n == 0) {
-	if(size > 0)
-	    dst[0] = '\0';
-	return (size > 0 ? 1: 0);
+    int i;
+
+    if(msg != NULL) fprintf(stderr,"%s\n",msg);
+    if(triples == NULL || nclistlength(triples)==0) {
+        fprintf(stderr,"<EMPTY>\n");
+        return;
     }
-	
-    va_start(args,n);
-    for(i=0;i<n;i++) {
-	char* q = va_arg(args, char*);
-	for(;;) {
-	    int c = *q++;
-	    if(c == '\0') break;
-	    if(avail == 0) {status = 0; goto done;}
-	    *p++ = c;
-	    avail--;
-	}
+    for(i=0;i<nclistlength(triples);i++) {
+	NCTriple* t = (NCTriple*)nclistget(triples,i);
+        fprintf(stderr,"\t%s\t%s\t%s\n",
+                ((t->host == NULL || strlen(t->host)==0)?"--":t->host),t->key,t->value);
     }
-    /* make sure we null terminate;
-       note that since avail was size-1, there
-       will always be room
-    */
-    *p = '\0';    
-
-done:
-    va_end(args);
-    return status;    
+    fflush(stderr);
 }
+#endif
+
diff --git a/libdispatch/dstring.c b/libdispatch/dstring.c
index 3466e53..2a3cece 100644
--- a/libdispatch/dstring.c
+++ b/libdispatch/dstring.c
@@ -5,8 +5,8 @@
 /* $Id: string.c,v 1.76 2010/05/26 21:43:33 dmh Exp $ */
 
 #include "config.h"
-#include <stdio.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
@@ -14,7 +14,6 @@
 #include "rnd.h"
 #include "ncutf8.h"
 
-
 /* There are 3 levels of UTF8 checking: 1=> (exact)validating 2=>relaxed
    and 3=>very relaxed
 */
@@ -302,3 +301,58 @@ strdup(const char* s)
 #endif
 
 /**************************************************/
+/* strlcat */
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller at courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef HAVE_STRLCAT
+#ifndef _MSC_VER /* We will use strcat_s */
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char* dst, const char* src, size_t dsize)
+{
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
+
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
+			n--;
+		}
+		src++;
+	}
+	*dst = '\0';
+
+	return(dlen + (src - osrc));	/* count does not include NUL */
+}
+#endif /*!_MSC_VER*/
+#endif /*!HAVE_STRLCAT*/
diff --git a/libdispatch/dtype.c b/libdispatch/dtype.c
index a4eaa75..82fafb4 100644
--- a/libdispatch/dtype.c
+++ b/libdispatch/dtype.c
@@ -39,9 +39,14 @@ type). Read attributes of the new type with nc_get_att (see
 /** \{ */
 
 
-/** \internal
+/** 
 \ingroup user_types
-Learn if two types are equal
+Learn if two types are equal.
+
+\note User-defined types in netCDF-4/HDF5 files must be committed to
+the file before nc_inq_type_equal() will work on the type. For
+uncommitted user-defined types, nc_inq_type_equal() will return
+::NC_EHDFERR. Commit types to the file with a call to nc_enddef().
 
 \param ncid1 \ref ncid of first typeid.
 \param typeid1 First typeid.
@@ -54,7 +59,11 @@ the two types are equal, a zero if they are not equal.
 \returns ::NC_EBADID Bad \ref ncid.
 \returns ::NC_EBADTYPE Bad type id.
 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
-\returns ::NC_EHDFERR An error was reported by the HDF5 layer.
+\returns ::NC_EHDFERR An error was reported by the HDF5 layer. This
+will occur if either of the types have not been committed to the file
+(with an nc_enddef()).
+
+\author Dennis Heimbigner, Ward Fisher, Ed Hartnett
  */
 int
 nc_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
@@ -87,6 +96,7 @@ found.
 \returns ::NC_EBADTYPE Bad type id.
 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
+\author Ed Hartnett, Dennis Heimbigner
  */
 int
 nc_inq_typeid(int ncid, const char *name, nc_type *typeidp)
@@ -130,6 +140,7 @@ compound types. \ref ignored_if_null.
 \returns ::NC_EBADTYPE Bad type id.
 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
+\author Ed Hartnett, Dennis Heimbigner
  */
 int
 nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size,
diff --git a/libdispatch/dutil.c b/libdispatch/dutil.c
new file mode 100644
index 0000000..7ec8625
--- /dev/null
+++ b/libdispatch/dutil.c
@@ -0,0 +1,254 @@
+/*********************************************************************
+ *   Copyright 2016, UCAR/Unidata
+ *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ *********************************************************************/
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef _MSC_VER
+#include <io.h>
+#endif
+#include "netcdf.h"
+#include "ncuri.h"
+#include "ncbytes.h"
+#include "nclog.h"
+#include "ncwinpath.h"
+
+#define NC_MAX_PATH 4096
+
+#define LBRACKET '['
+#define RBRACKET ']'
+
+/**************************************************/
+/**
+ * Provide a hidden interface to allow utilities
+ * to check if a given path name is really an ncdap4 url.
+ * If no, return null, else return basename of the url
+ * minus any extension.
+ */
+
+int
+NC__testurl(const char* path, char** basenamep)
+{
+    NCURI* uri;
+    int ok = NC_NOERR;
+    if(ncuriparse(path,&uri) != NCU_OK)
+	ok = NC_EURL;
+    else {
+	char* slash = (uri->path == NULL ? NULL : strrchr(uri->path, '/'));
+	char* dot;
+	if(slash == NULL) slash = (char*)path; else slash++;
+        slash = nulldup(slash);
+        if(slash == NULL)
+            dot = NULL;
+        else
+            dot = strrchr(slash, '.');
+        if(dot != NULL &&  dot != slash) *dot = '\0';
+        if(basenamep)
+            *basenamep=slash;
+        else if(slash)
+            free(slash);
+    }
+    ncurifree(uri);
+    return ok;
+}
+
+/* Return 1 if this machine is little endian */
+int
+NC_isLittleEndian(void)
+{
+    union {
+        unsigned char bytes[SIZEOF_INT];
+	int i;
+    } u;
+    u.i = 1;
+    return (u.bytes[0] == 1 ? 1 : 0);
+}
+
+char*
+NC_backslashEscape(const char* s)
+{
+    const char* p;
+    char* q;
+    size_t len;
+    char* escaped = NULL;
+
+    len = strlen(s);
+    escaped = (char*)malloc(1+(2*len)); /* max is everychar is escaped */
+    if(escaped == NULL) return NULL;
+    for(p=s,q=escaped;*p;p++) {
+        char c = *p;
+        switch (c) {
+	case '\\':
+	case '/':
+	case '.':
+	case '@':
+	    *q++ = '\\'; *q++ = '\\';
+	    break;
+	default: *q++ = c; break;
+        }
+    }
+    *q = '\0';
+    return escaped;
+}
+
+char*
+NC_backslashUnescape(const char* esc)
+{
+    size_t len;
+    char* s;
+    const char* p;
+    char* q;
+
+    if(esc == NULL) return NULL;
+    len = strlen(esc);
+    s = (char*)malloc(len+1);
+    if(s == NULL) return NULL;
+    for(p=esc,q=s;*p;) {
+	switch (*p) {
+	case '\\':
+	     p++;
+	     /* fall thru */
+	default: *q++ = *p++; break;
+	}
+    }
+    *q = '\0';
+    return s;
+}
+
+char*
+NC_entityescape(const char* s)
+{
+    const char* p;
+    char* q;
+    size_t len;
+    char* escaped = NULL;
+    const char* entity;
+
+    len = strlen(s);
+    escaped = (char*)malloc(1+(6*len)); /* 6 = |'| */
+    if(escaped == NULL) return NULL;
+    for(p=s,q=escaped;*p;p++) {
+	char c = *p;
+	switch (c) {
+	case '&':  entity = "&"; break;
+	case '<':  entity = "<"; break;
+	case '>':  entity = ">"; break;
+	case '"':  entity = """; break;
+	case '\'': entity = "'"; break;
+	default	 : entity = NULL; break;
+	}
+	if(entity == NULL)
+	    *q++ = c;
+	else {
+	    len = strlen(entity);
+	    memcpy(q,entity,len);
+	    q+=len;
+	}
+    }
+    *q = '\0';
+    return escaped;
+}
+
+int
+NC_readfile(const char* filename, NCbytes* content)
+{
+    int ret = NC_NOERR;
+    FILE* stream = NULL;
+    char part[1024];
+
+#ifdef _MSC_VER
+    stream = NCfopen(filename,"r");
+#else
+    stream = NCfopen(filename,"rb");
+#endif
+    if(stream == NULL) {ret=errno; goto done;}
+    for(;;) {
+	size_t count = fread(part, 1, sizeof(part), stream);
+	if(count <= 0) break;
+	ncbytesappendn(content,part,count);
+	if(ferror(stream)) {ret = NC_EIO; goto done;}
+	if(feof(stream)) break;
+    }
+    ncbytesnull(content);
+done:
+    if(stream) fclose(stream);
+    return ret;
+}
+
+/**
+Wrap mktmp and return the generated path,
+or null if failed.
+Base is the base file path. XXXXX is appended
+to allow mktmp add its unique id.
+Return the generated path.
+*/
+
+char*
+NC_mktmp(const char* base)
+{
+    int fd;
+    char* cvtpath = NULL;
+    char tmp[NC_MAX_PATH];
+#ifdef HAVE_MKSTEMP
+    mode_t mask;
+#endif
+
+    /* Make sure that this path conversion has been applied */
+    cvtpath = NCpathcvt(base);
+    strncpy(tmp,cvtpath,sizeof(tmp));
+    nullfree(cvtpath);
+	strncat(tmp, "XXXXXX", sizeof(tmp) - strlen(tmp) - 1);
+
+#ifdef HAVE_MKSTEMP
+    /* Note Potential problem: old versions of this function
+       leave the file in mode 0666 instead of 0600 */
+    mask=umask(0077);
+    fd = mkstemp(tmp);
+    (void)umask(mask);
+#else /* !HAVE_MKSTEMP */
+    {
+#ifdef HAVE_MKTEMP
+#ifdef _MSC_VER
+        /* Use _mktemp_s */
+	_mktemp_s(tmp,sizeof(tmp)-1);
+#else /*!_MSC_VER*/
+        mktemp(tmp);
+	tmo[sizeof[tmp]-1] = '\0';
+#endif
+#else /* !HAVE_MKTEMP */
+	/* Need to simulate by using some kind of pseudo-random number */
+	{
+	    int rno = rand();
+	    char spid[7];
+	    if(rno < 0) rno = -rno;
+            snprintf(spid,sizeof(spid),"%06d",rno);
+            strncat(tmp,spid,sizeof(tmp));
+	}
+#endif /* HAVE_MKTEMP */
+#ifdef _MSC_VER
+        fd=NCopen3(tmp,O_RDWR|O_BINARY|O_CREAT, _S_IREAD|_S_IWRITE);
+#else
+        fd=NCopen3(tmp,O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
+#endif
+    }
+#endif /* !HAVE_MKSTEMP */
+    if(fd < 0) {
+       nclog(NCLOGERR, "Could not create temp file: %s",tmp);
+       return NULL;
+    } else
+	close(fd);
+    return strdup(tmp);
+}
+
diff --git a/libdispatch/dv2i.c b/libdispatch/dv2i.c
index 0110d35..5d41238 100644
--- a/libdispatch/dv2i.c
+++ b/libdispatch/dv2i.c
@@ -13,10 +13,28 @@ See \ref copyright file for copying and redistribution conditions.
 #include <stdarg.h>
 #include "netcdf.h"
 #include "math.h"
-/* The subroutines in error.c emit no messages unless NC_VERBOSE bit
+
+/** \defgroup v2_api The Version 2 API
+
+NetCDF's modern history began with the introduction of the V2 netCDF
+API by Glenn Davis and Russ Rew in 1991. (The V1 API is lost to mists
+of time.)
+
+The V2 API is still fully supported, but should not be used for new
+development.
+
+All of the V2 functions have been reimplemented in terms of the V3 API
+code; see the documentation for the related V3 functions to get more
+documentation.
+
+The V2 API is tested in test directory nctest.
+*/
+
+/** The subroutines in error.c emit no messages unless NC_VERBOSE bit
  * is on.  They call exit() when NC_FATAL bit is on. */
 int ncopts = (NC_FATAL | NC_VERBOSE) ;
-int ncerr = NC_NOERR ;
+
+int ncerr = NC_NOERR ; /**< V2 API error code. */
 
 #if SIZEOF_LONG == SIZEOF_SIZE_T
 /*
@@ -24,13 +42,15 @@ int ncerr = NC_NOERR ;
  * to 'size_t' or 'ptrdiff_t'. Use dummy macros.
  */
 
-# define NDIMS_DECL
+# define NDIMS_DECL  /**< NDIMS declaration */
+
+/** @internal Declaration. */
 # define A_DECL(name, type, ndims, rhs) \
 	const type *const name = ((const type *)(rhs))
 
-# define A_FREE(name)
+# define A_FREE(name)  /**< Free a variable. */
 
-# define A_INIT(lhs, type, ndims, rhs)
+# define A_INIT(lhs, type, ndims, rhs)  /**< Init a variable */
 	
 #else 
 /*
@@ -98,11 +118,19 @@ static void* nvmalloc(off_t size) {
 
 #endif
 
-typedef signed char schar;
+typedef signed char schar;  /**< Signed character type. */
 
-/*
+/**
  * Computes number of record variables in an open netCDF file, and an array of
  * the record variable ids, if the array parameter is non-null.
+ *
+ * @param ncid File ID.
+ * @param nrecvarsp Pointer that gets number of record variables.
+ * @param recvarids Pointer that gets array of record variable IDs.
+ *
+ * @return ::NC_NOERR No error.
+ * @return -1 on error.
+ * @author Russ Rew
  */
 static int
 numrecvars(int ncid, int* nrecvarsp, int *recvarids)
@@ -146,9 +174,15 @@ numrecvars(int ncid, int* nrecvarsp, int *recvarids)
 }
 
 
-/*
+/**
  * Computes record size (in bytes) of the record variable with a specified
  * variable id.  Returns size as 0 if not a record variable.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param recsizep Pointer that gets record size.
+ *
+ * @return size, or 0 if not a record variable
  */
 static int
 ncrecsize(int ncid, int varid, size_t *recsizep)
@@ -190,9 +224,17 @@ ncrecsize(int ncid, int varid, size_t *recsizep)
 }
 
 
-/*
+/**
  * Retrieves the dimension sizes of a variable with a specified variable id in
- * an open netCDF file.  Returns -1 on error.
+ * an open netCDF file.  
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param sizes Pointer that gets sizes.
+ *
+ * @return ::NC_NOERR No error.
+ * @return -1 on error.
+ * @author Russ Rew
  */
 static int
 dimsizes(int ncid, int varid, size_t *sizes)
@@ -220,12 +262,29 @@ dimsizes(int ncid, int varid, size_t *sizes)
     return NC_NOERR;
 }
 
-
-/*
- * Retrieves the number of record variables, the record variable ids, and the
- * record size of each record variable.  If any pointer to info to be returned
- * is null, the associated information is not returned.  Returns -1 on error.
- */
+/** \ingroup v2_api
+
+Retrieves the number of record variables, the record variable ids, and the
+record size of each record variable.  If any pointer to info to be returned
+is null, the associated information is not returned.  Returns -1 on error.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 functions nc_inq_nvars(),
+nc_inq_unlimdim(), nc_inq_dim().
+
+\param ncid file ID
+\param nrecvarsp pointer that will get the number of record variables
+in the file.
+\param recvarids pointer to array that will get the variable IDs of
+all variables that use the record dimension.
+\param recsizes pointer to array that will dimension size of the
+record dimension for each variable.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Invalid variable ID.
+\returns ::NC_EINVAL Invalid input
+*/
 int
 nc_inq_rec(
 	int ncid,
@@ -270,16 +329,28 @@ nc_inq_rec(
 		return status;
 	    recsizes[varid] = rsize;
 	}
-	return NC_NOERR;
+    return NC_NOERR;
 }
 
+/** \ingroup v2_api
 
-/*
- * Write one record's worth of data, except don't write to variables for which
- * the address of the data to be written is NULL.  Return -1 on error.  This is
- * the same as the ncrecput() in the library, except that can handle errors
- * better.
- */
+Write one record's worth of data, except don't write to variables for which
+the address of the data to be written is NULL.  Return -1 on error.  This is
+the same as the ncrecput() in the library, except that can handle errors
+better.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_put_vara().
+
+\param ncid file ID
+\param recnum the record number to write.
+\param datap pointer to one record's worth of data for all variables.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Invalid variable ID.
+\returns ::NC_EINVAL Invalid input
+*/
 int
 nc_put_rec(
 	int ncid,
@@ -320,12 +391,27 @@ nc_put_rec(
 }
 
 
-/*
- * Read one record's worth of data, except don't read from variables for which
- * the address of the data to be read is null.  Return -1 on error.  This is
- * the same as the ncrecget() in the library, except that can handle errors
- * better.
- */
+/** \ingroup v2_api
+
+Read one record's worth of data, except don't read from variables for which
+the address of the data to be read is null.  Return -1 on error.  This is
+the same as the ncrecget() in the library, except that can handle errors
+better.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_vara().
+
+\param ncid file ID
+\param recnum the record number to read.
+\param datap pointer memory to hold one record's worth of data for all
+variables.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Invalid variable ID.
+\returns ::NC_EINVAL Invalid input
+
+*/
 int
 nc_get_rec(
 	int ncid,
@@ -364,8 +450,18 @@ nc_get_rec(
     return 0;
 }
 
-/*
- */
+/** \ingroup v2_api
+
+Show an error message and exit (based on ncopts).
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_strerror()
+
+\param routine_name
+\param err error code
+\param fmt pointer to a char array containing string format
+
+*/
 void
 nc_advise(const char *routine_name, int err, const char *fmt,...)
 {
@@ -399,6 +495,18 @@ nc_advise(const char *routine_name, int err, const char *fmt,...)
 
 /* End error handling */
 
+/** \ingroup v2_api
+
+Create a netCDF file.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_create().
+
+\param path path and filename of the file to be created.
+\param cmode see nc_create() for full discussion of the create mode.
+
+\returns the ncid of the created file.
+*/
 int
 nccreate(const char* path, int cmode)
 {
@@ -412,7 +520,18 @@ nccreate(const char* path, int cmode)
 	return ncid;
 }
 
+/** \ingroup v2_api
+
+Open a netCDF file.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_open().
+
+\param path path and filename of the file to be created.
+\param mode see nc_open() for full discussion of the open mode.
 
+\returns the ncid of the created file.
+*/
 int
 ncopen(const char *path, int mode)
 {
@@ -426,7 +545,17 @@ ncopen(const char *path, int mode)
 	return ncid;
 }
 
+/** \ingroup v2_api
 
+Put file in define mode.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_redef().
+
+\param ncid file ID
+
+\returns 0 for success, -1 for failure.
+*/
 int
 ncredef(int ncid)
 {
@@ -439,7 +568,17 @@ ncredef(int ncid)
 	return 0;
 }
 
+/** \ingroup v2_api
+
+End define mode for file.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_enddef().
 
+\param ncid file ID
+
+\returns 0 for success, -1 for failure.
+*/
 int
 ncendef(int ncid)
 {
@@ -452,7 +591,17 @@ ncendef(int ncid)
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Close a file.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_close().
+
+\param ncid file ID
 
+\returns 0 for success, -1 for failure.
+*/
 int
 ncclose(int ncid)
 {
@@ -466,7 +615,22 @@ ncclose(int ncid)
 	return 0;
 }
 
+/** \ingroup v2_api
 
+Learn about a file.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq().
+
+\param ncid file ID
+\param ndims pointer that will get number of dimensions.
+\param nvars pointer that will get number of variables.
+\param natts pointer that will get number of global attributes.
+\param recdim pointer that will get dimension ID of record dimension,
+or -1 if there is no record dimension.
+
+\returns 0 for success, -1 for failure.
+*/
 int
 ncinquire(
     int		ncid,
@@ -498,7 +662,17 @@ ncinquire(
 	return ncid;
 }
 
+/** \ingroup v2_api
+
+Sync a file.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_sync().
 
+\param ncid file ID
+
+\returns 0 for success, -1 for failure.
+*/
 int
 ncsync(int ncid)
 {
@@ -512,7 +686,16 @@ ncsync(int ncid)
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Abort defining a file.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_abort().
+
+\param ncid file ID
+\returns 0 for success, -1 for failure.
+*/
 int
 ncabort(int ncid)
 {
@@ -525,7 +708,20 @@ ncabort(int ncid)
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Define a dimension.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_def_dim().
+
+\param ncid file ID
+\param name name of dimension.
+\param length length of the dimension, NC_UNLIMITED for a record
+dimension.
+
+\returns dimid or -1 for failure.
+*/
 int
 ncdimdef(
     int		ncid,
@@ -549,7 +745,18 @@ ncdimdef(
 	return dimid;
 }
 
+/** \ingroup v2_api
+
+Find dimension ID from name.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq_dimid().
+
+\param ncid file ID
+\param name name of dimension.
 
+\returns dimid or -1 for failure.
+*/
 int
 ncdimid(int ncid, const char*	name)
 {
@@ -563,7 +770,20 @@ ncdimid(int ncid, const char*	name)
 	return dimid;
 }
 
+/** \ingroup v2_api
 
+Learn about a dimension.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq_dim().
+
+\param ncid file ID
+\param dimid the dimension ID to learn about
+\param name pointer that will get name of dimension.
+\param length pointer that will get length of dimension.
+
+\returns dimid or -1 for failure.
+*/
 int
 ncdiminq(
     int		ncid,
@@ -588,7 +808,19 @@ ncdiminq(
 	return dimid;
 }
 
+/** \ingroup v2_api
+
+Rename a dimension.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_rename_dim().
+
+\param ncid file ID
+\param dimid the dimension ID.
+\param name the new name.
+
+\returns dimid or -1 for failure.
+*/
 int
 ncdimrename(
     int		ncid,
@@ -605,7 +837,21 @@ ncdimrename(
 	return dimid;
 }
 
+/** \ingroup v2_api
+
+Define a variable.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_def_var().
+
+\param ncid file ID
+\param name the name of the variable.
+\param datatype the data type of the variable.
+\param ndims the number of dimensions.
+\param dim array of dimension IDs.
 
+\returns varid or -1 for failure.
+*/
 int
 ncvardef(
     int		ncid,
@@ -625,7 +871,18 @@ ncvardef(
 	return varid;
 }
 
+/** \ingroup v2_api
 
+Learn a variable ID from the name.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq_varid().
+
+\param ncid file ID
+\param name the name of the variable.
+
+\returns varid or -1 for failure.
+*/
 int
 ncvarid(
     int		ncid,
@@ -642,7 +899,23 @@ ncvarid(
 	return varid;
 }
 
+/** \ingroup v2_api
+
+Learn about a variable.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq_var().
 
+\param ncid file ID
+\param varid the variable ID.
+\param name pointer to array of char that will get name of variable.
+\param datatype pointer that will get variable data type.
+\param ndims pointer that will get number of dimensions.
+\param dim pointer to array that will get dimension IDs.
+\param natts pointer that will get number of variable attributes.
+
+\returns varid or -1 for failure.
+*/
 int
 ncvarinq(
     int		ncid,
@@ -674,7 +947,20 @@ ncvarinq(
 	return varid;
 }
 
+/** \ingroup v2_api
+
+Write 1 data value.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_put_var1().
 
+\param ncid file ID
+\param varid the variable ID.
+\param index pointer to array of index values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvarput1(
     int		ncid,
@@ -698,7 +984,20 @@ ncvarput1(
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Read 1 data value.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_var1().
+
+\param ncid file ID
+\param varid the variable ID.
+\param index pointer to array of index values.
+\param value pointer that will get data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvarget1(
     int		ncid,
@@ -722,7 +1021,21 @@ ncvarget1(
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Write some data.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_put_vara().
 
+\param ncid file ID
+\param varid the variable ID.
+\param start pointer to array of start values.
+\param count pointer to array of count values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvarput(
     int		ncid,
@@ -750,7 +1063,21 @@ ncvarput(
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Read some data.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_vara().
 
+\param ncid file ID
+\param varid the variable ID.
+\param start pointer to array of start values.
+\param count pointer to array of count values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvarget(
     int		ncid,
@@ -778,7 +1105,22 @@ ncvarget(
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Write strided data.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_put_vars().
+
+\param ncid file ID
+\param varid the variable ID.
+\param start pointer to array of start values.
+\param count pointer to array of count values.
+\param stride pointer to array of stride values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvarputs(
     int		ncid,
@@ -816,7 +1158,22 @@ ncvarputs(
 	}
 }
 
+/** \ingroup v2_api
+
+Read strided data.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_vars().
 
+\param ncid file ID
+\param varid the variable ID.
+\param start pointer to array of start values.
+\param count pointer to array of count values.
+\param stride pointer to array of stride values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvargets(
     int		ncid,
@@ -853,7 +1210,23 @@ ncvargets(
 	}
 }
 
+/** \ingroup v2_api
+
+Write mapped data.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_varm().
 
+\param ncid file ID
+\param varid the variable ID.
+\param start pointer to array of start values.
+\param count pointer to array of count values.
+\param stride pointer to array of stride values.
+\param map pointer to array of map values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvarputg(
     int		ncid,
@@ -910,7 +1283,23 @@ ncvarputg(
 	}
 }
 
+/** \ingroup v2_api
+
+Read mapped data.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_varm().
+
+\param ncid file ID
+\param varid the variable ID.
+\param start pointer to array of start values.
+\param count pointer to array of count values.
+\param stride pointer to array of stride values.
+\param map pointer to array of map values.
+\param value pointer to data.
+
+\returns 0 for success or -1 for failure.
+*/
 int
 ncvargetg(
     int		ncid,
@@ -967,7 +1356,19 @@ ncvargetg(
 	}
 }
 
+/** \ingroup v2_api
+
+Rename a variable.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_rename_var().
 
+\param ncid file ID
+\param varid the variable ID.
+\param name the new name.
+
+\returns varid or -1 for failure.
+*/
 int
 ncvarrename(
     int		ncid,
@@ -984,7 +1385,22 @@ ncvarrename(
 	return varid;
 }
 
+/** \ingroup v2_api
+
+Write an attribute.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_put_att_int(), etc.
 
+\param ncid file ID
+\param varid the variable ID or NC_GLOBAL.
+\param name the name of the attribute.
+\param datatype the type of the attribute.
+\param len the length of the attribute.
+\param value the attribute value.
+
+\returns dimid or -1 for failure.
+*/
 int
 ncattput(
     int		ncid,
@@ -1004,7 +1420,22 @@ ncattput(
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Learn about an attribute.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq_att().
+
+\param ncid file ID
+\param varid the variable ID.
+\param name the name of the attribute.
+\param datatype pointer that will get data type.
+\param len pointer that will get length.
+
+\returns 1 for success or -1 for failure. (That's a delightful
+artifact of a by-gone era of C programming, isn't it?)
+*/
 int
 ncattinq(
     int		ncid,
@@ -1028,10 +1459,22 @@ ncattinq(
 		*len = (int) ll;
 
 	return 1;
-
 }
 
+/** \ingroup v2_api
+
+Read an attribute.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_att_int(), etc.
+
+\param ncid file ID.
+\param varid the variable ID or NC_GLOBAL.
+\param name the name of the attribute.
+\param value pointer that will get the attribute data.
+
+\returns 1 for success or -1 for failure.
+*/
 int
 ncattget(
     int		ncid,
@@ -1049,7 +1492,21 @@ ncattget(
 	return 1;
 }
 
+/** \ingroup v2_api
+
+Copy an attribute.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_att_int(), etc.
+
+\param ncid_in file ID to copy from.
+\param varid_in the variable ID or NC_GLOBAL to copy from.
+\param name the name of the attribute.
+\param ncid_out file ID to copy to.
+\param varid_out the variable ID or NC_GLOBAL to copy to.
 
+\returns 0 for success or -1 for failure.
+*/
 int
 ncattcopy(
     int		ncid_in,
@@ -1068,7 +1525,20 @@ ncattcopy(
 	return 0;
 }
 
+/** \ingroup v2_api
 
+Learn attribute name from its number.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_inq_attname().
+
+\param ncid file ID
+\param varid the variable ID.
+\param attnum the number of the attribute.
+\param name the name of the attribute.
+
+\returns attnum for success or -1 for failure.
+*/
 int
 ncattname(
     int		ncid,
@@ -1086,7 +1556,20 @@ ncattname(
 	return attnum;
 }
 
+/** \ingroup v2_api
+
+Rename an attribute.
 
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_rename_att().
+
+\param ncid file ID
+\param varid the variable ID.
+\param name the attribute name.
+\param newname the new name.
+
+\returns 1 for success or -1 for failure.
+*/
 int
 ncattrename(
     int		ncid,
@@ -1104,7 +1587,19 @@ ncattrename(
 	return 1;
 }
 
+/** \ingroup v2_api
+
+Delete an attribute.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_delete_att().
+
+\param ncid file ID
+\param varid the variable ID.
+\param name the attribute name.
 
+\returns 1 for success or -1 for failure.
+*/
 int
 ncattdel(
     int		ncid,
@@ -1125,6 +1620,18 @@ ncattdel(
 
 #ifndef NO_NETCDF_2
 
+/** \ingroup v2_api
+
+Set the fill mode.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_set_fill().
+
+\param ncid file ID
+\param fillmode NC_FILL or NC_NOFILL.
+
+\returns oldmode for success or -1 for failure.
+*/
 int
 ncsetfill(
     int		ncid,
@@ -1141,7 +1648,20 @@ ncsetfill(
 	return oldmode;
 }
 
+/** \ingroup v2_api
 
+Learn record variables and the lengths of the record dimension.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 functions nc_inq_var()/nc_inq_dim().
+
+\param ncid file ID
+\param nrecvars pointer that will get number of record variables.
+\param recvarids pointer that will get array of record variable IDs.
+\param recsizes pointer that will get array of record dimension length.
+
+\returns oldmode for success or -1 for failure.
+*/
 int
 ncrecinq(
     int		ncid,
@@ -1183,7 +1703,22 @@ ncrecinq(
 	return (int) nrv;
 }
 
+/** \ingroup v2_api
+
+Read one record's worth of data, except don't read from variables for which
+the address of the data to be read is null.  Return -1 on error. This is
+the same as the nc_get_rec(), with poorer error handling.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_get_vara().
 
+\param ncid file ID
+\param recnum the record number to read.
+\param datap pointer memory to hold one record's worth of data for all
+variables.
+
+\returns 0 for success, -1 for error.
+*/
 int
 ncrecget(
     int		ncid,
@@ -1200,7 +1735,21 @@ ncrecget(
 	return 0;
 }
 
+/** \ingroup v2_api
+
+Write one record's worth of data, except don't write to variables for which
+the address of the data to be written is NULL.  Return -1 on error.  This is
+the same as the nc_put_rec(), but with poorer error handling.
+
+This is part of the legacy V2 API of netCDF. New code should be
+written with the V3 API. See V3 function nc_put_vara().
+
+\param ncid file ID
+\param recnum the record number to write.
+\param datap pointer to one record's worth of data for all variables.
 
+\returns 0 for success, -1 for error.
+*/
 int
 ncrecput(
     int		ncid,
diff --git a/libdispatch/dvar.c b/libdispatch/dvar.c
index 2a4cda8..11bc559 100644
--- a/libdispatch/dvar.c
+++ b/libdispatch/dvar.c
@@ -8,7 +8,8 @@ Research/Unidata. See COPYRIGHT file for more info.
 #include "ncdispatch.h"
 #include "netcdf_f.h"
 
-/** \defgroup variables Variables
+/**
+\defgroup variables Variables
 
 Variables hold multi-dimensional arrays of data.
 
@@ -121,14 +122,15 @@ classic or 64-bit offset format files, or in netCDF-4 files if they
 are created with the NC_CLASSIC_MODEL flags.
  */
 
-/** \name Defining Variables
+/**
+ at name Defining Variables
 
 Use these functions to define variables.
  */
 /*! \{ */
 
 /**
-\ingroup variables
+ at ingroup variables
 Define a new variable.
 
 This function adds a new variable to an open netCDF dataset or group.
@@ -136,45 +138,45 @@ It returns (as an argument) a variable ID, given the netCDF ID,
 the variable name, the variable type, the number of dimensions, and a
 list of the dimension IDs.
 
-\param ncid NetCDF or group ID, from a previous call to nc_open(),
+ at 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 name Variable \ref object_name.
+ at param name Variable \ref object_name.
 
-\param xtype \ref data_type of the variable.
+ at param xtype \ref data_type of the variable.
 
-\param ndims Number of dimensions for the variable. For example, 2
+ at param ndims Number of dimensions for the variable. For example, 2
 specifies a matrix, 1 specifies a vector, and 0 means the variable is
 a scalar with no dimensions. Must not be negative or greater than the
 predefined constant ::NC_MAX_VAR_DIMS.
 
-\param dimidsp Vector of ndims dimension IDs corresponding to the
+ at param dimidsp Vector of ndims dimension IDs corresponding to the
 variable dimensions. For classic model netCDF files, if the ID of the
 unlimited dimension is included, it must be first. This argument is
 ignored if ndims is 0. For expanded model netCDF4/HDF5 files, there
 may be any number of unlimited dimensions, and they may be used in any
 element of the dimids array.
 
-\param varidp Pointer to location for the returned variable ID.
+ at param varidp Pointer to location for the returned variable ID.
 
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Bad ncid.
-\returns ::NC_ENOTINDEFINE Not in define mode.
-\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
-\returns ::NC_EMAXVARS NC_MAX_VARS exceeded
-\returns ::NC_EBADTYPE Bad type.
-\returns ::NC_EINVAL Invalid input.
-\returns ::NC_ENAMEINUSE Name already in use.
-\returns ::NC_EPERM Attempt to create object in read-only file.
+ at returns ::NC_NOERR No error.
+ at returns ::NC_EBADID Bad ncid.
+ at returns ::NC_ENOTINDEFINE Not in define mode.
+ at returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+ at returns ::NC_EMAXVARS NC_MAX_VARS exceeded [Not enforced after 4.5.0]
+ at returns ::NC_EBADTYPE Bad type.
+ at returns ::NC_EINVAL Invalid input.
+ at returns ::NC_ENAMEINUSE Name already in use.
+ at returns ::NC_EPERM Attempt to create object in read-only file.
 
-\section nc_def_var_example Example
+ at section nc_def_var_example Example
 
 Here is an example using nc_def_var to create a variable named rh of
 type double with three dimensions, time, lat, and lon in a new netCDF
 dataset named foo.nc:
 
-\code
+ at code
      #include <netcdf.h>
         ...
      int  status;
@@ -200,8 +202,8 @@ dataset named foo.nc:
      rh_dimids[2] = lon_dim;
      status = nc_def_var (ncid, "rh", NC_DOUBLE, 3, rh_dimids, &rh_id);
      if (status != NC_NOERR) handle_error(status);
-\endcode
-
+ at endcode
+ at author Glenn Davis, Ed Hartnett, Dennis Heimbigner
  */
 int
 nc_def_var(int ncid, const char *name, nc_type xtype,
@@ -218,14 +220,16 @@ nc_def_var(int ncid, const char *name, nc_type xtype,
 }
 /*! \} */
 
-/** \name Rename a Variable
+/**
+ at name Rename a Variable
 
 Rename a variable.
  */
 /*! \{ */
 
-/** Rename a variable.
-\ingroup variables
+/**
+Rename a variable.
+ at ingroup variables
 
 This function changes the name of a netCDF variable in an open netCDF
 file or group. You cannot rename a variable to have the name of any existing
@@ -235,28 +239,28 @@ For classic format, 64-bit offset format, and netCDF-4/HDF5 with
 classic mode, if the new name is longer than the old name, the netCDF
 dataset must be in define mode.
 
-\param ncid NetCDF or group ID, from a previous call to nc_open(),
+ at 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
+ at param varid Variable ID
 
-\param name New name of the variable.
+ at param name New name of the variable.
 
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Bad ncid.
-\returns ::NC_ENOTVAR Invalid variable ID.
-\returns ::NC_EBADNAME Bad name.
-\returns ::NC_EMAXNAME Name is too long.
-\returns ::NC_ENAMEINUSE Name in use.
-\returns ::NC_ENOMEM Out of memory.
+ at returns ::NC_NOERR No error.
+ at returns ::NC_EBADID Bad ncid.
+ at returns ::NC_ENOTVAR Invalid variable ID.
+ at returns ::NC_EBADNAME Bad name.
+ at returns ::NC_EMAXNAME Name is too long.
+ at returns ::NC_ENAMEINUSE Name in use.
+ at returns ::NC_ENOMEM Out of memory.
 
-\section nc_rename_var_example Example
+ at section nc_rename_var_example Example
 
 Here is an example using nc_rename_var to rename the variable rh to
 rel_hum in an existing netCDF dataset named foo.nc:
 
-\code
+ at code
      #include <netcdf.h>
         ...
      int  status;
@@ -274,7 +278,7 @@ rel_hum in an existing netCDF dataset named foo.nc:
      if (status != NC_NOERR) handle_error(status);
      status = nc_enddef(ncid);
      if (status != NC_NOERR) handle_error(status);
-\endcode
+ at endcode
 
 */
 int
@@ -288,8 +292,15 @@ nc_rename_var(int ncid, int varid, const char *name)
 }
 /*! \} */
 
-/** \internal
-\ingroup variables
+/**
+ at ingroup variables
+ at internal Does a variable have a record dimension?
+
+ at param ncid File ID.
+ at param varid Variable ID.
+ at param nrecs Pointer that gets number of records.
+
+ at returns 0 if not a record var, 1 if it is.
  */
 int
 NC_is_recvar(int ncid, int varid, size_t* nrecs)
@@ -311,21 +322,31 @@ NC_is_recvar(int ncid, int varid, size_t* nrecs)
    return (dimset[0] == unlimid ? 1: 0);
 }
 
-/** \internal
-\ingroup variables
-Get the number of record dimensions for a variable and an array that
-identifies which of a variable's dimensions are record dimensions.
-Intended to be used instead of NC_is_recvar, which doesn't work for
-netCDF-4 variables which have multiple unlimited dimensions or an
-unlimited dimension that is not the first of a variable's dimensions.
+/**
+ at ingroup variables
+ at internal Get the number of record dimensions for a variable and an
+array that identifies which of a variable's dimensions are record
+dimensions. Intended to be used instead of NC_is_recvar(), which
+doesn't work for netCDF-4 variables which have multiple unlimited
+dimensions or an unlimited dimension that is not the first of a
+variable's dimensions.
+
+ at param ncid File ID.
+ at param varid Variable ID.
+ at param nrecdimsp Pointer that gets number of record dims.
+ at param is_recdim Pointer that gets 1 if there is one or more record
+dimensions, 0 if not.
+
+ at returns 0 if not a record var, 1 if it is.
+
 Example use:
-\code
+ at code
 int nrecdims;
 int is_recdim[NC_MAX_VAR_DIMS];
   ...
 status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim);
 isrecvar = (nrecdims > 0);
-\endcode
+ at endcode
  */
 int
 NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim)
@@ -520,6 +541,12 @@ NC_getshape(int ncid, int varid, int ndims, size_t* shape)
 #ifdef USE_NETCDF4
 /** \ingroup variables
 
+Change the cache settings for a chunked variable. This function allows
+users to control the amount of memory used in the per-variable chunk
+cache at the HDF5 level. Changing the chunk cache only has effect
+until the file is closed. Once re-opened, the variable chunk cache
+returns to its default value.
+
 \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().
@@ -542,6 +569,34 @@ chunks.
 \returns ::NC_ENOTVAR Invalid variable ID.
 \returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
 \returns ::NC_EINVAL Invalid input
+
+\section nc_def_var_chunk_cache_example Example
+
+In this example from nc_test4/tst_coords.c, a variable is defined, and
+the chunk cache settings are changed for that variable.
+
+\code
+   printf("**** testing setting cache values for coordinate variables...");
+   {
+#define RANK_1 1
+#define DIM0_NAME "d0"
+#define CACHE_SIZE 1000000
+#define CACHE_NELEMS 1009
+#define CACHE_PREEMPTION .90
+
+      int ncid, dimid, varid;
+      char name_in[NC_MAX_NAME + 1];
+
+      if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid)) ERR;
+      if (nc_def_var(ncid, DIM0_NAME, NC_DOUBLE, 1, &dimid, &varid)) ERR;
+      if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
+      if (nc_close(ncid)) ERR;
+
+      ...
+   }
+   SUMMARIZE_ERR;
+\endcode
  */
 int
 nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
@@ -556,6 +611,8 @@ nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
 
 /** \ingroup variables
 
+Get the per-variable chunk cache settings from the HDF5 layer.
+
 \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().
@@ -578,7 +635,8 @@ chunks are always preempted before other chunks. \ref ignored_if_null.
 \returns ::NC_NOERR No error.
 \returns ::NC_EBADID Bad ncid.
 \returns ::NC_ENOTVAR Invalid variable ID.
-\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+netcdf-4 file.
 \returns ::NC_EINVAL Invalid input
 */
 int
@@ -614,6 +672,87 @@ nc_free_string(size_t len, char **data)
    return NC_NOERR;
 }
 
+/**
+ * @ingroup variables
+ *
+ * Set the compression settings for a netCDF-4/HDF5 variable.
+ *
+ * This function must be called after nc_def_var and before nc_enddef
+ * or any functions which writes data to the file.
+ *
+ * @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
+ * @param shuffle True to turn on the shuffle filter.
+ * @param deflate True to turn on deflation for this variable.
+ * @param deflate_level A number between 0 (no compression) and 9
+ * (maximum compression).
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ * netcdf-4 file.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EPERM File is read only.
+ * @returns ::NC_EMAXDIMS Classic model file exceeds ::NC_MAX_VAR_DIMS.
+ * @returns ::NC_ESTRICTNC3 Attempting to create netCDF-4 type var in
+classic model file
+ * @returns ::NC_EBADTYPE Bad type.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @returns ::NC_EHDFERR Error returned by HDF5 layer.
+ * @returns ::NC_EINVAL Invalid input. Deflate can't be set unless
+variable storage is NC_CHUNK.
+
+ at section nc_def_var_deflate_example Example
+
+Here is an example from /examples/C/simple_xy_nc4_wr.c using
+nc_def_var_deflate to create a variable and then turn on the shuffle
+filter and compression.
+
+ at code
+#include <netcdf.h>
+#define NDIMS 2
+#define NX 6
+#define NY 12
+
+   int ncid, x_dimid, y_dimid, varid;
+   int dimids[NDIMS];
+   int shuffle, deflate, deflate_level;
+   int data_out[NX][NY];
+   int x, y, retval;
+
+   shuffle = NC_SHUFFLE;
+   deflate = 1;
+   deflate_level = 1;
+   ...
+   if ((retval = nc_create(FILE_NAME, NC_NETCDF4, &ncid)))
+      ERR(retval);
+
+   if ((retval = nc_def_dim(ncid, "x", NX, &x_dimid)))
+      ERR(retval);
+   if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid)))
+      ERR(retval);
+
+   dimids[0] = x_dimid;
+   dimids[1] = y_dimid;
+
+   if ((retval = nc_def_var(ncid, "data", NC_INT, NDIMS,
+                            dimids, &varid)))
+      ERR(retval);
+
+   ...
+
+   if ((retval = nc_def_var_deflate(ncid, varid, shuffle, deflate,
+                                    deflate_level)))
+      ERR(retval);
+        ...
+ at endcode
+*/
 int
 nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_level)
 {
@@ -623,6 +762,31 @@ nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_le
     return ncp->dispatch->def_var_deflate(ncid,varid,shuffle,deflate,deflate_level);
 }
 
+/**
+ * @ingroup variables
+ *
+ * Set checksum for a var.
+ *
+ * This function must be called after nc_def_var and before nc_enddef
+ * or any functions which writes data to the file.
+ *
+ * @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
+ * @param fletcher32 True to turn on Fletcher32 checksums for this
+ * variable.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+not netCDF-4/HDF5.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+netcdf-4 file.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_EINVAL Invalid input
+*/
 int
 nc_def_var_fletcher32(int ncid, int varid, int fletcher32)
 {
@@ -636,32 +800,59 @@ nc_def_var_fletcher32(int ncid, int varid, int fletcher32)
 
 \ingroup variables
 
-The function nc_def_var_chunking sets the chunking parameters for a variable in a netCDF-4 file. It can set the chunk sizes to get chunked storage, or it can set the contiguous flag to get contiguous storage.
-
-The total size of a chunk must be less than 4 GiB. That is, the product of all chunksizes and the size of the data (or the size of nc_vlen_t for VLEN types) must be less than 4 GiB.
-
-This function may only be called after the variable is defined, but before nc_enddef is called. Once the chunking parameters are set for a variable, they cannot be changed.
-
-Note that this does not work for scalar variables. Only non-scalar variables can have chunking.
-
-
-
- at param[in] ncid NetCDF ID, from a previous call to nc_open or nc_create.
- at param[in] varid Variable ID.
- at param[in] storage If ::NC_CONTIGUOUS, then contiguous storage is used for this variable. Variables with one or more unlimited dimensions cannot use contiguous storage. If contiguous storage is turned on, the chunksizes parameter is ignored. If ::NC_CHUNKED, then chunked storage is used for this variable. Chunk sizes may be specified with the chunksizes parameter or default sizes will be used if that parameter is NULL.
- at param[in] chunksizesp A pointer to an array list of chunk sizes. The array must have one chunksize for each dimension of the variable. If ::NC_CONTIGUOUS storage is set, then the chunksizes parameter is ignored.
-
- at returns ::NC_NOERR No error.
- at returns ::NC_EBADID Bad ID.
- at returns ::NC_ENOTNC4 Not a netCDF-4 file.
- at returns ::NC_ELATEDEF This variable has already been the subject of a nc_enddef call.  In netCDF-4 files nc_enddef will be called automatically for any data read or write. Once nc_enddef has been called after the nc_def_var call for a variable, it is impossible to set the chunking for that variable.
- at returns ::NC_ENOTINDEFINE Not in define mode.  This is returned for netCDF classic or 64-bit offset files, or for netCDF-4 files, when they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
- at returns ::NC_EPERM Attempt to create object in read-only file.
- at returns ::NC_EBADCHUNK Retunrs if the chunk size specified for a variable is larger than the length of the dimensions associated with variable.
+The function nc_def_var_chunking sets the chunking parameters for a
+variable in a netCDF-4 file. It can set the chunk sizes to get chunked
+storage, or it can set the contiguous flag to get contiguous storage.
+
+The total size of a chunk must be less than 4 GiB. That is, the
+product of all chunksizes and the size of the data (or the size of
+nc_vlen_t for VLEN types) must be less than 4 GiB.
+
+This function may only be called after the variable is defined, but
+before nc_enddef is called. Once the chunking parameters are set for a
+variable, they cannot be changed.
+
+Note that this does not work for scalar variables. Only non-scalar
+variables can have chunking.
+
+\param[in] ncid NetCDF ID, from a previous call to nc_open or
+nc_create.
+
+\param[in] varid Variable ID.
+
+\param[in] storage If ::NC_CONTIGUOUS, then contiguous storage is used
+for this variable. Variables with one or more unlimited dimensions
+cannot use contiguous storage. If contiguous storage is turned on, the
+chunksizes parameter is ignored. If ::NC_CHUNKED, then chunked storage
+is used for this variable. Chunk sizes may be specified with the
+chunksizes parameter or default sizes will be used if that parameter
+is NULL.
+
+\param[in] chunksizesp A pointer to an array list of chunk sizes. The
+array must have one chunksize for each dimension of the variable. If
+::NC_CONTIGUOUS storage is set, then the chunksizes parameter is
+ignored.
+
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ID.
+ * @returns ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @returns ::NC_ELATEDEF This variable has already been the subject of a
+nc_enddef call.  In netCDF-4 files nc_enddef will be called
+automatically for any data read or write. Once nc_enddef has been
+called after the nc_def_var call for a variable, it is impossible to
+set the chunking for that variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.  This is returned for
+netCDF classic or 64-bit offset files, or for netCDF-4 files, when
+they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
+ * @returns ::NC_EPERM Attempt to create object in read-only file.
+ * @returns ::NC_EBADCHUNK Retunrs if the chunk size specified for a
+variable is larger than the length of the dimensions associated with
+variable.
 
 \section nc_def_var_chunking_example Example
 
-In this example from libsrc4/tst_vars2.c, chunksizes are set with nc_var_def_chunking, and checked with nc_var_inq_chunking.
+In this example from libsrc4/tst_vars2.c, chunksizes are set with
+nc_var_def_chunking, and checked with nc_var_inq_chunking.
 
 \code
         printf("**** testing chunking...");
@@ -696,7 +887,6 @@ In this example from libsrc4/tst_vars2.c, chunksizes are set with nc_var_def_chu
               if (chunksize[d] != chunksize_in[d]) ERR;
            if (storage_in != NC_CHUNKED) ERR;
 \endcode
-
 */
 int
 nc_def_var_chunking(int ncid, int varid, int storage,
@@ -709,6 +899,71 @@ nc_def_var_chunking(int ncid, int varid, int storage,
 					   chunksizesp);
 }
 
+/*! Set the fill value for a netCDF4/HDF5 variable.
+
+\ingroup variables
+
+\param ncid NetCDF ID, from a previous call to nc_open or
+nc_create.
+
+\param varid Variable ID.
+
+\param no_fill Set to NC_NOFILL to turn off fill mode for this
+variable. Set to NC_FILL (the default) to turn on fill mode for the
+variable.
+
+\param fill_value the fill value to be used for this variable. Must be
+the same type as the variable. This must point to enough free memory
+to hold one element of the data type of the variable. (For example, an
+NC_INT will require 4 bytes for it's fill value, which is also an
+NC_INT.)
+
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ID.
+ * @returns ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.  This is returned for
+netCDF classic or 64-bit offset files, or for netCDF-4 files, when
+they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
+ * @returns ::NC_EPERM Attempt to create object in read-only file.
+
+\section nc_def_var_fill_example Example
+
+In this example from libsrc4/tst_vars.c, a variable is defined, and
+the fill mode turned off. Then nc_inq_fill() is used to check that the
+setting is correct. Then some data are written to the variable. Since
+the data that are written do not cover the full extent of the
+variable, the missing values will just be random. If fill value mode
+was turned on, the missing values would get the fill value.
+
+\code
+#define DIM7_LEN 2
+#define DIM7_NAME "dim_7_from_Indiana"
+#define VAR7_NAME "var_7_from_Idaho"
+#define NDIMS 1
+      int dimids[NDIMS];
+      size_t index[NDIMS];
+      int varid;
+      int no_fill;
+      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;
+
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
+      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
+		     &varid)) ERR;
+      if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
+
+      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
+      if (!no_fill) ERR;
+
+      index[0] = 1;
+      if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;
+
+      index[0] = 0;
+      if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;
+
+      if (nc_close(ncid)) ERR;
+\endcode
+*/
 int
 nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
 {
@@ -718,6 +973,73 @@ nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
     return ncp->dispatch->def_var_fill(ncid,varid,no_fill,fill_value);
 }
 
+/**
+ at ingroup variables
+
+Define endianness of a variable.
+
+With this function the endianness (i.e. order of bits in integers) can
+be changed on a per-variable basis. By default, the endianness is the
+same as the default endianness of the platform. But with
+nc_def_var_endianness the endianness can be explicitly set for a
+variable.
+
+This function may only be called after the variable is defined, but
+before nc_enddef is called. 
+
+ at param[in] ncid NetCDF ID, from a previous call to nc_open or
+nc_create.
+
+ at param[in] varid Variable ID.
+
+ at param[in] endian NC_ENDIAN_NATIVE to select the native endianness of
+the platform (the default), NC_ENDIAN_LITTLE to use little-endian,
+NC_ENDIAN_BIG to use big-endian.
+
+ at returns ::NC_NOERR No error.
+ at returns ::NC_EBADID Bad ID.
+ at returns ::NC_ENOTNC4 Not a netCDF-4 file.
+ at returns ::NC_ELATEDEF This variable has already been the subject of a
+nc_enddef call. In netCDF-4 files nc_enddef will be called
+automatically for any data read or write. Once nc_enddef has been
+called after the nc_def_var call for a variable, it is impossible to
+set the chunking for that variable.
+ at returns ::NC_ENOTINDEFINE Not in define mode. This is returned for
+netCDF classic or 64-bit offset files, or for netCDF-4 files, when
+they wwere created with NC_STRICT_NC3 flag. See \ref nc_create.
+ at returns ::NC_EPERM Attempt to create object in read-only file.
+
+ at section nc_def_var_endian_example Example
+
+In this example from libsrc4/tst_vars2.c, a variable is created, and
+the endianness set to NC_ENDIAN_BIG.
+
+ at code
+#define NDIMS4 1
+#define DIM4_NAME "Joe"
+#define VAR_NAME4 "Ed"
+#define DIM4_LEN 10
+   {
+      int dimids[NDIMS4], dimids_in[NDIMS4];
+      int varid;
+      int ndims, nvars, natts, unlimdimid;
+      nc_type xtype_in;
+      char name_in[NC_MAX_NAME + 1];
+      int data[DIM4_LEN], data_in[DIM4_LEN];
+      int endian_in;
+      int i;
+
+      for (i = 0; i < DIM4_LEN; i++)
+         data[i] = i;
+
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR;
+      if (dimids[0] != 0) ERR;
+      if (nc_def_var(ncid, VAR_NAME4, NC_INT, NDIMS4, dimids, &varid)) ERR;
+      if (nc_def_var_endian(ncid, varid, NC_ENDIAN_BIG)) ERR;
+ at endcode
+ at author Ed Hartnett
+*/
 int
 nc_def_var_endian(int ncid, int varid, int endian)
 {
@@ -727,4 +1049,25 @@ nc_def_var_endian(int ncid, int varid, int endian)
     return ncp->dispatch->def_var_endian(ncid,varid,endian);
 }
 
+/**
+ * Define a new variable filter.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param id
+ * @param nparams Number of filter parameters.
+ * @param parms Filter parameters.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
+int
+nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms)
+{
+    NC* ncp;
+    int stat = NC_check_id(ncid,&ncp);
+    if(stat != NC_NOERR) return stat;
+    return ncp->dispatch->def_var_filter(ncid,varid,id,nparams,parms);
+}
+
 #endif /* USE_NETCDF4 */
diff --git a/libdispatch/dvarget.c b/libdispatch/dvarget.c
index 30291d7..e11cb61 100644
--- a/libdispatch/dvarget.c
+++ b/libdispatch/dvarget.c
@@ -25,13 +25,19 @@ struct GETodometer {
 };
 
 
-/** \internal
-
+/**
+ * @internal Initialize odometer.
+ *
+ * @param odom Pointer to odometer.
+ * @param rank
+ * @param start Start indicies.
+ * @param edges Counts.
+ * @param stride Strides.
+ *
  */
 static void
-odom_init(struct GETodometer* odom,
-	    int rank,
-	    const size_t* start, const size_t* edges, const ptrdiff_t* stride)
+odom_init(struct GETodometer* odom, int rank, const size_t* start,
+          const size_t* edges, const ptrdiff_t* stride)
 {
     int i;
     memset(odom,0,sizeof(struct GETodometer));
@@ -46,8 +52,12 @@ odom_init(struct GETodometer* odom,
     }
 }
 
-/** \internal
-
+/**
+ * @internal Return true if there is more.
+ *
+ * @param odom Pointer to odometer.
+ *
+ * @return True if there is more, 0 otherwise.
  */
 static int
 odom_more(struct GETodometer* odom)
@@ -55,8 +65,12 @@ odom_more(struct GETodometer* odom)
     return (odom->index[0] < odom->stop[0]);
 }
 
-/** \internal
-
+/**
+ * @internal Move odometer.
+ *
+ * @param odom Pointer to odometer.
+ *
+ * @return 0 or 1
  */
 static int
 odom_next(struct GETodometer* odom)
@@ -102,8 +116,31 @@ NC_get_vara(int ncid, int varid,
    return stat;
 }
 
-/** \ingroup variables
+/** 
+Get data for a variable.
+
+\param ncid NetCDF or group ID.
+
+\param varid Variable ID
+
+\param value Pointer where the data will be copied. Memory must be
+allocated by the user before this function is called.
+
+\param memtype the NC type of the data after it is read into
+memory. Data are converted from the variable's type to the memtype as
+they are read.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOTVAR Variable not found.
+\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
+\returns ::NC_EEDGE Start+count exceeds dimension bound.
+\returns ::NC_ERANGE One or more of the values are out of range.
+\returns ::NC_EINDEFINE Operation not allowed in define mode.
+\returns ::NC_EBADID Bad ncid.
+
+\ingroup variables
 \internal
+\author Dennis Heimbigner
  */
 static int
 NC_get_var(int ncid, int varid, void *value, nc_type memtype)
@@ -529,9 +566,38 @@ NCDEFAULT_get_varm(int ncid, int varid, const size_t *start,
    return status;
 }
 
-/** \ingroup variables
+/** 
+Called by externally visible nc_get_vars_xxx routines.
+
+\param ncid NetCDF or group ID.
+
+\param varid Variable ID
+
+\param start start indices.
+
+\param edges count indices.
+
+\param stride data strides.
+
+\param value Pointer where the data will be copied. Memory must be
+allocated by the user before this function is called.
+
+\param memtype the NC type of the data after it is read into
+memory. Data are converted from the variable's type to the memtype as
+they are read.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOTVAR Variable not found.
+\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
+\returns ::NC_EEDGE Start+count exceeds dimension bound.
+\returns ::NC_ERANGE One or more of the values are out of range.
+\returns ::NC_EINDEFINE Operation not allowed in define mode.
+\returns ::NC_EBADID Bad ncid.
+
+\ingroup variables
 \internal
-Called by externally visible nc_get_vars_xxx routines */
+\author Dennis Heimbigner
+*/
 static int
 NC_get_vars(int ncid, int varid, const size_t *start,
 	    const size_t *edges, const ptrdiff_t *stride, void *value,
@@ -547,9 +613,41 @@ NC_get_vars(int ncid, int varid, const size_t *start,
    return ncp->dispatch->get_vars(ncid,varid,start,edges,stride,value,memtype);
 }
 
-/** \ingroup variables
+/** 
+Called by externally visible nc_get_varm_xxx routines. Note that the
+varm routines are deprecated. Use the vars routines instead for new
+code.
+
+\param ncid NetCDF or group ID.
+
+\param varid Variable ID
+
+\param start start indices.
+
+\param edges count indices.
+
+\param stride data strides.
+
+\param map mapping of dimensions.
+
+\param value Pointer where the data will be copied. Memory must be
+allocated by the user before this function is called.
+
+\param memtype the NC type of the data after it is read into
+memory. Data are converted from the variable's type to the memtype as
+they are read.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOTVAR Variable not found.
+\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
+\returns ::NC_EEDGE Start+count exceeds dimension bound.
+\returns ::NC_ERANGE One or more of the values are out of range.
+\returns ::NC_EINDEFINE Operation not allowed in define mode.
+\returns ::NC_EBADID Bad ncid.
+
+\ingroup variables
 \internal
-Called by externally visible nc_get_varm_xxx routines
+\author Dennis Heimbigner
  */
 static int
 NC_get_varm(int ncid, int varid, const size_t *start,
diff --git a/libdispatch/dvarinq.c b/libdispatch/dvarinq.c
index 369ca7b..5d5e78f 100644
--- a/libdispatch/dvarinq.c
+++ b/libdispatch/dvarinq.c
@@ -6,6 +6,14 @@ Research/Unidata. See COPYRIGHT file for more info.
 */
 
 #include "ncdispatch.h"
+#ifdef USE_NETCDF4
+#include <hdf5.h>
+#endif
+
+#ifndef H5Z_FILTER_SZIP
+/** ID of HDF SZIP filter. */
+#define H5Z_FILTER_SZIP 4
+#endif
 
 /** \name Learning about Variables
 
@@ -122,7 +130,8 @@ nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep,
    TRACE(nc_inq_var);
    return ncp->dispatch->inq_var_all(ncid, varid, name, xtypep, ndimsp,
 				     dimidsp, nattsp, NULL, NULL, NULL,
-				     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+				     NULL, NULL, NULL, NULL, NULL, NULL,
+				     NULL,NULL,NULL);
 }
 
 /**
@@ -172,7 +181,8 @@ nc_inq_vartype(int ncid, int varid, nc_type *typep)
 		     NULL, NULL);
 }
 
-/** Learn how many dimensions are associated with a variable.
+/** 
+Learn how many dimensions are associated with a variable.
 \ingroup variables
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
@@ -194,7 +204,8 @@ nc_inq_varndims(int ncid, int varid, int *ndimsp)
    return nc_inq_var(ncid, varid, NULL, NULL, ndimsp, NULL, NULL);
 }
 
-/** Learn the dimension IDs associated with a variable.
+/** 
+Learn the dimension IDs associated with a variable.
 \ingroup variables
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
@@ -217,7 +228,8 @@ nc_inq_vardimid(int ncid, int varid, int *dimidsp)
 		     dimidsp, NULL);
 }
 
-/** Learn how many attributes are associated with a variable.
+/** 
+Learn how many attributes are associated with a variable.
 \ingroup variables
 
 \param ncid NetCDF or group ID, from a previous call to nc_open(),
@@ -243,7 +255,6 @@ nc_inq_varnatts(int ncid, int varid, int *nattsp)
 		     nattsp);
 }
 
-#ifdef USE_NETCDF4
 /** \ingroup variables
 Learn the storage and deflate settings for a variable.
 
@@ -294,63 +305,7 @@ nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep,
       NULL, /*nofillp*/
       NULL, /*fillvaluep*/
       NULL, /*endianp*/
-      NULL, /*optionsmaskp*/
-      NULL /*pixelsp*/
-      );
-}
-
-/** \ingroup variables
-Learn the szip settings of a variable.
-
-This function returns the szip settings for a variable. NetCDF does
-not allow variables to be created with szip (due to license problems
-with the szip library), but we do enable read-only access of HDF5
-files with szip compression.
-
-This is a wrapper for nc_inq_var_all().
-
-\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
-
-\param options_maskp The szip options mask will be copied to this
-pointer. \ref ignored_if_null.
-
-\param pixels_per_blockp The szip pixels per block will be copied
-here. \ref ignored_if_null.
-
-\returns ::NC_NOERR No error.
-\returns ::NC_EBADID Bad ncid.
-\returns ::NC_ENOTNC4 Not a netCDF-4 file.
-\returns ::NC_ENOTVAR Invalid variable ID.
-*/
-int
-nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
-{
-   NC* ncp;
-   int stat = NC_check_id(ncid,&ncp);
-   if(stat != NC_NOERR) return stat;
-   TRACE(nc_inq_var_szip);
-   return ncp->dispatch->inq_var_all(
-      ncid, varid,
-      NULL, /*name*/
-      NULL, /*xtypep*/
-      NULL, /*ndimsp*/
-      NULL, /*dimidsp*/
-      NULL, /*nattsp*/
-      NULL, /*shufflep*/
-      NULL, /*deflatep*/
-      NULL, /*deflatelevelp*/
-      NULL, /*fletcher32p*/
-      NULL, /*contiguousp*/
-      NULL, /*chunksizep*/
-      NULL, /*nofillp*/
-      NULL, /*fillvaluep*/
-      NULL, /*endianp*/
-      options_maskp, /*optionsmaskp*/
-      pixels_per_blockp /*pixelsp*/
+      NULL,NULL,NULL
       );
 }
 
@@ -397,8 +352,7 @@ nc_inq_var_fletcher32(int ncid, int varid, int *fletcher32p)
       NULL, /*nofillp*/
       NULL, /*fillvaluep*/
       NULL, /*endianp*/
-      NULL, /*optionsmaskp*/
-      NULL /*pixelsp*/
+      NULL, NULL, NULL
       );
 }
 
@@ -471,7 +425,8 @@ nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp)
    TRACE(nc_inq_var_chunking);
    return ncp->dispatch->inq_var_all(ncid, varid, NULL, NULL, NULL, NULL,
 				     NULL, NULL, NULL, NULL, NULL, storagep,
-				     chunksizesp, NULL, NULL, NULL, NULL, NULL);
+				     chunksizesp, NULL, NULL, NULL,
+                                     NULL, NULL, NULL);
 }
 
 /** \ingroup variables
@@ -520,8 +475,7 @@ nc_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_valuep)
       no_fill, /*nofillp*/
       fill_valuep, /*fillvaluep*/
       NULL, /*endianp*/
-      NULL, /*optionsmaskp*/
-      NULL /*pixelsp*/
+      NULL, NULL, NULL
       );
 }
 
@@ -569,12 +523,11 @@ nc_inq_var_endian(int ncid, int varid, int *endianp)
       NULL, /*nofillp*/
       NULL, /*fillvaluep*/
       endianp, /*endianp*/
-      NULL, /*optionsmaskp*/
-      NULL /*pixelsp*/
-      );
+      NULL, NULL, NULL);
 }
 
-/*! Return number and list of unlimited dimensions.
+/**
+Return number and list of unlimited dimensions.
 
 In netCDF-4 files, it's possible to have multiple unlimited
 dimensions. This function returns a list of the unlimited dimension
@@ -583,61 +536,267 @@ ids visible in a group.
 Dimensions are visible in a group if they have been defined in that
 group, or any ancestor group.
 
-\param ncid NetCDF group ID, from a previous call to nc_open, nc_create, nc_def_grp, etc.
-\param nunlimdimsp A pointer to an int which will get the number of visible unlimited dimensions. Ignored if NULL.
-\param unlimdimidsp A pointer to an already allocated array of int which will get the ids of all visible unlimited dimensions. Ignored if NULL. To allocate the correct length for this array, call nc_inq_unlimdims with a NULL for this parameter and use the nunlimdimsp parameter to get the number of visible unlimited dimensions.
+\param ncid NetCDF file and group ID, from a previous call to nc_open(),
+nc_create(), nc_def_grp(), etc.
+
+\param nunlimdimsp A pointer to an int which will get the number of
+visible unlimited dimensions. Ignored if NULL.
+
+\param unlimdimidsp A pointer to an already allocated array of int
+which will get the ids of all visible unlimited dimensions. Ignored if
+NULL. To allocate the correct length for this array, call
+nc_inq_unlimdims with a NULL for this parameter and use the
+nunlimdimsp parameter to get the number of visible unlimited
+dimensions.
+
+\section nc_inq_unlimdims_example Example
+
+Here is an example from nc_test4/tst_dims.c. In this example we create
+a file with two unlimited dimensions, and then call nc_inq_unlimdims()
+to check that there are 2 unlimited dimensions, and that they have
+dimids 0 and 1.
+
+\code
+     #include <netcdf.h>
+        ...
+#define ROMULUS "Romulus"
+#define REMUS "Remus"
+#define DIMS2 2
+   printf("*** Testing file with two unlimited dimensions...");
+   {
+      int ncid, dimid[DIMS2];
+      int unlimdimid_in[DIMS2];
+      int nunlimdims_in;
+
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_dim(ncid, REMUS, NC_UNLIMITED, &dimid[0])) ERR;
+      if (nc_def_dim(ncid, ROMULUS, NC_UNLIMITED, &dimid[1])) ERR;
+
+      ...
+      if (nc_inq_unlimdims(ncid, &nunlimdims_in, unlimdimid_in)) ERR;
+      if (nunlimdims_in != 2 || unlimdimid_in[0] != 0 || unlimdimid_in[1] != 1) ERR;
+\endcode
 
 This function will return one of the following values.
 
 \returns ::NC_NOERR No error.
 \returns ::NC_EBADID Bad group id.
-\returns ::NC_ENOTNC4 Attempting a netCDF-4 operation on a netCDF-3 file. NetCDF-4 operations can only be performed on files defined with a create mode which includes flag HDF5. (see nc_open).
-\returns ::NC_ESTRICTNC3 This file was created with the strict netcdf-3 flag, therefore netcdf-4 operations are not allowed. (see nc_open).
+\returns ::NC_ENOTNC4 Attempting a netCDF-4 operation on a netCDF-3
+file. NetCDF-4 operations can only be performed on files defined with
+a create mode which includes flag HDF5. (see nc_open).
+\returns ::NC_ESTRICTNC3 This file was created with the strict
+netcdf-3 flag, therefore netcdf-4 operations are not allowed. (see
+nc_open).
 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
-
+\author Ed Hartnett, Dennis Heimbigner
  */
 int
 nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp)
 {
+#ifndef USE_NETCDF4
+    return NC_ENOTNC4;
+#else
     NC* ncp;
     int stat = NC_check_id(ncid,&ncp);
     if(stat != NC_NOERR) return stat;
-   TRACE(nc_inq_unlimdims);
+    TRACE(nc_inq_unlimdims);
     return ncp->dispatch->inq_unlimdims(ncid, nunlimdimsp,
 					unlimdimidsp);
+#endif
 }
 
-#endif /* USE_NETCDF4 */
+/** 
+Find the filter (if any) associated with a variable.
 
-/*!
+This is a wrapper for nc_inq_var_all().
 
-Used in libdap2 and libdap4.
-
- at param[in] ncid               ncid for file.
- at param[in] varid              varid for variable in question.
- at param[out] name              Pointer to memory to contain the name of the variable.
- at param[out] xtypep            Pointer to memory to contain the type of the variable.
- at param[out] ndimsp            Pointer to memory to store the number of associated dimensions for the variable.
- at param[out] dimidsp           Pointer to memory to store the dimids associated with the variable.
- at param[out] nattsp            Pointer to memory to store the number of attributes associated with the variable.
- at param[out] shufflep          Pointer to memory to store shuffle information associated with the variable.
- at param[out] deflatep          Pointer to memory to store compression type associated with the variable.
- at param[out] deflate_levelp    Pointer to memory to store compression level associated with the variable.
- at param[out] fletcher32p       Pointer to memory to store compression information associated with the variable.
- at param[out] contiguousp       Pointer to memory to store contiguous-data information associated with the variable.
- at param[out] chunksizesp       Pointer to memory to store chunksize information associated with the variable.
- at param[out] no_fill           Pointer to memory to store whether or not there is a fill value associated with the variable.
- at param[out] fill_valuep       Pointer to memory to store the fill value (if one exists) for the variable.
- at param[out] endiannessp       Pointer to memory to store endianness value. One of ::NC_ENDIAN_BIG ::NC_ENDIAN_LITTLE ::NC_ENDIAN_NATIVE
- at param[out] options_maskp     Pointer to memory to store mask options information.
- at param[out] pixels_per_blockp Pointer to memory to store pixels-per-block information for chunked data.
+\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().
 
-\note Expose access to nc_inq_var_all().
+\param varid Variable ID
 
-\internal
+\param idp Storage which will get the filter id.
+
+\param nparamsp Storage which will get the number of parameters to the
+filter
+
+\param params Storage which will get associated parameters. Note
+the caller must allocate and free.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOTNC4 Not a netCDF-4 file.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Invalid variable ID.
+\returns ::NC_EFILTER No filter defined.
 \ingroup variables
+\author Dennis Heimbigner
+*/
+int
+nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparamsp, unsigned int* params)
+{
+   NC* ncp;
+   int stat = NC_check_id(ncid,&ncp);
+   if(stat != NC_NOERR) return stat;
+   TRACE(nc_inq_var_filter);
+   return ncp->dispatch->inq_var_all(
+      ncid, varid,
+      NULL, /*name*/
+      NULL, /*xtypep*/
+      NULL, /*ndimsp*/
+      NULL, /*dimidsp*/
+      NULL, /*nattsp*/
+      NULL, /*shufflep*/
+      NULL, /*deflatep*/
+      NULL, /*deflatelevelp*/
+      NULL, /*fletcher32p*/
+      NULL, /*contiguousp*/
+      NULL, /*chunksizep*/
+      NULL, /*nofillp*/
+      NULL, /*fillvaluep*/
+      NULL, /*endianp*/
+      idp, nparamsp, params);
+}
+
+/** \ingroup variables
+Learn the szip settings of a variable.
+Similar to nc_inq_var_deflate.
+
+This function returns the szip settings for a variable.
+With the introduction of general filter support,
+szip inquiry is converted to use the filter interface.
+
+This is a wrapper for nc_inq_var_filter().
+
+\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
+
+\param options_maskp The szip options mask will be copied to this
+pointer. \ref ignored_if_null.
+
+\param pixels_per_blockp The szip pixels per block will be copied
+here. \ref ignored_if_null.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTNC4 Not a netCDF-4 file.
+\returns ::NC_ENOTVAR Invalid variable ID.
+\returns ::NC_EFILTER Variable is not szip encoded
+*/
+int
+nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
+{
+   NC* ncp;
+   unsigned int id;
+   size_t nparams;
+   unsigned int params[2];
 
+   int stat = NC_check_id(ncid,&ncp);
+   if(stat != NC_NOERR) return stat;
+   TRACE(nc_inq_var_szip);
 
+   /* Verify id and nparams */
+   stat = ncp->dispatch->inq_var_all(
+      ncid, varid,
+      NULL, /*name*/
+      NULL, /*xtypep*/
+      NULL, /*ndimsp*/
+      NULL, /*dimidsp*/
+      NULL, /*nattsp*/
+      NULL, /*shufflep*/
+      NULL, /*deflatep*/
+      NULL, /*deflatelevelp*/
+      NULL, /*fletcher32p*/
+      NULL, /*contiguousp*/
+      NULL, /*chunksizep*/
+      NULL, /*nofillp*/
+      NULL, /*fillvaluep*/
+      NULL, /*endianp*/
+      &id,
+      &nparams,
+      NULL
+      );
+   if(stat != NC_NOERR) return stat;
+   if(id != H5Z_FILTER_SZIP || nparams != 2)
+	return NC_EFILTER; /* not szip or bad # params */
+   /* Get params */
+   stat = ncp->dispatch->inq_var_all(
+      ncid, varid,
+      NULL, /*name*/
+      NULL, /*xtypep*/
+      NULL, /*ndimsp*/
+      NULL, /*dimidsp*/
+      NULL, /*nattsp*/
+      NULL, /*shufflep*/
+      NULL, /*deflatep*/
+      NULL, /*deflatelevelp*/
+      NULL, /*fletcher32p*/
+      NULL, /*contiguousp*/
+      NULL, /*chunksizep*/
+      NULL, /*nofillp*/
+      NULL, /*fillvaluep*/
+      NULL, /*endianp*/
+      &id,
+      &nparams,
+      params
+      );
+   if(stat != NC_NOERR) return stat;
+   /* Param[0] should be options_mask, Param[1] should be pixels_per_block */
+   if(options_maskp) *options_maskp = (int)params[0];
+   if(pixels_per_blockp) *pixels_per_blockp = (int)params[1];
+   return NC_NOERR;
+}
+
+/*!
+Learn all about a variable.
+
+ at param[in] ncid ncid for file.
+ at param[in] varid varid for variable in question.
+ at param[out] name Pointer to memory to contain the name of the
+variable.
+ at param[out] xtypep Pointer to memory to contain the type of the
+variable.
+ at param[out] ndimsp Pointer to memory to store the number of associated
+dimensions for the variable.
+ at param[out] dimidsp Pointer to memory to store the dimids associated
+with the variable.
+ at param[out] nattsp Pointer to memory to store the number of attributes
+associated with the variable.
+ at param[out] shufflep Pointer to memory to store shuffle information
+associated with the variable.
+ at param[out] deflatep Pointer to memory to store compression type
+associated with the variable.
+ at param[out] deflate_levelp Pointer to memory to store compression
+level associated with the variable.
+ at param[out] fletcher32p Pointer to memory to store compression
+information associated with the variable.
+ at param[out] contiguousp Pointer to memory to store contiguous-data
+information associated with the variable.
+ at param[out] chunksizesp Pointer to memory to store chunksize
+information associated with the variable.
+ at param[out] no_fill Pointer to memory to store whether or not there is
+a fill value associated with the variable.
+ at param[out] fill_valuep Pointer to memory to store the fill value (if
+one exists) for the variable.
+ at param[out] endiannessp Pointer to memory to store endianness
+value. One of ::NC_ENDIAN_BIG ::NC_ENDIAN_LITTLE ::NC_ENDIAN_NATIVE
+ at param[out] idp Pointer to memory to store filter id.
+ at param[out] nparamsp Pointer to memory to store filter parameter count.
+ at param[out] params Pointer to vector of unsigned integers into which
+to store filter parameters.
+\note Expose access to nc_inq_var_all().
+
+\returns ::NC_NOERR No error.
+\returns ::NC_EBADID Bad ncid.
+\returns ::NC_ENOTVAR Bad varid.
+\returns ::NC_ENOMEM Out of memory.
+\returns ::NC_EINVAL Invalid input.
+\author Ed Hartnett, Dennis Heimbigner
+\internal
+\ingroup variables
 */
 int
 NC_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
@@ -645,7 +804,8 @@ NC_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp)
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               )
 {
    NC* ncp;
    int stat = NC_check_id(ncid,&ncp);
@@ -657,8 +817,7 @@ NC_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
       contiguousp, chunksizesp,
       no_fill, fill_valuep,
       endiannessp,
-      options_maskp,
-      pixels_per_blockp);
+      idp,nparamsp,params);
 }
 
 /*! \} */  /* End of named group ...*/
diff --git a/libdispatch/dvarput.c b/libdispatch/dvarput.c
index 7b29d09..c7e1fc8 100644
--- a/libdispatch/dvarput.c
+++ b/libdispatch/dvarput.c
@@ -18,10 +18,19 @@ struct PUTodometer {
     size_t         stop[NC_MAX_VAR_DIMS];
 };
 
+/**
+ * @internal Initialize odometer.
+ *
+ * @param odom Pointer to odometer.
+ * @param rank
+ * @param start Start indicies.
+ * @param edges Counts.
+ * @param stride Strides.
+ *
+ */
 static void
-odom_init(struct PUTodometer* odom,
-	    int rank,
-	    const size_t* start, const size_t* edges, const ptrdiff_t* stride)
+odom_init(struct PUTodometer* odom, int rank, const size_t* start,
+          const size_t* edges, const ptrdiff_t* stride)
 {
     int i;
     memset(odom,0,sizeof(struct PUTodometer));
@@ -36,12 +45,26 @@ odom_init(struct PUTodometer* odom,
     }
 }
 
+/**
+ * @internal Return true if there is more.
+ *
+ * @param odom Pointer to odometer.
+ *
+ * @return True if there is more, 0 otherwise.
+ */
 static int
 odom_more(struct PUTodometer* odom)
 {
     return (odom->index[0] < odom->stop[0]);
 }
 
+/**
+ * @internal Return true if there is more.
+ *
+ * @param odom Pointer to odometer.
+ *
+ * @return True if there is more, 0 otherwise.
+ */
 static int
 odom_next(struct PUTodometer* odom)
 {
diff --git a/libdispatch/dwinpath.c b/libdispatch/dwinpath.c
index f14a8b6..b3c25c4 100644
--- a/libdispatch/dwinpath.c
+++ b/libdispatch/dwinpath.c
@@ -161,9 +161,7 @@ int
 NCopen3(const char* path, int flags, int mode)
 {
     int fd = -1;
-    fflush(stderr);
     char* cvtname = NCpathcvt(path);
-    fflush(stderr);
     if(cvtname == NULL) return -1;
     fd = open(cvtname,flags,mode);
     free(cvtname);    
diff --git a/libdispatch/nc.c b/libdispatch/nc.c
index f19b99f..5d5d1a2 100644
--- a/libdispatch/nc.c
+++ b/libdispatch/nc.c
@@ -54,13 +54,14 @@ free_NC(NC *ncp)
 }
 
 int
-new_NC(NC_Dispatch* dispatcher, const char* path, int mode, NC** ncpp)
+new_NC(NC_Dispatch* dispatcher, const char* path, int mode, int model, NC** ncpp)
 {
     NC *ncp = (NC*)calloc(1,sizeof(NC));
     if(ncp == NULL) return NC_ENOMEM;
     ncp->dispatch = dispatcher;
     ncp->path = nulldup(path);
     ncp->mode = mode;
+    ncp->model = model;
     if(ncp->path == NULL) { /* fail */
         free_NC(ncp);
 	return NC_ENOMEM;
diff --git a/libdispatch/ncuri.c b/libdispatch/ncuri.c
index fe80097..1e7340a 100644
--- a/libdispatch/ncuri.c
+++ b/libdispatch/ncuri.c
@@ -304,7 +304,6 @@ ncuriparse(const char* uri0, NCURI** durip)
 	/* Check for leading user:pwd@ */
         char* newhost = strchr(tmp.host,'@');
         if(newhost != NULL) {
-	    size_t rem;
 	    if(newhost == tmp.host)
 		{THROW(NCU_EUSRPWD);} /* we have proto://@ */
 	    terminate(newhost); /* overwrite '@' */
@@ -781,7 +780,6 @@ ncuriencodeonly(char* s, char* allowable)
 	    *outptr++ = '+';
         } else {
             /* search allowable */
-            int c2;
 	    char* p = strchr(allowable,c);
 	    if(p != NULL) {
                 *outptr++ = (char)c;
@@ -913,7 +911,8 @@ collectprefixparams(char* text, char** nextp)
     for(;;) {
 	char* p; char* q;
 	/* by construction, here we are at an LBRACKET: compress it out */
-	for(p=sp,q=sp+1;(*p++=*q++););	
+	for(p=sp,q=sp+1;(*p++=*q++);)
+	    ;	
         /* locate the next RRACKET */
         ep = nclocate(sp,RBRACKETSTR);
 	if(ep == NULL) break;/* we are done */
diff --git a/libdispatch/test_pathcvt.c b/libdispatch/test_pathcvt.c
index e277e92..7b93074 100644
--- a/libdispatch/test_pathcvt.c
+++ b/libdispatch/test_pathcvt.c
@@ -39,7 +39,6 @@ main(int argc, char** argv)
     int failcount = 0;
 
     for(test=PATHTESTS;test->path;test++) {
-	int ret = 0;
 	char* cvt = NCpathcvt(test->path);
 	if(cvt == NULL) {
 	    fprintf(stderr,"TEST returned NULL: %s\n",test->path);
diff --git a/libdispatch/utf8proc.c b/libdispatch/utf8proc.c
index 1ecbb1d..c680678 100644
--- a/libdispatch/utf8proc.c
+++ b/libdispatch/utf8proc.c
@@ -289,9 +289,10 @@ static nc_utf8proc_bool nc_grapheme_break_simple(int lbc, int tbc) {
 static nc_utf8proc_bool nc_grapheme_break_extended(int lbc, int tbc, nc_utf8proc_int32_t *state)
 {
   int lbc_override = lbc;
+  nc_utf8proc_bool break_permitted;
   if (state && *state != UTF8PROC_BOUNDCLASS_START)
     lbc_override = *state;
-  nc_utf8proc_bool break_permitted = nc_grapheme_break_simple(lbc_override, tbc);
+  break_permitted = nc_grapheme_break_simple(lbc_override, tbc);
   if (state) {
     // Special support for GB 12/13 made possible by GB999. After two RI
     // class codepoints we want to force a break. Do this by resetting the
diff --git a/libdispatch/utf8proc.h b/libdispatch/utf8proc.h
index ceea425..2d29524 100644
--- a/libdispatch/utf8proc.h
+++ b/libdispatch/utf8proc.h
@@ -81,29 +81,29 @@
 
 #if defined(_MSC_VER) && _MSC_VER < 1800
 // MSVC prior to 2013 lacked stdbool.h and inttypes.h
-typedef signed char utf8proc_int8_t;
-typedef unsigned char utf8proc_uint8_t;
-typedef short utf8proc_int16_t;
-typedef unsigned short utf8proc_uint16_t;
-typedef int utf8proc_int32_t;
-typedef unsigned int utf8proc_uint32_t;
+typedef signed char nc_utf8proc_int8_t;
+typedef unsigned char nc_utf8proc_uint8_t;
+typedef short nc_utf8proc_int16_t;
+typedef unsigned short nc_utf8proc_uint16_t;
+typedef int nc_utf8proc_int32_t;
+typedef unsigned int nc_utf8proc_uint32_t;
 #  ifdef _WIN64
-typedef __int64 utf8proc_ssize_t;
-typedef unsigned __int64 utf8proc_size_t;
+typedef __int64 nc_utf8proc_ssize_t;
+typedef unsigned __int64 nc_utf8proc_size_t;
 #  else
-typedef int utf8proc_ssize_t;
-typedef unsigned int utf8proc_size_t;
+typedef int nc_utf8proc_ssize_t;
+typedef unsigned int nc_utf8proc_size_t;
 #  endif
 #  ifndef __cplusplus
 // emulate C99 bool
-typedef unsigned char utf8proc_bool;
+typedef unsigned char nc_utf8proc_bool;
 #    ifndef __bool_true_false_are_defined
 #      define false 0
 #      define true 1
 #      define __bool_true_false_are_defined 1
 #    endif
 #  else
-typedef bool utf8proc_bool;
+typedef bool nc_utf8proc_bool;
 #  endif
 #else
 #  include <stddef.h>
diff --git a/liblib/CMakeLists.txt b/liblib/CMakeLists.txt
index d4c0453..52c144c 100644
--- a/liblib/CMakeLists.txt
+++ b/liblib/CMakeLists.txt
@@ -33,6 +33,14 @@ IF(MOD_NETCDF_NAME)
   SET_TARGET_PROPERTIES(netcdf PROPERTIES RUNTIME_OUTPUT_NAME ${NETCDF_LIB_NAME})
 ENDIF()
 
+# Make sure that netcdf.dll path does not include the build configuration
+IF(MSVC)
+  SET_TARGET_PROPERTIES(netcdf PROPERTIES
+	RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+	RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}
+	RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR})
+ENDIF()
+
 #####
 # Add dependencies required for linking.
 #####
diff --git a/liblib/Makefile.am b/liblib/Makefile.am
index e895af6..98d8637 100644
--- a/liblib/Makefile.am
+++ b/liblib/Makefile.am
@@ -18,18 +18,12 @@ lib_LTLIBRARIES = libnetcdf.la
 # for information regarding incrementing `-version-info`.
 ##
 
-libnetcdf_la_LDFLAGS = -version-info 13:0:0
+libnetcdf_la_LDFLAGS = -version-info 14:0:1
 
 libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS}
 libnetcdf_la_LIBADD =
 CLEANFILES =
 
-# Turn on some extra stuff when building a DLL for windows.
-if BUILD_DLL
-libnetcdf_la_LDFLAGS += -no-undefined -Wl,--output-def,netcdfdll.def
-libnetcdf_la_CPPFLAGS += -DDLL_EXPORT
-endif # BUILD_DLL
-
 # The v2 API...
 if BUILD_V2
 libnetcdf_la_LIBADD += ${top_builddir}/libdispatch/libnetcdf2.la
diff --git a/liblib/Makefile.in b/liblib/Makefile.in
index c2a4318..5a795f0 100644
--- a/liblib/Makefile.in
+++ b/liblib/Makefile.in
@@ -106,36 +106,29 @@ host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
-# Turn on some extra stuff when building a DLL for windows.
- at BUILD_DLL_TRUE@am__append_3 = -no-undefined -Wl,--output-def,netcdfdll.def
- at BUILD_DLL_TRUE@am__append_4 = -DDLL_EXPORT
-
 # The v2 API...
- at BUILD_V2_TRUE@am__append_5 = ${top_builddir}/libdispatch/libnetcdf2.la
+ at BUILD_V2_TRUE@am__append_2 = ${top_builddir}/libdispatch/libnetcdf2.la
 
 # + pnetcdf
- at USE_PNETCDF_TRUE@am__append_6 = -I${top_srcdir}/libsrcp
- at USE_PNETCDF_TRUE@am__append_7 = ${top_builddir}/libsrcp/libnetcdfp.la
+ at USE_PNETCDF_TRUE@am__append_3 = -I${top_srcdir}/libsrcp
+ at USE_PNETCDF_TRUE@am__append_4 = ${top_builddir}/libsrcp/libnetcdfp.la
 
 # + dap
- at ENABLE_DAP_TRUE@am__append_8 = -I${top_srcdir}/libdap2 -I${top_srcdir}/oc
- at ENABLE_DAP_TRUE@am__append_9 = ${top_builddir}/libdap2/libdap2.la \
+ at ENABLE_DAP_TRUE@am__append_5 = -I${top_srcdir}/libdap2 -I${top_srcdir}/oc
+ at ENABLE_DAP_TRUE@am__append_6 = ${top_builddir}/libdap2/libdap2.la \
 @ENABLE_DAP_TRUE@	${top_builddir}/oc2/liboc.la
- at ENABLE_DAP4_TRUE@am__append_10 = -I${top_srcdir}/libdap4
- at ENABLE_DAP4_TRUE@am__append_11 = ${top_builddir}/libdap4/libdap4.la
+ at ENABLE_DAP4_TRUE@am__append_7 = -I${top_srcdir}/libdap4
+ at ENABLE_DAP4_TRUE@am__append_8 = ${top_builddir}/libdap4/libdap4.la
 
 # NetCDF-4 ...
- at USE_NETCDF4_TRUE@am__append_12 = -I${top_srcdir}/libsrc4
- at USE_NETCDF4_TRUE@am__append_13 = ${top_builddir}/libsrc4/libnetcdf4.la
+ at USE_NETCDF4_TRUE@am__append_9 = -I${top_srcdir}/libsrc4
+ at USE_NETCDF4_TRUE@am__append_10 = ${top_builddir}/libsrc4/libnetcdf4.la
 
 # Not ready for prime time yet
 # libnetcdf_la_LIBADD += ${top_builddir}/libdiskless/libdiskless.la
 
 # Force binary mode for file read/write
- at ISCYGWIN_TRUE@am__append_14 = -lbinmode
+ at ISCYGWIN_TRUE@am__append_11 = -lbinmode
 subdir = liblib
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -178,10 +171,10 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
-libnetcdf_la_DEPENDENCIES = $(am__append_5) \
+libnetcdf_la_DEPENDENCIES = $(am__append_2) \
 	${top_builddir}/libdispatch/libdispatch.la \
-	${top_builddir}/libsrc/libnetcdf3.la $(am__append_7) \
-	$(am__append_9) $(am__append_11) $(am__append_13)
+	${top_builddir}/libsrc/libnetcdf3.la $(am__append_4) \
+	$(am__append_6) $(am__append_8) $(am__append_10)
 am_libnetcdf_la_OBJECTS = libnetcdf_la-nc_initialize.lo
 libnetcdf_la_OBJECTS = $(am_libnetcdf_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
@@ -258,13 +251,11 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
-	$(am__append_6) $(am__append_8) $(am__append_10) \
-	$(am__append_12)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_3) \
+	$(am__append_5) $(am__append_7) $(am__append_9)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AM_LDFLAGS = $(am__append_14)
+AM_LDFLAGS = $(am__append_11)
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -287,12 +278,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -318,6 +311,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -332,6 +326,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -435,7 +430,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 
@@ -445,15 +440,15 @@ lib_LTLIBRARIES = libnetcdf.la
 # These linker flags specify libtool version info.
 # See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
 # for information regarding incrementing `-version-info`.
-libnetcdf_la_LDFLAGS = -version-info 13:0:0 $(am__append_3)
-libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_4)
+libnetcdf_la_LDFLAGS = -version-info 14:0:1
+libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS}
 
 # The output library will always include netcdf3 and dispatch
 # libraries
-libnetcdf_la_LIBADD = $(am__append_5) \
+libnetcdf_la_LIBADD = $(am__append_2) \
 	${top_builddir}/libdispatch/libdispatch.la \
-	${top_builddir}/libsrc/libnetcdf3.la $(am__append_7) \
-	$(am__append_9) $(am__append_11) $(am__append_13)
+	${top_builddir}/libsrc/libnetcdf3.la $(am__append_4) \
+	$(am__append_6) $(am__append_8) $(am__append_10)
 CLEANFILES = 
 
 # We need at least one source file
diff --git a/libnetcdf.settings.in b/libnetcdf.settings.in
index 6983922..804edde 100644
--- a/libnetcdf.settings.in
+++ b/libnetcdf.settings.in
@@ -35,3 +35,4 @@ Diskless Support:	@HAS_DISKLESS@
 MMap Support:		@HAS_MMAP@
 JNA Support:		@HAS_JNA@
 CDF5 Support:		@HAS_CDF5@
+ERANGE fill Support:	@ENABLE_ERANGE_FILL@
diff --git a/libsrc/Makefile.am b/libsrc/Makefile.am
index ce48785..bd0e841 100644
--- a/libsrc/Makefile.am
+++ b/libsrc/Makefile.am
@@ -8,11 +8,6 @@ include $(top_srcdir)/lib_flags.am
 
 libnetcdf3_la_CPPFLAGS = ${AM_CPPFLAGS}
 
-# Turn on a pre-processor flag when building a DLL for windows.
-if BUILD_DLL
-libnetcdf3_la_CPPFLAGS += -DDLL_EXPORT
-endif # BUILD_DLL
-
 # These files comprise the netCDF-3 classic library code.
 libnetcdf3_la_SOURCES = v1hpg.c \
 putget.c attr.c nc3dispatch.c nc3internal.c var.c dim.c ncx.c nc_hashmap.c \
@@ -42,12 +37,12 @@ noinst_LTLIBRARIES = libnetcdf3.la
 # These files are cleaned on developer workstations (and then rebuilt
 # with m4), but they are included in the distribution so that the user
 # does not have to have m4.
-MAINTAINERCLEANFILES = $(man_MANS) attrx.c ncx.c putgetx.c
+MAINTAINERCLEANFILES = $(man_MANS) attr.c ncx.c putget.c
 EXTRA_DIST = attr.m4 ncx.m4 putget.m4 $(man_MANS) CMakeLists.txt XGetopt.c
 
 # This tells make how to turn .m4 files into .c files.
 .m4.c:
-	m4 $(AM_M4FLAGS) $(M4FLAGS) -s $< > $(top_srcdir)/libsrc/$@
+	m4 $(AM_M4FLAGS) $(M4FLAGS) -s $< > $(top_srcdir)/libsrc/$(@F)
 
 # The C API man page.
 man_MANS = netcdf.3
diff --git a/libsrc/Makefile.in b/libsrc/Makefile.in
index 63a2b7a..6577bc7 100644
--- a/libsrc/Makefile.in
+++ b/libsrc/Makefile.in
@@ -103,23 +103,17 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
-# Turn on a pre-processor flag when building a DLL for windows.
- at BUILD_DLL_TRUE@am__append_3 = -DDLL_EXPORT
- at BUILD_DISKLESS_TRUE@am__append_4 = memio.c
- at BUILD_DISKLESS_TRUE@@BUILD_MMAP_TRUE at am__append_5 = mmapio.c
+ at BUILD_DISKLESS_TRUE@am__append_2 = memio.c
+ at BUILD_DISKLESS_TRUE@@BUILD_MMAP_TRUE at am__append_3 = mmapio.c
 
 # Does the user want to use ffio, a replacement for posixio for Cray
 # computers?
- at USE_FFIO_TRUE@am__append_6 = ffio.c
- at USE_FFIO_FALSE@@USE_STDIO_TRUE at am__append_7 = ncstdio.c
- at USE_FFIO_FALSE@@USE_STDIO_FALSE at am__append_8 = posixio.c
- at USE_NETCDF4_TRUE@am__append_9 = -DNETCDF4=TRUE
- at BUILD_DAP_TRUE@am__append_10 = -DDAP=TRUE
- at BUILD_PARALLEL_TRUE@am__append_11 = -DPARALLEL_IO=TRUE
+ at USE_FFIO_TRUE@am__append_4 = ffio.c
+ at USE_FFIO_FALSE@@USE_STDIO_TRUE at am__append_5 = ncstdio.c
+ at USE_FFIO_FALSE@@USE_STDIO_FALSE at am__append_6 = posixio.c
+ at USE_NETCDF4_TRUE@am__append_7 = -DNETCDF4=TRUE
+ at BUILD_DAP_TRUE@am__append_8 = -DDAP=TRUE
+ at BUILD_PARALLEL_TRUE@am__append_9 = -DPARALLEL_IO=TRUE
 subdir = libsrc
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -257,11 +251,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -284,12 +277,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -315,6 +310,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -329,6 +325,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -432,28 +429,27 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
-libnetcdf3_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_3)
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
+libnetcdf3_la_CPPFLAGS = ${AM_CPPFLAGS}
 
 # These files comprise the netCDF-3 classic library code.
 libnetcdf3_la_SOURCES = v1hpg.c putget.c attr.c nc3dispatch.c \
 	nc3internal.c var.c dim.c ncx.c nc_hashmap.c ncx.h lookup3.c \
-	pstdint.h ncio.c ncio.h $(am__append_4) $(am__append_5) \
-	$(am__append_6) $(am__append_7) $(am__append_8)
+	pstdint.h ncio.c ncio.h $(am__append_2) $(am__append_3) \
+	$(am__append_4) $(am__append_5) $(am__append_6)
 noinst_LTLIBRARIES = libnetcdf3.la
 
 # These files are cleaned on developer workstations (and then rebuilt
 # with m4), but they are included in the distribution so that the user
 # does not have to have m4.
-MAINTAINERCLEANFILES = $(man_MANS) attrx.c ncx.c putgetx.c
+MAINTAINERCLEANFILES = $(man_MANS) attr.c ncx.c putget.c
 EXTRA_DIST = attr.m4 ncx.m4 putget.m4 $(man_MANS) CMakeLists.txt XGetopt.c
 
 # The C API man page.
 man_MANS = netcdf.3
 
 # Decide what goes in the man page, based on user configure options.
-ARGS_MANPAGE = -DAPI=C $(am__append_9) $(am__append_10) \
-	$(am__append_11)
+ARGS_MANPAGE = -DAPI=C $(am__append_7) $(am__append_8) $(am__append_9)
 all: all-am
 
 .SUFFIXES:
@@ -926,7 +922,7 @@ uninstall-man: uninstall-man3
 
 # This tells make how to turn .m4 files into .c files.
 .m4.c:
-	m4 $(AM_M4FLAGS) $(M4FLAGS) -s $< > $(top_srcdir)/libsrc/$@
+	m4 $(AM_M4FLAGS) $(M4FLAGS) -s $< > $(top_srcdir)/libsrc/$(@F)
 
 # This rule generates the C manpage.
 netcdf.3: $(top_srcdir)/docs/netcdf.m4
diff --git a/libsrc/attr.c b/libsrc/attr.c
index 8375000..1d5ef3b 100644
--- a/libsrc/attr.c
+++ b/libsrc/attr.c
@@ -2170,8 +2170,6 @@ NC3_put_att(
         old = *attrpp;
     } else {
         if(!NC_indef(ncp)) return NC_ENOTINDEFINE;
-
-        if(ncap->nelems >= NC_MAX_ATTRS) return NC_EMAXATTS;
     }
 
     status = NC_check_name(name);
diff --git a/libsrc/attr.m4 b/libsrc/attr.m4
index bf4c6fb..c91a124 100644
--- a/libsrc/attr.m4
+++ b/libsrc/attr.m4
@@ -883,8 +883,6 @@ NC3_put_att(
         old = *attrpp;
     } else {
         if(!NC_indef(ncp)) return NC_ENOTINDEFINE;
-
-        if(ncap->nelems >= NC_MAX_ATTRS) return NC_EMAXATTS;
     }
 
     status = NC_check_name(name);
diff --git a/libsrc/dim.c b/libsrc/dim.c
index a809fc1..c11e112 100644
--- a/libsrc/dim.c
+++ b/libsrc/dim.c
@@ -132,7 +132,6 @@ NC_finddim(const NC_dimarray *ncap, const char *uname, NC_dim **dimpp)
 {
 
    int dimid;
-   NC_dim ** loc;
    char *name;
 
    assert(ncap != NULL);
@@ -143,7 +142,6 @@ NC_finddim(const NC_dimarray *ncap, const char *uname, NC_dim **dimpp)
    {
       int stat;
       dimid = 0;
-      loc = (NC_dim **) ncap->value;
 
       /* normalized version of uname */
       stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char **)&name);
@@ -363,9 +361,6 @@ NC3_def_dim(int ncid, const char *name, size_t size, int *dimidp)
 		}
 	}
 
-	if(ncp->dims.nelems >= NC_MAX_DIMS)
-		return NC_EMAXDIMS;
-
 	dimid = NC_finddim(&ncp->dims, name, &dimp);
 	if(dimid != -1)
 		return NC_ENAMEINUSE;
diff --git a/libsrc/nc3dispatch.c b/libsrc/nc3dispatch.c
index e66afe7..ec59367 100644
--- a/libsrc/nc3dispatch.c
+++ b/libsrc/nc3dispatch.c
@@ -35,7 +35,8 @@ static int NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp, 
                int *no_fill, void *fill_valuep, int *endiannessp, 
-	       int *options_maskp, int *pixels_per_blockp);
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+               );
 
 static int NC3_var_par_access(int,int,int);
 
@@ -74,6 +75,8 @@ static int NC3_def_var_fletcher32(int,int,int);
 static int NC3_def_var_chunking(int,int,int,const size_t*);
 static int NC3_def_var_fill(int,int,int,const void*);
 static int NC3_def_var_endian(int,int,int);
+static int NC3_def_var_filter(int, int, unsigned int, size_t, const unsigned int*);
+
 static int NC3_set_var_chunk_cache(int,int,size_t,size_t,float);
 static int NC3_get_var_chunk_cache(int,int,size_t*,size_t*,float*);
 #endif /*USE_NETCDF4*/
@@ -163,6 +166,7 @@ NC3_def_var_fletcher32,
 NC3_def_var_chunking,
 NC3_def_var_fill,
 NC3_def_var_endian,
+NC3_def_var_filter,
 NC3_set_var_chunk_cache,
 NC3_get_var_chunk_cache,
 
@@ -191,7 +195,8 @@ NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp, 
                int *no_fill, void *fill_valuep, int *endiannessp, 
-	       int *options_maskp, int *pixels_per_blockp)
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params
+	       )
 {
     int stat = NC3_inq_var(ncid,varid,name,xtypep,ndimsp,dimidsp,nattsp);
     if(stat) return stat;
@@ -201,7 +206,9 @@ NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
     if(contiguousp) *contiguousp = NC_CONTIGUOUS;
     if(no_fill) *no_fill = 1;
     if(endiannessp) return NC_ENOTNC4;
-    if(options_maskp) return NC_ENOTNC4;
+    if(idp) return NC_ENOTNC4;
+    if(nparamsp) return NC_ENOTNC4;
+    if(params) return NC_ENOTNC4;
     return NC_NOERR;
 }
 
@@ -511,5 +518,11 @@ NC3_def_var_endian(int ncid, int varid, int endianness)
     return NC_ENOTNC4;
 }
 
+static int
+NC3_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms)
+{
+    return NC_ENOTNC4;
+}
+
 #endif /*USE_NETCDF4*/
     
diff --git a/libsrc/nc3internal.c b/libsrc/nc3internal.c
index da58f35..bbb2a62 100644
--- a/libsrc/nc3internal.c
+++ b/libsrc/nc3internal.c
@@ -1570,93 +1570,114 @@ NC3_inq_base_pe(int ncid, int *pe)
 	/*
 	 * !_CRAYMPP, only pe 0 is valid
 	 */
-	*pe = 0;
+	if (pe) *pe = 0;
 #endif /* _CRAYMPP && LOCKNUMREC */
 	return NC_NOERR;
 }
 
+/**
+ * Return the file format.
+ *
+ * \param ncid the ID of the open file.
+
+ * \param formatp a pointer that gets the format. Ignored if NULL.
+ *
+ * \returns NC_NOERR No error.
+ * \returns NC_EBADID Bad ncid.
+ * \internal
+ * \author Ed Hartnett, Dennis Heimbigner
+ */
 int
 NC3_inq_format(int ncid, int *formatp)
 {
-	int status;
-	NC *nc;
-	NC3_INFO* nc3;
+   int status;
+   NC *nc;
+   NC3_INFO* nc3;
 
-	status = NC_check_id(ncid, &nc);
-	if(status != NC_NOERR)
-		return status;
-	nc3 = NC3_DATA(nc);
+   status = NC_check_id(ncid, &nc);
+   if(status != NC_NOERR)
+      return status;
+   nc3 = NC3_DATA(nc);
+
+   /* Why even call this function with no format pointer? */
+   if (!formatp)
+      return NC_NOERR;
 
-	/* only need to check for netCDF-3 variants, since this is never called for netCDF-4 files */
+   /* only need to check for netCDF-3 variants, since this is never called for netCDF-4 files */
 #ifdef USE_CDF5
-	if (fIsSet(nc3->flags, NC_64BIT_DATA))
-	    *formatp = NC_FORMAT_CDF5;
-	else
+   if (fIsSet(nc3->flags, NC_64BIT_DATA))
+      *formatp = NC_FORMAT_CDF5;
+   else
 #endif
       if (fIsSet(nc3->flags, NC_64BIT_OFFSET))
-	    *formatp = NC_FORMAT_64BIT_OFFSET;
-	else
-	    *formatp = NC_FORMAT_CLASSIC;
-	return NC_NOERR;
+         *formatp = NC_FORMAT_64BIT_OFFSET;
+      else
+         *formatp = NC_FORMAT_CLASSIC;
+   return NC_NOERR;
 }
 
+/**
+ * Return the extended format (i.e. the dispatch model), plus the mode
+ * associated with an open file.
+ *
+ * \param ncid the ID of the open file.
+ * \param formatp a pointer that gets the extended format. Note that
+ * this is not the same as the format provided by nc_inq_format(). The
+ * extended foramt indicates the dispatch layer model. Classic, 64-bit
+ * offset, and CDF5 files all have an extended format of
+ * ::NC_FORMATX_NC3. Ignored if NULL.
+ * \param modep a pointer that gets the open/create mode associated with
+ * this file. Ignored if NULL.
+ *
+ * \returns NC_NOERR No error.
+ * \returns NC_EBADID Bad ncid.
+ * \internal
+ * \author Dennis Heimbigner
+ */
 int
 NC3_inq_format_extended(int ncid, int *formatp, int *modep)
 {
-	int status;
-	NC *nc;
-
-	status = NC_check_id(ncid, &nc);
-	if(status != NC_NOERR)
-		return status;
-        if(formatp) *formatp = NC_FORMATX_NC3;
-	if(modep) *modep = nc->mode;
-	return NC_NOERR;
+   int status;
+   NC *nc;
+
+   status = NC_check_id(ncid, &nc);
+   if(status != NC_NOERR)
+      return status;
+   if(formatp) *formatp = NC_FORMATX_NC3;
+   if(modep) *modep = nc->mode;
+   return NC_NOERR;
 }
 
-/* The sizes of types may vary from platform to platform, but within
- * netCDF files, type sizes are fixed. */
-#define NC_BYTE_LEN 1
-#define NC_CHAR_LEN 1
-#define NC_SHORT_LEN 2
-#define NC_INT_LEN 4
-#define NC_FLOAT_LEN 4
-#define NC_DOUBLE_LEN 8
-#define NUM_ATOMIC_TYPES 6
-
-/* This netCDF-4 function proved so popular that a netCDF-classic
- * version is provided. You're welcome. */
+/**
+ * Determine name and size of netCDF type. This netCDF-4 function
+ * proved so popular that a netCDF-classic version is provided. You're
+ * welcome.
+ * 
+ * \param ncid The ID of an open file.
+ * \param typeid The ID of a netCDF type.
+ * \param name Pointer that will get the name of the type. Maximum
+ * size will be NC_MAX_NAME. Ignored if NULL.
+ * \param size Pointer that will get size of type in bytes. Ignored if
+ * null.
+ *
+ * \returns NC_NOERR No error.
+ * \returns NC_EBADID Bad ncid.
+ * \returns NC_EBADTYPE Bad typeid.
+ * \internal
+ * \author Ed Hartnett
+ */
 int
 NC3_inq_type(int ncid, nc_type typeid, char *name, size_t *size)
 {
-#if 0
-   int atomic_size[NUM_ATOMIC_TYPES] = {NC_BYTE_LEN, NC_CHAR_LEN, NC_SHORT_LEN,
-					NC_INT_LEN, NC_FLOAT_LEN, NC_DOUBLE_LEN};
-   char atomic_name[NUM_ATOMIC_TYPES][NC_MAX_NAME + 1] = {"byte", "char", "short",
-							  "int", "float", "double"};
-#endif
-
    NC *ncp;
    int stat = NC_check_id(ncid, &ncp);
    if (stat != NC_NOERR)
-	return stat;
-
-   /* Only netCDF classic model and CDF-5 need to be handled. */
-   /* After discussion, this seems like an artificial limitation.
-      See https://github.com/Unidata/netcdf-c/issues/240 for more
-      discussion. */
-   /*
-   if((ncp->mode & NC_CDF5) != 0) {
-	if (typeid < NC_BYTE || typeid > NC_STRING)
-            return NC_EBADTYPE;
-   } else if (typeid < NC_BYTE || typeid > NC_DOUBLE)
-      return NC_EBADTYPE;
-   */
+      return stat;
+
    if(typeid < NC_BYTE || typeid > NC_STRING)
-     return NC_EBADTYPE;
+      return NC_EBADTYPE;
 
-   /* Give the user the values they want. Subtract one because types
-    * are numbered starting at 1, not 0. */
+   /* Give the user the values they want. */
    if (name)
       strcpy(name, NC_atomictypename(typeid));
    if (size)
@@ -1666,36 +1687,6 @@ NC3_inq_type(int ncid, nc_type typeid, char *name, size_t *size)
 }
 
 /**************************************************/
-#if 0
-int
-NC3_set_content(int ncid, size_t size, void* memory)
-{
-    int status = NC_NOERR;
-    NC *nc;
-    NC3_INFO* nc3;
-
-    status = NC_check_id(ncid, &nc);
-    if(status != NC_NOERR)
-        return status;
-    nc3 = NC3_DATA(nc);
-
-#ifdef USE_DISKLESS
-    fClr(nc3->flags, NC_CREAT);
-    status = memio_set_content(nc3->nciop, size, memory);
-    if(status != NC_NOERR) goto done;
-    status = nc_get_NC(nc3);
-    if(status != NC_NOERR) goto done;
-#else
-    status = NC_EDISKLESS;
-#endif
-
-done:
-    return status;
-}
-#endif
-
-/**************************************************/
-
 int
 nc_delete_mp(const char * path, int basepe)
 {
@@ -1778,11 +1769,12 @@ NC3_inq_var_fill(const NC_var *varp, void *fill_value)
      */
     attrpp = NC_findattr(&varp->attrs, _FillValue);
     if ( attrpp != NULL ) {
+        const void *xp;
         /* User defined fill value */
         if ( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 )
             return NC_EBADTYPE;
 
-        const void *xp = (*attrpp)->xvalue;
+        xp = (*attrpp)->xvalue;
         /* value stored in xvalue is in external representation, may need byte-swap */
         switch(varp->type) {
             case NC_CHAR:   return ncx_getn_text               (&xp, 1,               (char*)fill_value);
diff --git a/libsrc/nc_hashmap.c b/libsrc/nc_hashmap.c
index 2e27596..3a343eb 100644
--- a/libsrc/nc_hashmap.c
+++ b/libsrc/nc_hashmap.c
@@ -373,3 +373,26 @@ void NC_hashmapDelete(NC_hashmap* hash)
     free(hash);
   }
 }
+
+void
+NC_hashmap_verify(NC_hashmap* hash, NC_dim** dims)
+{
+    unsigned long i;
+    if(hash->count == 0) {
+	fprintf(stderr,"<empty>\n");
+	goto done;
+    }
+    for(i=0;i<hash->size;i++) {
+	hEntry* e = &hash->table[i];
+	if(e->flags == ACTIVE) {
+           fprintf(stderr,"[%d] key=%lu data=%ld",(int)i,e->key,e->data-1);
+	    if(dims != NULL) {
+	        fprintf(stderr," name=%s",dims[e->data-1]->name->cp);
+	    }	
+	    fprintf(stderr,"\n");
+	}
+    }
+
+done:
+    fflush(stderr);
+}
diff --git a/libsrc/ncx.c b/libsrc/ncx.c
index 78208c4..21762cb 100644
--- a/libsrc/ncx.c
+++ b/libsrc/ncx.c
@@ -398,10 +398,15 @@ swap8b(void *dst, const void *src)
     op = (uint32_t*)((char*)dst+4);
     *op = SWAP4(*op);
 #else
+    uint64_t tmp = *(uint64_t*)src;
+    tmp = SWAP8(tmp);
+    memcpy(dst, &tmp, 8);
+
+    /* Codes below will cause "break strict-aliasing rules" in gcc
     uint64_t *op = (uint64_t*)dst;
-    /* copy over, make the below swap in-place */
     *op = *(uint64_t*)src;
     *op = SWAP8(*op);
+    */
 #endif
 
 #if 0
@@ -533,26 +538,26 @@ swapn8b(void *dst, const void *src, size_t nn)
 
 #endif /* LITTLE_ENDIAN */
 
-#line 622
+#line 627
 
-#line 626
+#line 631
 
-#line 638
+#line 643
 
-#line 653
+#line 658
 
 
 /*
  * Primitive numeric conversion functions.
  */
 
-#line 681
+#line 686
 
-#line 729
+#line 734
 
-#line 762
+#line 767
 
-#line 808
+#line 813
 
 /* x_schar */
 /* x_uchar */
@@ -606,531 +611,531 @@ put_ix_short(void *xp, const ix_short *ip)
 }
 
 static int
-#line 860
+#line 865
 ncx_get_short_schar(const void *xp, schar *ip)
-#line 860
+#line 865
 {
-#line 860
+#line 865
     int err=NC_NOERR;
-#line 860
+#line 865
     ix_short xx;
-#line 860
+#line 865
     get_ix_short(xp, &xx);
-#line 860
+#line 865
 
-#line 860
+#line 865
 #if IX_SHORT_MAX > SCHAR_MAX
-#line 860
+#line 865
     if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
-#line 860
+#line 865
 #ifdef ERANGE_FILL
-#line 860
+#line 865
         *ip = NC_FILL_BYTE;
-#line 860
+#line 865
         return NC_ERANGE;
-#line 860
+#line 865
 #else
-#line 860
+#line 865
         err = NC_ERANGE;
-#line 860
+#line 865
 #endif
-#line 860
+#line 865
     }
-#line 860
+#line 865
 #endif
-#line 860
+#line 865
 
-#line 860
+#line 865
 
-#line 860
+#line 865
     *ip = (schar) xx;
-#line 860
+#line 865
     return err;
-#line 860
+#line 865
 }
-#line 860
+#line 865
 
 static int
-#line 861
+#line 866
 ncx_get_short_short(const void *xp, short *ip)
-#line 861
+#line 866
 {
-#line 861
+#line 866
     int err=NC_NOERR;
-#line 861
+#line 866
 #if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
-#line 861
+#line 866
     get_ix_short(xp, (ix_short *)ip);
-#line 861
+#line 866
 #else
-#line 861
+#line 866
     ix_short xx;
-#line 861
+#line 866
     get_ix_short(xp, &xx);
-#line 861
+#line 866
 
-#line 861
+#line 866
 #if IX_SHORT_MAX > SHORT_MAX
-#line 861
+#line 866
     if (xx > SHORT_MAX || xx < SHORT_MIN) {
-#line 861
+#line 866
 #ifdef ERANGE_FILL
-#line 861
+#line 866
         *ip = NC_FILL_SHORT;
-#line 861
+#line 866
         return NC_ERANGE;
-#line 861
+#line 866
 #else
-#line 861
+#line 866
         err = NC_ERANGE;
-#line 861
+#line 866
 #endif
-#line 861
+#line 866
     }
-#line 861
+#line 866
 #endif
-#line 861
+#line 866
 
-#line 861
+#line 866
 
-#line 861
+#line 866
     *ip = (short) xx;
-#line 861
+#line 866
 #endif
-#line 861
+#line 866
     return err;
-#line 861
+#line 866
 }
-#line 861
+#line 866
 
 static int
-#line 862
+#line 867
 ncx_get_short_int(const void *xp, int *ip)
-#line 862
+#line 867
 {
-#line 862
+#line 867
     int err=NC_NOERR;
-#line 862
+#line 867
 #if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
-#line 862
+#line 867
     get_ix_short(xp, (ix_short *)ip);
-#line 862
+#line 867
 #else
-#line 862
+#line 867
     ix_short xx;
-#line 862
+#line 867
     get_ix_short(xp, &xx);
-#line 862
+#line 867
 
-#line 862
+#line 867
 #if IX_SHORT_MAX > INT_MAX
-#line 862
+#line 867
     if (xx > INT_MAX || xx < INT_MIN) {
-#line 862
+#line 867
 #ifdef ERANGE_FILL
-#line 862
+#line 867
         *ip = NC_FILL_INT;
-#line 862
+#line 867
         return NC_ERANGE;
-#line 862
+#line 867
 #else
-#line 862
+#line 867
         err = NC_ERANGE;
-#line 862
+#line 867
 #endif
-#line 862
+#line 867
     }
-#line 862
+#line 867
 #endif
-#line 862
+#line 867
 
-#line 862
+#line 867
 
-#line 862
+#line 867
     *ip = (int) xx;
-#line 862
+#line 867
 #endif
-#line 862
+#line 867
     return err;
-#line 862
+#line 867
 }
-#line 862
+#line 867
 
 static int
-#line 863
+#line 868
 ncx_get_short_long(const void *xp, long *ip)
-#line 863
+#line 868
 {
-#line 863
+#line 868
     int err=NC_NOERR;
-#line 863
+#line 868
 #if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
-#line 863
+#line 868
     get_ix_short(xp, (ix_short *)ip);
-#line 863
+#line 868
 #else
-#line 863
+#line 868
     ix_short xx;
-#line 863
+#line 868
     get_ix_short(xp, &xx);
-#line 863
+#line 868
 
-#line 863
+#line 868
 #if IX_SHORT_MAX > LONG_MAX
-#line 863
+#line 868
     if (xx > LONG_MAX || xx < LONG_MIN) {
-#line 863
+#line 868
 #ifdef ERANGE_FILL
-#line 863
+#line 868
         *ip = NC_FILL_INT;
-#line 863
+#line 868
         return NC_ERANGE;
-#line 863
+#line 868
 #else
-#line 863
+#line 868
         err = NC_ERANGE;
-#line 863
+#line 868
 #endif
-#line 863
+#line 868
     }
-#line 863
+#line 868
 #endif
-#line 863
+#line 868
 
-#line 863
+#line 868
 
-#line 863
+#line 868
     *ip = (long) xx;
-#line 863
+#line 868
 #endif
-#line 863
+#line 868
     return err;
-#line 863
+#line 868
 }
-#line 863
+#line 868
 
 static int
-#line 864
+#line 869
 ncx_get_short_longlong(const void *xp, longlong *ip)
-#line 864
+#line 869
 {
-#line 864
+#line 869
     int err=NC_NOERR;
-#line 864
+#line 869
 #if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
-#line 864
+#line 869
     get_ix_short(xp, (ix_short *)ip);
-#line 864
+#line 869
 #else
-#line 864
+#line 869
     ix_short xx;
-#line 864
+#line 869
     get_ix_short(xp, &xx);
-#line 864
+#line 869
 
-#line 864
+#line 869
 #if IX_SHORT_MAX > LONGLONG_MAX
-#line 864
+#line 869
     if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
-#line 864
+#line 869
 #ifdef ERANGE_FILL
-#line 864
+#line 869
         *ip = NC_FILL_INT64;
-#line 864
+#line 869
         return NC_ERANGE;
-#line 864
+#line 869
 #else
-#line 864
+#line 869
         err = NC_ERANGE;
-#line 864
+#line 869
 #endif
-#line 864
+#line 869
     }
-#line 864
+#line 869
 #endif
-#line 864
+#line 869
 
-#line 864
+#line 869
 
-#line 864
+#line 869
     *ip = (longlong) xx;
-#line 864
+#line 869
 #endif
-#line 864
+#line 869
     return err;
-#line 864
+#line 869
 }
-#line 864
+#line 869
 
 static int
-#line 865
+#line 870
 ncx_get_short_ushort(const void *xp, ushort *ip)
-#line 865
+#line 870
 {
-#line 865
+#line 870
     int err=NC_NOERR;
-#line 865
+#line 870
     ix_short xx;
-#line 865
+#line 870
     get_ix_short(xp, &xx);
-#line 865
+#line 870
 
-#line 865
+#line 870
 #if IX_SHORT_MAX > USHORT_MAX
-#line 865
+#line 870
     if (xx > USHORT_MAX) {
-#line 865
+#line 870
 #ifdef ERANGE_FILL
-#line 865
+#line 870
         *ip = NC_FILL_USHORT;
-#line 865
+#line 870
         return NC_ERANGE;
-#line 865
+#line 870
 #else
-#line 865
+#line 870
         err = NC_ERANGE;
-#line 865
+#line 870
 #endif
-#line 865
+#line 870
     }
-#line 865
+#line 870
 #endif
-#line 865
+#line 870
 
-#line 865
+#line 870
     if (xx < 0) {
-#line 865
+#line 870
 #ifdef ERANGE_FILL
-#line 865
+#line 870
         *ip = NC_FILL_USHORT;
-#line 865
+#line 870
         return NC_ERANGE;
-#line 865
+#line 870
 #else
-#line 865
+#line 870
         err = NC_ERANGE; /* because ip is unsigned */
-#line 865
+#line 870
 #endif
-#line 865
+#line 870
     }
-#line 865
+#line 870
     *ip = (ushort) xx;
-#line 865
+#line 870
     return err;
-#line 865
+#line 870
 }
-#line 865
+#line 870
 
 static int
-#line 866
+#line 871
 ncx_get_short_uchar(const void *xp, uchar *ip)
-#line 866
+#line 871
 {
-#line 866
+#line 871
     int err=NC_NOERR;
-#line 866
+#line 871
     ix_short xx;
-#line 866
+#line 871
     get_ix_short(xp, &xx);
-#line 866
+#line 871
 
-#line 866
+#line 871
 #if IX_SHORT_MAX > UCHAR_MAX
-#line 866
+#line 871
     if (xx > UCHAR_MAX) {
-#line 866
+#line 871
 #ifdef ERANGE_FILL
-#line 866
+#line 871
         *ip = NC_FILL_UBYTE;
-#line 866
+#line 871
         return NC_ERANGE;
-#line 866
+#line 871
 #else
-#line 866
+#line 871
         err = NC_ERANGE;
-#line 866
+#line 871
 #endif
-#line 866
+#line 871
     }
-#line 866
+#line 871
 #endif
-#line 866
+#line 871
 
-#line 866
+#line 871
     if (xx < 0) {
-#line 866
+#line 871
 #ifdef ERANGE_FILL
-#line 866
+#line 871
         *ip = NC_FILL_UBYTE;
-#line 866
+#line 871
         return NC_ERANGE;
-#line 866
+#line 871
 #else
-#line 866
+#line 871
         err = NC_ERANGE; /* because ip is unsigned */
-#line 866
+#line 871
 #endif
-#line 866
+#line 871
     }
-#line 866
+#line 871
     *ip = (uchar) xx;
-#line 866
+#line 871
     return err;
-#line 866
+#line 871
 }
-#line 866
+#line 871
 
 static int
-#line 867
+#line 872
 ncx_get_short_uint(const void *xp, uint *ip)
-#line 867
+#line 872
 {
-#line 867
+#line 872
     int err=NC_NOERR;
-#line 867
+#line 872
     ix_short xx;
-#line 867
+#line 872
     get_ix_short(xp, &xx);
-#line 867
+#line 872
 
-#line 867
+#line 872
 #if IX_SHORT_MAX > UINT_MAX
-#line 867
+#line 872
     if (xx > UINT_MAX) {
-#line 867
+#line 872
 #ifdef ERANGE_FILL
-#line 867
+#line 872
         *ip = NC_FILL_UINT;
-#line 867
+#line 872
         return NC_ERANGE;
-#line 867
+#line 872
 #else
-#line 867
+#line 872
         err = NC_ERANGE;
-#line 867
+#line 872
 #endif
-#line 867
+#line 872
     }
-#line 867
+#line 872
 #endif
-#line 867
+#line 872
 
-#line 867
+#line 872
     if (xx < 0) {
-#line 867
+#line 872
 #ifdef ERANGE_FILL
-#line 867
+#line 872
         *ip = NC_FILL_UINT;
-#line 867
+#line 872
         return NC_ERANGE;
-#line 867
+#line 872
 #else
-#line 867
+#line 872
         err = NC_ERANGE; /* because ip is unsigned */
-#line 867
+#line 872
 #endif
-#line 867
+#line 872
     }
-#line 867
+#line 872
     *ip = (uint) xx;
-#line 867
+#line 872
     return err;
-#line 867
+#line 872
 }
-#line 867
+#line 872
 
 static int
-#line 868
+#line 873
 ncx_get_short_ulonglong(const void *xp, ulonglong *ip)
-#line 868
+#line 873
 {
-#line 868
+#line 873
     int err=NC_NOERR;
-#line 868
+#line 873
     ix_short xx;
-#line 868
+#line 873
     get_ix_short(xp, &xx);
-#line 868
+#line 873
 
-#line 868
+#line 873
 #if IX_SHORT_MAX > ULONGLONG_MAX
-#line 868
+#line 873
     if (xx > ULONGLONG_MAX) {
-#line 868
+#line 873
 #ifdef ERANGE_FILL
-#line 868
+#line 873
         *ip = NC_FILL_UINT64;
-#line 868
+#line 873
         return NC_ERANGE;
-#line 868
+#line 873
 #else
-#line 868
+#line 873
         err = NC_ERANGE;
-#line 868
+#line 873
 #endif
-#line 868
+#line 873
     }
-#line 868
+#line 873
 #endif
-#line 868
+#line 873
 
-#line 868
+#line 873
     if (xx < 0) {
-#line 868
+#line 873
 #ifdef ERANGE_FILL
-#line 868
+#line 873
         *ip = NC_FILL_UINT64;
-#line 868
+#line 873
         return NC_ERANGE;
-#line 868
+#line 873
 #else
-#line 868
+#line 873
         err = NC_ERANGE; /* because ip is unsigned */
-#line 868
+#line 873
 #endif
-#line 868
+#line 873
     }
-#line 868
+#line 873
     *ip = (ulonglong) xx;
-#line 868
+#line 873
     return err;
-#line 868
+#line 873
 }
-#line 868
+#line 873
 
 static int
-#line 869
+#line 874
 ncx_get_short_float(const void *xp, float *ip)
-#line 869
+#line 874
 {
-#line 869
+#line 874
 	ix_short xx;
-#line 869
+#line 874
 	get_ix_short(xp, &xx);
-#line 869
+#line 874
 	*ip = (float)xx;
-#line 869
+#line 874
 	return NC_NOERR;
-#line 869
+#line 874
 }
-#line 869
+#line 874
 
 static int
-#line 870
+#line 875
 ncx_get_short_double(const void *xp, double *ip)
-#line 870
+#line 875
 {
-#line 870
+#line 875
 	ix_short xx;
-#line 870
+#line 875
 	get_ix_short(xp, &xx);
-#line 870
+#line 875
 	*ip = (double)xx;
-#line 870
+#line 875
 	return NC_NOERR;
-#line 870
+#line 875
 }
-#line 870
+#line 875
 
 
 static int
@@ -1155,451 +1160,451 @@ ncx_put_short_uchar(void *xp, const uchar *ip, void *fillp)
 }
 
 static int
-#line 893
+#line 898
 ncx_put_short_short(void *xp, const short *ip, void *fillp)
-#line 893
+#line 898
 {
-#line 893
+#line 898
     int err=NC_NOERR;
-#line 893
+#line 898
 #if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
-#line 893
+#line 898
     put_ix_short(xp, (const ix_short *)ip);
-#line 893
+#line 898
 #else
-#line 893
+#line 898
     ix_short xx = NC_FILL_SHORT;
-#line 893
+#line 898
 
-#line 893
+#line 898
 #if IX_SHORT_MAX < SHORT_MAX
-#line 893
+#line 898
     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
-#line 893
+#line 898
         
-#line 893
+#line 898
 #ifdef ERANGE_FILL
-#line 893
+#line 898
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 893
+#line 898
 #endif
-#line 893
+#line 898
         err = NC_ERANGE;
-#line 893
+#line 898
     }
-#line 893
+#line 898
 #ifdef ERANGE_FILL
-#line 893
+#line 898
     else
-#line 893
+#line 898
 #endif
-#line 893
+#line 898
 #endif
-#line 893
+#line 898
         xx = (ix_short)*ip;
-#line 893
+#line 898
 
-#line 893
+#line 898
     put_ix_short(xp, &xx);
-#line 893
+#line 898
 #endif
-#line 893
+#line 898
     return err;
-#line 893
+#line 898
 }
-#line 893
+#line 898
 
 static int
-#line 894
+#line 899
 ncx_put_short_int(void *xp, const int *ip, void *fillp)
-#line 894
+#line 899
 {
-#line 894
+#line 899
     int err=NC_NOERR;
-#line 894
+#line 899
 #if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
-#line 894
+#line 899
     put_ix_short(xp, (const ix_short *)ip);
-#line 894
+#line 899
 #else
-#line 894
+#line 899
     ix_short xx = NC_FILL_SHORT;
-#line 894
+#line 899
 
-#line 894
+#line 899
 #if IX_SHORT_MAX < INT_MAX
-#line 894
+#line 899
     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
-#line 894
+#line 899
         
-#line 894
+#line 899
 #ifdef ERANGE_FILL
-#line 894
+#line 899
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 894
+#line 899
 #endif
-#line 894
+#line 899
         err = NC_ERANGE;
-#line 894
+#line 899
     }
-#line 894
+#line 899
 #ifdef ERANGE_FILL
-#line 894
+#line 899
     else
-#line 894
+#line 899
 #endif
-#line 894
+#line 899
 #endif
-#line 894
+#line 899
         xx = (ix_short)*ip;
-#line 894
+#line 899
 
-#line 894
+#line 899
     put_ix_short(xp, &xx);
-#line 894
+#line 899
 #endif
-#line 894
+#line 899
     return err;
-#line 894
+#line 899
 }
-#line 894
+#line 899
 
 static int
-#line 895
+#line 900
 ncx_put_short_long(void *xp, const long *ip, void *fillp)
-#line 895
+#line 900
 {
-#line 895
+#line 900
     int err=NC_NOERR;
-#line 895
+#line 900
 #if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
-#line 895
+#line 900
     put_ix_short(xp, (const ix_short *)ip);
-#line 895
+#line 900
 #else
-#line 895
+#line 900
     ix_short xx = NC_FILL_SHORT;
-#line 895
+#line 900
 
-#line 895
+#line 900
 #if IX_SHORT_MAX < LONG_MAX
-#line 895
+#line 900
     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
-#line 895
+#line 900
         
-#line 895
+#line 900
 #ifdef ERANGE_FILL
-#line 895
+#line 900
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 895
+#line 900
 #endif
-#line 895
+#line 900
         err = NC_ERANGE;
-#line 895
+#line 900
     }
-#line 895
+#line 900
 #ifdef ERANGE_FILL
-#line 895
+#line 900
     else
-#line 895
+#line 900
 #endif
-#line 895
+#line 900
 #endif
-#line 895
+#line 900
         xx = (ix_short)*ip;
-#line 895
+#line 900
 
-#line 895
+#line 900
     put_ix_short(xp, &xx);
-#line 895
+#line 900
 #endif
-#line 895
+#line 900
     return err;
-#line 895
+#line 900
 }
-#line 895
+#line 900
 
 static int
-#line 896
+#line 901
 ncx_put_short_longlong(void *xp, const longlong *ip, void *fillp)
-#line 896
+#line 901
 {
-#line 896
+#line 901
     int err=NC_NOERR;
-#line 896
+#line 901
 #if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
-#line 896
+#line 901
     put_ix_short(xp, (const ix_short *)ip);
-#line 896
+#line 901
 #else
-#line 896
+#line 901
     ix_short xx = NC_FILL_SHORT;
-#line 896
+#line 901
 
-#line 896
+#line 901
 #if IX_SHORT_MAX < LONGLONG_MAX
-#line 896
+#line 901
     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
-#line 896
+#line 901
         
-#line 896
+#line 901
 #ifdef ERANGE_FILL
-#line 896
+#line 901
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 896
+#line 901
 #endif
-#line 896
+#line 901
         err = NC_ERANGE;
-#line 896
+#line 901
     }
-#line 896
+#line 901
 #ifdef ERANGE_FILL
-#line 896
+#line 901
     else
-#line 896
+#line 901
 #endif
-#line 896
+#line 901
 #endif
-#line 896
+#line 901
         xx = (ix_short)*ip;
-#line 896
+#line 901
 
-#line 896
+#line 901
     put_ix_short(xp, &xx);
-#line 896
+#line 901
 #endif
-#line 896
+#line 901
     return err;
-#line 896
+#line 901
 }
-#line 896
+#line 901
 
 static int
-#line 897
+#line 902
 ncx_put_short_ushort(void *xp, const ushort *ip, void *fillp)
-#line 897
+#line 902
 {
-#line 897
+#line 902
     int err=NC_NOERR;
-#line 897
+#line 902
     ix_short xx = NC_FILL_SHORT;
-#line 897
+#line 902
 
-#line 897
+#line 902
 #if IX_SHORT_MAX < USHORT_MAX
-#line 897
+#line 902
     if (*ip > IX_SHORT_MAX) {
-#line 897
+#line 902
         
-#line 897
+#line 902
 #ifdef ERANGE_FILL
-#line 897
+#line 902
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 897
+#line 902
 #endif
-#line 897
+#line 902
         err = NC_ERANGE;
-#line 897
+#line 902
     }
-#line 897
+#line 902
 #ifdef ERANGE_FILL
-#line 897
+#line 902
     else
-#line 897
+#line 902
 #endif
-#line 897
+#line 902
 #endif
-#line 897
+#line 902
         xx = (ix_short)*ip;
-#line 897
+#line 902
 
-#line 897
+#line 902
     put_ix_short(xp, &xx);
-#line 897
+#line 902
     return err;
-#line 897
+#line 902
 }
-#line 897
+#line 902
 
 static int
-#line 898
+#line 903
 ncx_put_short_uint(void *xp, const uint *ip, void *fillp)
-#line 898
+#line 903
 {
-#line 898
+#line 903
     int err=NC_NOERR;
-#line 898
+#line 903
     ix_short xx = NC_FILL_SHORT;
-#line 898
+#line 903
 
-#line 898
+#line 903
 #if IX_SHORT_MAX < UINT_MAX
-#line 898
+#line 903
     if (*ip > IX_SHORT_MAX) {
-#line 898
+#line 903
         
-#line 898
+#line 903
 #ifdef ERANGE_FILL
-#line 898
+#line 903
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 898
+#line 903
 #endif
-#line 898
+#line 903
         err = NC_ERANGE;
-#line 898
+#line 903
     }
-#line 898
+#line 903
 #ifdef ERANGE_FILL
-#line 898
+#line 903
     else
-#line 898
+#line 903
 #endif
-#line 898
+#line 903
 #endif
-#line 898
+#line 903
         xx = (ix_short)*ip;
-#line 898
+#line 903
 
-#line 898
+#line 903
     put_ix_short(xp, &xx);
-#line 898
+#line 903
     return err;
-#line 898
+#line 903
 }
-#line 898
+#line 903
 
 static int
-#line 899
+#line 904
 ncx_put_short_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 899
+#line 904
 {
-#line 899
+#line 904
     int err=NC_NOERR;
-#line 899
+#line 904
     ix_short xx = NC_FILL_SHORT;
-#line 899
+#line 904
 
-#line 899
+#line 904
 #if IX_SHORT_MAX < ULONGLONG_MAX
-#line 899
+#line 904
     if (*ip > IX_SHORT_MAX) {
-#line 899
+#line 904
         
-#line 899
+#line 904
 #ifdef ERANGE_FILL
-#line 899
+#line 904
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 899
+#line 904
 #endif
-#line 899
+#line 904
         err = NC_ERANGE;
-#line 899
+#line 904
     }
-#line 899
+#line 904
 #ifdef ERANGE_FILL
-#line 899
+#line 904
     else
-#line 899
+#line 904
 #endif
-#line 899
+#line 904
 #endif
-#line 899
+#line 904
         xx = (ix_short)*ip;
-#line 899
+#line 904
 
-#line 899
+#line 904
     put_ix_short(xp, &xx);
-#line 899
+#line 904
     return err;
-#line 899
+#line 904
 }
-#line 899
+#line 904
 
 static int
-#line 900
+#line 905
 ncx_put_short_float(void *xp, const float *ip, void *fillp)
-#line 900
+#line 905
 {
-#line 900
+#line 905
     int err=NC_NOERR;
-#line 900
+#line 905
     ix_short xx = NC_FILL_SHORT;
-#line 900
+#line 905
 
-#line 900
+#line 905
     if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
-#line 900
+#line 905
         
-#line 900
+#line 905
 #ifdef ERANGE_FILL
-#line 900
+#line 905
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 900
+#line 905
 #endif
-#line 900
+#line 905
         err = NC_ERANGE;
-#line 900
+#line 905
     }
-#line 900
+#line 905
 #ifdef ERANGE_FILL
-#line 900
+#line 905
     else
-#line 900
+#line 905
 #endif
-#line 900
+#line 905
         xx = (ix_short)*ip;
-#line 900
+#line 905
 
-#line 900
+#line 905
     put_ix_short(xp, &xx);
-#line 900
+#line 905
     return err;
-#line 900
+#line 905
 }
-#line 900
+#line 905
 
 static int
-#line 901
+#line 906
 ncx_put_short_double(void *xp, const double *ip, void *fillp)
-#line 901
+#line 906
 {
-#line 901
+#line 906
     int err=NC_NOERR;
-#line 901
+#line 906
     ix_short xx = NC_FILL_SHORT;
-#line 901
+#line 906
 
-#line 901
+#line 906
     if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) {
-#line 901
+#line 906
         
-#line 901
+#line 906
 #ifdef ERANGE_FILL
-#line 901
+#line 906
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 901
+#line 906
 #endif
-#line 901
+#line 906
         err = NC_ERANGE;
-#line 901
+#line 906
     }
-#line 901
+#line 906
 #ifdef ERANGE_FILL
-#line 901
+#line 906
     else
-#line 901
+#line 906
 #endif
-#line 901
+#line 906
         xx = (ix_short)*ip;
-#line 901
+#line 906
 
-#line 901
+#line 906
     put_ix_short(xp, &xx);
-#line 901
+#line 906
     return err;
-#line 901
+#line 906
 }
-#line 901
+#line 906
 
 
 /* external NC_USHORT -------------------------------------------------------*/
@@ -1648,475 +1653,475 @@ put_ix_ushort(void *xp, const ix_ushort *ip)
 }
 
 static int
-#line 948
+#line 953
 ncx_get_ushort_schar(const void *xp, schar *ip)
-#line 948
+#line 953
 {
-#line 948
+#line 953
     int err=NC_NOERR;
-#line 948
+#line 953
     ix_ushort xx;
-#line 948
+#line 953
     get_ix_ushort(xp, &xx);
-#line 948
+#line 953
 
-#line 948
+#line 953
 #if IX_USHORT_MAX > SCHAR_MAX
-#line 948
+#line 953
     if (xx > SCHAR_MAX) {
-#line 948
+#line 953
 #ifdef ERANGE_FILL
-#line 948
+#line 953
         *ip = NC_FILL_BYTE;
-#line 948
+#line 953
         return NC_ERANGE;
-#line 948
+#line 953
 #else
-#line 948
+#line 953
         err = NC_ERANGE;
-#line 948
+#line 953
 #endif
-#line 948
+#line 953
     }
-#line 948
+#line 953
 #endif
-#line 948
+#line 953
 
-#line 948
+#line 953
 
-#line 948
+#line 953
     *ip = (schar) xx;
-#line 948
+#line 953
     return err;
-#line 948
+#line 953
 }
-#line 948
+#line 953
 
 static int
-#line 949
+#line 954
 ncx_get_ushort_short(const void *xp, short *ip)
-#line 949
+#line 954
 {
-#line 949
+#line 954
     int err=NC_NOERR;
-#line 949
+#line 954
     ix_ushort xx;
-#line 949
+#line 954
     get_ix_ushort(xp, &xx);
-#line 949
+#line 954
 
-#line 949
+#line 954
 #if IX_USHORT_MAX > SHORT_MAX
-#line 949
+#line 954
     if (xx > SHORT_MAX) {
-#line 949
+#line 954
 #ifdef ERANGE_FILL
-#line 949
+#line 954
         *ip = NC_FILL_SHORT;
-#line 949
+#line 954
         return NC_ERANGE;
-#line 949
+#line 954
 #else
-#line 949
+#line 954
         err = NC_ERANGE;
-#line 949
+#line 954
 #endif
-#line 949
+#line 954
     }
-#line 949
+#line 954
 #endif
-#line 949
+#line 954
 
-#line 949
+#line 954
 
-#line 949
+#line 954
     *ip = (short) xx;
-#line 949
+#line 954
     return err;
-#line 949
+#line 954
 }
-#line 949
+#line 954
 
 static int
-#line 950
+#line 955
 ncx_get_ushort_int(const void *xp, int *ip)
-#line 950
+#line 955
 {
-#line 950
+#line 955
     int err=NC_NOERR;
-#line 950
+#line 955
     ix_ushort xx;
-#line 950
+#line 955
     get_ix_ushort(xp, &xx);
-#line 950
+#line 955
 
-#line 950
+#line 955
 #if IX_USHORT_MAX > INT_MAX
-#line 950
+#line 955
     if (xx > INT_MAX) {
-#line 950
+#line 955
 #ifdef ERANGE_FILL
-#line 950
+#line 955
         *ip = NC_FILL_INT;
-#line 950
+#line 955
         return NC_ERANGE;
-#line 950
+#line 955
 #else
-#line 950
+#line 955
         err = NC_ERANGE;
-#line 950
+#line 955
 #endif
-#line 950
+#line 955
     }
-#line 950
+#line 955
 #endif
-#line 950
+#line 955
 
-#line 950
+#line 955
 
-#line 950
+#line 955
     *ip = (int) xx;
-#line 950
+#line 955
     return err;
-#line 950
+#line 955
 }
-#line 950
+#line 955
 
 static int
-#line 951
+#line 956
 ncx_get_ushort_long(const void *xp, long *ip)
-#line 951
+#line 956
 {
-#line 951
+#line 956
     int err=NC_NOERR;
-#line 951
+#line 956
     ix_ushort xx;
-#line 951
+#line 956
     get_ix_ushort(xp, &xx);
-#line 951
+#line 956
 
-#line 951
+#line 956
 #if IX_USHORT_MAX > LONG_MAX
-#line 951
+#line 956
     if (xx > LONG_MAX) {
-#line 951
+#line 956
 #ifdef ERANGE_FILL
-#line 951
+#line 956
         *ip = NC_FILL_INT;
-#line 951
+#line 956
         return NC_ERANGE;
-#line 951
+#line 956
 #else
-#line 951
+#line 956
         err = NC_ERANGE;
-#line 951
+#line 956
 #endif
-#line 951
+#line 956
     }
-#line 951
+#line 956
 #endif
-#line 951
+#line 956
 
-#line 951
+#line 956
 
-#line 951
+#line 956
     *ip = (long) xx;
-#line 951
+#line 956
     return err;
-#line 951
+#line 956
 }
-#line 951
+#line 956
 
 static int
-#line 952
+#line 957
 ncx_get_ushort_longlong(const void *xp, longlong *ip)
-#line 952
+#line 957
 {
-#line 952
+#line 957
     int err=NC_NOERR;
-#line 952
+#line 957
     ix_ushort xx;
-#line 952
+#line 957
     get_ix_ushort(xp, &xx);
-#line 952
+#line 957
 
-#line 952
+#line 957
 #if IX_USHORT_MAX > LONGLONG_MAX
-#line 952
+#line 957
     if (xx > LONGLONG_MAX) {
-#line 952
+#line 957
 #ifdef ERANGE_FILL
-#line 952
+#line 957
         *ip = NC_FILL_INT64;
-#line 952
+#line 957
         return NC_ERANGE;
-#line 952
+#line 957
 #else
-#line 952
+#line 957
         err = NC_ERANGE;
-#line 952
+#line 957
 #endif
-#line 952
+#line 957
     }
-#line 952
+#line 957
 #endif
-#line 952
+#line 957
 
-#line 952
+#line 957
 
-#line 952
+#line 957
     *ip = (longlong) xx;
-#line 952
+#line 957
     return err;
-#line 952
+#line 957
 }
-#line 952
+#line 957
 
 static int
-#line 953
+#line 958
 ncx_get_ushort_ushort(const void *xp, ushort *ip)
-#line 953
+#line 958
 {
-#line 953
+#line 958
     int err=NC_NOERR;
-#line 953
+#line 958
 #if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
-#line 953
+#line 958
     get_ix_ushort(xp, (ix_ushort *)ip);
-#line 953
+#line 958
 #else
-#line 953
+#line 958
     ix_ushort xx;
-#line 953
+#line 958
     get_ix_ushort(xp, &xx);
-#line 953
+#line 958
 
-#line 953
+#line 958
 #if IX_USHORT_MAX > USHORT_MAX
-#line 953
+#line 958
     if (xx > USHORT_MAX) {
-#line 953
+#line 958
 #ifdef ERANGE_FILL
-#line 953
+#line 958
         *ip = NC_FILL_USHORT;
-#line 953
+#line 958
         return NC_ERANGE;
-#line 953
+#line 958
 #else
-#line 953
+#line 958
         err = NC_ERANGE;
-#line 953
+#line 958
 #endif
-#line 953
+#line 958
     }
-#line 953
+#line 958
 #endif
-#line 953
+#line 958
 
-#line 953
+#line 958
 
-#line 953
+#line 958
     *ip = (ushort) xx;
-#line 953
+#line 958
 #endif
-#line 953
+#line 958
     return err;
-#line 953
+#line 958
 }
-#line 953
+#line 958
 
 static int
-#line 954
+#line 959
 ncx_get_ushort_uchar(const void *xp, uchar *ip)
-#line 954
+#line 959
 {
-#line 954
+#line 959
     int err=NC_NOERR;
-#line 954
+#line 959
 #if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
-#line 954
+#line 959
     get_ix_ushort(xp, (ix_ushort *)ip);
-#line 954
+#line 959
 #else
-#line 954
+#line 959
     ix_ushort xx;
-#line 954
+#line 959
     get_ix_ushort(xp, &xx);
-#line 954
+#line 959
 
-#line 954
+#line 959
 #if IX_USHORT_MAX > UCHAR_MAX
-#line 954
+#line 959
     if (xx > UCHAR_MAX) {
-#line 954
+#line 959
 #ifdef ERANGE_FILL
-#line 954
+#line 959
         *ip = NC_FILL_UBYTE;
-#line 954
+#line 959
         return NC_ERANGE;
-#line 954
+#line 959
 #else
-#line 954
+#line 959
         err = NC_ERANGE;
-#line 954
+#line 959
 #endif
-#line 954
+#line 959
     }
-#line 954
+#line 959
 #endif
-#line 954
+#line 959
 
-#line 954
+#line 959
 
-#line 954
+#line 959
     *ip = (uchar) xx;
-#line 954
+#line 959
 #endif
-#line 954
+#line 959
     return err;
-#line 954
+#line 959
 }
-#line 954
+#line 959
 
 static int
-#line 955
+#line 960
 ncx_get_ushort_uint(const void *xp, uint *ip)
-#line 955
+#line 960
 {
-#line 955
+#line 960
     int err=NC_NOERR;
-#line 955
+#line 960
 #if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
-#line 955
+#line 960
     get_ix_ushort(xp, (ix_ushort *)ip);
-#line 955
+#line 960
 #else
-#line 955
+#line 960
     ix_ushort xx;
-#line 955
+#line 960
     get_ix_ushort(xp, &xx);
-#line 955
+#line 960
 
-#line 955
+#line 960
 #if IX_USHORT_MAX > UINT_MAX
-#line 955
+#line 960
     if (xx > UINT_MAX) {
-#line 955
+#line 960
 #ifdef ERANGE_FILL
-#line 955
+#line 960
         *ip = NC_FILL_UINT;
-#line 955
+#line 960
         return NC_ERANGE;
-#line 955
+#line 960
 #else
-#line 955
+#line 960
         err = NC_ERANGE;
-#line 955
+#line 960
 #endif
-#line 955
+#line 960
     }
-#line 955
+#line 960
 #endif
-#line 955
+#line 960
 
-#line 955
+#line 960
 
-#line 955
+#line 960
     *ip = (uint) xx;
-#line 955
+#line 960
 #endif
-#line 955
+#line 960
     return err;
-#line 955
+#line 960
 }
-#line 955
+#line 960
 
 static int
-#line 956
+#line 961
 ncx_get_ushort_ulonglong(const void *xp, ulonglong *ip)
-#line 956
+#line 961
 {
-#line 956
+#line 961
     int err=NC_NOERR;
-#line 956
+#line 961
 #if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
-#line 956
+#line 961
     get_ix_ushort(xp, (ix_ushort *)ip);
-#line 956
+#line 961
 #else
-#line 956
+#line 961
     ix_ushort xx;
-#line 956
+#line 961
     get_ix_ushort(xp, &xx);
-#line 956
+#line 961
 
-#line 956
+#line 961
 #if IX_USHORT_MAX > ULONGLONG_MAX
-#line 956
+#line 961
     if (xx > ULONGLONG_MAX) {
-#line 956
+#line 961
 #ifdef ERANGE_FILL
-#line 956
+#line 961
         *ip = NC_FILL_UINT64;
-#line 956
+#line 961
         return NC_ERANGE;
-#line 956
+#line 961
 #else
-#line 956
+#line 961
         err = NC_ERANGE;
-#line 956
+#line 961
 #endif
-#line 956
+#line 961
     }
-#line 956
+#line 961
 #endif
-#line 956
+#line 961
 
-#line 956
+#line 961
 
-#line 956
+#line 961
     *ip = (ulonglong) xx;
-#line 956
+#line 961
 #endif
-#line 956
+#line 961
     return err;
-#line 956
+#line 961
 }
-#line 956
+#line 961
 
 static int
-#line 957
+#line 962
 ncx_get_ushort_float(const void *xp, float *ip)
-#line 957
+#line 962
 {
-#line 957
+#line 962
 	ix_ushort xx;
-#line 957
+#line 962
 	get_ix_ushort(xp, &xx);
-#line 957
+#line 962
 	*ip = (float)xx;
-#line 957
+#line 962
 	return NC_NOERR;
-#line 957
+#line 962
 }
-#line 957
+#line 962
 
 static int
-#line 958
+#line 963
 ncx_get_ushort_double(const void *xp, double *ip)
-#line 958
+#line 963
 {
-#line 958
+#line 963
 	ix_ushort xx;
-#line 958
+#line 963
 	get_ix_ushort(xp, &xx);
-#line 958
+#line 963
 	*ip = (double)xx;
-#line 958
+#line 963
 	return NC_NOERR;
-#line 958
+#line 963
 }
-#line 958
+#line 963
 
 
 static int
@@ -2156,523 +2161,523 @@ ncx_put_ushort_uchar(void *xp, const uchar *ip, void *fillp)
 }
 
 static int
-#line 996
+#line 1001
 ncx_put_ushort_short(void *xp, const short *ip, void *fillp)
-#line 996
+#line 1001
 {
-#line 996
+#line 1001
     int err=NC_NOERR;
-#line 996
+#line 1001
     ix_ushort xx = NC_FILL_USHORT;
-#line 996
+#line 1001
 
-#line 996
+#line 1001
 #if IX_USHORT_MAX < SHORT_MAX
-#line 996
+#line 1001
     if (*ip > IX_USHORT_MAX) {
-#line 996
+#line 1001
         
-#line 996
+#line 1001
 #ifdef ERANGE_FILL
-#line 996
+#line 1001
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 996
+#line 1001
 #endif
-#line 996
+#line 1001
         err = NC_ERANGE;
-#line 996
+#line 1001
     }
-#line 996
+#line 1001
 #ifdef ERANGE_FILL
-#line 996
+#line 1001
     else
-#line 996
+#line 1001
 #endif
-#line 996
+#line 1001
 #endif
-#line 996
+#line 1001
     if (*ip < 0) {
-#line 996
+#line 1001
         
-#line 996
+#line 1001
 #ifdef ERANGE_FILL
-#line 996
+#line 1001
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 996
+#line 1001
 #endif
-#line 996
+#line 1001
         err = NC_ERANGE; /* because xp is unsigned */
-#line 996
+#line 1001
     }
-#line 996
+#line 1001
 #ifdef ERANGE_FILL
-#line 996
+#line 1001
     else
-#line 996
+#line 1001
 #endif
-#line 996
+#line 1001
         xx = (ix_ushort)*ip;
-#line 996
+#line 1001
 
-#line 996
+#line 1001
     put_ix_ushort(xp, &xx);
-#line 996
+#line 1001
     return err;
-#line 996
+#line 1001
 }
-#line 996
+#line 1001
 
 static int
-#line 997
+#line 1002
 ncx_put_ushort_int(void *xp, const int *ip, void *fillp)
-#line 997
+#line 1002
 {
-#line 997
+#line 1002
     int err=NC_NOERR;
-#line 997
+#line 1002
     ix_ushort xx = NC_FILL_USHORT;
-#line 997
+#line 1002
 
-#line 997
+#line 1002
 #if IX_USHORT_MAX < INT_MAX
-#line 997
+#line 1002
     if (*ip > IX_USHORT_MAX) {
-#line 997
+#line 1002
         
-#line 997
+#line 1002
 #ifdef ERANGE_FILL
-#line 997
+#line 1002
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 997
+#line 1002
 #endif
-#line 997
+#line 1002
         err = NC_ERANGE;
-#line 997
+#line 1002
     }
-#line 997
+#line 1002
 #ifdef ERANGE_FILL
-#line 997
+#line 1002
     else
-#line 997
+#line 1002
 #endif
-#line 997
+#line 1002
 #endif
-#line 997
+#line 1002
     if (*ip < 0) {
-#line 997
+#line 1002
         
-#line 997
+#line 1002
 #ifdef ERANGE_FILL
-#line 997
+#line 1002
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 997
+#line 1002
 #endif
-#line 997
+#line 1002
         err = NC_ERANGE; /* because xp is unsigned */
-#line 997
+#line 1002
     }
-#line 997
+#line 1002
 #ifdef ERANGE_FILL
-#line 997
+#line 1002
     else
-#line 997
+#line 1002
 #endif
-#line 997
+#line 1002
         xx = (ix_ushort)*ip;
-#line 997
+#line 1002
 
-#line 997
+#line 1002
     put_ix_ushort(xp, &xx);
-#line 997
+#line 1002
     return err;
-#line 997
+#line 1002
 }
-#line 997
+#line 1002
 
 static int
-#line 998
+#line 1003
 ncx_put_ushort_long(void *xp, const long *ip, void *fillp)
-#line 998
+#line 1003
 {
-#line 998
+#line 1003
     int err=NC_NOERR;
-#line 998
+#line 1003
     ix_ushort xx = NC_FILL_USHORT;
-#line 998
+#line 1003
 
-#line 998
+#line 1003
 #if IX_USHORT_MAX < LONG_MAX
-#line 998
+#line 1003
     if (*ip > IX_USHORT_MAX) {
-#line 998
+#line 1003
         
-#line 998
+#line 1003
 #ifdef ERANGE_FILL
-#line 998
+#line 1003
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 998
+#line 1003
 #endif
-#line 998
+#line 1003
         err = NC_ERANGE;
-#line 998
+#line 1003
     }
-#line 998
+#line 1003
 #ifdef ERANGE_FILL
-#line 998
+#line 1003
     else
-#line 998
+#line 1003
 #endif
-#line 998
+#line 1003
 #endif
-#line 998
+#line 1003
     if (*ip < 0) {
-#line 998
+#line 1003
         
-#line 998
+#line 1003
 #ifdef ERANGE_FILL
-#line 998
+#line 1003
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 998
+#line 1003
 #endif
-#line 998
+#line 1003
         err = NC_ERANGE; /* because xp is unsigned */
-#line 998
+#line 1003
     }
-#line 998
+#line 1003
 #ifdef ERANGE_FILL
-#line 998
+#line 1003
     else
-#line 998
+#line 1003
 #endif
-#line 998
+#line 1003
         xx = (ix_ushort)*ip;
-#line 998
+#line 1003
 
-#line 998
+#line 1003
     put_ix_ushort(xp, &xx);
-#line 998
+#line 1003
     return err;
-#line 998
+#line 1003
 }
-#line 998
+#line 1003
 
 static int
-#line 999
+#line 1004
 ncx_put_ushort_longlong(void *xp, const longlong *ip, void *fillp)
-#line 999
+#line 1004
 {
-#line 999
+#line 1004
     int err=NC_NOERR;
-#line 999
+#line 1004
     ix_ushort xx = NC_FILL_USHORT;
-#line 999
+#line 1004
 
-#line 999
+#line 1004
 #if IX_USHORT_MAX < LONGLONG_MAX
-#line 999
+#line 1004
     if (*ip > IX_USHORT_MAX) {
-#line 999
+#line 1004
         
-#line 999
+#line 1004
 #ifdef ERANGE_FILL
-#line 999
+#line 1004
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 999
+#line 1004
 #endif
-#line 999
+#line 1004
         err = NC_ERANGE;
-#line 999
+#line 1004
     }
-#line 999
+#line 1004
 #ifdef ERANGE_FILL
-#line 999
+#line 1004
     else
-#line 999
+#line 1004
 #endif
-#line 999
+#line 1004
 #endif
-#line 999
+#line 1004
     if (*ip < 0) {
-#line 999
+#line 1004
         
-#line 999
+#line 1004
 #ifdef ERANGE_FILL
-#line 999
+#line 1004
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 999
+#line 1004
 #endif
-#line 999
+#line 1004
         err = NC_ERANGE; /* because xp is unsigned */
-#line 999
+#line 1004
     }
-#line 999
+#line 1004
 #ifdef ERANGE_FILL
-#line 999
+#line 1004
     else
-#line 999
+#line 1004
 #endif
-#line 999
+#line 1004
         xx = (ix_ushort)*ip;
-#line 999
+#line 1004
 
-#line 999
+#line 1004
     put_ix_ushort(xp, &xx);
-#line 999
+#line 1004
     return err;
-#line 999
+#line 1004
 }
-#line 999
+#line 1004
 
 static int
-#line 1000
+#line 1005
 ncx_put_ushort_ushort(void *xp, const ushort *ip, void *fillp)
-#line 1000
+#line 1005
 {
-#line 1000
+#line 1005
     int err=NC_NOERR;
-#line 1000
+#line 1005
 #if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
-#line 1000
+#line 1005
     put_ix_ushort(xp, (const ix_ushort *)ip);
-#line 1000
+#line 1005
 #else
-#line 1000
+#line 1005
     ix_ushort xx = NC_FILL_USHORT;
-#line 1000
+#line 1005
 
-#line 1000
+#line 1005
 #if IX_USHORT_MAX < USHORT_MAX
-#line 1000
+#line 1005
     if (*ip > IX_USHORT_MAX) {
-#line 1000
+#line 1005
         
-#line 1000
+#line 1005
 #ifdef ERANGE_FILL
-#line 1000
+#line 1005
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 1000
+#line 1005
 #endif
-#line 1000
+#line 1005
         err = NC_ERANGE;
-#line 1000
+#line 1005
     }
-#line 1000
+#line 1005
 #ifdef ERANGE_FILL
-#line 1000
+#line 1005
     else
-#line 1000
+#line 1005
 #endif
-#line 1000
+#line 1005
 #endif
-#line 1000
+#line 1005
         xx = (ix_ushort)*ip;
-#line 1000
+#line 1005
 
-#line 1000
+#line 1005
     put_ix_ushort(xp, &xx);
-#line 1000
+#line 1005
 #endif
-#line 1000
+#line 1005
     return err;
-#line 1000
+#line 1005
 }
-#line 1000
+#line 1005
 
 static int
-#line 1001
+#line 1006
 ncx_put_ushort_uint(void *xp, const uint *ip, void *fillp)
-#line 1001
+#line 1006
 {
-#line 1001
+#line 1006
     int err=NC_NOERR;
-#line 1001
+#line 1006
 #if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
-#line 1001
+#line 1006
     put_ix_ushort(xp, (const ix_ushort *)ip);
-#line 1001
+#line 1006
 #else
-#line 1001
+#line 1006
     ix_ushort xx = NC_FILL_USHORT;
-#line 1001
+#line 1006
 
-#line 1001
+#line 1006
 #if IX_USHORT_MAX < UINT_MAX
-#line 1001
+#line 1006
     if (*ip > IX_USHORT_MAX) {
-#line 1001
+#line 1006
         
-#line 1001
+#line 1006
 #ifdef ERANGE_FILL
-#line 1001
+#line 1006
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 1001
+#line 1006
 #endif
-#line 1001
+#line 1006
         err = NC_ERANGE;
-#line 1001
+#line 1006
     }
-#line 1001
+#line 1006
 #ifdef ERANGE_FILL
-#line 1001
+#line 1006
     else
-#line 1001
+#line 1006
 #endif
-#line 1001
+#line 1006
 #endif
-#line 1001
+#line 1006
         xx = (ix_ushort)*ip;
-#line 1001
+#line 1006
 
-#line 1001
+#line 1006
     put_ix_ushort(xp, &xx);
-#line 1001
+#line 1006
 #endif
-#line 1001
+#line 1006
     return err;
-#line 1001
+#line 1006
 }
-#line 1001
+#line 1006
 
 static int
-#line 1002
+#line 1007
 ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 1002
+#line 1007
 {
-#line 1002
+#line 1007
     int err=NC_NOERR;
-#line 1002
+#line 1007
 #if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
-#line 1002
+#line 1007
     put_ix_ushort(xp, (const ix_ushort *)ip);
-#line 1002
+#line 1007
 #else
-#line 1002
+#line 1007
     ix_ushort xx = NC_FILL_USHORT;
-#line 1002
+#line 1007
 
-#line 1002
+#line 1007
 #if IX_USHORT_MAX < ULONGLONG_MAX
-#line 1002
+#line 1007
     if (*ip > IX_USHORT_MAX) {
-#line 1002
+#line 1007
         
-#line 1002
+#line 1007
 #ifdef ERANGE_FILL
-#line 1002
+#line 1007
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 1002
+#line 1007
 #endif
-#line 1002
+#line 1007
         err = NC_ERANGE;
-#line 1002
+#line 1007
     }
-#line 1002
+#line 1007
 #ifdef ERANGE_FILL
-#line 1002
+#line 1007
     else
-#line 1002
+#line 1007
 #endif
-#line 1002
+#line 1007
 #endif
-#line 1002
+#line 1007
         xx = (ix_ushort)*ip;
-#line 1002
+#line 1007
 
-#line 1002
+#line 1007
     put_ix_ushort(xp, &xx);
-#line 1002
+#line 1007
 #endif
-#line 1002
+#line 1007
     return err;
-#line 1002
+#line 1007
 }
-#line 1002
+#line 1007
 
 static int
-#line 1003
+#line 1008
 ncx_put_ushort_float(void *xp, const float *ip, void *fillp)
-#line 1003
+#line 1008
 {
-#line 1003
+#line 1008
     int err=NC_NOERR;
-#line 1003
+#line 1008
     ix_ushort xx = NC_FILL_USHORT;
-#line 1003
+#line 1008
 
-#line 1003
+#line 1008
     if (*ip > (double)X_USHORT_MAX || *ip < 0) {
-#line 1003
+#line 1008
         
-#line 1003
+#line 1008
 #ifdef ERANGE_FILL
-#line 1003
+#line 1008
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 1003
+#line 1008
 #endif
-#line 1003
+#line 1008
         err = NC_ERANGE;
-#line 1003
+#line 1008
     }
-#line 1003
+#line 1008
 #ifdef ERANGE_FILL
-#line 1003
+#line 1008
     else
-#line 1003
+#line 1008
 #endif
-#line 1003
+#line 1008
         xx = (ix_ushort)*ip;
-#line 1003
+#line 1008
 
-#line 1003
+#line 1008
     put_ix_ushort(xp, &xx);
-#line 1003
+#line 1008
     return err;
-#line 1003
+#line 1008
 }
-#line 1003
+#line 1008
 
 static int
-#line 1004
+#line 1009
 ncx_put_ushort_double(void *xp, const double *ip, void *fillp)
-#line 1004
+#line 1009
 {
-#line 1004
+#line 1009
     int err=NC_NOERR;
-#line 1004
+#line 1009
     ix_ushort xx = NC_FILL_USHORT;
-#line 1004
+#line 1009
 
-#line 1004
+#line 1009
     if (*ip > X_USHORT_MAX || *ip < 0) {
-#line 1004
+#line 1009
         
-#line 1004
+#line 1009
 #ifdef ERANGE_FILL
-#line 1004
+#line 1009
             if (fillp != NULL) memcpy(&xx, fillp, 2);
-#line 1004
+#line 1009
 #endif
-#line 1004
+#line 1009
         err = NC_ERANGE;
-#line 1004
+#line 1009
     }
-#line 1004
+#line 1009
 #ifdef ERANGE_FILL
-#line 1004
+#line 1009
     else
-#line 1004
+#line 1009
 #endif
-#line 1004
+#line 1009
         xx = (ix_ushort)*ip;
-#line 1004
+#line 1009
 
-#line 1004
+#line 1009
     put_ix_ushort(xp, &xx);
-#line 1004
+#line 1009
     return err;
-#line 1004
+#line 1009
 }
-#line 1004
+#line 1009
 
 
 /* external NC_INT ----------------------------------------------------------*/
@@ -2729,532 +2734,532 @@ put_ix_int(void *xp, const ix_int *ip)
 
 #if X_SIZEOF_INT != SIZEOF_INT
 static int
-#line 1059
+#line 1064
 ncx_get_int_int(const void *xp, int *ip)
-#line 1059
+#line 1064
 {
-#line 1059
+#line 1064
     int err=NC_NOERR;
-#line 1059
+#line 1064
 #if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
-#line 1059
+#line 1064
     get_ix_int(xp, (ix_int *)ip);
-#line 1059
+#line 1064
 #else
-#line 1059
+#line 1064
     ix_int xx;
-#line 1059
+#line 1064
     get_ix_int(xp, &xx);
-#line 1059
+#line 1064
 
-#line 1059
+#line 1064
 #if IX_INT_MAX > INT_MAX
-#line 1059
+#line 1064
     if (xx > INT_MAX || xx < INT_MIN) {
-#line 1059
+#line 1064
 #ifdef ERANGE_FILL
-#line 1059
+#line 1064
         *ip = NC_FILL_INT;
-#line 1059
+#line 1064
         return NC_ERANGE;
-#line 1059
+#line 1064
 #else
-#line 1059
+#line 1064
         err = NC_ERANGE;
-#line 1059
+#line 1064
 #endif
-#line 1059
+#line 1064
     }
-#line 1059
+#line 1064
 #endif
-#line 1059
+#line 1064
 
-#line 1059
+#line 1064
 
-#line 1059
+#line 1064
     *ip = (int) xx;
-#line 1059
+#line 1064
 #endif
-#line 1059
+#line 1064
     return err;
-#line 1059
+#line 1064
 }
-#line 1059
+#line 1064
 
 #endif
 static int
-#line 1061
+#line 1066
 ncx_get_int_schar(const void *xp, schar *ip)
-#line 1061
+#line 1066
 {
-#line 1061
+#line 1066
     int err=NC_NOERR;
-#line 1061
+#line 1066
     ix_int xx;
-#line 1061
+#line 1066
     get_ix_int(xp, &xx);
-#line 1061
+#line 1066
 
-#line 1061
+#line 1066
 #if IX_INT_MAX > SCHAR_MAX
-#line 1061
+#line 1066
     if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
-#line 1061
+#line 1066
 #ifdef ERANGE_FILL
-#line 1061
+#line 1066
         *ip = NC_FILL_BYTE;
-#line 1061
+#line 1066
         return NC_ERANGE;
-#line 1061
+#line 1066
 #else
-#line 1061
+#line 1066
         err = NC_ERANGE;
-#line 1061
+#line 1066
 #endif
-#line 1061
+#line 1066
     }
-#line 1061
+#line 1066
 #endif
-#line 1061
+#line 1066
 
-#line 1061
+#line 1066
 
-#line 1061
+#line 1066
     *ip = (schar) xx;
-#line 1061
+#line 1066
     return err;
-#line 1061
+#line 1066
 }
-#line 1061
+#line 1066
 
 static int
-#line 1062
+#line 1067
 ncx_get_int_short(const void *xp, short *ip)
-#line 1062
+#line 1067
 {
-#line 1062
+#line 1067
     int err=NC_NOERR;
-#line 1062
+#line 1067
 #if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
-#line 1062
+#line 1067
     get_ix_int(xp, (ix_int *)ip);
-#line 1062
+#line 1067
 #else
-#line 1062
+#line 1067
     ix_int xx;
-#line 1062
+#line 1067
     get_ix_int(xp, &xx);
-#line 1062
+#line 1067
 
-#line 1062
+#line 1067
 #if IX_INT_MAX > SHORT_MAX
-#line 1062
+#line 1067
     if (xx > SHORT_MAX || xx < SHORT_MIN) {
-#line 1062
+#line 1067
 #ifdef ERANGE_FILL
-#line 1062
+#line 1067
         *ip = NC_FILL_SHORT;
-#line 1062
+#line 1067
         return NC_ERANGE;
-#line 1062
+#line 1067
 #else
-#line 1062
+#line 1067
         err = NC_ERANGE;
-#line 1062
+#line 1067
 #endif
-#line 1062
+#line 1067
     }
-#line 1062
+#line 1067
 #endif
-#line 1062
+#line 1067
 
-#line 1062
+#line 1067
 
-#line 1062
+#line 1067
     *ip = (short) xx;
-#line 1062
+#line 1067
 #endif
-#line 1062
+#line 1067
     return err;
-#line 1062
+#line 1067
 }
-#line 1062
+#line 1067
 
 static int
-#line 1063
+#line 1068
 ncx_get_int_long(const void *xp, long *ip)
-#line 1063
+#line 1068
 {
-#line 1063
+#line 1068
     int err=NC_NOERR;
-#line 1063
+#line 1068
 #if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
-#line 1063
+#line 1068
     get_ix_int(xp, (ix_int *)ip);
-#line 1063
+#line 1068
 #else
-#line 1063
+#line 1068
     ix_int xx;
-#line 1063
+#line 1068
     get_ix_int(xp, &xx);
-#line 1063
+#line 1068
 
-#line 1063
+#line 1068
 #if IX_INT_MAX > LONG_MAX
-#line 1063
+#line 1068
     if (xx > LONG_MAX || xx < LONG_MIN) {
-#line 1063
+#line 1068
 #ifdef ERANGE_FILL
-#line 1063
+#line 1068
         *ip = NC_FILL_INT;
-#line 1063
+#line 1068
         return NC_ERANGE;
-#line 1063
+#line 1068
 #else
-#line 1063
+#line 1068
         err = NC_ERANGE;
-#line 1063
+#line 1068
 #endif
-#line 1063
+#line 1068
     }
-#line 1063
+#line 1068
 #endif
-#line 1063
+#line 1068
 
-#line 1063
+#line 1068
 
-#line 1063
+#line 1068
     *ip = (long) xx;
-#line 1063
+#line 1068
 #endif
-#line 1063
+#line 1068
     return err;
-#line 1063
+#line 1068
 }
-#line 1063
+#line 1068
 
 static int
-#line 1064
+#line 1069
 ncx_get_int_longlong(const void *xp, longlong *ip)
-#line 1064
+#line 1069
 {
-#line 1064
+#line 1069
     int err=NC_NOERR;
-#line 1064
+#line 1069
 #if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
-#line 1064
+#line 1069
     get_ix_int(xp, (ix_int *)ip);
-#line 1064
+#line 1069
 #else
-#line 1064
+#line 1069
     ix_int xx;
-#line 1064
+#line 1069
     get_ix_int(xp, &xx);
-#line 1064
+#line 1069
 
-#line 1064
+#line 1069
 #if IX_INT_MAX > LONGLONG_MAX
-#line 1064
+#line 1069
     if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
-#line 1064
+#line 1069
 #ifdef ERANGE_FILL
-#line 1064
+#line 1069
         *ip = NC_FILL_INT64;
-#line 1064
+#line 1069
         return NC_ERANGE;
-#line 1064
+#line 1069
 #else
-#line 1064
+#line 1069
         err = NC_ERANGE;
-#line 1064
+#line 1069
 #endif
-#line 1064
+#line 1069
     }
-#line 1064
+#line 1069
 #endif
-#line 1064
+#line 1069
 
-#line 1064
+#line 1069
 
-#line 1064
+#line 1069
     *ip = (longlong) xx;
-#line 1064
+#line 1069
 #endif
-#line 1064
+#line 1069
     return err;
-#line 1064
+#line 1069
 }
-#line 1064
+#line 1069
 
 static int
-#line 1065
+#line 1070
 ncx_get_int_ushort(const void *xp, ushort *ip)
-#line 1065
+#line 1070
 {
-#line 1065
+#line 1070
     int err=NC_NOERR;
-#line 1065
+#line 1070
     ix_int xx;
-#line 1065
+#line 1070
     get_ix_int(xp, &xx);
-#line 1065
+#line 1070
 
-#line 1065
+#line 1070
 #if IX_INT_MAX > USHORT_MAX
-#line 1065
+#line 1070
     if (xx > USHORT_MAX) {
-#line 1065
+#line 1070
 #ifdef ERANGE_FILL
-#line 1065
+#line 1070
         *ip = NC_FILL_USHORT;
-#line 1065
+#line 1070
         return NC_ERANGE;
-#line 1065
+#line 1070
 #else
-#line 1065
+#line 1070
         err = NC_ERANGE;
-#line 1065
+#line 1070
 #endif
-#line 1065
+#line 1070
     }
-#line 1065
+#line 1070
 #endif
-#line 1065
+#line 1070
 
-#line 1065
+#line 1070
     if (xx < 0) {
-#line 1065
+#line 1070
 #ifdef ERANGE_FILL
-#line 1065
+#line 1070
         *ip = NC_FILL_USHORT;
-#line 1065
+#line 1070
         return NC_ERANGE;
-#line 1065
+#line 1070
 #else
-#line 1065
+#line 1070
         err = NC_ERANGE; /* because ip is unsigned */
-#line 1065
+#line 1070
 #endif
-#line 1065
+#line 1070
     }
-#line 1065
+#line 1070
     *ip = (ushort) xx;
-#line 1065
+#line 1070
     return err;
-#line 1065
+#line 1070
 }
-#line 1065
+#line 1070
 
 static int
-#line 1066
+#line 1071
 ncx_get_int_uchar(const void *xp, uchar *ip)
-#line 1066
+#line 1071
 {
-#line 1066
+#line 1071
     int err=NC_NOERR;
-#line 1066
+#line 1071
     ix_int xx;
-#line 1066
+#line 1071
     get_ix_int(xp, &xx);
-#line 1066
+#line 1071
 
-#line 1066
+#line 1071
 #if IX_INT_MAX > UCHAR_MAX
-#line 1066
+#line 1071
     if (xx > UCHAR_MAX) {
-#line 1066
+#line 1071
 #ifdef ERANGE_FILL
-#line 1066
+#line 1071
         *ip = NC_FILL_UBYTE;
-#line 1066
+#line 1071
         return NC_ERANGE;
-#line 1066
+#line 1071
 #else
-#line 1066
+#line 1071
         err = NC_ERANGE;
-#line 1066
+#line 1071
 #endif
-#line 1066
+#line 1071
     }
-#line 1066
+#line 1071
 #endif
-#line 1066
+#line 1071
 
-#line 1066
+#line 1071
     if (xx < 0) {
-#line 1066
+#line 1071
 #ifdef ERANGE_FILL
-#line 1066
+#line 1071
         *ip = NC_FILL_UBYTE;
-#line 1066
+#line 1071
         return NC_ERANGE;
-#line 1066
+#line 1071
 #else
-#line 1066
+#line 1071
         err = NC_ERANGE; /* because ip is unsigned */
-#line 1066
+#line 1071
 #endif
-#line 1066
+#line 1071
     }
-#line 1066
+#line 1071
     *ip = (uchar) xx;
-#line 1066
+#line 1071
     return err;
-#line 1066
+#line 1071
 }
-#line 1066
+#line 1071
 
 static int
-#line 1067
+#line 1072
 ncx_get_int_uint(const void *xp, uint *ip)
-#line 1067
+#line 1072
 {
-#line 1067
+#line 1072
     int err=NC_NOERR;
-#line 1067
+#line 1072
     ix_int xx;
-#line 1067
+#line 1072
     get_ix_int(xp, &xx);
-#line 1067
+#line 1072
 
-#line 1067
+#line 1072
 #if IX_INT_MAX > UINT_MAX
-#line 1067
+#line 1072
     if (xx > UINT_MAX) {
-#line 1067
+#line 1072
 #ifdef ERANGE_FILL
-#line 1067
+#line 1072
         *ip = NC_FILL_UINT;
-#line 1067
+#line 1072
         return NC_ERANGE;
-#line 1067
+#line 1072
 #else
-#line 1067
+#line 1072
         err = NC_ERANGE;
-#line 1067
+#line 1072
 #endif
-#line 1067
+#line 1072
     }
-#line 1067
+#line 1072
 #endif
-#line 1067
+#line 1072
 
-#line 1067
+#line 1072
     if (xx < 0) {
-#line 1067
+#line 1072
 #ifdef ERANGE_FILL
-#line 1067
+#line 1072
         *ip = NC_FILL_UINT;
-#line 1067
+#line 1072
         return NC_ERANGE;
-#line 1067
+#line 1072
 #else
-#line 1067
+#line 1072
         err = NC_ERANGE; /* because ip is unsigned */
-#line 1067
+#line 1072
 #endif
-#line 1067
+#line 1072
     }
-#line 1067
+#line 1072
     *ip = (uint) xx;
-#line 1067
+#line 1072
     return err;
-#line 1067
+#line 1072
 }
-#line 1067
+#line 1072
 
 static int
-#line 1068
+#line 1073
 ncx_get_int_ulonglong(const void *xp, ulonglong *ip)
-#line 1068
+#line 1073
 {
-#line 1068
+#line 1073
     int err=NC_NOERR;
-#line 1068
+#line 1073
     ix_int xx;
-#line 1068
+#line 1073
     get_ix_int(xp, &xx);
-#line 1068
+#line 1073
 
-#line 1068
+#line 1073
 #if IX_INT_MAX > ULONGLONG_MAX
-#line 1068
+#line 1073
     if (xx > ULONGLONG_MAX) {
-#line 1068
+#line 1073
 #ifdef ERANGE_FILL
-#line 1068
+#line 1073
         *ip = NC_FILL_UINT64;
-#line 1068
+#line 1073
         return NC_ERANGE;
-#line 1068
+#line 1073
 #else
-#line 1068
+#line 1073
         err = NC_ERANGE;
-#line 1068
+#line 1073
 #endif
-#line 1068
+#line 1073
     }
-#line 1068
+#line 1073
 #endif
-#line 1068
+#line 1073
 
-#line 1068
+#line 1073
     if (xx < 0) {
-#line 1068
+#line 1073
 #ifdef ERANGE_FILL
-#line 1068
+#line 1073
         *ip = NC_FILL_UINT64;
-#line 1068
+#line 1073
         return NC_ERANGE;
-#line 1068
+#line 1073
 #else
-#line 1068
+#line 1073
         err = NC_ERANGE; /* because ip is unsigned */
-#line 1068
+#line 1073
 #endif
-#line 1068
+#line 1073
     }
-#line 1068
+#line 1073
     *ip = (ulonglong) xx;
-#line 1068
+#line 1073
     return err;
-#line 1068
+#line 1073
 }
-#line 1068
+#line 1073
 
 static int
-#line 1069
+#line 1074
 ncx_get_int_float(const void *xp, float *ip)
-#line 1069
+#line 1074
 {
-#line 1069
+#line 1074
 	ix_int xx;
-#line 1069
+#line 1074
 	get_ix_int(xp, &xx);
-#line 1069
+#line 1074
 	*ip = (float)xx;
-#line 1069
+#line 1074
 	return NC_NOERR;
-#line 1069
+#line 1074
 }
-#line 1069
+#line 1074
 
 static int
-#line 1070
+#line 1075
 ncx_get_int_double(const void *xp, double *ip)
-#line 1070
+#line 1075
 {
-#line 1070
+#line 1075
 	ix_int xx;
-#line 1070
+#line 1075
 	get_ix_int(xp, &xx);
-#line 1070
+#line 1075
 	*ip = (double)xx;
-#line 1070
+#line 1075
 	return NC_NOERR;
-#line 1070
+#line 1075
 }
-#line 1070
+#line 1075
 
 
 static int
@@ -3290,452 +3295,452 @@ ncx_put_int_uchar(void *xp, const uchar *ip, void *fillp)
 
 #if X_SIZEOF_INT != SIZEOF_INT
 static int
-#line 1104
+#line 1109
 ncx_put_int_int(void *xp, const int *ip, void *fillp)
-#line 1104
+#line 1109
 {
-#line 1104
+#line 1109
     int err=NC_NOERR;
-#line 1104
+#line 1109
 #if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
-#line 1104
+#line 1109
     put_ix_int(xp, (const ix_int *)ip);
-#line 1104
+#line 1109
 #else
-#line 1104
+#line 1109
     ix_int xx = NC_FILL_INT;
-#line 1104
+#line 1109
 
-#line 1104
+#line 1109
 #if IX_INT_MAX < INT_MAX
-#line 1104
+#line 1109
     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
-#line 1104
+#line 1109
         
-#line 1104
+#line 1109
 #ifdef ERANGE_FILL
-#line 1104
+#line 1109
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1104
+#line 1109
 #endif
-#line 1104
+#line 1109
         err = NC_ERANGE;
-#line 1104
+#line 1109
     }
-#line 1104
+#line 1109
 #ifdef ERANGE_FILL
-#line 1104
+#line 1109
     else
-#line 1104
+#line 1109
 #endif
-#line 1104
+#line 1109
 #endif
-#line 1104
+#line 1109
         xx = (ix_int)*ip;
-#line 1104
+#line 1109
 
-#line 1104
+#line 1109
     put_ix_int(xp, &xx);
-#line 1104
+#line 1109
 #endif
-#line 1104
+#line 1109
     return err;
-#line 1104
+#line 1109
 }
-#line 1104
+#line 1109
 
 #endif
 static int
-#line 1106
+#line 1111
 ncx_put_int_short(void *xp, const short *ip, void *fillp)
-#line 1106
+#line 1111
 {
-#line 1106
+#line 1111
     int err=NC_NOERR;
-#line 1106
+#line 1111
 #if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
-#line 1106
+#line 1111
     put_ix_int(xp, (const ix_int *)ip);
-#line 1106
+#line 1111
 #else
-#line 1106
+#line 1111
     ix_int xx = NC_FILL_INT;
-#line 1106
+#line 1111
 
-#line 1106
+#line 1111
 #if IX_INT_MAX < SHORT_MAX
-#line 1106
+#line 1111
     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
-#line 1106
+#line 1111
         
-#line 1106
+#line 1111
 #ifdef ERANGE_FILL
-#line 1106
+#line 1111
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1106
+#line 1111
 #endif
-#line 1106
+#line 1111
         err = NC_ERANGE;
-#line 1106
+#line 1111
     }
-#line 1106
+#line 1111
 #ifdef ERANGE_FILL
-#line 1106
+#line 1111
     else
-#line 1106
+#line 1111
 #endif
-#line 1106
+#line 1111
 #endif
-#line 1106
+#line 1111
         xx = (ix_int)*ip;
-#line 1106
+#line 1111
 
-#line 1106
+#line 1111
     put_ix_int(xp, &xx);
-#line 1106
+#line 1111
 #endif
-#line 1106
+#line 1111
     return err;
-#line 1106
+#line 1111
 }
-#line 1106
+#line 1111
 
 static int
-#line 1107
+#line 1112
 ncx_put_int_long(void *xp, const long *ip, void *fillp)
-#line 1107
+#line 1112
 {
-#line 1107
+#line 1112
     int err=NC_NOERR;
-#line 1107
+#line 1112
 #if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
-#line 1107
+#line 1112
     put_ix_int(xp, (const ix_int *)ip);
-#line 1107
+#line 1112
 #else
-#line 1107
+#line 1112
     ix_int xx = NC_FILL_INT;
-#line 1107
+#line 1112
 
-#line 1107
+#line 1112
 #if IX_INT_MAX < LONG_MAX
-#line 1107
+#line 1112
     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
-#line 1107
+#line 1112
         
-#line 1107
+#line 1112
 #ifdef ERANGE_FILL
-#line 1107
+#line 1112
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1107
+#line 1112
 #endif
-#line 1107
+#line 1112
         err = NC_ERANGE;
-#line 1107
+#line 1112
     }
-#line 1107
+#line 1112
 #ifdef ERANGE_FILL
-#line 1107
+#line 1112
     else
-#line 1107
+#line 1112
 #endif
-#line 1107
+#line 1112
 #endif
-#line 1107
+#line 1112
         xx = (ix_int)*ip;
-#line 1107
+#line 1112
 
-#line 1107
+#line 1112
     put_ix_int(xp, &xx);
-#line 1107
+#line 1112
 #endif
-#line 1107
+#line 1112
     return err;
-#line 1107
+#line 1112
 }
-#line 1107
+#line 1112
 
 static int
-#line 1108
+#line 1113
 ncx_put_int_longlong(void *xp, const longlong *ip, void *fillp)
-#line 1108
+#line 1113
 {
-#line 1108
+#line 1113
     int err=NC_NOERR;
-#line 1108
+#line 1113
 #if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
-#line 1108
+#line 1113
     put_ix_int(xp, (const ix_int *)ip);
-#line 1108
+#line 1113
 #else
-#line 1108
+#line 1113
     ix_int xx = NC_FILL_INT;
-#line 1108
+#line 1113
 
-#line 1108
+#line 1113
 #if IX_INT_MAX < LONGLONG_MAX
-#line 1108
+#line 1113
     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
-#line 1108
+#line 1113
         
-#line 1108
+#line 1113
 #ifdef ERANGE_FILL
-#line 1108
+#line 1113
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1108
+#line 1113
 #endif
-#line 1108
+#line 1113
         err = NC_ERANGE;
-#line 1108
+#line 1113
     }
-#line 1108
+#line 1113
 #ifdef ERANGE_FILL
-#line 1108
+#line 1113
     else
-#line 1108
+#line 1113
 #endif
-#line 1108
+#line 1113
 #endif
-#line 1108
+#line 1113
         xx = (ix_int)*ip;
-#line 1108
+#line 1113
 
-#line 1108
+#line 1113
     put_ix_int(xp, &xx);
-#line 1108
+#line 1113
 #endif
-#line 1108
+#line 1113
     return err;
-#line 1108
+#line 1113
 }
-#line 1108
+#line 1113
 
 static int
-#line 1109
+#line 1114
 ncx_put_int_ushort(void *xp, const ushort *ip, void *fillp)
-#line 1109
+#line 1114
 {
-#line 1109
+#line 1114
     int err=NC_NOERR;
-#line 1109
+#line 1114
     ix_int xx = NC_FILL_INT;
-#line 1109
+#line 1114
 
-#line 1109
+#line 1114
 #if IX_INT_MAX < USHORT_MAX
-#line 1109
+#line 1114
     if (*ip > IX_INT_MAX) {
-#line 1109
+#line 1114
         
-#line 1109
+#line 1114
 #ifdef ERANGE_FILL
-#line 1109
+#line 1114
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1109
+#line 1114
 #endif
-#line 1109
+#line 1114
         err = NC_ERANGE;
-#line 1109
+#line 1114
     }
-#line 1109
+#line 1114
 #ifdef ERANGE_FILL
-#line 1109
+#line 1114
     else
-#line 1109
+#line 1114
 #endif
-#line 1109
+#line 1114
 #endif
-#line 1109
+#line 1114
         xx = (ix_int)*ip;
-#line 1109
+#line 1114
 
-#line 1109
+#line 1114
     put_ix_int(xp, &xx);
-#line 1109
+#line 1114
     return err;
-#line 1109
+#line 1114
 }
-#line 1109
+#line 1114
 
 static int
-#line 1110
+#line 1115
 ncx_put_int_uint(void *xp, const uint *ip, void *fillp)
-#line 1110
+#line 1115
 {
-#line 1110
+#line 1115
     int err=NC_NOERR;
-#line 1110
+#line 1115
     ix_int xx = NC_FILL_INT;
-#line 1110
+#line 1115
 
-#line 1110
+#line 1115
 #if IX_INT_MAX < UINT_MAX
-#line 1110
+#line 1115
     if (*ip > IX_INT_MAX) {
-#line 1110
+#line 1115
         
-#line 1110
+#line 1115
 #ifdef ERANGE_FILL
-#line 1110
+#line 1115
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1110
+#line 1115
 #endif
-#line 1110
+#line 1115
         err = NC_ERANGE;
-#line 1110
+#line 1115
     }
-#line 1110
+#line 1115
 #ifdef ERANGE_FILL
-#line 1110
+#line 1115
     else
-#line 1110
+#line 1115
 #endif
-#line 1110
+#line 1115
 #endif
-#line 1110
+#line 1115
         xx = (ix_int)*ip;
-#line 1110
+#line 1115
 
-#line 1110
+#line 1115
     put_ix_int(xp, &xx);
-#line 1110
+#line 1115
     return err;
-#line 1110
+#line 1115
 }
-#line 1110
+#line 1115
 
 static int
-#line 1111
+#line 1116
 ncx_put_int_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 1111
+#line 1116
 {
-#line 1111
+#line 1116
     int err=NC_NOERR;
-#line 1111
+#line 1116
     ix_int xx = NC_FILL_INT;
-#line 1111
+#line 1116
 
-#line 1111
+#line 1116
 #if IX_INT_MAX < ULONGLONG_MAX
-#line 1111
+#line 1116
     if (*ip > IX_INT_MAX) {
-#line 1111
+#line 1116
         
-#line 1111
+#line 1116
 #ifdef ERANGE_FILL
-#line 1111
+#line 1116
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1111
+#line 1116
 #endif
-#line 1111
+#line 1116
         err = NC_ERANGE;
-#line 1111
+#line 1116
     }
-#line 1111
+#line 1116
 #ifdef ERANGE_FILL
-#line 1111
+#line 1116
     else
-#line 1111
+#line 1116
 #endif
-#line 1111
+#line 1116
 #endif
-#line 1111
+#line 1116
         xx = (ix_int)*ip;
-#line 1111
+#line 1116
 
-#line 1111
+#line 1116
     put_ix_int(xp, &xx);
-#line 1111
+#line 1116
     return err;
-#line 1111
+#line 1116
 }
-#line 1111
+#line 1116
 
 static int
-#line 1112
+#line 1117
 ncx_put_int_float(void *xp, const float *ip, void *fillp)
-#line 1112
+#line 1117
 {
-#line 1112
+#line 1117
     int err=NC_NOERR;
-#line 1112
+#line 1117
     ix_int xx = NC_FILL_INT;
-#line 1112
+#line 1117
 
-#line 1112
+#line 1117
     if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
-#line 1112
+#line 1117
         
-#line 1112
+#line 1117
 #ifdef ERANGE_FILL
-#line 1112
+#line 1117
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1112
+#line 1117
 #endif
-#line 1112
+#line 1117
         err = NC_ERANGE;
-#line 1112
+#line 1117
     }
-#line 1112
+#line 1117
 #ifdef ERANGE_FILL
-#line 1112
+#line 1117
     else
-#line 1112
+#line 1117
 #endif
-#line 1112
+#line 1117
         xx = (ix_int)*ip;
-#line 1112
+#line 1117
 
-#line 1112
+#line 1117
     put_ix_int(xp, &xx);
-#line 1112
+#line 1117
     return err;
-#line 1112
+#line 1117
 }
-#line 1112
+#line 1117
 
 static int
-#line 1113
+#line 1118
 ncx_put_int_double(void *xp, const double *ip, void *fillp)
-#line 1113
+#line 1118
 {
-#line 1113
+#line 1118
     int err=NC_NOERR;
-#line 1113
+#line 1118
     ix_int xx = NC_FILL_INT;
-#line 1113
+#line 1118
 
-#line 1113
+#line 1118
     if (*ip > X_INT_MAX || *ip < X_INT_MIN) {
-#line 1113
+#line 1118
         
-#line 1113
+#line 1118
 #ifdef ERANGE_FILL
-#line 1113
+#line 1118
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1113
+#line 1118
 #endif
-#line 1113
+#line 1118
         err = NC_ERANGE;
-#line 1113
+#line 1118
     }
-#line 1113
+#line 1118
 #ifdef ERANGE_FILL
-#line 1113
+#line 1118
     else
-#line 1113
+#line 1118
 #endif
-#line 1113
+#line 1118
         xx = (ix_int)*ip;
-#line 1113
+#line 1118
 
-#line 1113
+#line 1118
     put_ix_int(xp, &xx);
-#line 1113
+#line 1118
     return err;
-#line 1113
+#line 1118
 }
-#line 1113
+#line 1118
 
 
 
@@ -3782,477 +3787,477 @@ put_ix_uint(void *xp, const ix_uint *ip)
 
 #if X_SIZEOF_UINT != SIZEOF_UINT
 static int
-#line 1158
+#line 1163
 ncx_get_uint_uint(const void *xp, uint *ip)
-#line 1158
+#line 1163
 {
-#line 1158
+#line 1163
     int err=NC_NOERR;
-#line 1158
+#line 1163
 #if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
-#line 1158
+#line 1163
     get_ix_uint(xp, (ix_uint *)ip);
-#line 1158
+#line 1163
 #else
-#line 1158
+#line 1163
     ix_uint xx;
-#line 1158
+#line 1163
     get_ix_uint(xp, &xx);
-#line 1158
+#line 1163
 
-#line 1158
+#line 1163
 #if IX_UINT_MAX > UINT_MAX
-#line 1158
+#line 1163
     if (xx > UINT_MAX) {
-#line 1158
+#line 1163
 #ifdef ERANGE_FILL
-#line 1158
+#line 1163
         *ip = NC_FILL_UINT;
-#line 1158
+#line 1163
         return NC_ERANGE;
-#line 1158
+#line 1163
 #else
-#line 1158
+#line 1163
         err = NC_ERANGE;
-#line 1158
+#line 1163
 #endif
-#line 1158
+#line 1163
     }
-#line 1158
+#line 1163
 #endif
-#line 1158
+#line 1163
 
-#line 1158
+#line 1163
 
-#line 1158
+#line 1163
     *ip = (uint) xx;
-#line 1158
+#line 1163
 #endif
-#line 1158
+#line 1163
     return err;
-#line 1158
+#line 1163
 }
-#line 1158
+#line 1163
 
 #endif
 
 static int
-#line 1161
+#line 1166
 ncx_get_uint_schar(const void *xp, schar *ip)
-#line 1161
+#line 1166
 {
-#line 1161
+#line 1166
     int err=NC_NOERR;
-#line 1161
+#line 1166
     ix_uint xx;
-#line 1161
+#line 1166
     get_ix_uint(xp, &xx);
-#line 1161
+#line 1166
 
-#line 1161
+#line 1166
 #if IX_UINT_MAX > SCHAR_MAX
-#line 1161
+#line 1166
     if (xx > SCHAR_MAX) {
-#line 1161
+#line 1166
 #ifdef ERANGE_FILL
-#line 1161
+#line 1166
         *ip = NC_FILL_BYTE;
-#line 1161
+#line 1166
         return NC_ERANGE;
-#line 1161
+#line 1166
 #else
-#line 1161
+#line 1166
         err = NC_ERANGE;
-#line 1161
+#line 1166
 #endif
-#line 1161
+#line 1166
     }
-#line 1161
+#line 1166
 #endif
-#line 1161
+#line 1166
 
-#line 1161
+#line 1166
 
-#line 1161
+#line 1166
     *ip = (schar) xx;
-#line 1161
+#line 1166
     return err;
-#line 1161
+#line 1166
 }
-#line 1161
+#line 1166
 
 static int
-#line 1162
+#line 1167
 ncx_get_uint_short(const void *xp, short *ip)
-#line 1162
+#line 1167
 {
-#line 1162
+#line 1167
     int err=NC_NOERR;
-#line 1162
+#line 1167
     ix_uint xx;
-#line 1162
+#line 1167
     get_ix_uint(xp, &xx);
-#line 1162
+#line 1167
 
-#line 1162
+#line 1167
 #if IX_UINT_MAX > SHORT_MAX
-#line 1162
+#line 1167
     if (xx > SHORT_MAX) {
-#line 1162
+#line 1167
 #ifdef ERANGE_FILL
-#line 1162
+#line 1167
         *ip = NC_FILL_SHORT;
-#line 1162
+#line 1167
         return NC_ERANGE;
-#line 1162
+#line 1167
 #else
-#line 1162
+#line 1167
         err = NC_ERANGE;
-#line 1162
+#line 1167
 #endif
-#line 1162
+#line 1167
     }
-#line 1162
+#line 1167
 #endif
-#line 1162
+#line 1167
 
-#line 1162
+#line 1167
 
-#line 1162
+#line 1167
     *ip = (short) xx;
-#line 1162
+#line 1167
     return err;
-#line 1162
+#line 1167
 }
-#line 1162
+#line 1167
 
 static int
-#line 1163
+#line 1168
 ncx_get_uint_int(const void *xp, int *ip)
-#line 1163
+#line 1168
 {
-#line 1163
+#line 1168
     int err=NC_NOERR;
-#line 1163
+#line 1168
     ix_uint xx;
-#line 1163
+#line 1168
     get_ix_uint(xp, &xx);
-#line 1163
+#line 1168
 
-#line 1163
+#line 1168
 #if IX_UINT_MAX > INT_MAX
-#line 1163
+#line 1168
     if (xx > INT_MAX) {
-#line 1163
+#line 1168
 #ifdef ERANGE_FILL
-#line 1163
+#line 1168
         *ip = NC_FILL_INT;
-#line 1163
+#line 1168
         return NC_ERANGE;
-#line 1163
+#line 1168
 #else
-#line 1163
+#line 1168
         err = NC_ERANGE;
-#line 1163
+#line 1168
 #endif
-#line 1163
+#line 1168
     }
-#line 1163
+#line 1168
 #endif
-#line 1163
+#line 1168
 
-#line 1163
+#line 1168
 
-#line 1163
+#line 1168
     *ip = (int) xx;
-#line 1163
+#line 1168
     return err;
-#line 1163
+#line 1168
 }
-#line 1163
+#line 1168
 
 static int
-#line 1164
+#line 1169
 ncx_get_uint_long(const void *xp, long *ip)
-#line 1164
+#line 1169
 {
-#line 1164
+#line 1169
     int err=NC_NOERR;
-#line 1164
+#line 1169
     ix_uint xx;
-#line 1164
+#line 1169
     get_ix_uint(xp, &xx);
-#line 1164
+#line 1169
 
-#line 1164
+#line 1169
 #if IX_UINT_MAX > LONG_MAX
-#line 1164
+#line 1169
     if (xx > LONG_MAX) {
-#line 1164
+#line 1169
 #ifdef ERANGE_FILL
-#line 1164
+#line 1169
         *ip = NC_FILL_INT;
-#line 1164
+#line 1169
         return NC_ERANGE;
-#line 1164
+#line 1169
 #else
-#line 1164
+#line 1169
         err = NC_ERANGE;
-#line 1164
+#line 1169
 #endif
-#line 1164
+#line 1169
     }
-#line 1164
+#line 1169
 #endif
-#line 1164
+#line 1169
 
-#line 1164
+#line 1169
 
-#line 1164
+#line 1169
     *ip = (long) xx;
-#line 1164
+#line 1169
     return err;
-#line 1164
+#line 1169
 }
-#line 1164
+#line 1169
 
 static int
-#line 1165
+#line 1170
 ncx_get_uint_longlong(const void *xp, longlong *ip)
-#line 1165
+#line 1170
 {
-#line 1165
+#line 1170
     int err=NC_NOERR;
-#line 1165
+#line 1170
     ix_uint xx;
-#line 1165
+#line 1170
     get_ix_uint(xp, &xx);
-#line 1165
+#line 1170
 
-#line 1165
+#line 1170
 #if IX_UINT_MAX > LONGLONG_MAX
-#line 1165
+#line 1170
     if (xx > LONGLONG_MAX) {
-#line 1165
+#line 1170
 #ifdef ERANGE_FILL
-#line 1165
+#line 1170
         *ip = NC_FILL_INT64;
-#line 1165
+#line 1170
         return NC_ERANGE;
-#line 1165
+#line 1170
 #else
-#line 1165
+#line 1170
         err = NC_ERANGE;
-#line 1165
+#line 1170
 #endif
-#line 1165
+#line 1170
     }
-#line 1165
+#line 1170
 #endif
-#line 1165
+#line 1170
 
-#line 1165
+#line 1170
 
-#line 1165
+#line 1170
     *ip = (longlong) xx;
-#line 1165
+#line 1170
     return err;
-#line 1165
+#line 1170
 }
-#line 1165
+#line 1170
 
 static int
-#line 1166
+#line 1171
 ncx_get_uint_ushort(const void *xp, ushort *ip)
-#line 1166
+#line 1171
 {
-#line 1166
+#line 1171
     int err=NC_NOERR;
-#line 1166
+#line 1171
 #if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
-#line 1166
+#line 1171
     get_ix_uint(xp, (ix_uint *)ip);
-#line 1166
+#line 1171
 #else
-#line 1166
+#line 1171
     ix_uint xx;
-#line 1166
+#line 1171
     get_ix_uint(xp, &xx);
-#line 1166
+#line 1171
 
-#line 1166
+#line 1171
 #if IX_UINT_MAX > USHORT_MAX
-#line 1166
+#line 1171
     if (xx > USHORT_MAX) {
-#line 1166
+#line 1171
 #ifdef ERANGE_FILL
-#line 1166
+#line 1171
         *ip = NC_FILL_USHORT;
-#line 1166
+#line 1171
         return NC_ERANGE;
-#line 1166
+#line 1171
 #else
-#line 1166
+#line 1171
         err = NC_ERANGE;
-#line 1166
+#line 1171
 #endif
-#line 1166
+#line 1171
     }
-#line 1166
+#line 1171
 #endif
-#line 1166
+#line 1171
 
-#line 1166
+#line 1171
 
-#line 1166
+#line 1171
     *ip = (ushort) xx;
-#line 1166
+#line 1171
 #endif
-#line 1166
+#line 1171
     return err;
-#line 1166
+#line 1171
 }
-#line 1166
+#line 1171
 
 static int
-#line 1167
+#line 1172
 ncx_get_uint_uchar(const void *xp, uchar *ip)
-#line 1167
+#line 1172
 {
-#line 1167
+#line 1172
     int err=NC_NOERR;
-#line 1167
+#line 1172
 #if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
-#line 1167
+#line 1172
     get_ix_uint(xp, (ix_uint *)ip);
-#line 1167
+#line 1172
 #else
-#line 1167
+#line 1172
     ix_uint xx;
-#line 1167
+#line 1172
     get_ix_uint(xp, &xx);
-#line 1167
+#line 1172
 
-#line 1167
+#line 1172
 #if IX_UINT_MAX > UCHAR_MAX
-#line 1167
+#line 1172
     if (xx > UCHAR_MAX) {
-#line 1167
+#line 1172
 #ifdef ERANGE_FILL
-#line 1167
+#line 1172
         *ip = NC_FILL_UBYTE;
-#line 1167
+#line 1172
         return NC_ERANGE;
-#line 1167
+#line 1172
 #else
-#line 1167
+#line 1172
         err = NC_ERANGE;
-#line 1167
+#line 1172
 #endif
-#line 1167
+#line 1172
     }
-#line 1167
+#line 1172
 #endif
-#line 1167
+#line 1172
 
-#line 1167
+#line 1172
 
-#line 1167
+#line 1172
     *ip = (uchar) xx;
-#line 1167
+#line 1172
 #endif
-#line 1167
+#line 1172
     return err;
-#line 1167
+#line 1172
 }
-#line 1167
+#line 1172
 
 static int
-#line 1168
+#line 1173
 ncx_get_uint_ulonglong(const void *xp, ulonglong *ip)
-#line 1168
+#line 1173
 {
-#line 1168
+#line 1173
     int err=NC_NOERR;
-#line 1168
+#line 1173
 #if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
-#line 1168
+#line 1173
     get_ix_uint(xp, (ix_uint *)ip);
-#line 1168
+#line 1173
 #else
-#line 1168
+#line 1173
     ix_uint xx;
-#line 1168
+#line 1173
     get_ix_uint(xp, &xx);
-#line 1168
+#line 1173
 
-#line 1168
+#line 1173
 #if IX_UINT_MAX > ULONGLONG_MAX
-#line 1168
+#line 1173
     if (xx > ULONGLONG_MAX) {
-#line 1168
+#line 1173
 #ifdef ERANGE_FILL
-#line 1168
+#line 1173
         *ip = NC_FILL_UINT64;
-#line 1168
+#line 1173
         return NC_ERANGE;
-#line 1168
+#line 1173
 #else
-#line 1168
+#line 1173
         err = NC_ERANGE;
-#line 1168
+#line 1173
 #endif
-#line 1168
+#line 1173
     }
-#line 1168
+#line 1173
 #endif
-#line 1168
+#line 1173
 
-#line 1168
+#line 1173
 
-#line 1168
+#line 1173
     *ip = (ulonglong) xx;
-#line 1168
+#line 1173
 #endif
-#line 1168
+#line 1173
     return err;
-#line 1168
+#line 1173
 }
-#line 1168
+#line 1173
 
 static int
-#line 1169
+#line 1174
 ncx_get_uint_float(const void *xp, float *ip)
-#line 1169
+#line 1174
 {
-#line 1169
+#line 1174
 	ix_uint xx;
-#line 1169
+#line 1174
 	get_ix_uint(xp, &xx);
-#line 1169
+#line 1174
 	*ip = (float)xx;
-#line 1169
+#line 1174
 	return NC_NOERR;
-#line 1169
+#line 1174
 }
-#line 1169
+#line 1174
 
 static int
-#line 1170
+#line 1175
 ncx_get_uint_double(const void *xp, double *ip)
-#line 1170
+#line 1175
 {
-#line 1170
+#line 1175
 	ix_uint xx;
-#line 1170
+#line 1175
 	get_ix_uint(xp, &xx);
-#line 1170
+#line 1175
 	*ip = (double)xx;
-#line 1170
+#line 1175
 	return NC_NOERR;
-#line 1170
+#line 1175
 }
-#line 1170
+#line 1175
 
 
 static int
@@ -4291,525 +4296,525 @@ ncx_put_uint_uchar(void *xp, const uchar *ip, void *fillp)
 
 #if X_SIZEOF_UINT != SIZEOF_UINT
 static int
-#line 1207
+#line 1212
 ncx_put_uint_uint(void *xp, const uint *ip, void *fillp)
-#line 1207
+#line 1212
 {
-#line 1207
+#line 1212
     int err=NC_NOERR;
-#line 1207
+#line 1212
 #if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
-#line 1207
+#line 1212
     put_ix_uint(xp, (const ix_uint *)ip);
-#line 1207
+#line 1212
 #else
-#line 1207
+#line 1212
     ix_uint xx = NC_FILL_UINT;
-#line 1207
+#line 1212
 
-#line 1207
+#line 1212
 #if IX_UINT_MAX < UINT_MAX
-#line 1207
+#line 1212
     if (*ip > IX_UINT_MAX) {
-#line 1207
+#line 1212
         
-#line 1207
+#line 1212
 #ifdef ERANGE_FILL
-#line 1207
+#line 1212
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1207
+#line 1212
 #endif
-#line 1207
+#line 1212
         err = NC_ERANGE;
-#line 1207
+#line 1212
     }
-#line 1207
+#line 1212
 #ifdef ERANGE_FILL
-#line 1207
+#line 1212
     else
-#line 1207
+#line 1212
 #endif
-#line 1207
+#line 1212
 #endif
-#line 1207
+#line 1212
         xx = (ix_uint)*ip;
-#line 1207
+#line 1212
 
-#line 1207
+#line 1212
     put_ix_uint(xp, &xx);
-#line 1207
+#line 1212
 #endif
-#line 1207
+#line 1212
     return err;
-#line 1207
+#line 1212
 }
-#line 1207
+#line 1212
 
 #endif
 
 static int
-#line 1210
+#line 1215
 ncx_put_uint_short(void *xp, const short *ip, void *fillp)
-#line 1210
+#line 1215
 {
-#line 1210
+#line 1215
     int err=NC_NOERR;
-#line 1210
+#line 1215
     ix_uint xx = NC_FILL_UINT;
-#line 1210
+#line 1215
 
-#line 1210
+#line 1215
 #if IX_UINT_MAX < SHORT_MAX
-#line 1210
+#line 1215
     if (*ip > IX_UINT_MAX) {
-#line 1210
+#line 1215
         
-#line 1210
+#line 1215
 #ifdef ERANGE_FILL
-#line 1210
+#line 1215
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1210
+#line 1215
 #endif
-#line 1210
+#line 1215
         err = NC_ERANGE;
-#line 1210
+#line 1215
     }
-#line 1210
+#line 1215
 #ifdef ERANGE_FILL
-#line 1210
+#line 1215
     else
-#line 1210
+#line 1215
 #endif
-#line 1210
+#line 1215
 #endif
-#line 1210
+#line 1215
     if (*ip < 0) {
-#line 1210
+#line 1215
         
-#line 1210
+#line 1215
 #ifdef ERANGE_FILL
-#line 1210
+#line 1215
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1210
+#line 1215
 #endif
-#line 1210
+#line 1215
         err = NC_ERANGE; /* because xp is unsigned */
-#line 1210
+#line 1215
     }
-#line 1210
+#line 1215
 #ifdef ERANGE_FILL
-#line 1210
+#line 1215
     else
-#line 1210
+#line 1215
 #endif
-#line 1210
+#line 1215
         xx = (ix_uint)*ip;
-#line 1210
+#line 1215
 
-#line 1210
+#line 1215
     put_ix_uint(xp, &xx);
-#line 1210
+#line 1215
     return err;
-#line 1210
+#line 1215
 }
-#line 1210
+#line 1215
 
 static int
-#line 1211
+#line 1216
 ncx_put_uint_int(void *xp, const int *ip, void *fillp)
-#line 1211
+#line 1216
 {
-#line 1211
+#line 1216
     int err=NC_NOERR;
-#line 1211
+#line 1216
     ix_uint xx = NC_FILL_UINT;
-#line 1211
+#line 1216
 
-#line 1211
+#line 1216
 #if IX_UINT_MAX < INT_MAX
-#line 1211
+#line 1216
     if (*ip > IX_UINT_MAX) {
-#line 1211
+#line 1216
         
-#line 1211
+#line 1216
 #ifdef ERANGE_FILL
-#line 1211
+#line 1216
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1211
+#line 1216
 #endif
-#line 1211
+#line 1216
         err = NC_ERANGE;
-#line 1211
+#line 1216
     }
-#line 1211
+#line 1216
 #ifdef ERANGE_FILL
-#line 1211
+#line 1216
     else
-#line 1211
+#line 1216
 #endif
-#line 1211
+#line 1216
 #endif
-#line 1211
+#line 1216
     if (*ip < 0) {
-#line 1211
+#line 1216
         
-#line 1211
+#line 1216
 #ifdef ERANGE_FILL
-#line 1211
+#line 1216
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1211
+#line 1216
 #endif
-#line 1211
+#line 1216
         err = NC_ERANGE; /* because xp is unsigned */
-#line 1211
+#line 1216
     }
-#line 1211
+#line 1216
 #ifdef ERANGE_FILL
-#line 1211
+#line 1216
     else
-#line 1211
+#line 1216
 #endif
-#line 1211
+#line 1216
         xx = (ix_uint)*ip;
-#line 1211
+#line 1216
 
-#line 1211
+#line 1216
     put_ix_uint(xp, &xx);
-#line 1211
+#line 1216
     return err;
-#line 1211
+#line 1216
 }
-#line 1211
+#line 1216
 
 static int
-#line 1212
+#line 1217
 ncx_put_uint_long(void *xp, const long *ip, void *fillp)
-#line 1212
+#line 1217
 {
-#line 1212
+#line 1217
     int err=NC_NOERR;
-#line 1212
+#line 1217
     ix_uint xx = NC_FILL_UINT;
-#line 1212
+#line 1217
 
-#line 1212
+#line 1217
 #if IX_UINT_MAX < LONG_MAX
-#line 1212
+#line 1217
     if (*ip > IX_UINT_MAX) {
-#line 1212
+#line 1217
         
-#line 1212
+#line 1217
 #ifdef ERANGE_FILL
-#line 1212
+#line 1217
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1212
+#line 1217
 #endif
-#line 1212
+#line 1217
         err = NC_ERANGE;
-#line 1212
+#line 1217
     }
-#line 1212
+#line 1217
 #ifdef ERANGE_FILL
-#line 1212
+#line 1217
     else
-#line 1212
+#line 1217
 #endif
-#line 1212
+#line 1217
 #endif
-#line 1212
+#line 1217
     if (*ip < 0) {
-#line 1212
+#line 1217
         
-#line 1212
+#line 1217
 #ifdef ERANGE_FILL
-#line 1212
+#line 1217
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1212
+#line 1217
 #endif
-#line 1212
+#line 1217
         err = NC_ERANGE; /* because xp is unsigned */
-#line 1212
+#line 1217
     }
-#line 1212
+#line 1217
 #ifdef ERANGE_FILL
-#line 1212
+#line 1217
     else
-#line 1212
+#line 1217
 #endif
-#line 1212
+#line 1217
         xx = (ix_uint)*ip;
-#line 1212
+#line 1217
 
-#line 1212
+#line 1217
     put_ix_uint(xp, &xx);
-#line 1212
+#line 1217
     return err;
-#line 1212
+#line 1217
 }
-#line 1212
+#line 1217
 
 static int
-#line 1213
+#line 1218
 ncx_put_uint_longlong(void *xp, const longlong *ip, void *fillp)
-#line 1213
+#line 1218
 {
-#line 1213
+#line 1218
     int err=NC_NOERR;
-#line 1213
+#line 1218
     ix_uint xx = NC_FILL_UINT;
-#line 1213
+#line 1218
 
-#line 1213
+#line 1218
 #if IX_UINT_MAX < LONGLONG_MAX
-#line 1213
+#line 1218
     if (*ip > IX_UINT_MAX) {
-#line 1213
+#line 1218
         
-#line 1213
+#line 1218
 #ifdef ERANGE_FILL
-#line 1213
+#line 1218
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1213
+#line 1218
 #endif
-#line 1213
+#line 1218
         err = NC_ERANGE;
-#line 1213
+#line 1218
     }
-#line 1213
+#line 1218
 #ifdef ERANGE_FILL
-#line 1213
+#line 1218
     else
-#line 1213
+#line 1218
 #endif
-#line 1213
+#line 1218
 #endif
-#line 1213
+#line 1218
     if (*ip < 0) {
-#line 1213
+#line 1218
         
-#line 1213
+#line 1218
 #ifdef ERANGE_FILL
-#line 1213
+#line 1218
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1213
+#line 1218
 #endif
-#line 1213
+#line 1218
         err = NC_ERANGE; /* because xp is unsigned */
-#line 1213
+#line 1218
     }
-#line 1213
+#line 1218
 #ifdef ERANGE_FILL
-#line 1213
+#line 1218
     else
-#line 1213
+#line 1218
 #endif
-#line 1213
+#line 1218
         xx = (ix_uint)*ip;
-#line 1213
+#line 1218
 
-#line 1213
+#line 1218
     put_ix_uint(xp, &xx);
-#line 1213
+#line 1218
     return err;
-#line 1213
+#line 1218
 }
-#line 1213
+#line 1218
 
 static int
-#line 1214
+#line 1219
 ncx_put_uint_ushort(void *xp, const ushort *ip, void *fillp)
-#line 1214
+#line 1219
 {
-#line 1214
+#line 1219
     int err=NC_NOERR;
-#line 1214
+#line 1219
 #if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
-#line 1214
+#line 1219
     put_ix_uint(xp, (const ix_uint *)ip);
-#line 1214
+#line 1219
 #else
-#line 1214
+#line 1219
     ix_uint xx = NC_FILL_UINT;
-#line 1214
+#line 1219
 
-#line 1214
+#line 1219
 #if IX_UINT_MAX < USHORT_MAX
-#line 1214
+#line 1219
     if (*ip > IX_UINT_MAX) {
-#line 1214
+#line 1219
         
-#line 1214
+#line 1219
 #ifdef ERANGE_FILL
-#line 1214
+#line 1219
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1214
+#line 1219
 #endif
-#line 1214
+#line 1219
         err = NC_ERANGE;
-#line 1214
+#line 1219
     }
-#line 1214
+#line 1219
 #ifdef ERANGE_FILL
-#line 1214
+#line 1219
     else
-#line 1214
+#line 1219
 #endif
-#line 1214
+#line 1219
 #endif
-#line 1214
+#line 1219
         xx = (ix_uint)*ip;
-#line 1214
+#line 1219
 
-#line 1214
+#line 1219
     put_ix_uint(xp, &xx);
-#line 1214
+#line 1219
 #endif
-#line 1214
+#line 1219
     return err;
-#line 1214
+#line 1219
 }
-#line 1214
+#line 1219
 
 static int
-#line 1215
+#line 1220
 ncx_put_uint_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 1215
+#line 1220
 {
-#line 1215
+#line 1220
     int err=NC_NOERR;
-#line 1215
+#line 1220
 #if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
-#line 1215
+#line 1220
     put_ix_uint(xp, (const ix_uint *)ip);
-#line 1215
+#line 1220
 #else
-#line 1215
+#line 1220
     ix_uint xx = NC_FILL_UINT;
-#line 1215
+#line 1220
 
-#line 1215
+#line 1220
 #if IX_UINT_MAX < ULONGLONG_MAX
-#line 1215
+#line 1220
     if (*ip > IX_UINT_MAX) {
-#line 1215
+#line 1220
         
-#line 1215
+#line 1220
 #ifdef ERANGE_FILL
-#line 1215
+#line 1220
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1215
+#line 1220
 #endif
-#line 1215
+#line 1220
         err = NC_ERANGE;
-#line 1215
+#line 1220
     }
-#line 1215
+#line 1220
 #ifdef ERANGE_FILL
-#line 1215
+#line 1220
     else
-#line 1215
+#line 1220
 #endif
-#line 1215
+#line 1220
 #endif
-#line 1215
+#line 1220
         xx = (ix_uint)*ip;
-#line 1215
+#line 1220
 
-#line 1215
+#line 1220
     put_ix_uint(xp, &xx);
-#line 1215
+#line 1220
 #endif
-#line 1215
+#line 1220
     return err;
-#line 1215
+#line 1220
 }
-#line 1215
+#line 1220
 
 static int
-#line 1216
+#line 1221
 ncx_put_uint_float(void *xp, const float *ip, void *fillp)
-#line 1216
+#line 1221
 {
-#line 1216
+#line 1221
     int err=NC_NOERR;
-#line 1216
+#line 1221
     ix_uint xx = NC_FILL_UINT;
-#line 1216
+#line 1221
 
-#line 1216
+#line 1221
     if (*ip > (double)X_UINT_MAX || *ip < 0) {
-#line 1216
+#line 1221
         
-#line 1216
+#line 1221
 #ifdef ERANGE_FILL
-#line 1216
+#line 1221
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1216
+#line 1221
 #endif
-#line 1216
+#line 1221
         err = NC_ERANGE;
-#line 1216
+#line 1221
     }
-#line 1216
+#line 1221
 #ifdef ERANGE_FILL
-#line 1216
+#line 1221
     else
-#line 1216
+#line 1221
 #endif
-#line 1216
+#line 1221
         xx = (ix_uint)*ip;
-#line 1216
+#line 1221
 
-#line 1216
+#line 1221
     put_ix_uint(xp, &xx);
-#line 1216
+#line 1221
     return err;
-#line 1216
+#line 1221
 }
-#line 1216
+#line 1221
 
 static int
-#line 1217
+#line 1222
 ncx_put_uint_double(void *xp, const double *ip, void *fillp)
-#line 1217
+#line 1222
 {
-#line 1217
+#line 1222
     int err=NC_NOERR;
-#line 1217
+#line 1222
     ix_uint xx = NC_FILL_UINT;
-#line 1217
+#line 1222
 
-#line 1217
+#line 1222
     if (*ip > X_UINT_MAX || *ip < 0) {
-#line 1217
+#line 1222
         
-#line 1217
+#line 1222
 #ifdef ERANGE_FILL
-#line 1217
+#line 1222
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1217
+#line 1222
 #endif
-#line 1217
+#line 1222
         err = NC_ERANGE;
-#line 1217
+#line 1222
     }
-#line 1217
+#line 1222
 #ifdef ERANGE_FILL
-#line 1217
+#line 1222
     else
-#line 1217
+#line 1222
 #endif
-#line 1217
+#line 1222
         xx = (ix_uint)*ip;
-#line 1217
+#line 1222
 
-#line 1217
+#line 1222
     put_ix_uint(xp, &xx);
-#line 1217
+#line 1222
     return err;
-#line 1217
+#line 1222
 }
-#line 1217
+#line 1222
 
 
 
@@ -4872,196 +4877,196 @@ static struct sgl_limits min = {
 	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }		/* Min IEEE */
 };
 
-#line 1331
+#line 1336
 static void
 get_ix_float(const void *xp, float *ip)
 {
 		struct vax_single *const vsp = (struct vax_single *) ip;
-#line 1334
+#line 1339
 		const struct ieee_single *const isp =
-#line 1334
+#line 1339
 			 (const struct ieee_single *) xp;
-#line 1334
+#line 1339
 		unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
-#line 1334
+#line 1339
 
-#line 1334
+#line 1339
 		switch(exp) {
-#line 1334
+#line 1339
 		case 0 :
-#line 1334
+#line 1339
 			/* ieee subnormal */
-#line 1334
+#line 1339
 			if (isp->mant_hi == min.ieee.mant_hi
-#line 1334
+#line 1339
 				&& isp->mant_lo_hi == min.ieee.mant_lo_hi
-#line 1334
+#line 1339
 				&& isp->mant_lo_lo == min.ieee.mant_lo_lo)
-#line 1334
+#line 1339
 			{
-#line 1334
+#line 1339
 				*vsp = min.s;
-#line 1334
+#line 1339
 			}
-#line 1334
+#line 1339
 			else
-#line 1334
+#line 1339
 			{
-#line 1334
+#line 1339
 				unsigned mantissa = (isp->mant_hi << 16)
-#line 1334
+#line 1339
 					 | isp->mant_lo_hi << 8
-#line 1334
+#line 1339
 					 | isp->mant_lo_lo;
-#line 1334
+#line 1339
 				unsigned tmp = mantissa >> 20;
-#line 1334
+#line 1339
 				if (tmp >= 4) {
-#line 1334
+#line 1339
 					vsp->exp = 2;
-#line 1334
+#line 1339
 				} else if (tmp >= 2) {
-#line 1334
+#line 1339
 					vsp->exp = 1;
-#line 1334
+#line 1339
 				} else {
-#line 1334
+#line 1339
 					*vsp = min.s;
-#line 1334
+#line 1339
 					break;
-#line 1334
+#line 1339
 				} /* else */
-#line 1334
+#line 1339
 				tmp = mantissa - (1 << (20 + vsp->exp ));
-#line 1334
+#line 1339
 				tmp <<= 3 - vsp->exp;
-#line 1334
+#line 1339
 				vsp->mantissa2 = tmp;
-#line 1334
+#line 1339
 				vsp->mantissa1 = (tmp >> 16);
-#line 1334
+#line 1339
 			}
-#line 1334
+#line 1339
 			break;
-#line 1334
+#line 1339
 		case 0xfe :
-#line 1334
+#line 1339
 		case 0xff :
-#line 1334
+#line 1339
 			*vsp = max.s;
-#line 1334
+#line 1339
 			break;
-#line 1334
+#line 1339
 		default :
-#line 1334
+#line 1339
 			vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
-#line 1334
+#line 1339
 			vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
-#line 1334
+#line 1339
 			vsp->mantissa1 = isp->mant_hi;
-#line 1334
+#line 1339
 		}
-#line 1334
+#line 1339
 
-#line 1334
+#line 1339
 		vsp->sign = isp->sign;
-#line 1334
+#line 1339
 
 }
 
-#line 1388
+#line 1393
 
 static void
 put_ix_float(void *xp, const float *ip)
 {
 		const struct vax_single *const vsp =
-#line 1392
+#line 1397
 			 (const struct vax_single *)ip;
-#line 1392
+#line 1397
 		struct ieee_single *const isp = (struct ieee_single *) xp;
-#line 1392
+#line 1397
 
-#line 1392
+#line 1397
 		switch(vsp->exp){
-#line 1392
+#line 1397
 		case 0 :
-#line 1392
+#line 1397
 			/* all vax float with zero exponent map to zero */
-#line 1392
+#line 1397
 			*isp = min.ieee;
-#line 1392
+#line 1397
 			break;
-#line 1392
+#line 1397
 		case 2 :
-#line 1392
+#line 1397
 		case 1 :
-#line 1392
+#line 1397
 		{
-#line 1392
+#line 1397
 			/* These will map to subnormals */
-#line 1392
+#line 1397
 			unsigned mantissa = (vsp->mantissa1 << 16)
-#line 1392
+#line 1397
 					 | vsp->mantissa2;
-#line 1392
+#line 1397
 			mantissa >>= 3 - vsp->exp;
-#line 1392
+#line 1397
 			mantissa += (1 << (20 + vsp->exp));
-#line 1392
+#line 1397
 			isp->mant_lo_lo = mantissa;
-#line 1392
+#line 1397
 			isp->mant_lo_hi = mantissa >> 8;
-#line 1392
+#line 1397
 			isp->mant_hi = mantissa >> 16;
-#line 1392
+#line 1397
 			isp->exp_lo = 0;
-#line 1392
+#line 1397
 			isp->exp_hi = 0;
-#line 1392
+#line 1397
 		}
-#line 1392
+#line 1397
 			break;
-#line 1392
+#line 1397
 		case 0xff : /* max.s.exp */
-#line 1392
+#line 1397
 			if (vsp->mantissa2 == max.s.mantissa2 &&
-#line 1392
+#line 1397
 			    vsp->mantissa1 == max.s.mantissa1)
-#line 1392
+#line 1397
 			{
-#line 1392
+#line 1397
 				/* map largest vax float to ieee infinity */
-#line 1392
+#line 1397
 				*isp = max.ieee;
-#line 1392
+#line 1397
 				break;
-#line 1392
+#line 1397
 			} /* else, fall thru */
-#line 1392
+#line 1397
 		default :
-#line 1392
+#line 1397
 		{
-#line 1392
+#line 1397
 			unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
-#line 1392
+#line 1397
 			isp->exp_hi = exp >> 1;
-#line 1392
+#line 1397
 			isp->exp_lo = exp;
-#line 1392
+#line 1397
 			isp->mant_lo_lo = vsp->mantissa2;
-#line 1392
+#line 1397
 			isp->mant_lo_hi = vsp->mantissa2 >> 8;
-#line 1392
+#line 1397
 			isp->mant_hi = vsp->mantissa1;
-#line 1392
+#line 1397
 		}
-#line 1392
+#line 1397
 		}
-#line 1392
+#line 1397
 
-#line 1392
+#line 1397
 		isp->sign = vsp->sign;
-#line 1392
+#line 1397
 
 }
 
@@ -5121,7 +5126,7 @@ static const int cs_ieis_bias = 0x4000 - 0x7f;
 
 static const int cs_id_bias = 0x4000 - 0x3ff;
 
-#line 1527
+#line 1532
 
 static void
 get_ix_float(const void *xp, float *ip)
@@ -5131,86 +5136,86 @@ get_ix_float(const void *xp, float *ip)
 	{
 		const ieee_single_hi *isp = (const ieee_single_hi *) xp;
 		cray_single *csp = (cray_single *) ip;
-#line 1535
+#line 1540
 
-#line 1535
+#line 1540
 		if (isp->exp == 0)
-#line 1535
+#line 1540
 		{
-#line 1535
+#line 1540
 			/* ieee subnormal */
-#line 1535
+#line 1540
 			*ip = (double)isp->mant;
-#line 1535
+#line 1540
 			if (isp->mant != 0)
-#line 1535
+#line 1540
 			{
-#line 1535
+#line 1540
 				csp->exp -= (ieee_single_bias + 22);
-#line 1535
+#line 1540
 			}
-#line 1535
+#line 1540
 		}
-#line 1535
+#line 1540
 		else
-#line 1535
+#line 1540
 		{
-#line 1535
+#line 1540
 			csp->exp  = isp->exp + cs_ieis_bias + 1;
-#line 1535
+#line 1540
 			csp->mant = isp->mant << (48 - 1 - 23);
-#line 1535
+#line 1540
 			csp->mant |= (1 << (48 - 1));
-#line 1535
+#line 1540
 		}
-#line 1535
+#line 1540
 		csp->sign = isp->sign;
-#line 1535
+#line 1540
 
-#line 1535
+#line 1540
 
 	}
 	else
 	{
 		const ieee_single_lo *isp = (const ieee_single_lo *) xp;
 		cray_single *csp = (cray_single *) ip;
-#line 1540
+#line 1545
 
-#line 1540
+#line 1545
 		if (isp->exp == 0)
-#line 1540
+#line 1545
 		{
-#line 1540
+#line 1545
 			/* ieee subnormal */
-#line 1540
+#line 1545
 			*ip = (double)isp->mant;
-#line 1540
+#line 1545
 			if (isp->mant != 0)
-#line 1540
+#line 1545
 			{
-#line 1540
+#line 1545
 				csp->exp -= (ieee_single_bias + 22);
-#line 1540
+#line 1545
 			}
-#line 1540
+#line 1545
 		}
-#line 1540
+#line 1545
 		else
-#line 1540
+#line 1545
 		{
-#line 1540
+#line 1545
 			csp->exp  = isp->exp + cs_ieis_bias + 1;
-#line 1540
+#line 1545
 			csp->mant = isp->mant << (48 - 1 - 23);
-#line 1540
+#line 1545
 			csp->mant |= (1 << (48 - 1));
-#line 1540
+#line 1545
 		}
-#line 1540
+#line 1545
 		csp->sign = isp->sign;
-#line 1540
+#line 1545
 
-#line 1540
+#line 1545
 
 	}
 }
@@ -5222,97 +5227,6 @@ put_ix_float(void *xp, const float *ip)
 	{
 		ieee_single_hi *isp = (ieee_single_hi*)xp;
 	const cray_single *csp = (const cray_single *) ip;
-#line 1550
-	int ieee_exp = csp->exp - cs_ieis_bias -1;
-#line 1550
-
-#line 1550
-	isp->sign = csp->sign;
-#line 1550
-
-#line 1550
-	if (ieee_exp >= 0xff)
-#line 1550
-	{
-#line 1550
-		/* NC_ERANGE => ieee Inf */
-#line 1550
-		isp->exp = 0xff;
-#line 1550
-		isp->mant = 0x0;
-#line 1550
-	}
-#line 1550
-	else if (ieee_exp > 0)
-#line 1550
-	{
-#line 1550
-		/* normal ieee representation */
-#line 1550
-		isp->exp  = ieee_exp;
-#line 1550
-		/* assumes cray rep is in normal form */
-#line 1550
-		assert(csp->mant & 0x800000000000);
-#line 1550
-		isp->mant = (((csp->mant << 1) &
-#line 1550
-				0xffffffffffff) >> (48 - 23));
-#line 1550
-	}
-#line 1550
-	else if (ieee_exp > -23)
-#line 1550
-	{
-#line 1550
-		/* ieee subnormal, right shift */
-#line 1550
-		const int rshift = (48 - 23 - ieee_exp);
-#line 1550
-
-#line 1550
-		isp->mant = csp->mant >> rshift;
-#line 1550
-
-#line 1550
-#if 0
-#line 1550
-		if (csp->mant & (1 << (rshift -1)))
-#line 1550
-		{
-#line 1550
-			/* round up */
-#line 1550
-			isp->mant++;
-#line 1550
-		}
-#line 1550
-#endif
-#line 1550
-
-#line 1550
-		isp->exp  = 0;
-#line 1550
-	}
-#line 1550
-	else
-#line 1550
-	{
-#line 1550
-		/* smaller than ieee can represent */
-#line 1550
-		isp->exp = 0;
-#line 1550
-		isp->mant = 0;
-#line 1550
-	}
-#line 1550
-
-	}
-	else
-	{
-		ieee_single_lo *isp = (ieee_single_lo*)xp;
-	const cray_single *csp = (const cray_single *) ip;
 #line 1555
 	int ieee_exp = csp->exp - cs_ieis_bias -1;
 #line 1555
@@ -5400,30 +5314,121 @@ put_ix_float(void *xp, const float *ip)
 #line 1555
 
 	}
-}
-
-#else
-	/* IEEE Cray with only doubles */
-static void
-get_ix_float(const void *xp, float *ip)
-{
+	else
+	{
+		ieee_single_lo *isp = (ieee_single_lo*)xp;
+	const cray_single *csp = (const cray_single *) ip;
+#line 1560
+	int ieee_exp = csp->exp - cs_ieis_bias -1;
+#line 1560
 
-	ieee_double *idp = (ieee_double *) ip;
+#line 1560
+	isp->sign = csp->sign;
+#line 1560
 
-	if (word_align(xp) == 0)
+#line 1560
+	if (ieee_exp >= 0xff)
+#line 1560
 	{
-		const ieee_single_hi *isp = (const ieee_single_hi *) xp;
-		if (isp->exp == 0 && isp->mant == 0)
-		{
-			idp->exp = 0;
-			idp->mant = 0;
-		}
-		else
-		{
-			idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
-			idp->mant = isp->mant << (52 - 23);
-		}
-		idp->sign = isp->sign;
+#line 1560
+		/* NC_ERANGE => ieee Inf */
+#line 1560
+		isp->exp = 0xff;
+#line 1560
+		isp->mant = 0x0;
+#line 1560
+	}
+#line 1560
+	else if (ieee_exp > 0)
+#line 1560
+	{
+#line 1560
+		/* normal ieee representation */
+#line 1560
+		isp->exp  = ieee_exp;
+#line 1560
+		/* assumes cray rep is in normal form */
+#line 1560
+		assert(csp->mant & 0x800000000000);
+#line 1560
+		isp->mant = (((csp->mant << 1) &
+#line 1560
+				0xffffffffffff) >> (48 - 23));
+#line 1560
+	}
+#line 1560
+	else if (ieee_exp > -23)
+#line 1560
+	{
+#line 1560
+		/* ieee subnormal, right shift */
+#line 1560
+		const int rshift = (48 - 23 - ieee_exp);
+#line 1560
+
+#line 1560
+		isp->mant = csp->mant >> rshift;
+#line 1560
+
+#line 1560
+#if 0
+#line 1560
+		if (csp->mant & (1 << (rshift -1)))
+#line 1560
+		{
+#line 1560
+			/* round up */
+#line 1560
+			isp->mant++;
+#line 1560
+		}
+#line 1560
+#endif
+#line 1560
+
+#line 1560
+		isp->exp  = 0;
+#line 1560
+	}
+#line 1560
+	else
+#line 1560
+	{
+#line 1560
+		/* smaller than ieee can represent */
+#line 1560
+		isp->exp = 0;
+#line 1560
+		isp->mant = 0;
+#line 1560
+	}
+#line 1560
+
+	}
+}
+
+#else
+	/* IEEE Cray with only doubles */
+static void
+get_ix_float(const void *xp, float *ip)
+{
+
+	ieee_double *idp = (ieee_double *) ip;
+
+	if (word_align(xp) == 0)
+	{
+		const ieee_single_hi *isp = (const ieee_single_hi *) xp;
+		if (isp->exp == 0 && isp->mant == 0)
+		{
+			idp->exp = 0;
+			idp->mant = 0;
+		}
+		else
+		{
+			idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
+			idp->mant = isp->mant << (52 - 23);
+		}
+		idp->sign = isp->sign;
 	}
 	else
 	{
@@ -5486,288 +5491,288 @@ ncx_get_float_float(const void *xp, float *ip, void *fillp)
 #define ix_float float
 
 static int
-#line 1642
+#line 1647
 ncx_get_float_schar(const void *xp, schar *ip)
-#line 1642
+#line 1647
 {
-#line 1642
+#line 1647
 	ix_float xx;
-#line 1642
+#line 1647
 	get_ix_float(xp, &xx);
-#line 1642
+#line 1647
 	if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
-#line 1642
+#line 1647
 #ifdef ERANGE_FILL
-#line 1642
+#line 1647
             *ip = NC_FILL_BYTE;
-#line 1642
+#line 1647
 #endif
-#line 1642
+#line 1647
             return NC_ERANGE;
-#line 1642
+#line 1647
         }
-#line 1642
+#line 1647
 	*ip = (schar)xx;
-#line 1642
+#line 1647
 	return NC_NOERR;
-#line 1642
+#line 1647
 }
-#line 1642
+#line 1647
 
 static int
-#line 1643
+#line 1648
 ncx_get_float_short(const void *xp, short *ip)
-#line 1643
+#line 1648
 {
-#line 1643
+#line 1648
 	ix_float xx;
-#line 1643
+#line 1648
 	get_ix_float(xp, &xx);
-#line 1643
+#line 1648
 	if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
-#line 1643
+#line 1648
 #ifdef ERANGE_FILL
-#line 1643
+#line 1648
             *ip = NC_FILL_SHORT;
-#line 1643
+#line 1648
 #endif
-#line 1643
+#line 1648
             return NC_ERANGE;
-#line 1643
+#line 1648
         }
-#line 1643
+#line 1648
 	*ip = (short)xx;
-#line 1643
+#line 1648
 	return NC_NOERR;
-#line 1643
+#line 1648
 }
-#line 1643
+#line 1648
 
 static int
-#line 1644
+#line 1649
 ncx_get_float_int(const void *xp, int *ip)
-#line 1644
+#line 1649
 {
-#line 1644
+#line 1649
 	ix_float xx;
-#line 1644
+#line 1649
 	get_ix_float(xp, &xx);
-#line 1644
+#line 1649
 	if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
-#line 1644
+#line 1649
 #ifdef ERANGE_FILL
-#line 1644
+#line 1649
             *ip = NC_FILL_INT;
-#line 1644
+#line 1649
 #endif
-#line 1644
+#line 1649
             return NC_ERANGE;
-#line 1644
+#line 1649
         }
-#line 1644
+#line 1649
 	*ip = (int)xx;
-#line 1644
+#line 1649
 	return NC_NOERR;
-#line 1644
+#line 1649
 }
-#line 1644
+#line 1649
 
 static int
-#line 1645
+#line 1650
 ncx_get_float_long(const void *xp, long *ip)
-#line 1645
+#line 1650
 {
-#line 1645
+#line 1650
 	ix_float xx;
-#line 1645
+#line 1650
 	get_ix_float(xp, &xx);
-#line 1645
+#line 1650
 	if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
-#line 1645
+#line 1650
 #ifdef ERANGE_FILL
-#line 1645
+#line 1650
             *ip = NC_FILL_INT;
-#line 1645
+#line 1650
 #endif
-#line 1645
+#line 1650
             return NC_ERANGE;
-#line 1645
+#line 1650
         }
-#line 1645
+#line 1650
 	*ip = (long)xx;
-#line 1645
+#line 1650
 	return NC_NOERR;
-#line 1645
+#line 1650
 }
-#line 1645
+#line 1650
 
 static int
-#line 1646
+#line 1651
 ncx_get_float_double(const void *xp, double *ip)
-#line 1646
+#line 1651
 {
-#line 1646
+#line 1651
 	ix_float xx;
-#line 1646
+#line 1651
 	get_ix_float(xp, &xx);
-#line 1646
+#line 1651
 	*ip = (double)xx;
-#line 1646
+#line 1651
 	return NC_NOERR;
-#line 1646
+#line 1651
 }
-#line 1646
+#line 1651
 
 static int
-#line 1647
+#line 1652
 ncx_get_float_longlong(const void *xp, longlong *ip)
-#line 1647
+#line 1652
 {
-#line 1647
+#line 1652
 	ix_float xx;
-#line 1647
+#line 1652
 	get_ix_float(xp, &xx);
-#line 1647
+#line 1652
 	if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
-#line 1647
+#line 1652
 	else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
-#line 1647
+#line 1652
 	else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
-#line 1647
+#line 1652
 #ifdef ERANGE_FILL
-#line 1647
+#line 1652
             *ip = NC_FILL_INT64;
-#line 1647
+#line 1652
 #endif
-#line 1647
+#line 1652
             return NC_ERANGE;
-#line 1647
+#line 1652
         }
-#line 1647
+#line 1652
 	else *ip = (longlong)xx;
-#line 1647
+#line 1652
 	return NC_NOERR;
-#line 1647
+#line 1652
 }
-#line 1647
+#line 1652
 
 static int
-#line 1648
+#line 1653
 ncx_get_float_uchar(const void *xp, uchar *ip)
-#line 1648
+#line 1653
 {
-#line 1648
+#line 1653
 	ix_float xx;
-#line 1648
+#line 1653
 	get_ix_float(xp, &xx);
-#line 1648
+#line 1653
 	if (xx > (double)UCHAR_MAX || xx < 0) {
-#line 1648
+#line 1653
 #ifdef ERANGE_FILL
-#line 1648
+#line 1653
             *ip = NC_FILL_UBYTE;
-#line 1648
+#line 1653
 #endif
-#line 1648
+#line 1653
             return NC_ERANGE;
-#line 1648
+#line 1653
         }
-#line 1648
+#line 1653
 	*ip = (uchar)xx;
-#line 1648
+#line 1653
 	return NC_NOERR;
-#line 1648
+#line 1653
 }
-#line 1648
+#line 1653
 
 static int
-#line 1649
+#line 1654
 ncx_get_float_ushort(const void *xp, ushort *ip)
-#line 1649
+#line 1654
 {
-#line 1649
+#line 1654
 	ix_float xx;
-#line 1649
+#line 1654
 	get_ix_float(xp, &xx);
-#line 1649
+#line 1654
 	if (xx > (double)USHORT_MAX || xx < 0) {
-#line 1649
+#line 1654
 #ifdef ERANGE_FILL
-#line 1649
+#line 1654
             *ip = NC_FILL_USHORT;
-#line 1649
+#line 1654
 #endif
-#line 1649
+#line 1654
             return NC_ERANGE;
-#line 1649
+#line 1654
         }
-#line 1649
+#line 1654
 	*ip = (ushort)xx;
-#line 1649
+#line 1654
 	return NC_NOERR;
-#line 1649
+#line 1654
 }
-#line 1649
+#line 1654
 
 static int
-#line 1650
+#line 1655
 ncx_get_float_uint(const void *xp, uint *ip)
-#line 1650
+#line 1655
 {
-#line 1650
+#line 1655
 	ix_float xx;
-#line 1650
+#line 1655
 	get_ix_float(xp, &xx);
-#line 1650
+#line 1655
 	if (xx > (double)UINT_MAX || xx < 0) {
-#line 1650
+#line 1655
 #ifdef ERANGE_FILL
-#line 1650
+#line 1655
             *ip = NC_FILL_UINT;
-#line 1650
+#line 1655
 #endif
-#line 1650
+#line 1655
             return NC_ERANGE;
-#line 1650
+#line 1655
         }
-#line 1650
+#line 1655
 	*ip = (uint)xx;
-#line 1650
+#line 1655
 	return NC_NOERR;
-#line 1650
+#line 1655
 }
-#line 1650
+#line 1655
 
 static int
-#line 1651
+#line 1656
 ncx_get_float_ulonglong(const void *xp, ulonglong *ip)
-#line 1651
+#line 1656
 {
-#line 1651
+#line 1656
 	ix_float xx;
-#line 1651
+#line 1656
 	get_ix_float(xp, &xx);
-#line 1651
+#line 1656
 	if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
-#line 1651
+#line 1656
 	else if (xx > (double)ULONGLONG_MAX || xx < 0) {
-#line 1651
+#line 1656
 #ifdef ERANGE_FILL
-#line 1651
+#line 1656
             *ip = NC_FILL_UINT64;
-#line 1651
+#line 1656
 #endif
-#line 1651
+#line 1656
             return NC_ERANGE;
-#line 1651
+#line 1656
         }
-#line 1651
+#line 1656
 	else *ip = (ulonglong)xx;
-#line 1651
+#line 1656
 	return NC_NOERR;
-#line 1651
+#line 1656
 }
-#line 1651
+#line 1656
 
 
 #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
@@ -5782,11 +5787,11 @@ ncx_put_float_float(void *xp, const float *ip, void *fillp)
 #endif
     if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
         
-#line 1664
+#line 1669
 #ifdef ERANGE_FILL
-#line 1664
+#line 1669
             if (fillp != NULL) memcpy(&tmp, fillp, 4);
-#line 1664
+#line 1669
 #endif
 #ifdef ERANGE_FILL
         _ip = &tmp;
@@ -5800,272 +5805,272 @@ ncx_put_float_float(void *xp, const float *ip, void *fillp)
 #endif
 
 static int
-#line 1676
+#line 1681
 ncx_put_float_schar(void *xp, const schar *ip, void *fillp)
-#line 1676
+#line 1681
 {
-#line 1676
+#line 1681
     int err=NC_NOERR;
-#line 1676
+#line 1681
     ix_float xx = NC_FILL_FLOAT;
-#line 1676
+#line 1681
 
-#line 1676
+#line 1681
     
-#line 1676
+#line 1681
         xx = (ix_float)*ip;
-#line 1676
+#line 1681
 
-#line 1676
+#line 1681
     put_ix_float(xp, &xx);
-#line 1676
+#line 1681
     return err;
-#line 1676
+#line 1681
 }
-#line 1676
+#line 1681
 
 static int
-#line 1677
+#line 1682
 ncx_put_float_short(void *xp, const short *ip, void *fillp)
-#line 1677
+#line 1682
 {
-#line 1677
+#line 1682
     int err=NC_NOERR;
-#line 1677
+#line 1682
     ix_float xx = NC_FILL_FLOAT;
-#line 1677
+#line 1682
 
-#line 1677
+#line 1682
     
-#line 1677
+#line 1682
         xx = (ix_float)*ip;
-#line 1677
+#line 1682
 
-#line 1677
+#line 1682
     put_ix_float(xp, &xx);
-#line 1677
+#line 1682
     return err;
-#line 1677
+#line 1682
 }
-#line 1677
+#line 1682
 
 static int
-#line 1678
+#line 1683
 ncx_put_float_int(void *xp, const int *ip, void *fillp)
-#line 1678
+#line 1683
 {
-#line 1678
+#line 1683
     int err=NC_NOERR;
-#line 1678
+#line 1683
     ix_float xx = NC_FILL_FLOAT;
-#line 1678
+#line 1683
 
-#line 1678
+#line 1683
     
-#line 1678
+#line 1683
         xx = (ix_float)*ip;
-#line 1678
+#line 1683
 
-#line 1678
+#line 1683
     put_ix_float(xp, &xx);
-#line 1678
+#line 1683
     return err;
-#line 1678
+#line 1683
 }
-#line 1678
+#line 1683
 
 static int
-#line 1679
+#line 1684
 ncx_put_float_long(void *xp, const long *ip, void *fillp)
-#line 1679
+#line 1684
 {
-#line 1679
+#line 1684
     int err=NC_NOERR;
-#line 1679
+#line 1684
     ix_float xx = NC_FILL_FLOAT;
-#line 1679
+#line 1684
 
-#line 1679
+#line 1684
     
-#line 1679
+#line 1684
         xx = (ix_float)*ip;
-#line 1679
+#line 1684
 
-#line 1679
+#line 1684
     put_ix_float(xp, &xx);
-#line 1679
+#line 1684
     return err;
-#line 1679
+#line 1684
 }
-#line 1679
+#line 1684
 
 static int
-#line 1680
+#line 1685
 ncx_put_float_double(void *xp, const double *ip, void *fillp)
-#line 1680
+#line 1685
 {
-#line 1680
+#line 1685
     int err=NC_NOERR;
-#line 1680
+#line 1685
     ix_float xx = NC_FILL_FLOAT;
-#line 1680
+#line 1685
 
-#line 1680
+#line 1685
     if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
-#line 1680
+#line 1685
         
-#line 1680
+#line 1685
 #ifdef ERANGE_FILL
-#line 1680
+#line 1685
             if (fillp != NULL) memcpy(&xx, fillp, 4);
-#line 1680
+#line 1685
 #endif
-#line 1680
+#line 1685
         err = NC_ERANGE;
-#line 1680
+#line 1685
     }
-#line 1680
+#line 1685
 #ifdef ERANGE_FILL
-#line 1680
+#line 1685
     else
-#line 1680
+#line 1685
 #endif
-#line 1680
+#line 1685
         xx = (ix_float)*ip;
-#line 1680
+#line 1685
 
-#line 1680
+#line 1685
     put_ix_float(xp, &xx);
-#line 1680
+#line 1685
     return err;
-#line 1680
+#line 1685
 }
-#line 1680
+#line 1685
 
 static int
-#line 1681
+#line 1686
 ncx_put_float_longlong(void *xp, const longlong *ip, void *fillp)
-#line 1681
+#line 1686
 {
-#line 1681
+#line 1686
     int err=NC_NOERR;
-#line 1681
+#line 1686
     ix_float xx = NC_FILL_FLOAT;
-#line 1681
+#line 1686
 
-#line 1681
+#line 1686
     
-#line 1681
+#line 1686
         xx = (ix_float)*ip;
-#line 1681
+#line 1686
 
-#line 1681
+#line 1686
     put_ix_float(xp, &xx);
-#line 1681
+#line 1686
     return err;
-#line 1681
+#line 1686
 }
-#line 1681
+#line 1686
 
 static int
-#line 1682
+#line 1687
 ncx_put_float_uchar(void *xp, const uchar *ip, void *fillp)
-#line 1682
+#line 1687
 {
-#line 1682
+#line 1687
     int err=NC_NOERR;
-#line 1682
+#line 1687
     ix_float xx = NC_FILL_FLOAT;
-#line 1682
+#line 1687
 
-#line 1682
+#line 1687
     
-#line 1682
+#line 1687
         xx = (ix_float)*ip;
-#line 1682
+#line 1687
 
-#line 1682
+#line 1687
     put_ix_float(xp, &xx);
-#line 1682
+#line 1687
     return err;
-#line 1682
+#line 1687
 }
-#line 1682
+#line 1687
 
 static int
-#line 1683
+#line 1688
 ncx_put_float_ushort(void *xp, const ushort *ip, void *fillp)
-#line 1683
+#line 1688
 {
-#line 1683
+#line 1688
     int err=NC_NOERR;
-#line 1683
+#line 1688
     ix_float xx = NC_FILL_FLOAT;
-#line 1683
+#line 1688
 
-#line 1683
+#line 1688
     
-#line 1683
+#line 1688
         xx = (ix_float)*ip;
-#line 1683
+#line 1688
 
-#line 1683
+#line 1688
     put_ix_float(xp, &xx);
-#line 1683
+#line 1688
     return err;
-#line 1683
+#line 1688
 }
-#line 1683
+#line 1688
 
 static int
-#line 1684
+#line 1689
 ncx_put_float_uint(void *xp, const uint *ip, void *fillp)
-#line 1684
+#line 1689
 {
-#line 1684
+#line 1689
     int err=NC_NOERR;
-#line 1684
+#line 1689
     ix_float xx = NC_FILL_FLOAT;
-#line 1684
+#line 1689
 
-#line 1684
+#line 1689
     
-#line 1684
+#line 1689
         xx = (ix_float)*ip;
-#line 1684
+#line 1689
 
-#line 1684
+#line 1689
     put_ix_float(xp, &xx);
-#line 1684
+#line 1689
     return err;
-#line 1684
+#line 1689
 }
-#line 1684
+#line 1689
 
 static int
-#line 1685
+#line 1690
 ncx_put_float_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 1685
+#line 1690
 {
-#line 1685
+#line 1690
     int err=NC_NOERR;
-#line 1685
+#line 1690
     ix_float xx = NC_FILL_FLOAT;
-#line 1685
+#line 1690
 
-#line 1685
+#line 1690
     
-#line 1685
+#line 1690
         xx = (ix_float)*ip;
-#line 1685
+#line 1690
 
-#line 1685
+#line 1690
     put_ix_float(xp, &xx);
-#line 1685
+#line 1690
     return err;
-#line 1685
+#line 1690
 }
-#line 1685
+#line 1690
 
 
 
@@ -6132,218 +6137,218 @@ static const struct dbl_limits {
 };
 
 
-#line 1799
+#line 1804
 static void
 get_ix_double(const void *xp, double *ip)
 {
 	struct vax_double *const vdp =
-#line 1802
+#line 1807
 			 (struct vax_double *)ip;
-#line 1802
+#line 1807
 	const struct ieee_double *const idp =
-#line 1802
+#line 1807
 			 (const struct ieee_double *) xp;
-#line 1802
+#line 1807
 	{
-#line 1802
+#line 1807
 		const struct dbl_limits *lim;
-#line 1802
+#line 1807
 		int ii;
-#line 1802
+#line 1807
 		for (ii = 0, lim = dbl_limits;
-#line 1802
+#line 1807
 			ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
-#line 1802
+#line 1807
 			ii++, lim++)
-#line 1802
+#line 1807
 		{
-#line 1802
+#line 1807
 			if ((idp->mant_lo == lim->ieee.mant_lo)
-#line 1802
+#line 1807
 				&& (idp->mant_4 == lim->ieee.mant_4)
-#line 1802
+#line 1807
 				&& (idp->mant_5 == lim->ieee.mant_5)
-#line 1802
+#line 1807
 				&& (idp->mant_6 == lim->ieee.mant_6)
-#line 1802
+#line 1807
 				&& (idp->exp_lo == lim->ieee.exp_lo)
-#line 1802
+#line 1807
 				&& (idp->exp_hi == lim->ieee.exp_hi)
-#line 1802
+#line 1807
 				)
-#line 1802
+#line 1807
 			{
-#line 1802
+#line 1807
 				*vdp = lim->d;
-#line 1802
+#line 1807
 				goto doneit;
-#line 1802
+#line 1807
 			}
-#line 1802
+#line 1807
 		}
-#line 1802
+#line 1807
 	}
-#line 1802
+#line 1807
 	{
-#line 1802
+#line 1807
 		unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
-#line 1802
+#line 1807
 		vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
-#line 1802
+#line 1807
 	}
-#line 1802
+#line 1807
 	{
-#line 1802
+#line 1807
 		unsigned mant_hi = ((idp->mant_6 << 16)
-#line 1802
+#line 1807
 				 | (idp->mant_5 << 8)
-#line 1802
+#line 1807
 				 | idp->mant_4);
-#line 1802
+#line 1807
 		unsigned mant_lo = SWAP4(idp->mant_lo);
-#line 1802
+#line 1807
 		vdp->mantissa1 = (mant_hi >> 13);
-#line 1802
+#line 1807
 		vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
-#line 1802
+#line 1807
 				| (mant_lo >> 29);
-#line 1802
+#line 1807
 		vdp->mantissa3 = (mant_lo >> 13);
-#line 1802
+#line 1807
 		vdp->mantissa4 = (mant_lo << 3);
-#line 1802
+#line 1807
 	}
-#line 1802
+#line 1807
 	doneit:
-#line 1802
+#line 1807
 		vdp->sign = idp->sign;
-#line 1802
+#line 1807
 
 }
 
 
-#line 1872
+#line 1877
 static void
 put_ix_double(void *xp, const double *ip)
 {
 	const struct vax_double *const vdp =
-#line 1875
+#line 1880
 			(const struct vax_double *)ip;
-#line 1875
+#line 1880
 	struct ieee_double *const idp =
-#line 1875
+#line 1880
 			 (struct ieee_double *) xp;
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 	if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
-#line 1875
+#line 1880
 		(vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
-#line 1875
+#line 1880
 		(vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
-#line 1875
+#line 1880
 		(vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
-#line 1875
+#line 1880
 		(vdp->exp == dbl_limits[0].d.exp))
-#line 1875
+#line 1880
 	{
-#line 1875
+#line 1880
 		*idp = dbl_limits[0].ieee;
-#line 1875
+#line 1880
 		goto shipit;
-#line 1875
+#line 1880
 	}
-#line 1875
+#line 1880
 	if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
-#line 1875
+#line 1880
 		(vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
-#line 1875
+#line 1880
 		(vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
-#line 1875
+#line 1880
 		(vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
-#line 1875
+#line 1880
 		(vdp->exp == dbl_limits[1].d.exp))
-#line 1875
+#line 1880
 	{
-#line 1875
+#line 1880
 		*idp = dbl_limits[1].ieee;
-#line 1875
+#line 1880
 		goto shipit;
-#line 1875
+#line 1880
 	}
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 	{
-#line 1875
+#line 1880
 		unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 		unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
-#line 1875
+#line 1880
 			(vdp->mantissa3 << 13) |
-#line 1875
+#line 1880
 			((vdp->mantissa4 >> 3) & MASK(13));
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 		unsigned mant_hi = (vdp->mantissa1 << 13)
-#line 1875
+#line 1880
 				 | (vdp->mantissa2 >> 3);
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 		if ((vdp->mantissa4 & 7) > 4)
-#line 1875
+#line 1880
 		{
-#line 1875
+#line 1880
 			/* round up */
-#line 1875
+#line 1880
 			mant_lo++;
-#line 1875
+#line 1880
 			if (mant_lo == 0)
-#line 1875
+#line 1880
 			{
-#line 1875
+#line 1880
 				mant_hi++;
-#line 1875
+#line 1880
 				if (mant_hi > 0xffffff)
-#line 1875
+#line 1880
 				{
-#line 1875
+#line 1880
 					mant_hi = 0;
-#line 1875
+#line 1880
 					exp++;
-#line 1875
+#line 1880
 				}
-#line 1875
+#line 1880
 			}
-#line 1875
+#line 1880
 		}
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 		idp->mant_lo = SWAP4(mant_lo);
-#line 1875
+#line 1880
 		idp->mant_6 = mant_hi >> 16;
-#line 1875
+#line 1880
 		idp->mant_5 = (mant_hi & 0xff00) >> 8;
-#line 1875
+#line 1880
 		idp->mant_4 = mant_hi;
-#line 1875
+#line 1880
 		idp->exp_hi = exp >> 4;
-#line 1875
+#line 1880
 		idp->exp_lo = exp;
-#line 1875
+#line 1880
 	}
-#line 1875
+#line 1880
 
-#line 1875
+#line 1880
 	shipit:
-#line 1875
+#line 1880
 		idp->sign = vdp->sign;
-#line 1875
+#line 1880
 
 }
 
@@ -6437,271 +6442,271 @@ put_ix_double(void *xp, const double *ip)
 #define ix_double double
 
 static int
-#line 1967
+#line 1972
 ncx_get_double_schar(const void *xp, schar *ip)
-#line 1967
+#line 1972
 {
-#line 1967
+#line 1972
 	ix_double xx;
-#line 1967
+#line 1972
 	get_ix_double(xp, &xx);
-#line 1967
+#line 1972
 	if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
-#line 1967
+#line 1972
 #ifdef ERANGE_FILL
-#line 1967
+#line 1972
             *ip = NC_FILL_BYTE;
-#line 1967
+#line 1972
 #endif
-#line 1967
+#line 1972
             return NC_ERANGE;
-#line 1967
+#line 1972
         }
-#line 1967
+#line 1972
 	*ip = (schar)xx;
-#line 1967
+#line 1972
 	return NC_NOERR;
-#line 1967
+#line 1972
 }
-#line 1967
+#line 1972
 
 static int
-#line 1968
+#line 1973
 ncx_get_double_short(const void *xp, short *ip)
-#line 1968
+#line 1973
 {
-#line 1968
+#line 1973
 	ix_double xx;
-#line 1968
+#line 1973
 	get_ix_double(xp, &xx);
-#line 1968
+#line 1973
 	if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
-#line 1968
+#line 1973
 #ifdef ERANGE_FILL
-#line 1968
+#line 1973
             *ip = NC_FILL_SHORT;
-#line 1968
+#line 1973
 #endif
-#line 1968
+#line 1973
             return NC_ERANGE;
-#line 1968
+#line 1973
         }
-#line 1968
+#line 1973
 	*ip = (short)xx;
-#line 1968
+#line 1973
 	return NC_NOERR;
-#line 1968
+#line 1973
 }
-#line 1968
+#line 1973
 
 static int
-#line 1969
+#line 1974
 ncx_get_double_int(const void *xp, int *ip)
-#line 1969
+#line 1974
 {
-#line 1969
+#line 1974
 	ix_double xx;
-#line 1969
+#line 1974
 	get_ix_double(xp, &xx);
-#line 1969
+#line 1974
 	if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
-#line 1969
+#line 1974
 #ifdef ERANGE_FILL
-#line 1969
+#line 1974
             *ip = NC_FILL_INT;
-#line 1969
+#line 1974
 #endif
-#line 1969
+#line 1974
             return NC_ERANGE;
-#line 1969
+#line 1974
         }
-#line 1969
+#line 1974
 	*ip = (int)xx;
-#line 1969
+#line 1974
 	return NC_NOERR;
-#line 1969
+#line 1974
 }
-#line 1969
+#line 1974
 
 static int
-#line 1970
+#line 1975
 ncx_get_double_long(const void *xp, long *ip)
-#line 1970
+#line 1975
 {
-#line 1970
+#line 1975
 	ix_double xx;
-#line 1970
+#line 1975
 	get_ix_double(xp, &xx);
-#line 1970
+#line 1975
 	if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
-#line 1970
+#line 1975
 #ifdef ERANGE_FILL
-#line 1970
+#line 1975
             *ip = NC_FILL_INT;
-#line 1970
+#line 1975
 #endif
-#line 1970
+#line 1975
             return NC_ERANGE;
-#line 1970
+#line 1975
         }
-#line 1970
+#line 1975
 	*ip = (long)xx;
-#line 1970
+#line 1975
 	return NC_NOERR;
-#line 1970
+#line 1975
 }
-#line 1970
+#line 1975
 
 static int
-#line 1971
+#line 1976
 ncx_get_double_longlong(const void *xp, longlong *ip)
-#line 1971
+#line 1976
 {
-#line 1971
+#line 1976
 	ix_double xx;
-#line 1971
+#line 1976
 	get_ix_double(xp, &xx);
-#line 1971
+#line 1976
 	if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
-#line 1971
+#line 1976
 	else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
-#line 1971
+#line 1976
 	else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
-#line 1971
+#line 1976
 #ifdef ERANGE_FILL
-#line 1971
+#line 1976
             *ip = NC_FILL_INT64;
-#line 1971
+#line 1976
 #endif
-#line 1971
+#line 1976
             return NC_ERANGE;
-#line 1971
+#line 1976
         }
-#line 1971
+#line 1976
 	else *ip = (longlong)xx;
-#line 1971
+#line 1976
 	return NC_NOERR;
-#line 1971
+#line 1976
 }
-#line 1971
+#line 1976
 
 static int
-#line 1972
+#line 1977
 ncx_get_double_uchar(const void *xp, uchar *ip)
-#line 1972
+#line 1977
 {
-#line 1972
+#line 1977
 	ix_double xx;
-#line 1972
+#line 1977
 	get_ix_double(xp, &xx);
-#line 1972
+#line 1977
 	if (xx > (double)UCHAR_MAX || xx < 0) {
-#line 1972
+#line 1977
 #ifdef ERANGE_FILL
-#line 1972
+#line 1977
             *ip = NC_FILL_UBYTE;
-#line 1972
+#line 1977
 #endif
-#line 1972
+#line 1977
             return NC_ERANGE;
-#line 1972
+#line 1977
         }
-#line 1972
+#line 1977
 	*ip = (uchar)xx;
-#line 1972
+#line 1977
 	return NC_NOERR;
-#line 1972
+#line 1977
 }
-#line 1972
+#line 1977
 
 static int
-#line 1973
+#line 1978
 ncx_get_double_ushort(const void *xp, ushort *ip)
-#line 1973
+#line 1978
 {
-#line 1973
+#line 1978
 	ix_double xx;
-#line 1973
+#line 1978
 	get_ix_double(xp, &xx);
-#line 1973
+#line 1978
 	if (xx > (double)USHORT_MAX || xx < 0) {
-#line 1973
+#line 1978
 #ifdef ERANGE_FILL
-#line 1973
+#line 1978
             *ip = NC_FILL_USHORT;
-#line 1973
+#line 1978
 #endif
-#line 1973
+#line 1978
             return NC_ERANGE;
-#line 1973
+#line 1978
         }
-#line 1973
+#line 1978
 	*ip = (ushort)xx;
-#line 1973
+#line 1978
 	return NC_NOERR;
-#line 1973
+#line 1978
 }
-#line 1973
+#line 1978
 
 static int
-#line 1974
+#line 1979
 ncx_get_double_uint(const void *xp, uint *ip)
-#line 1974
+#line 1979
 {
-#line 1974
+#line 1979
 	ix_double xx;
-#line 1974
+#line 1979
 	get_ix_double(xp, &xx);
-#line 1974
+#line 1979
 	if (xx > (double)UINT_MAX || xx < 0) {
-#line 1974
+#line 1979
 #ifdef ERANGE_FILL
-#line 1974
+#line 1979
             *ip = NC_FILL_UINT;
-#line 1974
+#line 1979
 #endif
-#line 1974
+#line 1979
             return NC_ERANGE;
-#line 1974
+#line 1979
         }
-#line 1974
+#line 1979
 	*ip = (uint)xx;
-#line 1974
+#line 1979
 	return NC_NOERR;
-#line 1974
+#line 1979
 }
-#line 1974
+#line 1979
 
 static int
-#line 1975
+#line 1980
 ncx_get_double_ulonglong(const void *xp, ulonglong *ip)
-#line 1975
+#line 1980
 {
-#line 1975
+#line 1980
 	ix_double xx;
-#line 1975
+#line 1980
 	get_ix_double(xp, &xx);
-#line 1975
+#line 1980
 	if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
-#line 1975
+#line 1980
 	else if (xx > (double)ULONGLONG_MAX || xx < 0) {
-#line 1975
+#line 1980
 #ifdef ERANGE_FILL
-#line 1975
+#line 1980
             *ip = NC_FILL_UINT64;
-#line 1975
+#line 1980
 #endif
-#line 1975
+#line 1980
             return NC_ERANGE;
-#line 1975
+#line 1980
         }
-#line 1975
+#line 1980
 	else *ip = (ulonglong)xx;
-#line 1975
+#line 1980
 	return NC_NOERR;
-#line 1975
+#line 1980
 }
-#line 1975
+#line 1980
 
 
 static int
@@ -6740,133 +6745,8 @@ ncx_get_double_double(const void *xp, double *ip, void *fillp)
 #endif
 
 static int
-#line 2012
-ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
-#line 2012
-{
-#line 2012
-    int err=NC_NOERR;
-#line 2012
-    ix_double xx = NC_FILL_DOUBLE;
-#line 2012
-
-#line 2012
-    
-#line 2012
-        xx = (ix_double)*ip;
-#line 2012
-
-#line 2012
-    put_ix_double(xp, &xx);
-#line 2012
-    return err;
-#line 2012
-}
-#line 2012
-
-static int
-#line 2013
-ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
-#line 2013
-{
-#line 2013
-    int err=NC_NOERR;
-#line 2013
-    ix_double xx = NC_FILL_DOUBLE;
-#line 2013
-
-#line 2013
-    
-#line 2013
-        xx = (ix_double)*ip;
-#line 2013
-
-#line 2013
-    put_ix_double(xp, &xx);
-#line 2013
-    return err;
-#line 2013
-}
-#line 2013
-
-static int
-#line 2014
-ncx_put_double_short(void *xp, const short *ip, void *fillp)
-#line 2014
-{
-#line 2014
-    int err=NC_NOERR;
-#line 2014
-    ix_double xx = NC_FILL_DOUBLE;
-#line 2014
-
-#line 2014
-    
-#line 2014
-        xx = (ix_double)*ip;
-#line 2014
-
-#line 2014
-    put_ix_double(xp, &xx);
-#line 2014
-    return err;
-#line 2014
-}
-#line 2014
-
-static int
-#line 2015
-ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
-#line 2015
-{
-#line 2015
-    int err=NC_NOERR;
-#line 2015
-    ix_double xx = NC_FILL_DOUBLE;
-#line 2015
-
-#line 2015
-    
-#line 2015
-        xx = (ix_double)*ip;
-#line 2015
-
-#line 2015
-    put_ix_double(xp, &xx);
-#line 2015
-    return err;
-#line 2015
-}
-#line 2015
-
-static int
-#line 2016
-ncx_put_double_int(void *xp, const int *ip, void *fillp)
-#line 2016
-{
-#line 2016
-    int err=NC_NOERR;
-#line 2016
-    ix_double xx = NC_FILL_DOUBLE;
-#line 2016
-
-#line 2016
-    
-#line 2016
-        xx = (ix_double)*ip;
-#line 2016
-
-#line 2016
-    put_ix_double(xp, &xx);
-#line 2016
-    return err;
-#line 2016
-}
-#line 2016
-
-static int
 #line 2017
-ncx_put_double_long(void *xp, const long *ip, void *fillp)
+ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
 #line 2017
 {
 #line 2017
@@ -6891,7 +6771,7 @@ ncx_put_double_long(void *xp, const long *ip, void *fillp)
 
 static int
 #line 2018
-ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
+ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
 #line 2018
 {
 #line 2018
@@ -6916,7 +6796,7 @@ ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
 
 static int
 #line 2019
-ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
+ncx_put_double_short(void *xp, const short *ip, void *fillp)
 #line 2019
 {
 #line 2019
@@ -6941,7 +6821,7 @@ ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
 
 static int
 #line 2020
-ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
+ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
 #line 2020
 {
 #line 2020
@@ -6964,7 +6844,132 @@ ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
 }
 #line 2020
 
-
+static int
+#line 2021
+ncx_put_double_int(void *xp, const int *ip, void *fillp)
+#line 2021
+{
+#line 2021
+    int err=NC_NOERR;
+#line 2021
+    ix_double xx = NC_FILL_DOUBLE;
+#line 2021
+
+#line 2021
+    
+#line 2021
+        xx = (ix_double)*ip;
+#line 2021
+
+#line 2021
+    put_ix_double(xp, &xx);
+#line 2021
+    return err;
+#line 2021
+}
+#line 2021
+
+static int
+#line 2022
+ncx_put_double_long(void *xp, const long *ip, void *fillp)
+#line 2022
+{
+#line 2022
+    int err=NC_NOERR;
+#line 2022
+    ix_double xx = NC_FILL_DOUBLE;
+#line 2022
+
+#line 2022
+    
+#line 2022
+        xx = (ix_double)*ip;
+#line 2022
+
+#line 2022
+    put_ix_double(xp, &xx);
+#line 2022
+    return err;
+#line 2022
+}
+#line 2022
+
+static int
+#line 2023
+ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
+#line 2023
+{
+#line 2023
+    int err=NC_NOERR;
+#line 2023
+    ix_double xx = NC_FILL_DOUBLE;
+#line 2023
+
+#line 2023
+    
+#line 2023
+        xx = (ix_double)*ip;
+#line 2023
+
+#line 2023
+    put_ix_double(xp, &xx);
+#line 2023
+    return err;
+#line 2023
+}
+#line 2023
+
+static int
+#line 2024
+ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
+#line 2024
+{
+#line 2024
+    int err=NC_NOERR;
+#line 2024
+    ix_double xx = NC_FILL_DOUBLE;
+#line 2024
+
+#line 2024
+    
+#line 2024
+        xx = (ix_double)*ip;
+#line 2024
+
+#line 2024
+    put_ix_double(xp, &xx);
+#line 2024
+    return err;
+#line 2024
+}
+#line 2024
+
+static int
+#line 2025
+ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
+#line 2025
+{
+#line 2025
+    int err=NC_NOERR;
+#line 2025
+    ix_double xx = NC_FILL_DOUBLE;
+#line 2025
+
+#line 2025
+    
+#line 2025
+        xx = (ix_double)*ip;
+#line 2025
+
+#line 2025
+    put_ix_double(xp, &xx);
+#line 2025
+    return err;
+#line 2025
+}
+#line 2025
+
+
 static int
 ncx_put_double_float(void *xp, const float *ip, void *fillp)
 {
@@ -6973,11 +6978,11 @@ ncx_put_double_float(void *xp, const float *ip, void *fillp)
 #if 1	/* TODO: figure this out (if condition below will never be true)*/
     if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
         
-#line 2029
+#line 2034
 #ifdef ERANGE_FILL
-#line 2029
+#line 2034
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2029
+#line 2034
 #endif
         err = NC_ERANGE;
     }
@@ -7003,11 +7008,11 @@ ncx_put_double_double(void *xp, const double *ip, void *fillp)
 #endif
     if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
         
-#line 2053
+#line 2058
 #ifdef ERANGE_FILL
-#line 2053
+#line 2058
             if (fillp != NULL) memcpy(&tmp, fillp, 8);
-#line 2053
+#line 2058
 #endif
 #ifdef ERANGE_FILL
         _ip = &tmp;
@@ -7072,1076 +7077,1076 @@ put_ix_int64(void *xp, const ix_int64 *ip)
 
 #if X_SIZEOF_INT64 != SIZEOF_LONGLONG
 static int
-#line 2116
+#line 2121
 ncx_get_longlong_longlong(const void *xp, longlong *ip)
-#line 2116
+#line 2121
 {
-#line 2116
+#line 2121
     int err=NC_NOERR;
-#line 2116
+#line 2121
 #if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
-#line 2116
+#line 2121
     get_ix_int64(xp, (ix_int64 *)ip);
-#line 2116
+#line 2121
 #else
-#line 2116
+#line 2121
     ix_int64 xx;
-#line 2116
+#line 2121
     get_ix_int64(xp, &xx);
-#line 2116
+#line 2121
 
-#line 2116
+#line 2121
 #if IX_INT64_MAX > LONGLONG_MAX
-#line 2116
+#line 2121
     if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
-#line 2116
+#line 2121
 #ifdef ERANGE_FILL
-#line 2116
+#line 2121
         *ip = NC_FILL_INT64;
-#line 2116
+#line 2121
         return NC_ERANGE;
-#line 2116
+#line 2121
 #else
-#line 2116
+#line 2121
         err = NC_ERANGE;
-#line 2116
+#line 2121
 #endif
-#line 2116
+#line 2121
     }
-#line 2116
+#line 2121
 #endif
-#line 2116
+#line 2121
 
-#line 2116
+#line 2121
 
-#line 2116
+#line 2121
     *ip = (longlong) xx;
-#line 2116
+#line 2121
 #endif
-#line 2116
+#line 2121
     return err;
-#line 2116
+#line 2121
 }
-#line 2116
+#line 2121
 
 #endif
 static int
-#line 2118
+#line 2123
 ncx_get_longlong_schar(const void *xp, schar *ip)
-#line 2118
+#line 2123
 {
-#line 2118
+#line 2123
     int err=NC_NOERR;
-#line 2118
+#line 2123
     ix_int64 xx;
-#line 2118
+#line 2123
     get_ix_int64(xp, &xx);
-#line 2118
+#line 2123
 
-#line 2118
+#line 2123
 #if IX_INT64_MAX > SCHAR_MAX
-#line 2118
+#line 2123
     if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
-#line 2118
+#line 2123
 #ifdef ERANGE_FILL
-#line 2118
+#line 2123
         *ip = NC_FILL_BYTE;
-#line 2118
+#line 2123
         return NC_ERANGE;
-#line 2118
+#line 2123
 #else
-#line 2118
+#line 2123
         err = NC_ERANGE;
-#line 2118
+#line 2123
 #endif
-#line 2118
+#line 2123
     }
-#line 2118
+#line 2123
 #endif
-#line 2118
+#line 2123
 
-#line 2118
+#line 2123
 
-#line 2118
+#line 2123
     *ip = (schar) xx;
-#line 2118
+#line 2123
     return err;
-#line 2118
+#line 2123
 }
-#line 2118
+#line 2123
 
 static int
-#line 2119
+#line 2124
 ncx_get_longlong_short(const void *xp, short *ip)
-#line 2119
+#line 2124
 {
-#line 2119
+#line 2124
     int err=NC_NOERR;
-#line 2119
+#line 2124
 #if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
-#line 2119
+#line 2124
     get_ix_int64(xp, (ix_int64 *)ip);
-#line 2119
+#line 2124
 #else
-#line 2119
+#line 2124
     ix_int64 xx;
-#line 2119
+#line 2124
     get_ix_int64(xp, &xx);
-#line 2119
+#line 2124
 
-#line 2119
+#line 2124
 #if IX_INT64_MAX > SHORT_MAX
-#line 2119
+#line 2124
     if (xx > SHORT_MAX || xx < SHORT_MIN) {
-#line 2119
+#line 2124
 #ifdef ERANGE_FILL
-#line 2119
+#line 2124
         *ip = NC_FILL_SHORT;
-#line 2119
+#line 2124
         return NC_ERANGE;
-#line 2119
+#line 2124
 #else
-#line 2119
+#line 2124
         err = NC_ERANGE;
-#line 2119
+#line 2124
 #endif
-#line 2119
+#line 2124
     }
-#line 2119
+#line 2124
 #endif
-#line 2119
+#line 2124
 
-#line 2119
+#line 2124
 
-#line 2119
+#line 2124
     *ip = (short) xx;
-#line 2119
+#line 2124
 #endif
-#line 2119
+#line 2124
     return err;
-#line 2119
+#line 2124
 }
-#line 2119
+#line 2124
 
 static int
-#line 2120
+#line 2125
 ncx_get_longlong_int(const void *xp, int *ip)
-#line 2120
+#line 2125
 {
-#line 2120
+#line 2125
     int err=NC_NOERR;
-#line 2120
+#line 2125
 #if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
-#line 2120
+#line 2125
     get_ix_int64(xp, (ix_int64 *)ip);
-#line 2120
+#line 2125
 #else
-#line 2120
+#line 2125
     ix_int64 xx;
-#line 2120
+#line 2125
     get_ix_int64(xp, &xx);
-#line 2120
+#line 2125
 
-#line 2120
+#line 2125
 #if IX_INT64_MAX > INT_MAX
-#line 2120
+#line 2125
     if (xx > INT_MAX || xx < INT_MIN) {
-#line 2120
+#line 2125
 #ifdef ERANGE_FILL
-#line 2120
+#line 2125
         *ip = NC_FILL_INT;
-#line 2120
+#line 2125
         return NC_ERANGE;
-#line 2120
+#line 2125
 #else
-#line 2120
+#line 2125
         err = NC_ERANGE;
-#line 2120
+#line 2125
 #endif
-#line 2120
+#line 2125
     }
-#line 2120
+#line 2125
 #endif
-#line 2120
+#line 2125
 
-#line 2120
+#line 2125
 
-#line 2120
+#line 2125
     *ip = (int) xx;
-#line 2120
+#line 2125
 #endif
-#line 2120
+#line 2125
     return err;
-#line 2120
+#line 2125
 }
-#line 2120
+#line 2125
 
 static int
-#line 2121
+#line 2126
 ncx_get_longlong_long(const void *xp, long *ip)
-#line 2121
+#line 2126
 {
-#line 2121
+#line 2126
     int err=NC_NOERR;
-#line 2121
+#line 2126
 #if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
-#line 2121
+#line 2126
     get_ix_int64(xp, (ix_int64 *)ip);
-#line 2121
+#line 2126
 #else
-#line 2121
+#line 2126
     ix_int64 xx;
-#line 2121
+#line 2126
     get_ix_int64(xp, &xx);
-#line 2121
+#line 2126
 
-#line 2121
+#line 2126
 #if IX_INT64_MAX > LONG_MAX
-#line 2121
+#line 2126
     if (xx > LONG_MAX || xx < LONG_MIN) {
-#line 2121
+#line 2126
 #ifdef ERANGE_FILL
-#line 2121
+#line 2126
         *ip = NC_FILL_INT;
-#line 2121
+#line 2126
         return NC_ERANGE;
-#line 2121
+#line 2126
 #else
-#line 2121
+#line 2126
         err = NC_ERANGE;
-#line 2121
+#line 2126
 #endif
-#line 2121
+#line 2126
     }
-#line 2121
+#line 2126
 #endif
-#line 2121
+#line 2126
 
-#line 2121
+#line 2126
 
-#line 2121
+#line 2126
     *ip = (long) xx;
-#line 2121
+#line 2126
 #endif
-#line 2121
+#line 2126
     return err;
-#line 2121
+#line 2126
 }
-#line 2121
+#line 2126
 
 static int
-#line 2122
+#line 2127
 ncx_get_longlong_ushort(const void *xp, ushort *ip)
-#line 2122
+#line 2127
 {
-#line 2122
+#line 2127
     int err=NC_NOERR;
-#line 2122
+#line 2127
     ix_int64 xx;
-#line 2122
+#line 2127
     get_ix_int64(xp, &xx);
-#line 2122
+#line 2127
 
-#line 2122
+#line 2127
 #if IX_INT64_MAX > USHORT_MAX
-#line 2122
+#line 2127
     if (xx > USHORT_MAX) {
-#line 2122
+#line 2127
 #ifdef ERANGE_FILL
-#line 2122
+#line 2127
         *ip = NC_FILL_USHORT;
-#line 2122
+#line 2127
         return NC_ERANGE;
-#line 2122
+#line 2127
 #else
-#line 2122
+#line 2127
         err = NC_ERANGE;
-#line 2122
+#line 2127
 #endif
-#line 2122
+#line 2127
     }
-#line 2122
+#line 2127
 #endif
-#line 2122
+#line 2127
 
-#line 2122
+#line 2127
     if (xx < 0) {
-#line 2122
+#line 2127
 #ifdef ERANGE_FILL
-#line 2122
+#line 2127
         *ip = NC_FILL_USHORT;
-#line 2122
+#line 2127
         return NC_ERANGE;
-#line 2122
+#line 2127
 #else
-#line 2122
+#line 2127
         err = NC_ERANGE; /* because ip is unsigned */
-#line 2122
+#line 2127
 #endif
-#line 2122
+#line 2127
     }
-#line 2122
+#line 2127
     *ip = (ushort) xx;
-#line 2122
+#line 2127
     return err;
-#line 2122
+#line 2127
 }
-#line 2122
+#line 2127
 
 static int
-#line 2123
+#line 2128
 ncx_get_longlong_uchar(const void *xp, uchar *ip)
-#line 2123
+#line 2128
 {
-#line 2123
+#line 2128
     int err=NC_NOERR;
-#line 2123
+#line 2128
     ix_int64 xx;
-#line 2123
+#line 2128
     get_ix_int64(xp, &xx);
-#line 2123
+#line 2128
 
-#line 2123
+#line 2128
 #if IX_INT64_MAX > UCHAR_MAX
-#line 2123
+#line 2128
     if (xx > UCHAR_MAX) {
-#line 2123
+#line 2128
 #ifdef ERANGE_FILL
-#line 2123
+#line 2128
         *ip = NC_FILL_UBYTE;
-#line 2123
+#line 2128
         return NC_ERANGE;
-#line 2123
+#line 2128
 #else
-#line 2123
+#line 2128
         err = NC_ERANGE;
-#line 2123
+#line 2128
 #endif
-#line 2123
+#line 2128
     }
-#line 2123
+#line 2128
 #endif
-#line 2123
+#line 2128
 
-#line 2123
+#line 2128
     if (xx < 0) {
-#line 2123
+#line 2128
 #ifdef ERANGE_FILL
-#line 2123
+#line 2128
         *ip = NC_FILL_UBYTE;
-#line 2123
+#line 2128
         return NC_ERANGE;
-#line 2123
+#line 2128
 #else
-#line 2123
+#line 2128
         err = NC_ERANGE; /* because ip is unsigned */
-#line 2123
+#line 2128
 #endif
-#line 2123
+#line 2128
     }
-#line 2123
+#line 2128
     *ip = (uchar) xx;
-#line 2123
+#line 2128
     return err;
-#line 2123
+#line 2128
 }
-#line 2123
+#line 2128
 
 static int
-#line 2124
+#line 2129
 ncx_get_longlong_uint(const void *xp, uint *ip)
-#line 2124
+#line 2129
 {
-#line 2124
+#line 2129
     int err=NC_NOERR;
-#line 2124
+#line 2129
     ix_int64 xx;
-#line 2124
+#line 2129
     get_ix_int64(xp, &xx);
-#line 2124
+#line 2129
 
-#line 2124
+#line 2129
 #if IX_INT64_MAX > UINT_MAX
-#line 2124
+#line 2129
     if (xx > UINT_MAX) {
-#line 2124
+#line 2129
 #ifdef ERANGE_FILL
-#line 2124
+#line 2129
         *ip = NC_FILL_UINT;
-#line 2124
+#line 2129
         return NC_ERANGE;
-#line 2124
+#line 2129
 #else
-#line 2124
+#line 2129
         err = NC_ERANGE;
-#line 2124
+#line 2129
 #endif
-#line 2124
+#line 2129
     }
-#line 2124
+#line 2129
 #endif
-#line 2124
+#line 2129
 
-#line 2124
+#line 2129
     if (xx < 0) {
-#line 2124
+#line 2129
 #ifdef ERANGE_FILL
-#line 2124
+#line 2129
         *ip = NC_FILL_UINT;
-#line 2124
+#line 2129
         return NC_ERANGE;
-#line 2124
+#line 2129
 #else
-#line 2124
+#line 2129
         err = NC_ERANGE; /* because ip is unsigned */
-#line 2124
+#line 2129
 #endif
-#line 2124
+#line 2129
     }
-#line 2124
+#line 2129
     *ip = (uint) xx;
-#line 2124
+#line 2129
     return err;
-#line 2124
+#line 2129
 }
-#line 2124
+#line 2129
 
 static int
-#line 2125
+#line 2130
 ncx_get_longlong_ulonglong(const void *xp, ulonglong *ip)
-#line 2125
+#line 2130
 {
-#line 2125
+#line 2130
     int err=NC_NOERR;
-#line 2125
+#line 2130
     ix_int64 xx;
-#line 2125
+#line 2130
     get_ix_int64(xp, &xx);
-#line 2125
+#line 2130
 
-#line 2125
+#line 2130
 #if IX_INT64_MAX > ULONGLONG_MAX
-#line 2125
+#line 2130
     if (xx > ULONGLONG_MAX) {
-#line 2125
+#line 2130
 #ifdef ERANGE_FILL
-#line 2125
+#line 2130
         *ip = NC_FILL_UINT64;
-#line 2125
+#line 2130
         return NC_ERANGE;
-#line 2125
+#line 2130
 #else
-#line 2125
+#line 2130
         err = NC_ERANGE;
-#line 2125
+#line 2130
 #endif
-#line 2125
+#line 2130
     }
-#line 2125
+#line 2130
 #endif
-#line 2125
+#line 2130
 
-#line 2125
+#line 2130
     if (xx < 0) {
-#line 2125
+#line 2130
 #ifdef ERANGE_FILL
-#line 2125
+#line 2130
         *ip = NC_FILL_UINT64;
-#line 2125
+#line 2130
         return NC_ERANGE;
-#line 2125
+#line 2130
 #else
-#line 2125
+#line 2130
         err = NC_ERANGE; /* because ip is unsigned */
-#line 2125
+#line 2130
 #endif
-#line 2125
+#line 2130
     }
-#line 2125
+#line 2130
     *ip = (ulonglong) xx;
-#line 2125
+#line 2130
     return err;
-#line 2125
+#line 2130
 }
-#line 2125
+#line 2130
 
 static int
-#line 2126
+#line 2131
 ncx_get_longlong_float(const void *xp, float *ip)
-#line 2126
+#line 2131
 {
-#line 2126
+#line 2131
 	ix_int64 xx;
-#line 2126
+#line 2131
 	get_ix_int64(xp, &xx);
-#line 2126
+#line 2131
 	*ip = (float)xx;
-#line 2126
+#line 2131
 	return NC_NOERR;
-#line 2126
+#line 2131
 }
-#line 2126
+#line 2131
 
 static int
-#line 2127
+#line 2132
 ncx_get_longlong_double(const void *xp, double *ip)
-#line 2127
+#line 2132
 {
-#line 2127
+#line 2132
 	ix_int64 xx;
-#line 2127
+#line 2132
 	get_ix_int64(xp, &xx);
-#line 2127
+#line 2132
 	*ip = (double)xx;
-#line 2127
+#line 2132
 	return NC_NOERR;
-#line 2127
+#line 2132
 }
-#line 2127
+#line 2132
 
 
 #if X_SIZEOF_INT64 != SIZEOF_LONGLONG
 static int
-#line 2130
+#line 2135
 ncx_put_longlong_longlong(void *xp, const longlong *ip, void *fillp)
-#line 2130
+#line 2135
 {
-#line 2130
+#line 2135
     int err=NC_NOERR;
-#line 2130
+#line 2135
 #if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
-#line 2130
+#line 2135
     put_ix_int64(xp, (const ix_int64 *)ip);
-#line 2130
+#line 2135
 #else
-#line 2130
+#line 2135
     ix_int64 xx = NC_FILL_INT64;
-#line 2130
+#line 2135
 
-#line 2130
+#line 2135
 #if IX_INT64_MAX < LONGLONG_MAX
-#line 2130
+#line 2135
     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
-#line 2130
+#line 2135
         
-#line 2130
+#line 2135
 #ifdef ERANGE_FILL
-#line 2130
+#line 2135
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2130
+#line 2135
 #endif
-#line 2130
+#line 2135
         err = NC_ERANGE;
-#line 2130
+#line 2135
     }
-#line 2130
+#line 2135
 #ifdef ERANGE_FILL
-#line 2130
+#line 2135
     else
-#line 2130
+#line 2135
 #endif
-#line 2130
+#line 2135
 #endif
-#line 2130
+#line 2135
         xx = (ix_int64)*ip;
-#line 2130
+#line 2135
 
-#line 2130
+#line 2135
     put_ix_int64(xp, &xx);
-#line 2130
+#line 2135
 #endif
-#line 2130
+#line 2135
     return err;
-#line 2130
+#line 2135
 }
-#line 2130
+#line 2135
 
 #endif
 static int
-#line 2132
+#line 2137
 ncx_put_longlong_schar(void *xp, const schar *ip, void *fillp)
-#line 2132
+#line 2137
 {
-#line 2132
+#line 2137
     int err=NC_NOERR;
-#line 2132
+#line 2137
     ix_int64 xx = NC_FILL_INT64;
-#line 2132
+#line 2137
 
-#line 2132
+#line 2137
 #if IX_INT64_MAX < SCHAR_MAX
-#line 2132
+#line 2137
     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
-#line 2132
+#line 2137
         
-#line 2132
+#line 2137
 #ifdef ERANGE_FILL
-#line 2132
+#line 2137
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2132
+#line 2137
 #endif
-#line 2132
+#line 2137
         err = NC_ERANGE;
-#line 2132
+#line 2137
     }
-#line 2132
+#line 2137
 #ifdef ERANGE_FILL
-#line 2132
+#line 2137
     else
-#line 2132
+#line 2137
 #endif
-#line 2132
+#line 2137
 #endif
-#line 2132
+#line 2137
         xx = (ix_int64)*ip;
-#line 2132
+#line 2137
 
-#line 2132
+#line 2137
     put_ix_int64(xp, &xx);
-#line 2132
+#line 2137
     return err;
-#line 2132
+#line 2137
 }
-#line 2132
+#line 2137
 
 static int
-#line 2133
+#line 2138
 ncx_put_longlong_short(void *xp, const short *ip, void *fillp)
-#line 2133
+#line 2138
 {
-#line 2133
+#line 2138
     int err=NC_NOERR;
-#line 2133
+#line 2138
 #if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
-#line 2133
+#line 2138
     put_ix_int64(xp, (const ix_int64 *)ip);
-#line 2133
+#line 2138
 #else
-#line 2133
+#line 2138
     ix_int64 xx = NC_FILL_INT64;
-#line 2133
+#line 2138
 
-#line 2133
+#line 2138
 #if IX_INT64_MAX < SHORT_MAX
-#line 2133
+#line 2138
     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
-#line 2133
+#line 2138
         
-#line 2133
+#line 2138
 #ifdef ERANGE_FILL
-#line 2133
+#line 2138
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2133
+#line 2138
 #endif
-#line 2133
+#line 2138
         err = NC_ERANGE;
-#line 2133
+#line 2138
     }
-#line 2133
+#line 2138
 #ifdef ERANGE_FILL
-#line 2133
+#line 2138
     else
-#line 2133
+#line 2138
 #endif
-#line 2133
+#line 2138
 #endif
-#line 2133
+#line 2138
         xx = (ix_int64)*ip;
-#line 2133
+#line 2138
 
-#line 2133
+#line 2138
     put_ix_int64(xp, &xx);
-#line 2133
+#line 2138
 #endif
-#line 2133
+#line 2138
     return err;
-#line 2133
+#line 2138
 }
-#line 2133
+#line 2138
 
 static int
-#line 2134
+#line 2139
 ncx_put_longlong_int(void *xp, const int *ip, void *fillp)
-#line 2134
+#line 2139
 {
-#line 2134
+#line 2139
     int err=NC_NOERR;
-#line 2134
+#line 2139
 #if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
-#line 2134
+#line 2139
     put_ix_int64(xp, (const ix_int64 *)ip);
-#line 2134
+#line 2139
 #else
-#line 2134
+#line 2139
     ix_int64 xx = NC_FILL_INT64;
-#line 2134
+#line 2139
 
-#line 2134
+#line 2139
 #if IX_INT64_MAX < INT_MAX
-#line 2134
+#line 2139
     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
-#line 2134
+#line 2139
         
-#line 2134
+#line 2139
 #ifdef ERANGE_FILL
-#line 2134
+#line 2139
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2134
+#line 2139
 #endif
-#line 2134
+#line 2139
         err = NC_ERANGE;
-#line 2134
+#line 2139
     }
-#line 2134
+#line 2139
 #ifdef ERANGE_FILL
-#line 2134
+#line 2139
     else
-#line 2134
+#line 2139
 #endif
-#line 2134
+#line 2139
 #endif
-#line 2134
+#line 2139
         xx = (ix_int64)*ip;
-#line 2134
+#line 2139
 
-#line 2134
+#line 2139
     put_ix_int64(xp, &xx);
-#line 2134
+#line 2139
 #endif
-#line 2134
+#line 2139
     return err;
-#line 2134
+#line 2139
 }
-#line 2134
+#line 2139
 
 static int
-#line 2135
+#line 2140
 ncx_put_longlong_long(void *xp, const long *ip, void *fillp)
-#line 2135
+#line 2140
 {
-#line 2135
+#line 2140
     int err=NC_NOERR;
-#line 2135
+#line 2140
 #if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
-#line 2135
+#line 2140
     put_ix_int64(xp, (const ix_int64 *)ip);
-#line 2135
+#line 2140
 #else
-#line 2135
+#line 2140
     ix_int64 xx = NC_FILL_INT64;
-#line 2135
+#line 2140
 
-#line 2135
+#line 2140
 #if IX_INT64_MAX < LONG_MAX
-#line 2135
+#line 2140
     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
-#line 2135
+#line 2140
         
-#line 2135
+#line 2140
 #ifdef ERANGE_FILL
-#line 2135
+#line 2140
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2135
+#line 2140
 #endif
-#line 2135
+#line 2140
         err = NC_ERANGE;
-#line 2135
+#line 2140
     }
-#line 2135
+#line 2140
 #ifdef ERANGE_FILL
-#line 2135
+#line 2140
     else
-#line 2135
+#line 2140
 #endif
-#line 2135
+#line 2140
 #endif
-#line 2135
+#line 2140
         xx = (ix_int64)*ip;
-#line 2135
+#line 2140
 
-#line 2135
+#line 2140
     put_ix_int64(xp, &xx);
-#line 2135
+#line 2140
 #endif
-#line 2135
+#line 2140
     return err;
-#line 2135
+#line 2140
 }
-#line 2135
+#line 2140
 
 static int
-#line 2136
+#line 2141
 ncx_put_longlong_ushort(void *xp, const ushort *ip, void *fillp)
-#line 2136
+#line 2141
 {
-#line 2136
+#line 2141
     int err=NC_NOERR;
-#line 2136
+#line 2141
     ix_int64 xx = NC_FILL_INT64;
-#line 2136
+#line 2141
 
-#line 2136
+#line 2141
 #if IX_INT64_MAX < USHORT_MAX
-#line 2136
+#line 2141
     if (*ip > IX_INT64_MAX) {
-#line 2136
+#line 2141
         
-#line 2136
+#line 2141
 #ifdef ERANGE_FILL
-#line 2136
+#line 2141
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2136
+#line 2141
 #endif
-#line 2136
+#line 2141
         err = NC_ERANGE;
-#line 2136
+#line 2141
     }
-#line 2136
+#line 2141
 #ifdef ERANGE_FILL
-#line 2136
+#line 2141
     else
-#line 2136
+#line 2141
 #endif
-#line 2136
+#line 2141
 #endif
-#line 2136
+#line 2141
         xx = (ix_int64)*ip;
-#line 2136
+#line 2141
 
-#line 2136
+#line 2141
     put_ix_int64(xp, &xx);
-#line 2136
+#line 2141
     return err;
-#line 2136
+#line 2141
 }
-#line 2136
+#line 2141
 
 static int
-#line 2137
+#line 2142
 ncx_put_longlong_uchar(void *xp, const uchar *ip, void *fillp)
-#line 2137
+#line 2142
 {
-#line 2137
+#line 2142
     int err=NC_NOERR;
-#line 2137
+#line 2142
     ix_int64 xx = NC_FILL_INT64;
-#line 2137
+#line 2142
 
-#line 2137
+#line 2142
 #if IX_INT64_MAX < UCHAR_MAX
-#line 2137
+#line 2142
     if (*ip > IX_INT64_MAX) {
-#line 2137
+#line 2142
         
-#line 2137
+#line 2142
 #ifdef ERANGE_FILL
-#line 2137
+#line 2142
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2137
+#line 2142
 #endif
-#line 2137
+#line 2142
         err = NC_ERANGE;
-#line 2137
+#line 2142
     }
-#line 2137
+#line 2142
 #ifdef ERANGE_FILL
-#line 2137
+#line 2142
     else
-#line 2137
+#line 2142
 #endif
-#line 2137
+#line 2142
 #endif
-#line 2137
+#line 2142
         xx = (ix_int64)*ip;
-#line 2137
+#line 2142
 
-#line 2137
+#line 2142
     put_ix_int64(xp, &xx);
-#line 2137
+#line 2142
     return err;
-#line 2137
+#line 2142
 }
-#line 2137
+#line 2142
 
 static int
-#line 2138
+#line 2143
 ncx_put_longlong_uint(void *xp, const uint *ip, void *fillp)
-#line 2138
+#line 2143
 {
-#line 2138
+#line 2143
     int err=NC_NOERR;
-#line 2138
+#line 2143
     ix_int64 xx = NC_FILL_INT64;
-#line 2138
+#line 2143
 
-#line 2138
+#line 2143
 #if IX_INT64_MAX < UINT_MAX
-#line 2138
+#line 2143
     if (*ip > IX_INT64_MAX) {
-#line 2138
+#line 2143
         
-#line 2138
+#line 2143
 #ifdef ERANGE_FILL
-#line 2138
+#line 2143
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2138
+#line 2143
 #endif
-#line 2138
+#line 2143
         err = NC_ERANGE;
-#line 2138
+#line 2143
     }
-#line 2138
+#line 2143
 #ifdef ERANGE_FILL
-#line 2138
+#line 2143
     else
-#line 2138
+#line 2143
 #endif
-#line 2138
+#line 2143
 #endif
-#line 2138
+#line 2143
         xx = (ix_int64)*ip;
-#line 2138
+#line 2143
 
-#line 2138
+#line 2143
     put_ix_int64(xp, &xx);
-#line 2138
+#line 2143
     return err;
-#line 2138
+#line 2143
 }
-#line 2138
+#line 2143
 
 static int
-#line 2139
+#line 2144
 ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 2139
+#line 2144
 {
-#line 2139
+#line 2144
     int err=NC_NOERR;
-#line 2139
+#line 2144
     ix_int64 xx = NC_FILL_INT64;
-#line 2139
+#line 2144
 
-#line 2139
+#line 2144
 #if IX_INT64_MAX < ULONGLONG_MAX
-#line 2139
+#line 2144
     if (*ip > IX_INT64_MAX) {
-#line 2139
+#line 2144
         
-#line 2139
+#line 2144
 #ifdef ERANGE_FILL
-#line 2139
+#line 2144
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2139
+#line 2144
 #endif
-#line 2139
+#line 2144
         err = NC_ERANGE;
-#line 2139
+#line 2144
     }
-#line 2139
+#line 2144
 #ifdef ERANGE_FILL
-#line 2139
+#line 2144
     else
-#line 2139
+#line 2144
 #endif
-#line 2139
+#line 2144
 #endif
-#line 2139
+#line 2144
         xx = (ix_int64)*ip;
-#line 2139
+#line 2144
 
-#line 2139
+#line 2144
     put_ix_int64(xp, &xx);
-#line 2139
+#line 2144
     return err;
-#line 2139
+#line 2144
 }
-#line 2139
+#line 2144
 
 static int
-#line 2140
+#line 2145
 ncx_put_longlong_float(void *xp, const float *ip, void *fillp)
-#line 2140
+#line 2145
 {
-#line 2140
+#line 2145
     int err=NC_NOERR;
-#line 2140
+#line 2145
     ix_int64 xx = NC_FILL_INT64;
-#line 2140
+#line 2145
 
-#line 2140
+#line 2145
     if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
-#line 2140
+#line 2145
         
-#line 2140
+#line 2145
 #ifdef ERANGE_FILL
-#line 2140
+#line 2145
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2140
+#line 2145
 #endif
-#line 2140
+#line 2145
         err = NC_ERANGE;
-#line 2140
+#line 2145
     }
-#line 2140
+#line 2145
 #ifdef ERANGE_FILL
-#line 2140
+#line 2145
     else
-#line 2140
+#line 2145
 #endif
-#line 2140
+#line 2145
         xx = (ix_int64)*ip;
-#line 2140
+#line 2145
 
-#line 2140
+#line 2145
     put_ix_int64(xp, &xx);
-#line 2140
+#line 2145
     return err;
-#line 2140
+#line 2145
 }
-#line 2140
+#line 2145
 
 static int
-#line 2141
+#line 2146
 ncx_put_longlong_double(void *xp, const double *ip, void *fillp)
-#line 2141
+#line 2146
 {
-#line 2141
+#line 2146
     int err=NC_NOERR;
-#line 2141
+#line 2146
     ix_int64 xx = NC_FILL_INT64;
-#line 2141
+#line 2146
 
-#line 2141
+#line 2146
     if (*ip > X_INT64_MAX || *ip < X_INT64_MIN) {
-#line 2141
+#line 2146
         
-#line 2141
+#line 2146
 #ifdef ERANGE_FILL
-#line 2141
+#line 2146
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2141
+#line 2146
 #endif
-#line 2141
+#line 2146
         err = NC_ERANGE;
-#line 2141
+#line 2146
     }
-#line 2141
+#line 2146
 #ifdef ERANGE_FILL
-#line 2141
+#line 2146
     else
-#line 2141
+#line 2146
 #endif
-#line 2141
+#line 2146
         xx = (ix_int64)*ip;
-#line 2141
+#line 2146
 
-#line 2141
+#line 2146
     put_ix_int64(xp, &xx);
-#line 2141
+#line 2146
     return err;
-#line 2141
+#line 2146
 }
-#line 2141
+#line 2146
 
 
 
@@ -8196,1120 +8201,1120 @@ put_ix_uint64(void *xp, const ix_uint64 *ip)
 
 #if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
 static int
-#line 2194
+#line 2199
 ncx_get_ulonglong_ulonglong(const void *xp, ulonglong *ip)
-#line 2194
+#line 2199
 {
-#line 2194
+#line 2199
     int err=NC_NOERR;
-#line 2194
+#line 2199
 #if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
-#line 2194
+#line 2199
     get_ix_uint64(xp, (ix_uint64 *)ip);
-#line 2194
+#line 2199
 #else
-#line 2194
+#line 2199
     ix_uint64 xx;
-#line 2194
+#line 2199
     get_ix_uint64(xp, &xx);
-#line 2194
+#line 2199
 
-#line 2194
+#line 2199
 #if IX_UINT64_MAX > ULONGLONG_MAX
-#line 2194
+#line 2199
     if (xx > ULONGLONG_MAX) {
-#line 2194
+#line 2199
 #ifdef ERANGE_FILL
-#line 2194
+#line 2199
         *ip = NC_FILL_UINT64;
-#line 2194
+#line 2199
         return NC_ERANGE;
-#line 2194
+#line 2199
 #else
-#line 2194
+#line 2199
         err = NC_ERANGE;
-#line 2194
+#line 2199
 #endif
-#line 2194
+#line 2199
     }
-#line 2194
+#line 2199
 #endif
-#line 2194
+#line 2199
 
-#line 2194
+#line 2199
 
-#line 2194
+#line 2199
     *ip = (ulonglong) xx;
-#line 2194
+#line 2199
 #endif
-#line 2194
+#line 2199
     return err;
-#line 2194
+#line 2199
 }
-#line 2194
+#line 2199
 
 #endif
 static int
-#line 2196
+#line 2201
 ncx_get_ulonglong_schar(const void *xp, schar *ip)
-#line 2196
+#line 2201
 {
-#line 2196
+#line 2201
     int err=NC_NOERR;
-#line 2196
+#line 2201
     ix_uint64 xx;
-#line 2196
+#line 2201
     get_ix_uint64(xp, &xx);
-#line 2196
+#line 2201
 
-#line 2196
+#line 2201
 #if IX_UINT64_MAX > SCHAR_MAX
-#line 2196
+#line 2201
     if (xx > SCHAR_MAX) {
-#line 2196
+#line 2201
 #ifdef ERANGE_FILL
-#line 2196
+#line 2201
         *ip = NC_FILL_BYTE;
-#line 2196
+#line 2201
         return NC_ERANGE;
-#line 2196
+#line 2201
 #else
-#line 2196
+#line 2201
         err = NC_ERANGE;
-#line 2196
+#line 2201
 #endif
-#line 2196
+#line 2201
     }
-#line 2196
+#line 2201
 #endif
-#line 2196
+#line 2201
 
-#line 2196
+#line 2201
 
-#line 2196
+#line 2201
     *ip = (schar) xx;
-#line 2196
+#line 2201
     return err;
-#line 2196
+#line 2201
 }
-#line 2196
+#line 2201
 
 static int
-#line 2197
+#line 2202
 ncx_get_ulonglong_short(const void *xp, short *ip)
-#line 2197
+#line 2202
 {
-#line 2197
+#line 2202
     int err=NC_NOERR;
-#line 2197
+#line 2202
     ix_uint64 xx;
-#line 2197
+#line 2202
     get_ix_uint64(xp, &xx);
-#line 2197
+#line 2202
 
-#line 2197
+#line 2202
 #if IX_UINT64_MAX > SHORT_MAX
-#line 2197
+#line 2202
     if (xx > SHORT_MAX) {
-#line 2197
+#line 2202
 #ifdef ERANGE_FILL
-#line 2197
+#line 2202
         *ip = NC_FILL_SHORT;
-#line 2197
+#line 2202
         return NC_ERANGE;
-#line 2197
+#line 2202
 #else
-#line 2197
+#line 2202
         err = NC_ERANGE;
-#line 2197
+#line 2202
 #endif
-#line 2197
+#line 2202
     }
-#line 2197
+#line 2202
 #endif
-#line 2197
+#line 2202
 
-#line 2197
+#line 2202
 
-#line 2197
+#line 2202
     *ip = (short) xx;
-#line 2197
+#line 2202
     return err;
-#line 2197
+#line 2202
 }
-#line 2197
+#line 2202
 
 static int
-#line 2198
+#line 2203
 ncx_get_ulonglong_int(const void *xp, int *ip)
-#line 2198
+#line 2203
 {
-#line 2198
+#line 2203
     int err=NC_NOERR;
-#line 2198
+#line 2203
     ix_uint64 xx;
-#line 2198
+#line 2203
     get_ix_uint64(xp, &xx);
-#line 2198
+#line 2203
 
-#line 2198
+#line 2203
 #if IX_UINT64_MAX > INT_MAX
-#line 2198
+#line 2203
     if (xx > INT_MAX) {
-#line 2198
+#line 2203
 #ifdef ERANGE_FILL
-#line 2198
+#line 2203
         *ip = NC_FILL_INT;
-#line 2198
+#line 2203
         return NC_ERANGE;
-#line 2198
+#line 2203
 #else
-#line 2198
+#line 2203
         err = NC_ERANGE;
-#line 2198
+#line 2203
 #endif
-#line 2198
+#line 2203
     }
-#line 2198
+#line 2203
 #endif
-#line 2198
+#line 2203
 
-#line 2198
+#line 2203
 
-#line 2198
+#line 2203
     *ip = (int) xx;
-#line 2198
+#line 2203
     return err;
-#line 2198
+#line 2203
 }
-#line 2198
+#line 2203
 
 static int
-#line 2199
+#line 2204
 ncx_get_ulonglong_long(const void *xp, long *ip)
-#line 2199
+#line 2204
 {
-#line 2199
+#line 2204
     int err=NC_NOERR;
-#line 2199
+#line 2204
     ix_uint64 xx;
-#line 2199
+#line 2204
     get_ix_uint64(xp, &xx);
-#line 2199
+#line 2204
 
-#line 2199
+#line 2204
 #if IX_UINT64_MAX > LONG_MAX
-#line 2199
+#line 2204
     if (xx > LONG_MAX) {
-#line 2199
+#line 2204
 #ifdef ERANGE_FILL
-#line 2199
+#line 2204
         *ip = NC_FILL_INT;
-#line 2199
+#line 2204
         return NC_ERANGE;
-#line 2199
+#line 2204
 #else
-#line 2199
+#line 2204
         err = NC_ERANGE;
-#line 2199
+#line 2204
 #endif
-#line 2199
+#line 2204
     }
-#line 2199
+#line 2204
 #endif
-#line 2199
+#line 2204
 
-#line 2199
+#line 2204
 
-#line 2199
+#line 2204
     *ip = (long) xx;
-#line 2199
+#line 2204
     return err;
-#line 2199
+#line 2204
 }
-#line 2199
+#line 2204
 
 static int
-#line 2200
+#line 2205
 ncx_get_ulonglong_longlong(const void *xp, longlong *ip)
-#line 2200
+#line 2205
 {
-#line 2200
+#line 2205
     int err=NC_NOERR;
-#line 2200
+#line 2205
     ix_uint64 xx;
-#line 2200
+#line 2205
     get_ix_uint64(xp, &xx);
-#line 2200
+#line 2205
 
-#line 2200
+#line 2205
 #if IX_UINT64_MAX > LONGLONG_MAX
-#line 2200
+#line 2205
     if (xx > LONGLONG_MAX) {
-#line 2200
+#line 2205
 #ifdef ERANGE_FILL
-#line 2200
+#line 2205
         *ip = NC_FILL_INT64;
-#line 2200
+#line 2205
         return NC_ERANGE;
-#line 2200
+#line 2205
 #else
-#line 2200
+#line 2205
         err = NC_ERANGE;
-#line 2200
+#line 2205
 #endif
-#line 2200
+#line 2205
     }
-#line 2200
+#line 2205
 #endif
-#line 2200
+#line 2205
 
-#line 2200
+#line 2205
 
-#line 2200
+#line 2205
     *ip = (longlong) xx;
-#line 2200
+#line 2205
     return err;
-#line 2200
+#line 2205
 }
-#line 2200
+#line 2205
 
 static int
-#line 2201
+#line 2206
 ncx_get_ulonglong_ushort(const void *xp, ushort *ip)
-#line 2201
+#line 2206
 {
-#line 2201
+#line 2206
     int err=NC_NOERR;
-#line 2201
+#line 2206
 #if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
-#line 2201
+#line 2206
     get_ix_uint64(xp, (ix_uint64 *)ip);
-#line 2201
+#line 2206
 #else
-#line 2201
+#line 2206
     ix_uint64 xx;
-#line 2201
+#line 2206
     get_ix_uint64(xp, &xx);
-#line 2201
+#line 2206
 
-#line 2201
+#line 2206
 #if IX_UINT64_MAX > USHORT_MAX
-#line 2201
+#line 2206
     if (xx > USHORT_MAX) {
-#line 2201
+#line 2206
 #ifdef ERANGE_FILL
-#line 2201
+#line 2206
         *ip = NC_FILL_USHORT;
-#line 2201
+#line 2206
         return NC_ERANGE;
-#line 2201
+#line 2206
 #else
-#line 2201
+#line 2206
         err = NC_ERANGE;
-#line 2201
+#line 2206
 #endif
-#line 2201
+#line 2206
     }
-#line 2201
+#line 2206
 #endif
-#line 2201
+#line 2206
 
-#line 2201
+#line 2206
 
-#line 2201
+#line 2206
     *ip = (ushort) xx;
-#line 2201
+#line 2206
 #endif
-#line 2201
+#line 2206
     return err;
-#line 2201
+#line 2206
 }
-#line 2201
+#line 2206
 
 static int
-#line 2202
+#line 2207
 ncx_get_ulonglong_uchar(const void *xp, uchar *ip)
-#line 2202
+#line 2207
 {
-#line 2202
+#line 2207
     int err=NC_NOERR;
-#line 2202
+#line 2207
 #if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
-#line 2202
+#line 2207
     get_ix_uint64(xp, (ix_uint64 *)ip);
-#line 2202
+#line 2207
 #else
-#line 2202
+#line 2207
     ix_uint64 xx;
-#line 2202
+#line 2207
     get_ix_uint64(xp, &xx);
-#line 2202
+#line 2207
 
-#line 2202
+#line 2207
 #if IX_UINT64_MAX > UCHAR_MAX
-#line 2202
+#line 2207
     if (xx > UCHAR_MAX) {
-#line 2202
+#line 2207
 #ifdef ERANGE_FILL
-#line 2202
+#line 2207
         *ip = NC_FILL_UBYTE;
-#line 2202
+#line 2207
         return NC_ERANGE;
-#line 2202
+#line 2207
 #else
-#line 2202
+#line 2207
         err = NC_ERANGE;
-#line 2202
+#line 2207
 #endif
-#line 2202
+#line 2207
     }
-#line 2202
+#line 2207
 #endif
-#line 2202
+#line 2207
 
-#line 2202
+#line 2207
 
-#line 2202
+#line 2207
     *ip = (uchar) xx;
-#line 2202
+#line 2207
 #endif
-#line 2202
+#line 2207
     return err;
-#line 2202
+#line 2207
 }
-#line 2202
+#line 2207
 
 static int
-#line 2203
+#line 2208
 ncx_get_ulonglong_uint(const void *xp, uint *ip)
-#line 2203
+#line 2208
 {
-#line 2203
+#line 2208
     int err=NC_NOERR;
-#line 2203
+#line 2208
 #if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
-#line 2203
+#line 2208
     get_ix_uint64(xp, (ix_uint64 *)ip);
-#line 2203
+#line 2208
 #else
-#line 2203
+#line 2208
     ix_uint64 xx;
-#line 2203
+#line 2208
     get_ix_uint64(xp, &xx);
-#line 2203
+#line 2208
 
-#line 2203
+#line 2208
 #if IX_UINT64_MAX > UINT_MAX
-#line 2203
+#line 2208
     if (xx > UINT_MAX) {
-#line 2203
+#line 2208
 #ifdef ERANGE_FILL
-#line 2203
+#line 2208
         *ip = NC_FILL_UINT;
-#line 2203
+#line 2208
         return NC_ERANGE;
-#line 2203
+#line 2208
 #else
-#line 2203
+#line 2208
         err = NC_ERANGE;
-#line 2203
+#line 2208
 #endif
-#line 2203
+#line 2208
     }
-#line 2203
+#line 2208
 #endif
-#line 2203
+#line 2208
 
-#line 2203
+#line 2208
 
-#line 2203
+#line 2208
     *ip = (uint) xx;
-#line 2203
+#line 2208
 #endif
-#line 2203
+#line 2208
     return err;
-#line 2203
+#line 2208
 }
-#line 2203
+#line 2208
 
 static int
-#line 2204
+#line 2209
 ncx_get_ulonglong_float(const void *xp, float *ip)
-#line 2204
+#line 2209
 {
-#line 2204
+#line 2209
 	ix_uint64 xx;
-#line 2204
+#line 2209
 	get_ix_uint64(xp, &xx);
-#line 2204
+#line 2209
 	*ip = (float)xx;
-#line 2204
+#line 2209
 	return NC_NOERR;
-#line 2204
+#line 2209
 }
-#line 2204
+#line 2209
 
 static int
-#line 2205
+#line 2210
 ncx_get_ulonglong_double(const void *xp, double *ip)
-#line 2205
+#line 2210
 {
-#line 2205
+#line 2210
 	ix_uint64 xx;
-#line 2205
+#line 2210
 	get_ix_uint64(xp, &xx);
-#line 2205
+#line 2210
 	*ip = (double)xx;
-#line 2205
+#line 2210
 	return NC_NOERR;
-#line 2205
+#line 2210
 }
-#line 2205
+#line 2210
 
 
 #if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
 static int
-#line 2208
+#line 2213
 ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
-#line 2208
+#line 2213
 {
-#line 2208
+#line 2213
     int err=NC_NOERR;
-#line 2208
+#line 2213
 #if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
-#line 2208
+#line 2213
     put_ix_uint64(xp, (const ix_uint64 *)ip);
-#line 2208
+#line 2213
 #else
-#line 2208
+#line 2213
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2208
+#line 2213
 
-#line 2208
+#line 2213
 #if IX_UINT64_MAX < ULONGLONG_MAX
-#line 2208
+#line 2213
     if (*ip > IX_UINT64_MAX) {
-#line 2208
+#line 2213
         
-#line 2208
+#line 2213
 #ifdef ERANGE_FILL
-#line 2208
+#line 2213
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2208
+#line 2213
 #endif
-#line 2208
+#line 2213
         err = NC_ERANGE;
-#line 2208
+#line 2213
     }
-#line 2208
+#line 2213
 #ifdef ERANGE_FILL
-#line 2208
+#line 2213
     else
-#line 2208
+#line 2213
 #endif
-#line 2208
+#line 2213
 #endif
-#line 2208
+#line 2213
         xx = (ix_uint64)*ip;
-#line 2208
+#line 2213
 
-#line 2208
+#line 2213
     put_ix_uint64(xp, &xx);
-#line 2208
+#line 2213
 #endif
-#line 2208
+#line 2213
     return err;
-#line 2208
+#line 2213
 }
-#line 2208
+#line 2213
 
 #endif
 static int
-#line 2210
+#line 2215
 ncx_put_ulonglong_schar(void *xp, const schar *ip, void *fillp)
-#line 2210
+#line 2215
 {
-#line 2210
+#line 2215
     int err=NC_NOERR;
-#line 2210
+#line 2215
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2210
+#line 2215
 
-#line 2210
+#line 2215
 #if IX_UINT64_MAX < SCHAR_MAX
-#line 2210
+#line 2215
     if (*ip > IX_UINT64_MAX) {
-#line 2210
+#line 2215
         
-#line 2210
+#line 2215
 #ifdef ERANGE_FILL
-#line 2210
+#line 2215
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2210
+#line 2215
 #endif
-#line 2210
+#line 2215
         err = NC_ERANGE;
-#line 2210
+#line 2215
     }
-#line 2210
+#line 2215
 #ifdef ERANGE_FILL
-#line 2210
+#line 2215
     else
-#line 2210
+#line 2215
 #endif
-#line 2210
+#line 2215
 #endif
-#line 2210
+#line 2215
     if (*ip < 0) {
-#line 2210
+#line 2215
         
-#line 2210
+#line 2215
 #ifdef ERANGE_FILL
-#line 2210
+#line 2215
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2210
+#line 2215
 #endif
-#line 2210
+#line 2215
         err = NC_ERANGE; /* because xp is unsigned */
-#line 2210
+#line 2215
     }
-#line 2210
+#line 2215
 #ifdef ERANGE_FILL
-#line 2210
+#line 2215
     else
-#line 2210
+#line 2215
 #endif
-#line 2210
+#line 2215
         xx = (ix_uint64)*ip;
-#line 2210
+#line 2215
 
-#line 2210
+#line 2215
     put_ix_uint64(xp, &xx);
-#line 2210
+#line 2215
     return err;
-#line 2210
+#line 2215
 }
-#line 2210
+#line 2215
 
 static int
-#line 2211
+#line 2216
 ncx_put_ulonglong_short(void *xp, const short *ip, void *fillp)
-#line 2211
+#line 2216
 {
-#line 2211
+#line 2216
     int err=NC_NOERR;
-#line 2211
+#line 2216
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2211
+#line 2216
 
-#line 2211
+#line 2216
 #if IX_UINT64_MAX < SHORT_MAX
-#line 2211
+#line 2216
     if (*ip > IX_UINT64_MAX) {
-#line 2211
+#line 2216
         
-#line 2211
+#line 2216
 #ifdef ERANGE_FILL
-#line 2211
+#line 2216
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2211
+#line 2216
 #endif
-#line 2211
+#line 2216
         err = NC_ERANGE;
-#line 2211
+#line 2216
     }
-#line 2211
+#line 2216
 #ifdef ERANGE_FILL
-#line 2211
+#line 2216
     else
-#line 2211
+#line 2216
 #endif
-#line 2211
+#line 2216
 #endif
-#line 2211
+#line 2216
     if (*ip < 0) {
-#line 2211
+#line 2216
         
-#line 2211
+#line 2216
 #ifdef ERANGE_FILL
-#line 2211
+#line 2216
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2211
+#line 2216
 #endif
-#line 2211
+#line 2216
         err = NC_ERANGE; /* because xp is unsigned */
-#line 2211
+#line 2216
     }
-#line 2211
+#line 2216
 #ifdef ERANGE_FILL
-#line 2211
+#line 2216
     else
-#line 2211
+#line 2216
 #endif
-#line 2211
+#line 2216
         xx = (ix_uint64)*ip;
-#line 2211
+#line 2216
 
-#line 2211
+#line 2216
     put_ix_uint64(xp, &xx);
-#line 2211
+#line 2216
     return err;
-#line 2211
+#line 2216
 }
-#line 2211
+#line 2216
 
 static int
-#line 2212
+#line 2217
 ncx_put_ulonglong_int(void *xp, const int *ip, void *fillp)
-#line 2212
+#line 2217
 {
-#line 2212
+#line 2217
     int err=NC_NOERR;
-#line 2212
+#line 2217
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2212
+#line 2217
 
-#line 2212
+#line 2217
 #if IX_UINT64_MAX < INT_MAX
-#line 2212
+#line 2217
     if (*ip > IX_UINT64_MAX) {
-#line 2212
+#line 2217
         
-#line 2212
+#line 2217
 #ifdef ERANGE_FILL
-#line 2212
+#line 2217
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2212
+#line 2217
 #endif
-#line 2212
+#line 2217
         err = NC_ERANGE;
-#line 2212
+#line 2217
     }
-#line 2212
+#line 2217
 #ifdef ERANGE_FILL
-#line 2212
+#line 2217
     else
-#line 2212
+#line 2217
 #endif
-#line 2212
+#line 2217
 #endif
-#line 2212
+#line 2217
     if (*ip < 0) {
-#line 2212
+#line 2217
         
-#line 2212
+#line 2217
 #ifdef ERANGE_FILL
-#line 2212
+#line 2217
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2212
+#line 2217
 #endif
-#line 2212
+#line 2217
         err = NC_ERANGE; /* because xp is unsigned */
-#line 2212
+#line 2217
     }
-#line 2212
+#line 2217
 #ifdef ERANGE_FILL
-#line 2212
+#line 2217
     else
-#line 2212
+#line 2217
 #endif
-#line 2212
+#line 2217
         xx = (ix_uint64)*ip;
-#line 2212
+#line 2217
 
-#line 2212
+#line 2217
     put_ix_uint64(xp, &xx);
-#line 2212
+#line 2217
     return err;
-#line 2212
+#line 2217
 }
-#line 2212
+#line 2217
 
 static int
-#line 2213
+#line 2218
 ncx_put_ulonglong_long(void *xp, const long *ip, void *fillp)
-#line 2213
+#line 2218
 {
-#line 2213
+#line 2218
     int err=NC_NOERR;
-#line 2213
+#line 2218
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2213
+#line 2218
 
-#line 2213
+#line 2218
 #if IX_UINT64_MAX < LONG_MAX
-#line 2213
+#line 2218
     if (*ip > IX_UINT64_MAX) {
-#line 2213
+#line 2218
         
-#line 2213
+#line 2218
 #ifdef ERANGE_FILL
-#line 2213
+#line 2218
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2213
+#line 2218
 #endif
-#line 2213
+#line 2218
         err = NC_ERANGE;
-#line 2213
+#line 2218
     }
-#line 2213
+#line 2218
 #ifdef ERANGE_FILL
-#line 2213
+#line 2218
     else
-#line 2213
+#line 2218
 #endif
-#line 2213
+#line 2218
 #endif
-#line 2213
+#line 2218
     if (*ip < 0) {
-#line 2213
+#line 2218
         
-#line 2213
+#line 2218
 #ifdef ERANGE_FILL
-#line 2213
+#line 2218
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2213
+#line 2218
 #endif
-#line 2213
+#line 2218
         err = NC_ERANGE; /* because xp is unsigned */
-#line 2213
+#line 2218
     }
-#line 2213
+#line 2218
 #ifdef ERANGE_FILL
-#line 2213
+#line 2218
     else
-#line 2213
+#line 2218
 #endif
-#line 2213
+#line 2218
         xx = (ix_uint64)*ip;
-#line 2213
+#line 2218
 
-#line 2213
+#line 2218
     put_ix_uint64(xp, &xx);
-#line 2213
+#line 2218
     return err;
-#line 2213
+#line 2218
 }
-#line 2213
+#line 2218
 
 static int
-#line 2214
+#line 2219
 ncx_put_ulonglong_longlong(void *xp, const longlong *ip, void *fillp)
-#line 2214
+#line 2219
 {
-#line 2214
+#line 2219
     int err=NC_NOERR;
-#line 2214
+#line 2219
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2214
+#line 2219
 
-#line 2214
+#line 2219
 #if IX_UINT64_MAX < LONGLONG_MAX
-#line 2214
+#line 2219
     if (*ip > IX_UINT64_MAX) {
-#line 2214
+#line 2219
         
-#line 2214
+#line 2219
 #ifdef ERANGE_FILL
-#line 2214
+#line 2219
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2214
+#line 2219
 #endif
-#line 2214
+#line 2219
         err = NC_ERANGE;
-#line 2214
+#line 2219
     }
-#line 2214
+#line 2219
 #ifdef ERANGE_FILL
-#line 2214
+#line 2219
     else
-#line 2214
+#line 2219
 #endif
-#line 2214
+#line 2219
 #endif
-#line 2214
+#line 2219
     if (*ip < 0) {
-#line 2214
+#line 2219
         
-#line 2214
+#line 2219
 #ifdef ERANGE_FILL
-#line 2214
+#line 2219
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2214
+#line 2219
 #endif
-#line 2214
+#line 2219
         err = NC_ERANGE; /* because xp is unsigned */
-#line 2214
+#line 2219
     }
-#line 2214
+#line 2219
 #ifdef ERANGE_FILL
-#line 2214
+#line 2219
     else
-#line 2214
+#line 2219
 #endif
-#line 2214
+#line 2219
         xx = (ix_uint64)*ip;
-#line 2214
+#line 2219
 
-#line 2214
+#line 2219
     put_ix_uint64(xp, &xx);
-#line 2214
+#line 2219
     return err;
-#line 2214
+#line 2219
 }
-#line 2214
+#line 2219
 
 static int
-#line 2215
+#line 2220
 ncx_put_ulonglong_uchar(void *xp, const uchar *ip, void *fillp)
-#line 2215
+#line 2220
 {
-#line 2215
+#line 2220
     int err=NC_NOERR;
-#line 2215
+#line 2220
 #if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
-#line 2215
+#line 2220
     put_ix_uint64(xp, (const ix_uint64 *)ip);
-#line 2215
+#line 2220
 #else
-#line 2215
+#line 2220
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2215
+#line 2220
 
-#line 2215
+#line 2220
 #if IX_UINT64_MAX < UCHAR_MAX
-#line 2215
+#line 2220
     if (*ip > IX_UINT64_MAX) {
-#line 2215
+#line 2220
         
-#line 2215
+#line 2220
 #ifdef ERANGE_FILL
-#line 2215
+#line 2220
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2215
+#line 2220
 #endif
-#line 2215
+#line 2220
         err = NC_ERANGE;
-#line 2215
+#line 2220
     }
-#line 2215
+#line 2220
 #ifdef ERANGE_FILL
-#line 2215
+#line 2220
     else
-#line 2215
+#line 2220
 #endif
-#line 2215
+#line 2220
 #endif
-#line 2215
+#line 2220
         xx = (ix_uint64)*ip;
-#line 2215
+#line 2220
 
-#line 2215
+#line 2220
     put_ix_uint64(xp, &xx);
-#line 2215
+#line 2220
 #endif
-#line 2215
+#line 2220
     return err;
-#line 2215
+#line 2220
 }
-#line 2215
+#line 2220
 
 static int
-#line 2216
+#line 2221
 ncx_put_ulonglong_ushort(void *xp, const ushort *ip, void *fillp)
-#line 2216
+#line 2221
 {
-#line 2216
+#line 2221
     int err=NC_NOERR;
-#line 2216
+#line 2221
 #if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
-#line 2216
+#line 2221
     put_ix_uint64(xp, (const ix_uint64 *)ip);
-#line 2216
+#line 2221
 #else
-#line 2216
+#line 2221
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2216
+#line 2221
 
-#line 2216
+#line 2221
 #if IX_UINT64_MAX < USHORT_MAX
-#line 2216
+#line 2221
     if (*ip > IX_UINT64_MAX) {
-#line 2216
+#line 2221
         
-#line 2216
+#line 2221
 #ifdef ERANGE_FILL
-#line 2216
+#line 2221
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2216
+#line 2221
 #endif
-#line 2216
+#line 2221
         err = NC_ERANGE;
-#line 2216
+#line 2221
     }
-#line 2216
+#line 2221
 #ifdef ERANGE_FILL
-#line 2216
+#line 2221
     else
-#line 2216
+#line 2221
 #endif
-#line 2216
+#line 2221
 #endif
-#line 2216
+#line 2221
         xx = (ix_uint64)*ip;
-#line 2216
+#line 2221
 
-#line 2216
+#line 2221
     put_ix_uint64(xp, &xx);
-#line 2216
+#line 2221
 #endif
-#line 2216
+#line 2221
     return err;
-#line 2216
+#line 2221
 }
-#line 2216
+#line 2221
 
 static int
-#line 2217
+#line 2222
 ncx_put_ulonglong_uint(void *xp, const uint *ip, void *fillp)
-#line 2217
+#line 2222
 {
-#line 2217
+#line 2222
     int err=NC_NOERR;
-#line 2217
+#line 2222
 #if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
-#line 2217
+#line 2222
     put_ix_uint64(xp, (const ix_uint64 *)ip);
-#line 2217
+#line 2222
 #else
-#line 2217
+#line 2222
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2217
+#line 2222
 
-#line 2217
+#line 2222
 #if IX_UINT64_MAX < UINT_MAX
-#line 2217
+#line 2222
     if (*ip > IX_UINT64_MAX) {
-#line 2217
+#line 2222
         
-#line 2217
+#line 2222
 #ifdef ERANGE_FILL
-#line 2217
+#line 2222
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2217
+#line 2222
 #endif
-#line 2217
+#line 2222
         err = NC_ERANGE;
-#line 2217
+#line 2222
     }
-#line 2217
+#line 2222
 #ifdef ERANGE_FILL
-#line 2217
+#line 2222
     else
-#line 2217
+#line 2222
 #endif
-#line 2217
+#line 2222
 #endif
-#line 2217
+#line 2222
         xx = (ix_uint64)*ip;
-#line 2217
+#line 2222
 
-#line 2217
+#line 2222
     put_ix_uint64(xp, &xx);
-#line 2217
+#line 2222
 #endif
-#line 2217
+#line 2222
     return err;
-#line 2217
+#line 2222
 }
-#line 2217
+#line 2222
 
 static int
-#line 2218
+#line 2223
 ncx_put_ulonglong_float(void *xp, const float *ip, void *fillp)
-#line 2218
+#line 2223
 {
-#line 2218
+#line 2223
     int err=NC_NOERR;
-#line 2218
+#line 2223
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2218
+#line 2223
 
-#line 2218
+#line 2223
     if (*ip > (double)X_UINT64_MAX || *ip < 0) {
-#line 2218
+#line 2223
         
-#line 2218
+#line 2223
 #ifdef ERANGE_FILL
-#line 2218
+#line 2223
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2218
+#line 2223
 #endif
-#line 2218
+#line 2223
         err = NC_ERANGE;
-#line 2218
+#line 2223
     }
-#line 2218
+#line 2223
 #ifdef ERANGE_FILL
-#line 2218
+#line 2223
     else
-#line 2218
+#line 2223
 #endif
-#line 2218
+#line 2223
         xx = (ix_uint64)*ip;
-#line 2218
+#line 2223
 
-#line 2218
+#line 2223
     put_ix_uint64(xp, &xx);
-#line 2218
+#line 2223
     return err;
-#line 2218
+#line 2223
 }
-#line 2218
+#line 2223
 
 static int
-#line 2219
+#line 2224
 ncx_put_ulonglong_double(void *xp, const double *ip, void *fillp)
-#line 2219
+#line 2224
 {
-#line 2219
+#line 2224
     int err=NC_NOERR;
-#line 2219
+#line 2224
     ix_uint64 xx = NC_FILL_UINT64;
-#line 2219
+#line 2224
 
-#line 2219
+#line 2224
     if (*ip > X_UINT64_MAX || *ip < 0) {
-#line 2219
+#line 2224
         
-#line 2219
+#line 2224
 #ifdef ERANGE_FILL
-#line 2219
+#line 2224
             if (fillp != NULL) memcpy(&xx, fillp, 8);
-#line 2219
+#line 2224
 #endif
-#line 2219
+#line 2224
         err = NC_ERANGE;
-#line 2219
+#line 2224
     }
-#line 2219
+#line 2224
 #ifdef ERANGE_FILL
-#line 2219
+#line 2224
     else
-#line 2219
+#line 2224
 #endif
-#line 2219
+#line 2224
         xx = (ix_uint64)*ip;
-#line 2219
+#line 2224
 
-#line 2219
+#line 2224
     put_ix_uint64(xp, &xx);
-#line 2219
+#line 2224
     return err;
-#line 2219
+#line 2224
 }
-#line 2219
+#line 2224
 
 
 
@@ -9356,6 +9361,9 @@ ncx_get_size_t(const void **xpp,  size_t *ulp)
 int
 ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
 {
+	/* similar to put_ix_int() */
+	uchar *cp = (uchar *) *xpp;
+
 	/* No negative offsets stored in netcdf */
 	if (*lp < 0) {
 	  /* Assume this is an overflow of a 32-bit int... */
@@ -9364,9 +9372,6 @@ ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
 
 	assert(sizeof_off_t == 4 || sizeof_off_t == 8);
 
-	/* similar to put_ix_int() */
-	uchar *cp = (uchar *) *xpp;
-
 	if (sizeof_off_t == 4) {
 		*cp++ = (uchar) ((*lp)               >> 24);
 		*cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
@@ -9563,2087 +9568,2087 @@ ncx_put_uint64(void **xpp, const unsigned long long ip)
 /*
  * Aggregate numeric conversion functions.
  */
-#line 2475
+#line 2480
 
-#line 2878
+#line 2883
 
-#line 2884
+#line 2889
 
 /* schar ---------------------------------------------------------------------*/
 
-#line 2888
+#line 2893
 int
 ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
 {
 		(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 2891
+#line 2896
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 2891
+#line 2896
 	return NC_NOERR;
-#line 2891
+#line 2896
 
 }
 int
-#line 2893
+#line 2898
 ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 2893
+#line 2898
 {
-#line 2893
+#line 2898
     int status = NC_NOERR;
-#line 2893
+#line 2898
     schar *xp = (schar *)(*xpp);
-#line 2893
+#line 2898
 
-#line 2893
+#line 2898
     while (nelems-- != 0) {
-#line 2893
+#line 2898
         
-#line 2893
+#line 2898
         if (*xp < 0) {
-#line 2893
+#line 2898
 #ifdef ERANGE_FILL
-#line 2893
+#line 2898
             *tp = NC_FILL_UBYTE;
-#line 2893
+#line 2898
 #endif
-#line 2893
+#line 2898
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2893
+#line 2898
             
-#line 2893
+#line 2898
 #ifdef ERANGE_FILL
-#line 2893
+#line 2898
             xp++; tp++; continue;
-#line 2893
+#line 2898
 #endif
-#line 2893
+#line 2898
         }
-#line 2893
+#line 2898
         *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
-#line 2893
+#line 2898
     }
-#line 2893
+#line 2898
 
-#line 2893
+#line 2898
     *xpp = (const void *)xp;
-#line 2893
+#line 2898
     return status;
-#line 2893
+#line 2898
 }
-#line 2893
+#line 2898
 
 int
-#line 2894
+#line 2899
 ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
-#line 2894
+#line 2899
 {
-#line 2894
+#line 2899
     int status = NC_NOERR;
-#line 2894
+#line 2899
     schar *xp = (schar *)(*xpp);
-#line 2894
+#line 2899
 
-#line 2894
+#line 2899
     while (nelems-- != 0) {
-#line 2894
+#line 2899
         
-#line 2894
+#line 2899
         *tp++ = (short)  (*xp++);  /* type cast from schar to short */
-#line 2894
+#line 2899
     }
-#line 2894
+#line 2899
 
-#line 2894
+#line 2899
     *xpp = (const void *)xp;
-#line 2894
+#line 2899
     return status;
-#line 2894
+#line 2899
 }
-#line 2894
+#line 2899
 
 int
-#line 2895
+#line 2900
 ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
-#line 2895
+#line 2900
 {
-#line 2895
+#line 2900
     int status = NC_NOERR;
-#line 2895
+#line 2900
     schar *xp = (schar *)(*xpp);
-#line 2895
+#line 2900
 
-#line 2895
+#line 2900
     while (nelems-- != 0) {
-#line 2895
+#line 2900
         
-#line 2895
+#line 2900
         *tp++ = (int)  (*xp++);  /* type cast from schar to int */
-#line 2895
+#line 2900
     }
-#line 2895
+#line 2900
 
-#line 2895
+#line 2900
     *xpp = (const void *)xp;
-#line 2895
+#line 2900
     return status;
-#line 2895
+#line 2900
 }
-#line 2895
+#line 2900
 
 int
-#line 2896
+#line 2901
 ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
-#line 2896
+#line 2901
 {
-#line 2896
+#line 2901
     int status = NC_NOERR;
-#line 2896
+#line 2901
     schar *xp = (schar *)(*xpp);
-#line 2896
+#line 2901
 
-#line 2896
+#line 2901
     while (nelems-- != 0) {
-#line 2896
+#line 2901
         
-#line 2896
+#line 2901
         *tp++ = (long)  (*xp++);  /* type cast from schar to long */
-#line 2896
+#line 2901
     }
-#line 2896
+#line 2901
 
-#line 2896
+#line 2901
     *xpp = (const void *)xp;
-#line 2896
+#line 2901
     return status;
-#line 2896
+#line 2901
 }
-#line 2896
+#line 2901
 
 int
-#line 2897
+#line 2902
 ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
-#line 2897
+#line 2902
 {
-#line 2897
+#line 2902
     int status = NC_NOERR;
-#line 2897
+#line 2902
     schar *xp = (schar *)(*xpp);
-#line 2897
+#line 2902
 
-#line 2897
+#line 2902
     while (nelems-- != 0) {
-#line 2897
+#line 2902
         
-#line 2897
+#line 2902
         *tp++ = (float)  (*xp++);  /* type cast from schar to float */
-#line 2897
+#line 2902
     }
-#line 2897
+#line 2902
 
-#line 2897
+#line 2902
     *xpp = (const void *)xp;
-#line 2897
+#line 2902
     return status;
-#line 2897
+#line 2902
 }
-#line 2897
+#line 2902
 
 int
-#line 2898
+#line 2903
 ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
-#line 2898
+#line 2903
 {
-#line 2898
+#line 2903
     int status = NC_NOERR;
-#line 2898
+#line 2903
     schar *xp = (schar *)(*xpp);
-#line 2898
+#line 2903
 
-#line 2898
+#line 2903
     while (nelems-- != 0) {
-#line 2898
+#line 2903
         
-#line 2898
+#line 2903
         *tp++ = (double)  (*xp++);  /* type cast from schar to double */
-#line 2898
+#line 2903
     }
-#line 2898
+#line 2903
 
-#line 2898
+#line 2903
     *xpp = (const void *)xp;
-#line 2898
+#line 2903
     return status;
-#line 2898
+#line 2903
 }
-#line 2898
+#line 2903
 
 int
-#line 2899
+#line 2904
 ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 2899
+#line 2904
 {
-#line 2899
+#line 2904
     int status = NC_NOERR;
-#line 2899
+#line 2904
     schar *xp = (schar *)(*xpp);
-#line 2899
+#line 2904
 
-#line 2899
+#line 2904
     while (nelems-- != 0) {
-#line 2899
+#line 2904
         
-#line 2899
+#line 2904
         *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
-#line 2899
+#line 2904
     }
-#line 2899
+#line 2904
 
-#line 2899
+#line 2904
     *xpp = (const void *)xp;
-#line 2899
+#line 2904
     return status;
-#line 2899
+#line 2904
 }
-#line 2899
+#line 2904
 
 int
-#line 2900
+#line 2905
 ncx_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 2900
+#line 2905
 {
-#line 2900
+#line 2905
     int status = NC_NOERR;
-#line 2900
+#line 2905
     schar *xp = (schar *)(*xpp);
-#line 2900
+#line 2905
 
-#line 2900
+#line 2905
     while (nelems-- != 0) {
-#line 2900
+#line 2905
         
-#line 2900
+#line 2905
         if (*xp < 0) {
-#line 2900
+#line 2905
 #ifdef ERANGE_FILL
-#line 2900
+#line 2905
             *tp = NC_FILL_USHORT;
-#line 2900
+#line 2905
 #endif
-#line 2900
+#line 2905
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2900
+#line 2905
             
-#line 2900
+#line 2905
 #ifdef ERANGE_FILL
-#line 2900
+#line 2905
             xp++; tp++; continue;
-#line 2900
+#line 2905
 #endif
-#line 2900
+#line 2905
         }
-#line 2900
+#line 2905
         *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
-#line 2900
+#line 2905
     }
-#line 2900
+#line 2905
 
-#line 2900
+#line 2905
     *xpp = (const void *)xp;
-#line 2900
+#line 2905
     return status;
-#line 2900
+#line 2905
 }
-#line 2900
+#line 2905
 
 int
-#line 2901
+#line 2906
 ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
-#line 2901
+#line 2906
 {
-#line 2901
+#line 2906
     int status = NC_NOERR;
-#line 2901
+#line 2906
     schar *xp = (schar *)(*xpp);
-#line 2901
+#line 2906
 
-#line 2901
+#line 2906
     while (nelems-- != 0) {
-#line 2901
+#line 2906
         
-#line 2901
+#line 2906
         if (*xp < 0) {
-#line 2901
+#line 2906
 #ifdef ERANGE_FILL
-#line 2901
+#line 2906
             *tp = NC_FILL_UINT;
-#line 2901
+#line 2906
 #endif
-#line 2901
+#line 2906
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2901
+#line 2906
             
-#line 2901
+#line 2906
 #ifdef ERANGE_FILL
-#line 2901
+#line 2906
             xp++; tp++; continue;
-#line 2901
+#line 2906
 #endif
-#line 2901
+#line 2906
         }
-#line 2901
+#line 2906
         *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
-#line 2901
+#line 2906
     }
-#line 2901
+#line 2906
 
-#line 2901
+#line 2906
     *xpp = (const void *)xp;
-#line 2901
+#line 2906
     return status;
-#line 2901
+#line 2906
 }
-#line 2901
+#line 2906
 
 int
-#line 2902
+#line 2907
 ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 2902
+#line 2907
 {
-#line 2902
+#line 2907
     int status = NC_NOERR;
-#line 2902
+#line 2907
     schar *xp = (schar *)(*xpp);
-#line 2902
+#line 2907
 
-#line 2902
+#line 2907
     while (nelems-- != 0) {
-#line 2902
+#line 2907
         
-#line 2902
+#line 2907
         if (*xp < 0) {
-#line 2902
+#line 2907
 #ifdef ERANGE_FILL
-#line 2902
+#line 2907
             *tp = NC_FILL_UINT64;
-#line 2902
+#line 2907
 #endif
-#line 2902
+#line 2907
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2902
+#line 2907
             
-#line 2902
+#line 2907
 #ifdef ERANGE_FILL
-#line 2902
+#line 2907
             xp++; tp++; continue;
-#line 2902
+#line 2907
 #endif
-#line 2902
+#line 2907
         }
-#line 2902
+#line 2907
         *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
-#line 2902
+#line 2907
     }
-#line 2902
+#line 2907
 
-#line 2902
+#line 2907
     *xpp = (const void *)xp;
-#line 2902
+#line 2907
     return status;
-#line 2902
+#line 2907
 }
-#line 2902
+#line 2907
 
 
-#line 2905
+#line 2910
 int
 ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
 {
 		size_t rndup = nelems % X_ALIGN;
-#line 2908
+#line 2913
 
-#line 2908
+#line 2913
 	if (rndup)
-#line 2908
+#line 2913
 		rndup = X_ALIGN - rndup;
-#line 2908
+#line 2913
 
-#line 2908
+#line 2913
 	(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 2908
+#line 2913
 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
-#line 2908
+#line 2913
 
-#line 2908
+#line 2913
 	return NC_NOERR;
-#line 2908
+#line 2913
 
 }
 int
-#line 2910
+#line 2915
 ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 2910
+#line 2915
 {
-#line 2910
+#line 2915
     int status = NC_NOERR;
-#line 2910
+#line 2915
     size_t rndup = nelems % X_ALIGN;
-#line 2910
+#line 2915
     schar *xp = (schar *) *xpp;
-#line 2910
+#line 2915
 
-#line 2910
+#line 2915
     if (rndup)
-#line 2910
+#line 2915
         rndup = X_ALIGN - rndup;
-#line 2910
+#line 2915
 
-#line 2910
+#line 2915
     while (nelems-- != 0) {
-#line 2910
+#line 2915
         
-#line 2910
+#line 2915
         if (*xp < 0) {
-#line 2910
+#line 2915
 #ifdef ERANGE_FILL
-#line 2910
+#line 2915
             *tp = NC_FILL_UBYTE;
-#line 2910
+#line 2915
 #endif
-#line 2910
+#line 2915
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2910
+#line 2915
             
-#line 2910
+#line 2915
 #ifdef ERANGE_FILL
-#line 2910
+#line 2915
             xp++; tp++; continue;
-#line 2910
+#line 2915
 #endif
-#line 2910
+#line 2915
         }
-#line 2910
+#line 2915
         *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
-#line 2910
+#line 2915
     }
-#line 2910
+#line 2915
 
-#line 2910
+#line 2915
     *xpp = (void *)(xp + rndup);
-#line 2910
+#line 2915
     return status;
-#line 2910
+#line 2915
 }
-#line 2910
+#line 2915
 
 int
-#line 2911
+#line 2916
 ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
-#line 2911
+#line 2916
 {
-#line 2911
+#line 2916
     int status = NC_NOERR;
-#line 2911
+#line 2916
     size_t rndup = nelems % X_ALIGN;
-#line 2911
+#line 2916
     schar *xp = (schar *) *xpp;
-#line 2911
+#line 2916
 
-#line 2911
+#line 2916
     if (rndup)
-#line 2911
+#line 2916
         rndup = X_ALIGN - rndup;
-#line 2911
+#line 2916
 
-#line 2911
+#line 2916
     while (nelems-- != 0) {
-#line 2911
+#line 2916
         
-#line 2911
+#line 2916
         *tp++ = (short)  (*xp++);  /* type cast from schar to short */
-#line 2911
+#line 2916
     }
-#line 2911
+#line 2916
 
-#line 2911
+#line 2916
     *xpp = (void *)(xp + rndup);
-#line 2911
+#line 2916
     return status;
-#line 2911
+#line 2916
 }
-#line 2911
+#line 2916
 
 int
-#line 2912
+#line 2917
 ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
-#line 2912
+#line 2917
 {
-#line 2912
+#line 2917
     int status = NC_NOERR;
-#line 2912
+#line 2917
     size_t rndup = nelems % X_ALIGN;
-#line 2912
+#line 2917
     schar *xp = (schar *) *xpp;
-#line 2912
+#line 2917
 
-#line 2912
+#line 2917
     if (rndup)
-#line 2912
+#line 2917
         rndup = X_ALIGN - rndup;
-#line 2912
+#line 2917
 
-#line 2912
+#line 2917
     while (nelems-- != 0) {
-#line 2912
+#line 2917
         
-#line 2912
+#line 2917
         *tp++ = (int)  (*xp++);  /* type cast from schar to int */
-#line 2912
+#line 2917
     }
-#line 2912
+#line 2917
 
-#line 2912
+#line 2917
     *xpp = (void *)(xp + rndup);
-#line 2912
+#line 2917
     return status;
-#line 2912
+#line 2917
 }
-#line 2912
+#line 2917
 
 int
-#line 2913
+#line 2918
 ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
-#line 2913
+#line 2918
 {
-#line 2913
+#line 2918
     int status = NC_NOERR;
-#line 2913
+#line 2918
     size_t rndup = nelems % X_ALIGN;
-#line 2913
+#line 2918
     schar *xp = (schar *) *xpp;
-#line 2913
+#line 2918
 
-#line 2913
+#line 2918
     if (rndup)
-#line 2913
+#line 2918
         rndup = X_ALIGN - rndup;
-#line 2913
+#line 2918
 
-#line 2913
+#line 2918
     while (nelems-- != 0) {
-#line 2913
+#line 2918
         
-#line 2913
+#line 2918
         *tp++ = (long)  (*xp++);  /* type cast from schar to long */
-#line 2913
+#line 2918
     }
-#line 2913
+#line 2918
 
-#line 2913
+#line 2918
     *xpp = (void *)(xp + rndup);
-#line 2913
+#line 2918
     return status;
-#line 2913
+#line 2918
 }
-#line 2913
+#line 2918
 
 int
-#line 2914
+#line 2919
 ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
-#line 2914
+#line 2919
 {
-#line 2914
+#line 2919
     int status = NC_NOERR;
-#line 2914
+#line 2919
     size_t rndup = nelems % X_ALIGN;
-#line 2914
+#line 2919
     schar *xp = (schar *) *xpp;
-#line 2914
+#line 2919
 
-#line 2914
+#line 2919
     if (rndup)
-#line 2914
+#line 2919
         rndup = X_ALIGN - rndup;
-#line 2914
+#line 2919
 
-#line 2914
+#line 2919
     while (nelems-- != 0) {
-#line 2914
+#line 2919
         
-#line 2914
+#line 2919
         *tp++ = (float)  (*xp++);  /* type cast from schar to float */
-#line 2914
+#line 2919
     }
-#line 2914
+#line 2919
 
-#line 2914
+#line 2919
     *xpp = (void *)(xp + rndup);
-#line 2914
+#line 2919
     return status;
-#line 2914
+#line 2919
 }
-#line 2914
+#line 2919
 
 int
-#line 2915
+#line 2920
 ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
-#line 2915
+#line 2920
 {
-#line 2915
+#line 2920
     int status = NC_NOERR;
-#line 2915
+#line 2920
     size_t rndup = nelems % X_ALIGN;
-#line 2915
+#line 2920
     schar *xp = (schar *) *xpp;
-#line 2915
+#line 2920
 
-#line 2915
+#line 2920
     if (rndup)
-#line 2915
+#line 2920
         rndup = X_ALIGN - rndup;
-#line 2915
+#line 2920
 
-#line 2915
+#line 2920
     while (nelems-- != 0) {
-#line 2915
+#line 2920
         
-#line 2915
+#line 2920
         *tp++ = (double)  (*xp++);  /* type cast from schar to double */
-#line 2915
+#line 2920
     }
-#line 2915
+#line 2920
 
-#line 2915
+#line 2920
     *xpp = (void *)(xp + rndup);
-#line 2915
+#line 2920
     return status;
-#line 2915
+#line 2920
 }
-#line 2915
+#line 2920
 
 int
-#line 2916
+#line 2921
 ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 2916
+#line 2921
 {
-#line 2916
+#line 2921
     int status = NC_NOERR;
-#line 2916
+#line 2921
     size_t rndup = nelems % X_ALIGN;
-#line 2916
+#line 2921
     schar *xp = (schar *) *xpp;
-#line 2916
+#line 2921
 
-#line 2916
+#line 2921
     if (rndup)
-#line 2916
+#line 2921
         rndup = X_ALIGN - rndup;
-#line 2916
+#line 2921
 
-#line 2916
+#line 2921
     while (nelems-- != 0) {
-#line 2916
+#line 2921
         
-#line 2916
+#line 2921
         *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
-#line 2916
+#line 2921
     }
-#line 2916
+#line 2921
 
-#line 2916
+#line 2921
     *xpp = (void *)(xp + rndup);
-#line 2916
+#line 2921
     return status;
-#line 2916
+#line 2921
 }
-#line 2916
+#line 2921
 
 int
-#line 2917
+#line 2922
 ncx_pad_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 2917
+#line 2922
 {
-#line 2917
+#line 2922
     int status = NC_NOERR;
-#line 2917
+#line 2922
     size_t rndup = nelems % X_ALIGN;
-#line 2917
+#line 2922
     schar *xp = (schar *) *xpp;
-#line 2917
+#line 2922
 
-#line 2917
+#line 2922
     if (rndup)
-#line 2917
+#line 2922
         rndup = X_ALIGN - rndup;
-#line 2917
+#line 2922
 
-#line 2917
+#line 2922
     while (nelems-- != 0) {
-#line 2917
+#line 2922
         
-#line 2917
+#line 2922
         if (*xp < 0) {
-#line 2917
+#line 2922
 #ifdef ERANGE_FILL
-#line 2917
+#line 2922
             *tp = NC_FILL_USHORT;
-#line 2917
+#line 2922
 #endif
-#line 2917
+#line 2922
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2917
+#line 2922
             
-#line 2917
+#line 2922
 #ifdef ERANGE_FILL
-#line 2917
+#line 2922
             xp++; tp++; continue;
-#line 2917
+#line 2922
 #endif
-#line 2917
+#line 2922
         }
-#line 2917
+#line 2922
         *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
-#line 2917
+#line 2922
     }
-#line 2917
+#line 2922
 
-#line 2917
+#line 2922
     *xpp = (void *)(xp + rndup);
-#line 2917
+#line 2922
     return status;
-#line 2917
+#line 2922
 }
-#line 2917
+#line 2922
 
 int
-#line 2918
+#line 2923
 ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
-#line 2918
+#line 2923
 {
-#line 2918
+#line 2923
     int status = NC_NOERR;
-#line 2918
+#line 2923
     size_t rndup = nelems % X_ALIGN;
-#line 2918
+#line 2923
     schar *xp = (schar *) *xpp;
-#line 2918
+#line 2923
 
-#line 2918
+#line 2923
     if (rndup)
-#line 2918
+#line 2923
         rndup = X_ALIGN - rndup;
-#line 2918
+#line 2923
 
-#line 2918
+#line 2923
     while (nelems-- != 0) {
-#line 2918
+#line 2923
         
-#line 2918
+#line 2923
         if (*xp < 0) {
-#line 2918
+#line 2923
 #ifdef ERANGE_FILL
-#line 2918
+#line 2923
             *tp = NC_FILL_UINT;
-#line 2918
+#line 2923
 #endif
-#line 2918
+#line 2923
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2918
+#line 2923
             
-#line 2918
+#line 2923
 #ifdef ERANGE_FILL
-#line 2918
+#line 2923
             xp++; tp++; continue;
-#line 2918
+#line 2923
 #endif
-#line 2918
+#line 2923
         }
-#line 2918
+#line 2923
         *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
-#line 2918
+#line 2923
     }
-#line 2918
+#line 2923
 
-#line 2918
+#line 2923
     *xpp = (void *)(xp + rndup);
-#line 2918
+#line 2923
     return status;
-#line 2918
+#line 2923
 }
-#line 2918
+#line 2923
 
 int
-#line 2919
+#line 2924
 ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 2919
+#line 2924
 {
-#line 2919
+#line 2924
     int status = NC_NOERR;
-#line 2919
+#line 2924
     size_t rndup = nelems % X_ALIGN;
-#line 2919
+#line 2924
     schar *xp = (schar *) *xpp;
-#line 2919
+#line 2924
 
-#line 2919
+#line 2924
     if (rndup)
-#line 2919
+#line 2924
         rndup = X_ALIGN - rndup;
-#line 2919
+#line 2924
 
-#line 2919
+#line 2924
     while (nelems-- != 0) {
-#line 2919
+#line 2924
         
-#line 2919
+#line 2924
         if (*xp < 0) {
-#line 2919
+#line 2924
 #ifdef ERANGE_FILL
-#line 2919
+#line 2924
             *tp = NC_FILL_UINT64;
-#line 2919
+#line 2924
 #endif
-#line 2919
+#line 2924
             status = NC_ERANGE; /* because tp is unsigned */
-#line 2919
+#line 2924
             
-#line 2919
+#line 2924
 #ifdef ERANGE_FILL
-#line 2919
+#line 2924
             xp++; tp++; continue;
-#line 2919
+#line 2924
 #endif
-#line 2919
+#line 2924
         }
-#line 2919
+#line 2924
         *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
-#line 2919
+#line 2924
     }
-#line 2919
+#line 2924
 
-#line 2919
+#line 2924
     *xpp = (void *)(xp + rndup);
-#line 2919
+#line 2924
     return status;
-#line 2919
+#line 2924
 }
-#line 2919
+#line 2924
 
 
-#line 2922
+#line 2927
 int
 ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
 {
 		(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 2925
+#line 2930
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 2925
+#line 2930
 
-#line 2925
+#line 2930
 	return NC_NOERR;
-#line 2925
+#line 2930
 
 }
 int
-#line 2927
+#line 2932
 ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 2927
+#line 2932
 {
-#line 2927
+#line 2932
     int status = NC_NOERR;
-#line 2927
+#line 2932
     schar *xp = (schar *) *xpp;
-#line 2927
+#line 2932
 
-#line 2927
+#line 2932
     while (nelems-- != 0) {
-#line 2927
+#line 2932
         if (*tp > (uchar)X_SCHAR_MAX ) {
-#line 2927
+#line 2932
             
-#line 2927
+#line 2932
 #ifdef ERANGE_FILL
-#line 2927
+#line 2932
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2927
+#line 2932
 #endif
-#line 2927
+#line 2932
             status = NC_ERANGE;
-#line 2927
+#line 2932
             
-#line 2927
+#line 2932
 #ifdef ERANGE_FILL
-#line 2927
+#line 2932
             xp++; tp++; continue;
-#line 2927
+#line 2932
 #endif
-#line 2927
+#line 2932
         }
-#line 2927
+#line 2932
         *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
-#line 2927
+#line 2932
     }
-#line 2927
+#line 2932
 
-#line 2927
+#line 2932
     *xpp = (void *)xp;
-#line 2927
+#line 2932
     return status;
-#line 2927
+#line 2932
 }
-#line 2927
+#line 2932
 
 int
-#line 2928
+#line 2933
 ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 2928
+#line 2933
 {
-#line 2928
+#line 2933
     int status = NC_NOERR;
-#line 2928
+#line 2933
     schar *xp = (schar *) *xpp;
-#line 2928
+#line 2933
 
-#line 2928
+#line 2933
     while (nelems-- != 0) {
-#line 2928
+#line 2933
         if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2928
+#line 2933
             
-#line 2928
+#line 2933
 #ifdef ERANGE_FILL
-#line 2928
+#line 2933
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2928
+#line 2933
 #endif
-#line 2928
+#line 2933
             status = NC_ERANGE;
-#line 2928
+#line 2933
             
-#line 2928
+#line 2933
 #ifdef ERANGE_FILL
-#line 2928
+#line 2933
             xp++; tp++; continue;
-#line 2928
+#line 2933
 #endif
-#line 2928
+#line 2933
         }
-#line 2928
+#line 2933
         *xp++ = (schar)  *tp++; /* type cast from short to schar */
-#line 2928
+#line 2933
     }
-#line 2928
+#line 2933
 
-#line 2928
+#line 2933
     *xpp = (void *)xp;
-#line 2928
+#line 2933
     return status;
-#line 2928
+#line 2933
 }
-#line 2928
+#line 2933
 
 int
-#line 2929
+#line 2934
 ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 2929
+#line 2934
 {
-#line 2929
+#line 2934
     int status = NC_NOERR;
-#line 2929
+#line 2934
     schar *xp = (schar *) *xpp;
-#line 2929
+#line 2934
 
-#line 2929
+#line 2934
     while (nelems-- != 0) {
-#line 2929
+#line 2934
         if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2929
+#line 2934
             
-#line 2929
+#line 2934
 #ifdef ERANGE_FILL
-#line 2929
+#line 2934
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2929
+#line 2934
 #endif
-#line 2929
+#line 2934
             status = NC_ERANGE;
-#line 2929
+#line 2934
             
-#line 2929
+#line 2934
 #ifdef ERANGE_FILL
-#line 2929
+#line 2934
             xp++; tp++; continue;
-#line 2929
+#line 2934
 #endif
-#line 2929
+#line 2934
         }
-#line 2929
+#line 2934
         *xp++ = (schar)  *tp++; /* type cast from int to schar */
-#line 2929
+#line 2934
     }
-#line 2929
+#line 2934
 
-#line 2929
+#line 2934
     *xpp = (void *)xp;
-#line 2929
+#line 2934
     return status;
-#line 2929
+#line 2934
 }
-#line 2929
+#line 2934
 
 int
-#line 2930
+#line 2935
 ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 2930
+#line 2935
 {
-#line 2930
+#line 2935
     int status = NC_NOERR;
-#line 2930
+#line 2935
     schar *xp = (schar *) *xpp;
-#line 2930
+#line 2935
 
-#line 2930
+#line 2935
     while (nelems-- != 0) {
-#line 2930
+#line 2935
         if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2930
+#line 2935
             
-#line 2930
+#line 2935
 #ifdef ERANGE_FILL
-#line 2930
+#line 2935
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2930
+#line 2935
 #endif
-#line 2930
+#line 2935
             status = NC_ERANGE;
-#line 2930
+#line 2935
             
-#line 2930
+#line 2935
 #ifdef ERANGE_FILL
-#line 2930
+#line 2935
             xp++; tp++; continue;
-#line 2930
+#line 2935
 #endif
-#line 2930
+#line 2935
         }
-#line 2930
+#line 2935
         *xp++ = (schar)  *tp++; /* type cast from long to schar */
-#line 2930
+#line 2935
     }
-#line 2930
+#line 2935
 
-#line 2930
+#line 2935
     *xpp = (void *)xp;
-#line 2930
+#line 2935
     return status;
-#line 2930
+#line 2935
 }
-#line 2930
+#line 2935
 
 int
-#line 2931
+#line 2936
 ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 2931
+#line 2936
 {
-#line 2931
+#line 2936
     int status = NC_NOERR;
-#line 2931
+#line 2936
     schar *xp = (schar *) *xpp;
-#line 2931
+#line 2936
 
-#line 2931
+#line 2936
     while (nelems-- != 0) {
-#line 2931
+#line 2936
         if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2931
+#line 2936
             
-#line 2931
+#line 2936
 #ifdef ERANGE_FILL
-#line 2931
+#line 2936
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2931
+#line 2936
 #endif
-#line 2931
+#line 2936
             status = NC_ERANGE;
-#line 2931
+#line 2936
             
-#line 2931
+#line 2936
 #ifdef ERANGE_FILL
-#line 2931
+#line 2936
             xp++; tp++; continue;
-#line 2931
+#line 2936
 #endif
-#line 2931
+#line 2936
         }
-#line 2931
+#line 2936
         *xp++ = (schar)  *tp++; /* type cast from float to schar */
-#line 2931
+#line 2936
     }
-#line 2931
+#line 2936
 
-#line 2931
+#line 2936
     *xpp = (void *)xp;
-#line 2931
+#line 2936
     return status;
-#line 2931
+#line 2936
 }
-#line 2931
+#line 2936
 
 int
-#line 2932
+#line 2937
 ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 2932
+#line 2937
 {
-#line 2932
+#line 2937
     int status = NC_NOERR;
-#line 2932
+#line 2937
     schar *xp = (schar *) *xpp;
-#line 2932
+#line 2937
 
-#line 2932
+#line 2937
     while (nelems-- != 0) {
-#line 2932
+#line 2937
         if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2932
+#line 2937
             
-#line 2932
+#line 2937
 #ifdef ERANGE_FILL
-#line 2932
+#line 2937
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2932
+#line 2937
 #endif
-#line 2932
+#line 2937
             status = NC_ERANGE;
-#line 2932
+#line 2937
             
-#line 2932
+#line 2937
 #ifdef ERANGE_FILL
-#line 2932
+#line 2937
             xp++; tp++; continue;
-#line 2932
+#line 2937
 #endif
-#line 2932
+#line 2937
         }
-#line 2932
+#line 2937
         *xp++ = (schar)  *tp++; /* type cast from double to schar */
-#line 2932
+#line 2937
     }
-#line 2932
+#line 2937
 
-#line 2932
+#line 2937
     *xpp = (void *)xp;
-#line 2932
+#line 2937
     return status;
-#line 2932
+#line 2937
 }
-#line 2932
+#line 2937
 
 int
-#line 2933
+#line 2938
 ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 2933
+#line 2938
 {
-#line 2933
+#line 2938
     int status = NC_NOERR;
-#line 2933
+#line 2938
     schar *xp = (schar *) *xpp;
-#line 2933
+#line 2938
 
-#line 2933
+#line 2938
     while (nelems-- != 0) {
-#line 2933
+#line 2938
         if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2933
+#line 2938
             
-#line 2933
+#line 2938
 #ifdef ERANGE_FILL
-#line 2933
+#line 2938
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2933
+#line 2938
 #endif
-#line 2933
+#line 2938
             status = NC_ERANGE;
-#line 2933
+#line 2938
             
-#line 2933
+#line 2938
 #ifdef ERANGE_FILL
-#line 2933
+#line 2938
             xp++; tp++; continue;
-#line 2933
+#line 2938
 #endif
-#line 2933
+#line 2938
         }
-#line 2933
+#line 2938
         *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
-#line 2933
+#line 2938
     }
-#line 2933
+#line 2938
 
-#line 2933
+#line 2938
     *xpp = (void *)xp;
-#line 2933
+#line 2938
     return status;
-#line 2933
+#line 2938
 }
-#line 2933
+#line 2938
 
 int
-#line 2934
+#line 2939
 ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 2934
+#line 2939
 {
-#line 2934
+#line 2939
     int status = NC_NOERR;
-#line 2934
+#line 2939
     schar *xp = (schar *) *xpp;
-#line 2934
+#line 2939
 
-#line 2934
+#line 2939
     while (nelems-- != 0) {
-#line 2934
+#line 2939
         if (*tp > (ushort)X_SCHAR_MAX ) {
-#line 2934
+#line 2939
             
-#line 2934
+#line 2939
 #ifdef ERANGE_FILL
-#line 2934
+#line 2939
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2934
+#line 2939
 #endif
-#line 2934
+#line 2939
             status = NC_ERANGE;
-#line 2934
+#line 2939
             
-#line 2934
+#line 2939
 #ifdef ERANGE_FILL
-#line 2934
+#line 2939
             xp++; tp++; continue;
-#line 2934
+#line 2939
 #endif
-#line 2934
+#line 2939
         }
-#line 2934
+#line 2939
         *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
-#line 2934
+#line 2939
     }
-#line 2934
+#line 2939
 
-#line 2934
+#line 2939
     *xpp = (void *)xp;
-#line 2934
+#line 2939
     return status;
-#line 2934
+#line 2939
 }
-#line 2934
+#line 2939
 
 int
-#line 2935
+#line 2940
 ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 2935
+#line 2940
 {
-#line 2935
+#line 2940
     int status = NC_NOERR;
-#line 2935
+#line 2940
     schar *xp = (schar *) *xpp;
-#line 2935
+#line 2940
 
-#line 2935
+#line 2940
     while (nelems-- != 0) {
-#line 2935
+#line 2940
         if (*tp > (uint)X_SCHAR_MAX ) {
-#line 2935
+#line 2940
             
-#line 2935
+#line 2940
 #ifdef ERANGE_FILL
-#line 2935
+#line 2940
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2935
+#line 2940
 #endif
-#line 2935
+#line 2940
             status = NC_ERANGE;
-#line 2935
+#line 2940
             
-#line 2935
+#line 2940
 #ifdef ERANGE_FILL
-#line 2935
+#line 2940
             xp++; tp++; continue;
-#line 2935
+#line 2940
 #endif
-#line 2935
+#line 2940
         }
-#line 2935
+#line 2940
         *xp++ = (schar)  *tp++; /* type cast from uint to schar */
-#line 2935
+#line 2940
     }
-#line 2935
+#line 2940
 
-#line 2935
+#line 2940
     *xpp = (void *)xp;
-#line 2935
+#line 2940
     return status;
-#line 2935
+#line 2940
 }
-#line 2935
+#line 2940
 
 int
-#line 2936
+#line 2941
 ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 2936
+#line 2941
 {
-#line 2936
+#line 2941
     int status = NC_NOERR;
-#line 2936
+#line 2941
     schar *xp = (schar *) *xpp;
-#line 2936
+#line 2941
 
-#line 2936
+#line 2941
     while (nelems-- != 0) {
-#line 2936
+#line 2941
         if (*tp > (ulonglong)X_SCHAR_MAX ) {
-#line 2936
+#line 2941
             
-#line 2936
+#line 2941
 #ifdef ERANGE_FILL
-#line 2936
+#line 2941
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2936
+#line 2941
 #endif
-#line 2936
+#line 2941
             status = NC_ERANGE;
-#line 2936
+#line 2941
             
-#line 2936
+#line 2941
 #ifdef ERANGE_FILL
-#line 2936
+#line 2941
             xp++; tp++; continue;
-#line 2936
+#line 2941
 #endif
-#line 2936
+#line 2941
         }
-#line 2936
+#line 2941
         *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
-#line 2936
+#line 2941
     }
-#line 2936
+#line 2941
 
-#line 2936
+#line 2941
     *xpp = (void *)xp;
-#line 2936
+#line 2941
     return status;
-#line 2936
+#line 2941
 }
-#line 2936
+#line 2941
 
 
-#line 2939
+#line 2944
 int
 ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
 {
 		size_t rndup = nelems % X_ALIGN;
-#line 2942
+#line 2947
 
-#line 2942
+#line 2947
 	if (rndup)
-#line 2942
+#line 2947
 		rndup = X_ALIGN - rndup;
-#line 2942
+#line 2947
 
-#line 2942
+#line 2947
 	(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 2942
+#line 2947
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 2942
+#line 2947
 
-#line 2942
+#line 2947
 	if (rndup)
-#line 2942
+#line 2947
 	{
-#line 2942
+#line 2947
 		(void) memcpy(*xpp, nada, (size_t)rndup);
-#line 2942
+#line 2947
 		*xpp = (void *)((char *)(*xpp) + rndup);
-#line 2942
+#line 2947
 	}
-#line 2942
+#line 2947
 
-#line 2942
+#line 2947
 	return NC_NOERR;
-#line 2942
+#line 2947
 
 }
 int
-#line 2944
+#line 2949
 ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 2944
+#line 2949
 {
-#line 2944
+#line 2949
     int status = NC_NOERR;
-#line 2944
+#line 2949
     size_t rndup = nelems % X_ALIGN;
-#line 2944
+#line 2949
     schar *xp = (schar *) *xpp;
-#line 2944
+#line 2949
 
-#line 2944
+#line 2949
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2944
+#line 2949
 
-#line 2944
+#line 2949
     while (nelems-- != 0) {
-#line 2944
+#line 2949
         if (*tp > (uchar)X_SCHAR_MAX ) {
-#line 2944
+#line 2949
             
-#line 2944
+#line 2949
 #ifdef ERANGE_FILL
-#line 2944
+#line 2949
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2944
+#line 2949
 #endif
-#line 2944
+#line 2949
             status = NC_ERANGE;
-#line 2944
+#line 2949
             
-#line 2944
+#line 2949
 #ifdef ERANGE_FILL
-#line 2944
+#line 2949
             xp++; tp++; continue;
-#line 2944
+#line 2949
 #endif
-#line 2944
+#line 2949
         }
-#line 2944
+#line 2949
         *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
-#line 2944
+#line 2949
     }
-#line 2944
+#line 2949
 
-#line 2944
+#line 2949
 
-#line 2944
+#line 2949
     if (rndup) {
-#line 2944
+#line 2949
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2944
+#line 2949
         xp += rndup;
-#line 2944
+#line 2949
     }
-#line 2944
+#line 2949
 
-#line 2944
+#line 2949
     *xpp = (void *)xp;
-#line 2944
+#line 2949
     return status;
-#line 2944
+#line 2949
 }
-#line 2944
+#line 2949
 
 int
-#line 2945
+#line 2950
 ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 2945
+#line 2950
 {
-#line 2945
+#line 2950
     int status = NC_NOERR;
-#line 2945
+#line 2950
     size_t rndup = nelems % X_ALIGN;
-#line 2945
+#line 2950
     schar *xp = (schar *) *xpp;
-#line 2945
+#line 2950
 
-#line 2945
+#line 2950
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2945
+#line 2950
 
-#line 2945
+#line 2950
     while (nelems-- != 0) {
-#line 2945
+#line 2950
         if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2945
+#line 2950
             
-#line 2945
+#line 2950
 #ifdef ERANGE_FILL
-#line 2945
+#line 2950
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2945
+#line 2950
 #endif
-#line 2945
+#line 2950
             status = NC_ERANGE;
-#line 2945
+#line 2950
             
-#line 2945
+#line 2950
 #ifdef ERANGE_FILL
-#line 2945
+#line 2950
             xp++; tp++; continue;
-#line 2945
+#line 2950
 #endif
-#line 2945
+#line 2950
         }
-#line 2945
+#line 2950
         *xp++ = (schar)  *tp++; /* type cast from short to schar */
-#line 2945
+#line 2950
     }
-#line 2945
+#line 2950
 
-#line 2945
+#line 2950
 
-#line 2945
+#line 2950
     if (rndup) {
-#line 2945
+#line 2950
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2945
+#line 2950
         xp += rndup;
-#line 2945
+#line 2950
     }
-#line 2945
+#line 2950
 
-#line 2945
+#line 2950
     *xpp = (void *)xp;
-#line 2945
+#line 2950
     return status;
-#line 2945
+#line 2950
 }
-#line 2945
+#line 2950
 
 int
-#line 2946
+#line 2951
 ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 2946
+#line 2951
 {
-#line 2946
+#line 2951
     int status = NC_NOERR;
-#line 2946
+#line 2951
     size_t rndup = nelems % X_ALIGN;
-#line 2946
+#line 2951
     schar *xp = (schar *) *xpp;
-#line 2946
+#line 2951
 
-#line 2946
+#line 2951
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2946
+#line 2951
 
-#line 2946
+#line 2951
     while (nelems-- != 0) {
-#line 2946
+#line 2951
         if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2946
+#line 2951
             
-#line 2946
+#line 2951
 #ifdef ERANGE_FILL
-#line 2946
+#line 2951
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2946
+#line 2951
 #endif
-#line 2946
+#line 2951
             status = NC_ERANGE;
-#line 2946
+#line 2951
             
-#line 2946
+#line 2951
 #ifdef ERANGE_FILL
-#line 2946
+#line 2951
             xp++; tp++; continue;
-#line 2946
+#line 2951
 #endif
-#line 2946
+#line 2951
         }
-#line 2946
+#line 2951
         *xp++ = (schar)  *tp++; /* type cast from int to schar */
-#line 2946
+#line 2951
     }
-#line 2946
+#line 2951
 
-#line 2946
+#line 2951
 
-#line 2946
+#line 2951
     if (rndup) {
-#line 2946
+#line 2951
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2946
+#line 2951
         xp += rndup;
-#line 2946
+#line 2951
     }
-#line 2946
+#line 2951
 
-#line 2946
+#line 2951
     *xpp = (void *)xp;
-#line 2946
+#line 2951
     return status;
-#line 2946
+#line 2951
 }
-#line 2946
+#line 2951
 
 int
-#line 2947
+#line 2952
 ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 2947
+#line 2952
 {
-#line 2947
+#line 2952
     int status = NC_NOERR;
-#line 2947
+#line 2952
     size_t rndup = nelems % X_ALIGN;
-#line 2947
+#line 2952
     schar *xp = (schar *) *xpp;
-#line 2947
+#line 2952
 
-#line 2947
+#line 2952
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2947
+#line 2952
 
-#line 2947
+#line 2952
     while (nelems-- != 0) {
-#line 2947
+#line 2952
         if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2947
+#line 2952
             
-#line 2947
+#line 2952
 #ifdef ERANGE_FILL
-#line 2947
+#line 2952
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2947
+#line 2952
 #endif
-#line 2947
+#line 2952
             status = NC_ERANGE;
-#line 2947
+#line 2952
             
-#line 2947
+#line 2952
 #ifdef ERANGE_FILL
-#line 2947
+#line 2952
             xp++; tp++; continue;
-#line 2947
+#line 2952
 #endif
-#line 2947
+#line 2952
         }
-#line 2947
+#line 2952
         *xp++ = (schar)  *tp++; /* type cast from long to schar */
-#line 2947
+#line 2952
     }
-#line 2947
+#line 2952
 
-#line 2947
+#line 2952
 
-#line 2947
+#line 2952
     if (rndup) {
-#line 2947
+#line 2952
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2947
+#line 2952
         xp += rndup;
-#line 2947
+#line 2952
     }
-#line 2947
+#line 2952
 
-#line 2947
+#line 2952
     *xpp = (void *)xp;
-#line 2947
+#line 2952
     return status;
-#line 2947
+#line 2952
 }
-#line 2947
+#line 2952
 
 int
-#line 2948
+#line 2953
 ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 2948
+#line 2953
 {
-#line 2948
+#line 2953
     int status = NC_NOERR;
-#line 2948
+#line 2953
     size_t rndup = nelems % X_ALIGN;
-#line 2948
+#line 2953
     schar *xp = (schar *) *xpp;
-#line 2948
+#line 2953
 
-#line 2948
+#line 2953
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2948
+#line 2953
 
-#line 2948
+#line 2953
     while (nelems-- != 0) {
-#line 2948
+#line 2953
         if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2948
+#line 2953
             
-#line 2948
+#line 2953
 #ifdef ERANGE_FILL
-#line 2948
+#line 2953
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2948
+#line 2953
 #endif
-#line 2948
+#line 2953
             status = NC_ERANGE;
-#line 2948
+#line 2953
             
-#line 2948
+#line 2953
 #ifdef ERANGE_FILL
-#line 2948
+#line 2953
             xp++; tp++; continue;
-#line 2948
+#line 2953
 #endif
-#line 2948
+#line 2953
         }
-#line 2948
+#line 2953
         *xp++ = (schar)  *tp++; /* type cast from float to schar */
-#line 2948
+#line 2953
     }
-#line 2948
+#line 2953
 
-#line 2948
+#line 2953
 
-#line 2948
+#line 2953
     if (rndup) {
-#line 2948
+#line 2953
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2948
+#line 2953
         xp += rndup;
-#line 2948
+#line 2953
     }
-#line 2948
+#line 2953
 
-#line 2948
+#line 2953
     *xpp = (void *)xp;
-#line 2948
+#line 2953
     return status;
-#line 2948
+#line 2953
 }
-#line 2948
+#line 2953
 
 int
-#line 2949
+#line 2954
 ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 2949
+#line 2954
 {
-#line 2949
+#line 2954
     int status = NC_NOERR;
-#line 2949
+#line 2954
     size_t rndup = nelems % X_ALIGN;
-#line 2949
+#line 2954
     schar *xp = (schar *) *xpp;
-#line 2949
+#line 2954
 
-#line 2949
+#line 2954
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2949
+#line 2954
 
-#line 2949
+#line 2954
     while (nelems-- != 0) {
-#line 2949
+#line 2954
         if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2949
+#line 2954
             
-#line 2949
+#line 2954
 #ifdef ERANGE_FILL
-#line 2949
+#line 2954
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2949
+#line 2954
 #endif
-#line 2949
+#line 2954
             status = NC_ERANGE;
-#line 2949
+#line 2954
             
-#line 2949
+#line 2954
 #ifdef ERANGE_FILL
-#line 2949
+#line 2954
             xp++; tp++; continue;
-#line 2949
+#line 2954
 #endif
-#line 2949
+#line 2954
         }
-#line 2949
+#line 2954
         *xp++ = (schar)  *tp++; /* type cast from double to schar */
-#line 2949
+#line 2954
     }
-#line 2949
+#line 2954
 
-#line 2949
+#line 2954
 
-#line 2949
+#line 2954
     if (rndup) {
-#line 2949
+#line 2954
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2949
+#line 2954
         xp += rndup;
-#line 2949
+#line 2954
     }
-#line 2949
+#line 2954
 
-#line 2949
+#line 2954
     *xpp = (void *)xp;
-#line 2949
+#line 2954
     return status;
-#line 2949
+#line 2954
 }
-#line 2949
+#line 2954
 
 int
-#line 2950
+#line 2955
 ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 2950
+#line 2955
 {
-#line 2950
+#line 2955
     int status = NC_NOERR;
-#line 2950
+#line 2955
     size_t rndup = nelems % X_ALIGN;
-#line 2950
+#line 2955
     schar *xp = (schar *) *xpp;
-#line 2950
+#line 2955
 
-#line 2950
+#line 2955
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2950
+#line 2955
 
-#line 2950
+#line 2955
     while (nelems-- != 0) {
-#line 2950
+#line 2955
         if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
-#line 2950
+#line 2955
             
-#line 2950
+#line 2955
 #ifdef ERANGE_FILL
-#line 2950
+#line 2955
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2950
+#line 2955
 #endif
-#line 2950
+#line 2955
             status = NC_ERANGE;
-#line 2950
+#line 2955
             
-#line 2950
+#line 2955
 #ifdef ERANGE_FILL
-#line 2950
+#line 2955
             xp++; tp++; continue;
-#line 2950
+#line 2955
 #endif
-#line 2950
+#line 2955
         }
-#line 2950
+#line 2955
         *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
-#line 2950
+#line 2955
     }
-#line 2950
+#line 2955
 
-#line 2950
+#line 2955
 
-#line 2950
+#line 2955
     if (rndup) {
-#line 2950
+#line 2955
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2950
+#line 2955
         xp += rndup;
-#line 2950
+#line 2955
     }
-#line 2950
+#line 2955
 
-#line 2950
+#line 2955
     *xpp = (void *)xp;
-#line 2950
+#line 2955
     return status;
-#line 2950
+#line 2955
 }
-#line 2950
+#line 2955
 
 int
-#line 2951
+#line 2956
 ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 2951
+#line 2956
 {
-#line 2951
+#line 2956
     int status = NC_NOERR;
-#line 2951
+#line 2956
     size_t rndup = nelems % X_ALIGN;
-#line 2951
+#line 2956
     schar *xp = (schar *) *xpp;
-#line 2951
+#line 2956
 
-#line 2951
+#line 2956
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2951
+#line 2956
 
-#line 2951
+#line 2956
     while (nelems-- != 0) {
-#line 2951
+#line 2956
         if (*tp > (ushort)X_SCHAR_MAX ) {
-#line 2951
+#line 2956
             
-#line 2951
+#line 2956
 #ifdef ERANGE_FILL
-#line 2951
+#line 2956
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2951
+#line 2956
 #endif
-#line 2951
+#line 2956
             status = NC_ERANGE;
-#line 2951
+#line 2956
             
-#line 2951
+#line 2956
 #ifdef ERANGE_FILL
-#line 2951
+#line 2956
             xp++; tp++; continue;
-#line 2951
+#line 2956
 #endif
-#line 2951
+#line 2956
         }
-#line 2951
+#line 2956
         *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
-#line 2951
+#line 2956
     }
-#line 2951
+#line 2956
 
-#line 2951
+#line 2956
 
-#line 2951
+#line 2956
     if (rndup) {
-#line 2951
+#line 2956
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2951
+#line 2956
         xp += rndup;
-#line 2951
+#line 2956
     }
-#line 2951
+#line 2956
 
-#line 2951
+#line 2956
     *xpp = (void *)xp;
-#line 2951
+#line 2956
     return status;
-#line 2951
+#line 2956
 }
-#line 2951
+#line 2956
 
 int
-#line 2952
+#line 2957
 ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 2952
+#line 2957
 {
-#line 2952
+#line 2957
     int status = NC_NOERR;
-#line 2952
+#line 2957
     size_t rndup = nelems % X_ALIGN;
-#line 2952
+#line 2957
     schar *xp = (schar *) *xpp;
-#line 2952
+#line 2957
 
-#line 2952
+#line 2957
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2952
+#line 2957
 
-#line 2952
+#line 2957
     while (nelems-- != 0) {
-#line 2952
+#line 2957
         if (*tp > (uint)X_SCHAR_MAX ) {
-#line 2952
+#line 2957
             
-#line 2952
+#line 2957
 #ifdef ERANGE_FILL
-#line 2952
+#line 2957
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2952
+#line 2957
 #endif
-#line 2952
+#line 2957
             status = NC_ERANGE;
-#line 2952
+#line 2957
             
-#line 2952
+#line 2957
 #ifdef ERANGE_FILL
-#line 2952
+#line 2957
             xp++; tp++; continue;
-#line 2952
+#line 2957
 #endif
-#line 2952
+#line 2957
         }
-#line 2952
+#line 2957
         *xp++ = (schar)  *tp++; /* type cast from uint to schar */
-#line 2952
+#line 2957
     }
-#line 2952
+#line 2957
 
-#line 2952
+#line 2957
 
-#line 2952
+#line 2957
     if (rndup) {
-#line 2952
+#line 2957
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2952
+#line 2957
         xp += rndup;
-#line 2952
+#line 2957
     }
-#line 2952
+#line 2957
 
-#line 2952
+#line 2957
     *xpp = (void *)xp;
-#line 2952
+#line 2957
     return status;
-#line 2952
+#line 2957
 }
-#line 2952
+#line 2957
 
 int
-#line 2953
+#line 2958
 ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 2953
+#line 2958
 {
-#line 2953
+#line 2958
     int status = NC_NOERR;
-#line 2953
+#line 2958
     size_t rndup = nelems % X_ALIGN;
-#line 2953
+#line 2958
     schar *xp = (schar *) *xpp;
-#line 2953
+#line 2958
 
-#line 2953
+#line 2958
     if (rndup) rndup = X_ALIGN - rndup;
-#line 2953
+#line 2958
 
-#line 2953
+#line 2958
     while (nelems-- != 0) {
-#line 2953
+#line 2958
         if (*tp > (ulonglong)X_SCHAR_MAX ) {
-#line 2953
+#line 2958
             
-#line 2953
+#line 2958
 #ifdef ERANGE_FILL
-#line 2953
+#line 2958
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 2953
+#line 2958
 #endif
-#line 2953
+#line 2958
             status = NC_ERANGE;
-#line 2953
+#line 2958
             
-#line 2953
+#line 2958
 #ifdef ERANGE_FILL
-#line 2953
+#line 2958
             xp++; tp++; continue;
-#line 2953
+#line 2958
 #endif
-#line 2953
+#line 2958
         }
-#line 2953
+#line 2958
         *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
-#line 2953
+#line 2958
     }
-#line 2953
+#line 2958
 
-#line 2953
+#line 2958
 
-#line 2953
+#line 2958
     if (rndup) {
-#line 2953
+#line 2958
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 2953
+#line 2958
         xp += rndup;
-#line 2953
+#line 2958
     }
-#line 2953
+#line 2958
 
-#line 2953
+#line 2958
     *xpp = (void *)xp;
-#line 2953
+#line 2958
     return status;
-#line 2953
+#line 2958
 }
-#line 2953
+#line 2958
 
 
 
 /* uchar ---------------------------------------------------------------------*/
-#line 2959
+#line 2964
 int
 ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
 {
@@ -11655,11 +11660,11 @@ ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
             *tp = NC_FILL_BYTE;
        	    status = NC_ERANGE;
             
-#line 2969
+#line 2974
 #ifdef ERANGE_FILL
-#line 2969
+#line 2974
             xp++; tp++; continue;
-#line 2969
+#line 2974
 #endif
         }
 	*tp++ = (schar) *xp++; /* type cast from uchar to schar */
@@ -11668,281 +11673,281 @@ ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
     *xpp = (const void *)xp;
     return status;
 }
-#line 2978
+#line 2983
 int
 ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
 {
 		(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 2981
+#line 2986
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 2981
+#line 2986
 	return NC_NOERR;
-#line 2981
+#line 2986
 
 }
 int
-#line 2983
+#line 2988
 ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
-#line 2983
+#line 2988
 {
-#line 2983
+#line 2988
     int status = NC_NOERR;
-#line 2983
+#line 2988
     uchar *xp = (uchar *)(*xpp);
-#line 2983
+#line 2988
 
-#line 2983
+#line 2988
     while (nelems-- != 0) {
-#line 2983
+#line 2988
         
-#line 2983
+#line 2988
         *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
-#line 2983
+#line 2988
     }
-#line 2983
+#line 2988
 
-#line 2983
+#line 2988
     *xpp = (const void *)xp;
-#line 2983
+#line 2988
     return status;
-#line 2983
+#line 2988
 }
-#line 2983
+#line 2988
 
 int
-#line 2984
+#line 2989
 ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
-#line 2984
+#line 2989
 {
-#line 2984
+#line 2989
     int status = NC_NOERR;
-#line 2984
+#line 2989
     uchar *xp = (uchar *)(*xpp);
-#line 2984
+#line 2989
 
-#line 2984
+#line 2989
     while (nelems-- != 0) {
-#line 2984
+#line 2989
         
-#line 2984
+#line 2989
         *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
-#line 2984
+#line 2989
     }
-#line 2984
+#line 2989
 
-#line 2984
+#line 2989
     *xpp = (const void *)xp;
-#line 2984
+#line 2989
     return status;
-#line 2984
+#line 2989
 }
-#line 2984
+#line 2989
 
 int
-#line 2985
+#line 2990
 ncx_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
-#line 2985
+#line 2990
 {
-#line 2985
+#line 2990
     int status = NC_NOERR;
-#line 2985
+#line 2990
     uchar *xp = (uchar *)(*xpp);
-#line 2985
+#line 2990
 
-#line 2985
+#line 2990
     while (nelems-- != 0) {
-#line 2985
+#line 2990
         
-#line 2985
+#line 2990
         *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
-#line 2985
+#line 2990
     }
-#line 2985
+#line 2990
 
-#line 2985
+#line 2990
     *xpp = (const void *)xp;
-#line 2985
+#line 2990
     return status;
-#line 2985
+#line 2990
 }
-#line 2985
+#line 2990
 
 int
-#line 2986
+#line 2991
 ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
-#line 2986
+#line 2991
 {
-#line 2986
+#line 2991
     int status = NC_NOERR;
-#line 2986
+#line 2991
     uchar *xp = (uchar *)(*xpp);
-#line 2986
+#line 2991
 
-#line 2986
+#line 2991
     while (nelems-- != 0) {
-#line 2986
+#line 2991
         
-#line 2986
+#line 2991
         *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
-#line 2986
+#line 2991
     }
-#line 2986
+#line 2991
 
-#line 2986
+#line 2991
     *xpp = (const void *)xp;
-#line 2986
+#line 2991
     return status;
-#line 2986
+#line 2991
 }
-#line 2986
+#line 2991
 
 int
-#line 2987
+#line 2992
 ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
-#line 2987
+#line 2992
 {
-#line 2987
+#line 2992
     int status = NC_NOERR;
-#line 2987
+#line 2992
     uchar *xp = (uchar *)(*xpp);
-#line 2987
+#line 2992
 
-#line 2987
+#line 2992
     while (nelems-- != 0) {
-#line 2987
+#line 2992
         
-#line 2987
+#line 2992
         *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
-#line 2987
+#line 2992
     }
-#line 2987
+#line 2992
 
-#line 2987
+#line 2992
     *xpp = (const void *)xp;
-#line 2987
+#line 2992
     return status;
-#line 2987
+#line 2992
 }
-#line 2987
+#line 2992
 
 int
-#line 2988
+#line 2993
 ncx_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 2988
+#line 2993
 {
-#line 2988
+#line 2993
     int status = NC_NOERR;
-#line 2988
+#line 2993
     uchar *xp = (uchar *)(*xpp);
-#line 2988
+#line 2993
 
-#line 2988
+#line 2993
     while (nelems-- != 0) {
-#line 2988
+#line 2993
         
-#line 2988
+#line 2993
         *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
-#line 2988
+#line 2993
     }
-#line 2988
+#line 2993
 
-#line 2988
+#line 2993
     *xpp = (const void *)xp;
-#line 2988
+#line 2993
     return status;
-#line 2988
+#line 2993
 }
-#line 2988
+#line 2993
 
 int
-#line 2989
+#line 2994
 ncx_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 2989
+#line 2994
 {
-#line 2989
+#line 2994
     int status = NC_NOERR;
-#line 2989
+#line 2994
     uchar *xp = (uchar *)(*xpp);
-#line 2989
+#line 2994
 
-#line 2989
+#line 2994
     while (nelems-- != 0) {
-#line 2989
+#line 2994
         
-#line 2989
+#line 2994
         *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
-#line 2989
+#line 2994
     }
-#line 2989
+#line 2994
 
-#line 2989
+#line 2994
     *xpp = (const void *)xp;
-#line 2989
+#line 2994
     return status;
-#line 2989
+#line 2994
 }
-#line 2989
+#line 2994
 
 int
-#line 2990
+#line 2995
 ncx_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
-#line 2990
+#line 2995
 {
-#line 2990
+#line 2995
     int status = NC_NOERR;
-#line 2990
+#line 2995
     uchar *xp = (uchar *)(*xpp);
-#line 2990
+#line 2995
 
-#line 2990
+#line 2995
     while (nelems-- != 0) {
-#line 2990
+#line 2995
         
-#line 2990
+#line 2995
         *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
-#line 2990
+#line 2995
     }
-#line 2990
+#line 2995
 
-#line 2990
+#line 2995
     *xpp = (const void *)xp;
-#line 2990
+#line 2995
     return status;
-#line 2990
+#line 2995
 }
-#line 2990
+#line 2995
 
 int
-#line 2991
+#line 2996
 ncx_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 2991
+#line 2996
 {
-#line 2991
+#line 2996
     int status = NC_NOERR;
-#line 2991
+#line 2996
     uchar *xp = (uchar *)(*xpp);
-#line 2991
+#line 2996
 
-#line 2991
+#line 2996
     while (nelems-- != 0) {
-#line 2991
+#line 2996
         
-#line 2991
+#line 2996
         *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
-#line 2991
+#line 2996
     }
-#line 2991
+#line 2996
 
-#line 2991
+#line 2996
     *xpp = (const void *)xp;
-#line 2991
+#line 2996
     return status;
-#line 2991
+#line 2996
 }
-#line 2991
+#line 2996
 
 
-#line 2994
+#line 2999
 int
 ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
 {
@@ -11957,11 +11962,11 @@ ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
             *tp = NC_FILL_BYTE;
             status = NC_ERANGE;
             
-#line 3007
+#line 3012
 #ifdef ERANGE_FILL
-#line 3007
+#line 3012
             xp++; tp++; continue;
-#line 3007
+#line 3012
 #endif
         }
         *tp++ = (schar) *xp++; /* type cast from uchar to schar */
@@ -11970,365 +11975,365 @@ ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
     *xpp = (void *)(xp + rndup);
     return status;
 }
-#line 3016
+#line 3021
 int
 ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
 {
 		size_t rndup = nelems % X_ALIGN;
-#line 3019
+#line 3024
 
-#line 3019
+#line 3024
 	if (rndup)
-#line 3019
+#line 3024
 		rndup = X_ALIGN - rndup;
-#line 3019
+#line 3024
 
-#line 3019
+#line 3024
 	(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 3019
+#line 3024
 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
-#line 3019
+#line 3024
 
-#line 3019
+#line 3024
 	return NC_NOERR;
-#line 3019
+#line 3024
 
 }
 int
-#line 3021
+#line 3026
 ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
-#line 3021
+#line 3026
 {
-#line 3021
+#line 3026
     int status = NC_NOERR;
-#line 3021
+#line 3026
     size_t rndup = nelems % X_ALIGN;
-#line 3021
+#line 3026
     uchar *xp = (uchar *) *xpp;
-#line 3021
+#line 3026
 
-#line 3021
+#line 3026
     if (rndup)
-#line 3021
+#line 3026
         rndup = X_ALIGN - rndup;
-#line 3021
+#line 3026
 
-#line 3021
+#line 3026
     while (nelems-- != 0) {
-#line 3021
+#line 3026
         
-#line 3021
+#line 3026
         *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
-#line 3021
+#line 3026
     }
-#line 3021
+#line 3026
 
-#line 3021
+#line 3026
     *xpp = (void *)(xp + rndup);
-#line 3021
+#line 3026
     return status;
-#line 3021
+#line 3026
 }
-#line 3021
+#line 3026
 
 int
-#line 3022
+#line 3027
 ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
-#line 3022
+#line 3027
 {
-#line 3022
+#line 3027
     int status = NC_NOERR;
-#line 3022
+#line 3027
     size_t rndup = nelems % X_ALIGN;
-#line 3022
+#line 3027
     uchar *xp = (uchar *) *xpp;
-#line 3022
+#line 3027
 
-#line 3022
+#line 3027
     if (rndup)
-#line 3022
+#line 3027
         rndup = X_ALIGN - rndup;
-#line 3022
+#line 3027
 
-#line 3022
+#line 3027
     while (nelems-- != 0) {
-#line 3022
+#line 3027
         
-#line 3022
+#line 3027
         *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
-#line 3022
+#line 3027
     }
-#line 3022
+#line 3027
 
-#line 3022
+#line 3027
     *xpp = (void *)(xp + rndup);
-#line 3022
+#line 3027
     return status;
-#line 3022
+#line 3027
 }
-#line 3022
+#line 3027
 
 int
-#line 3023
+#line 3028
 ncx_pad_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
-#line 3023
+#line 3028
 {
-#line 3023
+#line 3028
     int status = NC_NOERR;
-#line 3023
+#line 3028
     size_t rndup = nelems % X_ALIGN;
-#line 3023
+#line 3028
     uchar *xp = (uchar *) *xpp;
-#line 3023
+#line 3028
 
-#line 3023
+#line 3028
     if (rndup)
-#line 3023
+#line 3028
         rndup = X_ALIGN - rndup;
-#line 3023
+#line 3028
 
-#line 3023
+#line 3028
     while (nelems-- != 0) {
-#line 3023
+#line 3028
         
-#line 3023
+#line 3028
         *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
-#line 3023
+#line 3028
     }
-#line 3023
+#line 3028
 
-#line 3023
+#line 3028
     *xpp = (void *)(xp + rndup);
-#line 3023
+#line 3028
     return status;
-#line 3023
+#line 3028
 }
-#line 3023
+#line 3028
 
 int
-#line 3024
+#line 3029
 ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
-#line 3024
+#line 3029
 {
-#line 3024
+#line 3029
     int status = NC_NOERR;
-#line 3024
+#line 3029
     size_t rndup = nelems % X_ALIGN;
-#line 3024
+#line 3029
     uchar *xp = (uchar *) *xpp;
-#line 3024
+#line 3029
 
-#line 3024
+#line 3029
     if (rndup)
-#line 3024
+#line 3029
         rndup = X_ALIGN - rndup;
-#line 3024
+#line 3029
 
-#line 3024
+#line 3029
     while (nelems-- != 0) {
-#line 3024
+#line 3029
         
-#line 3024
+#line 3029
         *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
-#line 3024
+#line 3029
     }
-#line 3024
+#line 3029
 
-#line 3024
+#line 3029
     *xpp = (void *)(xp + rndup);
-#line 3024
+#line 3029
     return status;
-#line 3024
+#line 3029
 }
-#line 3024
+#line 3029
 
 int
-#line 3025
+#line 3030
 ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
-#line 3025
+#line 3030
 {
-#line 3025
+#line 3030
     int status = NC_NOERR;
-#line 3025
+#line 3030
     size_t rndup = nelems % X_ALIGN;
-#line 3025
+#line 3030
     uchar *xp = (uchar *) *xpp;
-#line 3025
+#line 3030
 
-#line 3025
+#line 3030
     if (rndup)
-#line 3025
+#line 3030
         rndup = X_ALIGN - rndup;
-#line 3025
+#line 3030
 
-#line 3025
+#line 3030
     while (nelems-- != 0) {
-#line 3025
+#line 3030
         
-#line 3025
+#line 3030
         *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
-#line 3025
+#line 3030
     }
-#line 3025
+#line 3030
 
-#line 3025
+#line 3030
     *xpp = (void *)(xp + rndup);
-#line 3025
+#line 3030
     return status;
-#line 3025
+#line 3030
 }
-#line 3025
+#line 3030
 
 int
-#line 3026
+#line 3031
 ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3026
+#line 3031
 {
-#line 3026
+#line 3031
     int status = NC_NOERR;
-#line 3026
+#line 3031
     size_t rndup = nelems % X_ALIGN;
-#line 3026
+#line 3031
     uchar *xp = (uchar *) *xpp;
-#line 3026
+#line 3031
 
-#line 3026
+#line 3031
     if (rndup)
-#line 3026
+#line 3031
         rndup = X_ALIGN - rndup;
-#line 3026
+#line 3031
 
-#line 3026
+#line 3031
     while (nelems-- != 0) {
-#line 3026
+#line 3031
         
-#line 3026
+#line 3031
         *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
-#line 3026
+#line 3031
     }
-#line 3026
+#line 3031
 
-#line 3026
+#line 3031
     *xpp = (void *)(xp + rndup);
-#line 3026
+#line 3031
     return status;
-#line 3026
+#line 3031
 }
-#line 3026
+#line 3031
 
 int
-#line 3027
+#line 3032
 ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3027
+#line 3032
 {
-#line 3027
+#line 3032
     int status = NC_NOERR;
-#line 3027
+#line 3032
     size_t rndup = nelems % X_ALIGN;
-#line 3027
+#line 3032
     uchar *xp = (uchar *) *xpp;
-#line 3027
+#line 3032
 
-#line 3027
+#line 3032
     if (rndup)
-#line 3027
+#line 3032
         rndup = X_ALIGN - rndup;
-#line 3027
+#line 3032
 
-#line 3027
+#line 3032
     while (nelems-- != 0) {
-#line 3027
+#line 3032
         
-#line 3027
+#line 3032
         *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
-#line 3027
+#line 3032
     }
-#line 3027
+#line 3032
 
-#line 3027
+#line 3032
     *xpp = (void *)(xp + rndup);
-#line 3027
+#line 3032
     return status;
-#line 3027
+#line 3032
 }
-#line 3027
+#line 3032
 
 int
-#line 3028
+#line 3033
 ncx_pad_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3028
+#line 3033
 {
-#line 3028
+#line 3033
     int status = NC_NOERR;
-#line 3028
+#line 3033
     size_t rndup = nelems % X_ALIGN;
-#line 3028
+#line 3033
     uchar *xp = (uchar *) *xpp;
-#line 3028
+#line 3033
 
-#line 3028
+#line 3033
     if (rndup)
-#line 3028
+#line 3033
         rndup = X_ALIGN - rndup;
-#line 3028
+#line 3033
 
-#line 3028
+#line 3033
     while (nelems-- != 0) {
-#line 3028
+#line 3033
         
-#line 3028
+#line 3033
         *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
-#line 3028
+#line 3033
     }
-#line 3028
+#line 3033
 
-#line 3028
+#line 3033
     *xpp = (void *)(xp + rndup);
-#line 3028
+#line 3033
     return status;
-#line 3028
+#line 3033
 }
-#line 3028
+#line 3033
 
 int
-#line 3029
+#line 3034
 ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3029
+#line 3034
 {
-#line 3029
+#line 3034
     int status = NC_NOERR;
-#line 3029
+#line 3034
     size_t rndup = nelems % X_ALIGN;
-#line 3029
+#line 3034
     uchar *xp = (uchar *) *xpp;
-#line 3029
+#line 3034
 
-#line 3029
+#line 3034
     if (rndup)
-#line 3029
+#line 3034
         rndup = X_ALIGN - rndup;
-#line 3029
+#line 3034
 
-#line 3029
+#line 3034
     while (nelems-- != 0) {
-#line 3029
+#line 3034
         
-#line 3029
+#line 3034
         *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
-#line 3029
+#line 3034
     }
-#line 3029
+#line 3034
 
-#line 3029
+#line 3034
     *xpp = (void *)(xp + rndup);
-#line 3029
+#line 3034
     return status;
-#line 3029
+#line 3034
 }
-#line 3029
+#line 3034
 
 
-#line 3032
+#line 3037
 int
 ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
 {
@@ -12338,19 +12343,19 @@ ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
     while (nelems-- != 0) {
         if (*tp < 0) {
             
-#line 3040
+#line 3045
 #ifdef ERANGE_FILL
-#line 3040
+#line 3045
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3040
+#line 3045
 #endif
             status = NC_ERANGE;
             
-#line 3042
+#line 3047
 #ifdef ERANGE_FILL
-#line 3042
+#line 3047
             xp++; tp++; continue;
-#line 3042
+#line 3047
 #endif
         }
         *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
@@ -12359,268 +12364,23 @@ ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
     *xpp = (void *)xp;
     return status;
 }
-#line 3051
+#line 3056
 int
 ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
 {
 		(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 3054
-	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3054
-
-#line 3054
-	return NC_NOERR;
-#line 3054
-
-}
-int
-#line 3056
-ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3056
-{
-#line 3056
-    int status = NC_NOERR;
-#line 3056
-    uchar *xp = (uchar *) *xpp;
-#line 3056
-
-#line 3056
-    while (nelems-- != 0) {
-#line 3056
-        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
-#line 3056
-            
-#line 3056
-#ifdef ERANGE_FILL
-#line 3056
-            if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3056
-#endif
-#line 3056
-            status = NC_ERANGE;
-#line 3056
-            
-#line 3056
-#ifdef ERANGE_FILL
-#line 3056
-            xp++; tp++; continue;
-#line 3056
-#endif
-#line 3056
-        }
-#line 3056
-        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
-#line 3056
-    }
-#line 3056
-
-#line 3056
-    *xpp = (void *)xp;
-#line 3056
-    return status;
-#line 3056
-}
-#line 3056
-
-int
-#line 3057
-ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3057
-{
-#line 3057
-    int status = NC_NOERR;
-#line 3057
-    uchar *xp = (uchar *) *xpp;
-#line 3057
-
-#line 3057
-    while (nelems-- != 0) {
-#line 3057
-        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
-#line 3057
-            
-#line 3057
-#ifdef ERANGE_FILL
-#line 3057
-            if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3057
-#endif
-#line 3057
-            status = NC_ERANGE;
-#line 3057
-            
-#line 3057
-#ifdef ERANGE_FILL
-#line 3057
-            xp++; tp++; continue;
-#line 3057
-#endif
-#line 3057
-        }
-#line 3057
-        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
-#line 3057
-    }
-#line 3057
-
-#line 3057
-    *xpp = (void *)xp;
-#line 3057
-    return status;
-#line 3057
-}
-#line 3057
-
-int
-#line 3058
-ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3058
-{
-#line 3058
-    int status = NC_NOERR;
-#line 3058
-    uchar *xp = (uchar *) *xpp;
-#line 3058
-
-#line 3058
-    while (nelems-- != 0) {
-#line 3058
-        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
-#line 3058
-            
-#line 3058
-#ifdef ERANGE_FILL
-#line 3058
-            if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3058
-#endif
-#line 3058
-            status = NC_ERANGE;
-#line 3058
-            
-#line 3058
-#ifdef ERANGE_FILL
-#line 3058
-            xp++; tp++; continue;
-#line 3058
-#endif
-#line 3058
-        }
-#line 3058
-        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
-#line 3058
-    }
-#line 3058
-
-#line 3058
-    *xpp = (void *)xp;
-#line 3058
-    return status;
-#line 3058
-}
-#line 3058
-
-int
-#line 3059
-ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3059
-{
-#line 3059
-    int status = NC_NOERR;
-#line 3059
-    uchar *xp = (uchar *) *xpp;
-#line 3059
-
-#line 3059
-    while (nelems-- != 0) {
-#line 3059
-        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
-#line 3059
-            
-#line 3059
-#ifdef ERANGE_FILL
-#line 3059
-            if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3059
-#endif
-#line 3059
-            status = NC_ERANGE;
-#line 3059
-            
-#line 3059
-#ifdef ERANGE_FILL
-#line 3059
-            xp++; tp++; continue;
-#line 3059
-#endif
-#line 3059
-        }
-#line 3059
-        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
 #line 3059
-    }
+	*xpp = (void *)((char *)(*xpp) + nelems);
 #line 3059
 
 #line 3059
-    *xpp = (void *)xp;
-#line 3059
-    return status;
-#line 3059
-}
+	return NC_NOERR;
 #line 3059
 
-int
-#line 3060
-ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3060
-{
-#line 3060
-    int status = NC_NOERR;
-#line 3060
-    uchar *xp = (uchar *) *xpp;
-#line 3060
-
-#line 3060
-    while (nelems-- != 0) {
-#line 3060
-        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
-#line 3060
-            
-#line 3060
-#ifdef ERANGE_FILL
-#line 3060
-            if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3060
-#endif
-#line 3060
-            status = NC_ERANGE;
-#line 3060
-            
-#line 3060
-#ifdef ERANGE_FILL
-#line 3060
-            xp++; tp++; continue;
-#line 3060
-#endif
-#line 3060
-        }
-#line 3060
-        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
-#line 3060
-    }
-#line 3060
-
-#line 3060
-    *xpp = (void *)xp;
-#line 3060
-    return status;
-#line 3060
 }
-#line 3060
-
 int
 #line 3061
-ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
+ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
 #line 3061
 {
 #line 3061
@@ -12632,7 +12392,7 @@ ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fil
 #line 3061
     while (nelems-- != 0) {
 #line 3061
-        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
+        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
 #line 3061
             
 #line 3061
@@ -12654,7 +12414,7 @@ ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fil
 #line 3061
         }
 #line 3061
-        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
 #line 3061
     }
 #line 3061
@@ -12669,7 +12429,7 @@ ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fil
 
 int
 #line 3062
-ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
+ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
 #line 3062
 {
 #line 3062
@@ -12681,7 +12441,7 @@ ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
 #line 3062
     while (nelems-- != 0) {
 #line 3062
-        if (*tp > (ushort)X_UCHAR_MAX ) {
+        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
 #line 3062
             
 #line 3062
@@ -12703,7 +12463,7 @@ ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
 #line 3062
         }
 #line 3062
-        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
 #line 3062
     }
 #line 3062
@@ -12718,7 +12478,7 @@ ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
 
 int
 #line 3063
-ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
+ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
 #line 3063
 {
 #line 3063
@@ -12730,7 +12490,7 @@ ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 #line 3063
     while (nelems-- != 0) {
 #line 3063
-        if (*tp > (uint)X_UCHAR_MAX ) {
+        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
 #line 3063
             
 #line 3063
@@ -12752,7 +12512,7 @@ ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 #line 3063
         }
 #line 3063
-        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
 #line 3063
     }
 #line 3063
@@ -12767,7 +12527,7 @@ ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 
 int
 #line 3064
-ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
+ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
 #line 3064
 {
 #line 3064
@@ -12779,7 +12539,7 @@ ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *f
 #line 3064
     while (nelems-- != 0) {
 #line 3064
-        if (*tp > (ulonglong)X_UCHAR_MAX ) {
+        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
 #line 3064
             
 #line 3064
@@ -12801,7 +12561,7 @@ ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *f
 #line 3064
         }
 #line 3064
-        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
 #line 3064
     }
 #line 3064
@@ -12814,420 +12574,330 @@ ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *f
 }
 #line 3064
 
-
-#line 3067
 int
-ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
+#line 3065
+ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
+#line 3065
 {
+#line 3065
     int status = NC_NOERR;
-    size_t rndup = nelems % X_ALIGN;
+#line 3065
     uchar *xp = (uchar *) *xpp;
+#line 3065
 
-    if (rndup) rndup = X_ALIGN - rndup;
-
+#line 3065
     while (nelems-- != 0) {
-        if (*tp < 0) {
+#line 3065
+        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
+#line 3065
             
-#line 3078
+#line 3065
 #ifdef ERANGE_FILL
-#line 3078
+#line 3065
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3078
+#line 3065
 #endif
+#line 3065
             status = NC_ERANGE;
+#line 3065
             
-#line 3080
+#line 3065
 #ifdef ERANGE_FILL
-#line 3080
+#line 3065
             xp++; tp++; continue;
-#line 3080
+#line 3065
 #endif
+#line 3065
         }
-        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
-    }
-
-    if (rndup) {
-        (void) memcpy(xp, nada, (size_t)rndup);
-        xp += rndup;
+#line 3065
+        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
+#line 3065
     }
+#line 3065
 
+#line 3065
     *xpp = (void *)xp;
+#line 3065
     return status;
+#line 3065
 }
-#line 3094
-int
-ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-{
-		size_t rndup = nelems % X_ALIGN;
-#line 3097
-
-#line 3097
-	if (rndup)
-#line 3097
-		rndup = X_ALIGN - rndup;
-#line 3097
-
-#line 3097
-	(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 3097
-	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3097
-
-#line 3097
-	if (rndup)
-#line 3097
-	{
-#line 3097
-		(void) memcpy(*xpp, nada, (size_t)rndup);
-#line 3097
-		*xpp = (void *)((char *)(*xpp) + rndup);
-#line 3097
-	}
-#line 3097
-
-#line 3097
-	return NC_NOERR;
-#line 3097
+#line 3065
 
-}
 int
-#line 3099
-ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3099
+#line 3066
+ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
+#line 3066
 {
-#line 3099
+#line 3066
     int status = NC_NOERR;
-#line 3099
-    size_t rndup = nelems % X_ALIGN;
-#line 3099
+#line 3066
     uchar *xp = (uchar *) *xpp;
-#line 3099
-
-#line 3099
-    if (rndup) rndup = X_ALIGN - rndup;
-#line 3099
+#line 3066
 
-#line 3099
+#line 3066
     while (nelems-- != 0) {
-#line 3099
-        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
-#line 3099
+#line 3066
+        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
+#line 3066
             
-#line 3099
+#line 3066
 #ifdef ERANGE_FILL
-#line 3099
+#line 3066
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3099
+#line 3066
 #endif
-#line 3099
+#line 3066
             status = NC_ERANGE;
-#line 3099
+#line 3066
             
-#line 3099
+#line 3066
 #ifdef ERANGE_FILL
-#line 3099
+#line 3066
             xp++; tp++; continue;
-#line 3099
+#line 3066
 #endif
-#line 3099
+#line 3066
         }
-#line 3099
-        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
-#line 3099
-    }
-#line 3099
-
-#line 3099
-
-#line 3099
-    if (rndup) {
-#line 3099
-        (void) memcpy(xp, nada, (size_t)rndup);
-#line 3099
-        xp += rndup;
-#line 3099
+#line 3066
+        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
+#line 3066
     }
-#line 3099
+#line 3066
 
-#line 3099
+#line 3066
     *xpp = (void *)xp;
-#line 3099
+#line 3066
     return status;
-#line 3099
+#line 3066
 }
-#line 3099
+#line 3066
 
 int
-#line 3100
-ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3100
+#line 3067
+ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
+#line 3067
 {
-#line 3100
+#line 3067
     int status = NC_NOERR;
-#line 3100
-    size_t rndup = nelems % X_ALIGN;
-#line 3100
+#line 3067
     uchar *xp = (uchar *) *xpp;
-#line 3100
-
-#line 3100
-    if (rndup) rndup = X_ALIGN - rndup;
-#line 3100
+#line 3067
 
-#line 3100
+#line 3067
     while (nelems-- != 0) {
-#line 3100
-        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
-#line 3100
+#line 3067
+        if (*tp > (ushort)X_UCHAR_MAX ) {
+#line 3067
             
-#line 3100
+#line 3067
 #ifdef ERANGE_FILL
-#line 3100
+#line 3067
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3100
+#line 3067
 #endif
-#line 3100
+#line 3067
             status = NC_ERANGE;
-#line 3100
+#line 3067
             
-#line 3100
+#line 3067
 #ifdef ERANGE_FILL
-#line 3100
+#line 3067
             xp++; tp++; continue;
-#line 3100
+#line 3067
 #endif
-#line 3100
+#line 3067
         }
-#line 3100
-        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
-#line 3100
-    }
-#line 3100
-
-#line 3100
-
-#line 3100
-    if (rndup) {
-#line 3100
-        (void) memcpy(xp, nada, (size_t)rndup);
-#line 3100
-        xp += rndup;
-#line 3100
+#line 3067
+        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
+#line 3067
     }
-#line 3100
+#line 3067
 
-#line 3100
+#line 3067
     *xpp = (void *)xp;
-#line 3100
+#line 3067
     return status;
-#line 3100
+#line 3067
 }
-#line 3100
+#line 3067
 
 int
-#line 3101
-ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3101
+#line 3068
+ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
+#line 3068
 {
-#line 3101
+#line 3068
     int status = NC_NOERR;
-#line 3101
-    size_t rndup = nelems % X_ALIGN;
-#line 3101
+#line 3068
     uchar *xp = (uchar *) *xpp;
-#line 3101
-
-#line 3101
-    if (rndup) rndup = X_ALIGN - rndup;
-#line 3101
+#line 3068
 
-#line 3101
+#line 3068
     while (nelems-- != 0) {
-#line 3101
-        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
-#line 3101
+#line 3068
+        if (*tp > (uint)X_UCHAR_MAX ) {
+#line 3068
             
-#line 3101
+#line 3068
 #ifdef ERANGE_FILL
-#line 3101
+#line 3068
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3101
+#line 3068
 #endif
-#line 3101
+#line 3068
             status = NC_ERANGE;
-#line 3101
+#line 3068
             
-#line 3101
+#line 3068
 #ifdef ERANGE_FILL
-#line 3101
+#line 3068
             xp++; tp++; continue;
-#line 3101
+#line 3068
 #endif
-#line 3101
+#line 3068
         }
-#line 3101
-        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
-#line 3101
-    }
-#line 3101
-
-#line 3101
-
-#line 3101
-    if (rndup) {
-#line 3101
-        (void) memcpy(xp, nada, (size_t)rndup);
-#line 3101
-        xp += rndup;
-#line 3101
+#line 3068
+        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
+#line 3068
     }
-#line 3101
+#line 3068
 
-#line 3101
+#line 3068
     *xpp = (void *)xp;
-#line 3101
+#line 3068
     return status;
-#line 3101
+#line 3068
 }
-#line 3101
+#line 3068
 
 int
-#line 3102
-ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3102
+#line 3069
+ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
+#line 3069
 {
-#line 3102
+#line 3069
     int status = NC_NOERR;
-#line 3102
-    size_t rndup = nelems % X_ALIGN;
-#line 3102
+#line 3069
     uchar *xp = (uchar *) *xpp;
-#line 3102
-
-#line 3102
-    if (rndup) rndup = X_ALIGN - rndup;
-#line 3102
+#line 3069
 
-#line 3102
+#line 3069
     while (nelems-- != 0) {
-#line 3102
-        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
-#line 3102
+#line 3069
+        if (*tp > (ulonglong)X_UCHAR_MAX ) {
+#line 3069
             
-#line 3102
+#line 3069
 #ifdef ERANGE_FILL
-#line 3102
+#line 3069
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3102
+#line 3069
 #endif
-#line 3102
+#line 3069
             status = NC_ERANGE;
-#line 3102
+#line 3069
             
-#line 3102
+#line 3069
 #ifdef ERANGE_FILL
-#line 3102
+#line 3069
             xp++; tp++; continue;
-#line 3102
+#line 3069
 #endif
-#line 3102
+#line 3069
         }
-#line 3102
-        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
-#line 3102
-    }
-#line 3102
-
-#line 3102
-
-#line 3102
-    if (rndup) {
-#line 3102
-        (void) memcpy(xp, nada, (size_t)rndup);
-#line 3102
-        xp += rndup;
-#line 3102
+#line 3069
+        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
+#line 3069
     }
-#line 3102
+#line 3069
 
-#line 3102
+#line 3069
     *xpp = (void *)xp;
-#line 3102
+#line 3069
     return status;
-#line 3102
+#line 3069
 }
-#line 3102
+#line 3069
 
+
+#line 3072
 int
-#line 3103
-ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3103
+ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
 {
-#line 3103
     int status = NC_NOERR;
-#line 3103
     size_t rndup = nelems % X_ALIGN;
-#line 3103
     uchar *xp = (uchar *) *xpp;
-#line 3103
 
-#line 3103
     if (rndup) rndup = X_ALIGN - rndup;
-#line 3103
 
-#line 3103
     while (nelems-- != 0) {
-#line 3103
-        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
-#line 3103
+        if (*tp < 0) {
             
-#line 3103
+#line 3083
 #ifdef ERANGE_FILL
-#line 3103
+#line 3083
             if (fillp != NULL) memcpy(xp, fillp, 1);
-#line 3103
+#line 3083
 #endif
-#line 3103
             status = NC_ERANGE;
-#line 3103
             
-#line 3103
+#line 3085
 #ifdef ERANGE_FILL
-#line 3103
+#line 3085
             xp++; tp++; continue;
-#line 3103
+#line 3085
 #endif
-#line 3103
         }
-#line 3103
-        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
-#line 3103
+        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
     }
-#line 3103
-
-#line 3103
 
-#line 3103
     if (rndup) {
-#line 3103
         (void) memcpy(xp, nada, (size_t)rndup);
-#line 3103
         xp += rndup;
-#line 3103
     }
-#line 3103
 
-#line 3103
     *xpp = (void *)xp;
-#line 3103
     return status;
-#line 3103
 }
-#line 3103
+#line 3099
+int
+ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
+{
+		size_t rndup = nelems % X_ALIGN;
+#line 3102
+
+#line 3102
+	if (rndup)
+#line 3102
+		rndup = X_ALIGN - rndup;
+#line 3102
+
+#line 3102
+	(void) memcpy(*xpp, tp, (size_t)nelems);
+#line 3102
+	*xpp = (void *)((char *)(*xpp) + nelems);
+#line 3102
 
+#line 3102
+	if (rndup)
+#line 3102
+	{
+#line 3102
+		(void) memcpy(*xpp, nada, (size_t)rndup);
+#line 3102
+		*xpp = (void *)((char *)(*xpp) + rndup);
+#line 3102
+	}
+#line 3102
+
+#line 3102
+	return NC_NOERR;
+#line 3102
+
+}
 int
 #line 3104
-ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
+ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
 #line 3104
 {
 #line 3104
@@ -13245,7 +12915,7 @@ ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void
 #line 3104
     while (nelems-- != 0) {
 #line 3104
-        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
+        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
 #line 3104
             
 #line 3104
@@ -13267,7 +12937,7 @@ ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void
 #line 3104
         }
 #line 3104
-        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
 #line 3104
     }
 #line 3104
@@ -13294,7 +12964,7 @@ ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void
 
 int
 #line 3105
-ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
+ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
 #line 3105
 {
 #line 3105
@@ -13312,7 +12982,7 @@ ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fil
 #line 3105
     while (nelems-- != 0) {
 #line 3105
-        if (*tp > (ushort)X_UCHAR_MAX ) {
+        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
 #line 3105
             
 #line 3105
@@ -13334,7 +13004,7 @@ ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fil
 #line 3105
         }
 #line 3105
-        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
 #line 3105
     }
 #line 3105
@@ -13361,7 +13031,7 @@ ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fil
 
 int
 #line 3106
-ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
+ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
 #line 3106
 {
 #line 3106
@@ -13379,7 +13049,7 @@ ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 #line 3106
     while (nelems-- != 0) {
 #line 3106
-        if (*tp > (uint)X_UCHAR_MAX ) {
+        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
 #line 3106
             
 #line 3106
@@ -13401,7 +13071,7 @@ ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 #line 3106
         }
 #line 3106
-        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
 #line 3106
     }
 #line 3106
@@ -13428,7 +13098,7 @@ ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 
 int
 #line 3107
-ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
+ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
 #line 3107
 {
 #line 3107
@@ -13446,7 +13116,7 @@ ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, voi
 #line 3107
     while (nelems-- != 0) {
 #line 3107
-        if (*tp > (ulonglong)X_UCHAR_MAX ) {
+        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
 #line 3107
             
 #line 3107
@@ -13468,7 +13138,7 @@ ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, voi
 #line 3107
         }
 #line 3107
-        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
+        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
 #line 3107
     }
 #line 3107
@@ -13493,1916 +13163,2251 @@ ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, voi
 }
 #line 3107
 
-
-/* short ---------------------------------------------------------------------*/
-
-#if X_SIZEOF_SHORT == SIZEOF_SHORT
-/* optimized version */
 int
-ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
+#line 3108
+ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
+#line 3108
 {
-#ifdef WORDS_BIGENDIAN
-	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
-# else
-	swapn2b(tp, *xpp, nelems);
-# endif
-	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
-	return NC_NOERR;
+#line 3108
+    int status = NC_NOERR;
+#line 3108
+    size_t rndup = nelems % X_ALIGN;
+#line 3108
+    uchar *xp = (uchar *) *xpp;
+#line 3108
+
+#line 3108
+    if (rndup) rndup = X_ALIGN - rndup;
+#line 3108
+
+#line 3108
+    while (nelems-- != 0) {
+#line 3108
+        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
+#line 3108
+            
+#line 3108
+#ifdef ERANGE_FILL
+#line 3108
+            if (fillp != NULL) memcpy(xp, fillp, 1);
+#line 3108
+#endif
+#line 3108
+            status = NC_ERANGE;
+#line 3108
+            
+#line 3108
+#ifdef ERANGE_FILL
+#line 3108
+            xp++; tp++; continue;
+#line 3108
+#endif
+#line 3108
+        }
+#line 3108
+        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
+#line 3108
+    }
+#line 3108
+
+#line 3108
+
+#line 3108
+    if (rndup) {
+#line 3108
+        (void) memcpy(xp, nada, (size_t)rndup);
+#line 3108
+        xp += rndup;
+#line 3108
+    }
+#line 3108
+
+#line 3108
+    *xpp = (void *)xp;
+#line 3108
+    return status;
+#line 3108
 }
-#else
+#line 3108
+
 int
-#line 3125
-ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
-#line 3125
+#line 3109
+ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
+#line 3109
 {
-#line 3125
-#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3125
+#line 3109
+    int status = NC_NOERR;
+#line 3109
+    size_t rndup = nelems % X_ALIGN;
+#line 3109
+    uchar *xp = (uchar *) *xpp;
+#line 3109
 
-#line 3125
- /* basic algorithm is:
-#line 3125
-  *   - ensure sane alignment of input data
-#line 3125
-  *   - copy (conversion happens automatically) input data
-#line 3125
-  *     to output
-#line 3125
+#line 3109
+    if (rndup) rndup = X_ALIGN - rndup;
+#line 3109
+
+#line 3109
+    while (nelems-- != 0) {
+#line 3109
+        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
+#line 3109
+            
+#line 3109
+#ifdef ERANGE_FILL
+#line 3109
+            if (fillp != NULL) memcpy(xp, fillp, 1);
+#line 3109
+#endif
+#line 3109
+            status = NC_ERANGE;
+#line 3109
+            
+#line 3109
+#ifdef ERANGE_FILL
+#line 3109
+            xp++; tp++; continue;
+#line 3109
+#endif
+#line 3109
+        }
+#line 3109
+        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
+#line 3109
+    }
+#line 3109
+
+#line 3109
+
+#line 3109
+    if (rndup) {
+#line 3109
+        (void) memcpy(xp, nada, (size_t)rndup);
+#line 3109
+        xp += rndup;
+#line 3109
+    }
+#line 3109
+
+#line 3109
+    *xpp = (void *)xp;
+#line 3109
+    return status;
+#line 3109
+}
+#line 3109
+
+int
+#line 3110
+ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
+#line 3110
+{
+#line 3110
+    int status = NC_NOERR;
+#line 3110
+    size_t rndup = nelems % X_ALIGN;
+#line 3110
+    uchar *xp = (uchar *) *xpp;
+#line 3110
+
+#line 3110
+    if (rndup) rndup = X_ALIGN - rndup;
+#line 3110
+
+#line 3110
+    while (nelems-- != 0) {
+#line 3110
+        if (*tp > (ushort)X_UCHAR_MAX ) {
+#line 3110
+            
+#line 3110
+#ifdef ERANGE_FILL
+#line 3110
+            if (fillp != NULL) memcpy(xp, fillp, 1);
+#line 3110
+#endif
+#line 3110
+            status = NC_ERANGE;
+#line 3110
+            
+#line 3110
+#ifdef ERANGE_FILL
+#line 3110
+            xp++; tp++; continue;
+#line 3110
+#endif
+#line 3110
+        }
+#line 3110
+        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
+#line 3110
+    }
+#line 3110
+
+#line 3110
+
+#line 3110
+    if (rndup) {
+#line 3110
+        (void) memcpy(xp, nada, (size_t)rndup);
+#line 3110
+        xp += rndup;
+#line 3110
+    }
+#line 3110
+
+#line 3110
+    *xpp = (void *)xp;
+#line 3110
+    return status;
+#line 3110
+}
+#line 3110
+
+int
+#line 3111
+ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
+#line 3111
+{
+#line 3111
+    int status = NC_NOERR;
+#line 3111
+    size_t rndup = nelems % X_ALIGN;
+#line 3111
+    uchar *xp = (uchar *) *xpp;
+#line 3111
+
+#line 3111
+    if (rndup) rndup = X_ALIGN - rndup;
+#line 3111
+
+#line 3111
+    while (nelems-- != 0) {
+#line 3111
+        if (*tp > (uint)X_UCHAR_MAX ) {
+#line 3111
+            
+#line 3111
+#ifdef ERANGE_FILL
+#line 3111
+            if (fillp != NULL) memcpy(xp, fillp, 1);
+#line 3111
+#endif
+#line 3111
+            status = NC_ERANGE;
+#line 3111
+            
+#line 3111
+#ifdef ERANGE_FILL
+#line 3111
+            xp++; tp++; continue;
+#line 3111
+#endif
+#line 3111
+        }
+#line 3111
+        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
+#line 3111
+    }
+#line 3111
+
+#line 3111
+
+#line 3111
+    if (rndup) {
+#line 3111
+        (void) memcpy(xp, nada, (size_t)rndup);
+#line 3111
+        xp += rndup;
+#line 3111
+    }
+#line 3111
+
+#line 3111
+    *xpp = (void *)xp;
+#line 3111
+    return status;
+#line 3111
+}
+#line 3111
+
+int
+#line 3112
+ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
+#line 3112
+{
+#line 3112
+    int status = NC_NOERR;
+#line 3112
+    size_t rndup = nelems % X_ALIGN;
+#line 3112
+    uchar *xp = (uchar *) *xpp;
+#line 3112
+
+#line 3112
+    if (rndup) rndup = X_ALIGN - rndup;
+#line 3112
+
+#line 3112
+    while (nelems-- != 0) {
+#line 3112
+        if (*tp > (ulonglong)X_UCHAR_MAX ) {
+#line 3112
+            
+#line 3112
+#ifdef ERANGE_FILL
+#line 3112
+            if (fillp != NULL) memcpy(xp, fillp, 1);
+#line 3112
+#endif
+#line 3112
+            status = NC_ERANGE;
+#line 3112
+            
+#line 3112
+#ifdef ERANGE_FILL
+#line 3112
+            xp++; tp++; continue;
+#line 3112
+#endif
+#line 3112
+        }
+#line 3112
+        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
+#line 3112
+    }
+#line 3112
+
+#line 3112
+
+#line 3112
+    if (rndup) {
+#line 3112
+        (void) memcpy(xp, nada, (size_t)rndup);
+#line 3112
+        xp += rndup;
+#line 3112
+    }
+#line 3112
+
+#line 3112
+    *xpp = (void *)xp;
+#line 3112
+    return status;
+#line 3112
+}
+#line 3112
+
+
+/* short ---------------------------------------------------------------------*/
+
+#if X_SIZEOF_SHORT == SIZEOF_SHORT
+/* optimized version */
+int
+ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
+{
+#ifdef WORDS_BIGENDIAN
+	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
+# else
+	swapn2b(tp, *xpp, nelems);
+# endif
+	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
+	return NC_NOERR;
+}
+#else
+int
+#line 3130
+ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
+#line 3130
+{
+#line 3130
+#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
+#line 3130
+
+#line 3130
+ /* basic algorithm is:
+#line 3130
+  *   - ensure sane alignment of input data
+#line 3130
+  *   - copy (conversion happens automatically) input data
+#line 3130
+  *     to output
+#line 3130
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3125
+#line 3130
   *     at next location for converted output
-#line 3125
+#line 3130
   */
-#line 3125
+#line 3130
   long i, j, ni;
-#line 3125
+#line 3130
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3125
+#line 3130
   short *xp;
-#line 3125
+#line 3130
   int nrange = 0;         /* number of range errors */
-#line 3125
+#line 3130
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3125
+#line 3130
   long cxp = (long) *((char**)xpp);
-#line 3125
+#line 3130
 
-#line 3125
+#line 3130
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3125
+#line 3130
   /* sjl: manually stripmine so we can limit amount of
-#line 3125
+#line 3130
    * vector work space reserved to LOOPCNT elements. Also
-#line 3125
+#line 3130
    * makes vectorisation easy */
-#line 3125
+#line 3130
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3125
+#line 3130
     ni=Min(nelems-j,LOOPCNT);
-#line 3125
+#line 3130
     if (realign) {
-#line 3125
+#line 3130
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3125
+#line 3130
       xp = tmp;
-#line 3125
+#line 3130
     } else {
-#line 3125
+#line 3130
       xp = (short *) *xpp;
-#line 3125
+#line 3130
     }
-#line 3125
+#line 3130
    /* copy the next block */
-#line 3125
+#line 3130
 #pragma cdir loopcnt=LOOPCNT
-#line 3125
+#line 3130
 #pragma cdir shortloop
-#line 3125
+#line 3130
     for (i=0; i<ni; i++) {
-#line 3125
+#line 3130
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3125
+#line 3130
      /* test for range errors (not always needed but do it anyway) */
-#line 3125
+#line 3130
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3125
+#line 3130
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3125
+#line 3130
       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
-#line 3125
+#line 3130
     }
-#line 3125
+#line 3130
    /* update xpp and tp */
-#line 3125
+#line 3130
     if (realign) xp = (short *) *xpp;
-#line 3125
+#line 3130
     xp += ni;
-#line 3125
+#line 3130
     tp += ni;
-#line 3125
+#line 3130
     *xpp = (void*)xp;
-#line 3125
+#line 3130
   }
-#line 3125
+#line 3130
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3125
+#line 3130
 
-#line 3125
+#line 3130
 #else   /* not SX */
-#line 3125
+#line 3130
 	const char *xp = (const char *) *xpp;
-#line 3125
+#line 3130
 	int status = NC_NOERR;
-#line 3125
+#line 3130
 
-#line 3125
+#line 3130
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3125
+#line 3130
 	{
-#line 3125
+#line 3130
 		const int lstatus = ncx_get_short_short(xp, tp);
-#line 3125
+#line 3130
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3125
+#line 3130
 			status = lstatus;
-#line 3125
+#line 3130
 	}
-#line 3125
+#line 3130
 
-#line 3125
+#line 3130
 	*xpp = (const void *)xp;
-#line 3125
+#line 3130
 	return status;
-#line 3125
+#line 3130
 #endif
-#line 3125
+#line 3130
 }
-#line 3125
+#line 3130
 
 #endif
 int
-#line 3127
+#line 3132
 ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3127
+#line 3132
 {
-#line 3127
+#line 3132
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3127
+#line 3132
 
-#line 3127
+#line 3132
  /* basic algorithm is:
-#line 3127
+#line 3132
   *   - ensure sane alignment of input data
-#line 3127
+#line 3132
   *   - copy (conversion happens automatically) input data
-#line 3127
+#line 3132
   *     to output
-#line 3127
+#line 3132
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3127
+#line 3132
   *     at next location for converted output
-#line 3127
+#line 3132
   */
-#line 3127
+#line 3132
   long i, j, ni;
-#line 3127
+#line 3132
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3127
+#line 3132
   short *xp;
-#line 3127
+#line 3132
   int nrange = 0;         /* number of range errors */
-#line 3127
+#line 3132
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3127
+#line 3132
   long cxp = (long) *((char**)xpp);
-#line 3127
+#line 3132
 
-#line 3127
+#line 3132
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3127
+#line 3132
   /* sjl: manually stripmine so we can limit amount of
-#line 3127
+#line 3132
    * vector work space reserved to LOOPCNT elements. Also
-#line 3127
+#line 3132
    * makes vectorisation easy */
-#line 3127
+#line 3132
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3127
+#line 3132
     ni=Min(nelems-j,LOOPCNT);
-#line 3127
+#line 3132
     if (realign) {
-#line 3127
+#line 3132
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3127
+#line 3132
       xp = tmp;
-#line 3127
+#line 3132
     } else {
-#line 3127
+#line 3132
       xp = (short *) *xpp;
-#line 3127
+#line 3132
     }
-#line 3127
+#line 3132
    /* copy the next block */
-#line 3127
+#line 3132
 #pragma cdir loopcnt=LOOPCNT
-#line 3127
+#line 3132
 #pragma cdir shortloop
-#line 3127
+#line 3132
     for (i=0; i<ni; i++) {
-#line 3127
+#line 3132
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3127
+#line 3132
      /* test for range errors (not always needed but do it anyway) */
-#line 3127
+#line 3132
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3127
+#line 3132
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3127
+#line 3132
       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
-#line 3127
+#line 3132
     }
-#line 3127
+#line 3132
    /* update xpp and tp */
-#line 3127
+#line 3132
     if (realign) xp = (short *) *xpp;
-#line 3127
+#line 3132
     xp += ni;
-#line 3127
+#line 3132
     tp += ni;
-#line 3127
+#line 3132
     *xpp = (void*)xp;
-#line 3127
+#line 3132
   }
-#line 3127
+#line 3132
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3127
+#line 3132
 
-#line 3127
+#line 3132
 #else   /* not SX */
-#line 3127
+#line 3132
 	const char *xp = (const char *) *xpp;
-#line 3127
+#line 3132
 	int status = NC_NOERR;
-#line 3127
+#line 3132
 
-#line 3127
+#line 3132
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3127
+#line 3132
 	{
-#line 3127
+#line 3132
 		const int lstatus = ncx_get_short_schar(xp, tp);
-#line 3127
+#line 3132
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3127
+#line 3132
 			status = lstatus;
-#line 3127
+#line 3132
 	}
-#line 3127
+#line 3132
 
-#line 3127
+#line 3132
 	*xpp = (const void *)xp;
-#line 3127
+#line 3132
 	return status;
-#line 3127
+#line 3132
 #endif
-#line 3127
+#line 3132
 }
-#line 3127
+#line 3132
 
 int
-#line 3128
+#line 3133
 ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
-#line 3128
+#line 3133
 {
-#line 3128
+#line 3133
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3128
+#line 3133
 
-#line 3128
+#line 3133
  /* basic algorithm is:
-#line 3128
+#line 3133
   *   - ensure sane alignment of input data
-#line 3128
+#line 3133
   *   - copy (conversion happens automatically) input data
-#line 3128
+#line 3133
   *     to output
-#line 3128
+#line 3133
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3128
+#line 3133
   *     at next location for converted output
-#line 3128
+#line 3133
   */
-#line 3128
+#line 3133
   long i, j, ni;
-#line 3128
+#line 3133
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3128
+#line 3133
   short *xp;
-#line 3128
+#line 3133
   int nrange = 0;         /* number of range errors */
-#line 3128
+#line 3133
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3128
+#line 3133
   long cxp = (long) *((char**)xpp);
-#line 3128
+#line 3133
 
-#line 3128
+#line 3133
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3128
+#line 3133
   /* sjl: manually stripmine so we can limit amount of
-#line 3128
+#line 3133
    * vector work space reserved to LOOPCNT elements. Also
-#line 3128
+#line 3133
    * makes vectorisation easy */
-#line 3128
+#line 3133
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3128
+#line 3133
     ni=Min(nelems-j,LOOPCNT);
-#line 3128
+#line 3133
     if (realign) {
-#line 3128
+#line 3133
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3128
+#line 3133
       xp = tmp;
-#line 3128
+#line 3133
     } else {
-#line 3128
+#line 3133
       xp = (short *) *xpp;
-#line 3128
+#line 3133
     }
-#line 3128
+#line 3133
    /* copy the next block */
-#line 3128
+#line 3133
 #pragma cdir loopcnt=LOOPCNT
-#line 3128
+#line 3133
 #pragma cdir shortloop
-#line 3128
+#line 3133
     for (i=0; i<ni; i++) {
-#line 3128
+#line 3133
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3128
+#line 3133
      /* test for range errors (not always needed but do it anyway) */
-#line 3128
+#line 3133
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3128
+#line 3133
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3128
+#line 3133
       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
-#line 3128
+#line 3133
     }
-#line 3128
+#line 3133
    /* update xpp and tp */
-#line 3128
+#line 3133
     if (realign) xp = (short *) *xpp;
-#line 3128
+#line 3133
     xp += ni;
-#line 3128
+#line 3133
     tp += ni;
-#line 3128
+#line 3133
     *xpp = (void*)xp;
-#line 3128
+#line 3133
   }
-#line 3128
+#line 3133
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3128
+#line 3133
 
-#line 3128
+#line 3133
 #else   /* not SX */
-#line 3128
+#line 3133
 	const char *xp = (const char *) *xpp;
-#line 3128
+#line 3133
 	int status = NC_NOERR;
-#line 3128
+#line 3133
 
-#line 3128
+#line 3133
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3128
+#line 3133
 	{
-#line 3128
+#line 3133
 		const int lstatus = ncx_get_short_int(xp, tp);
-#line 3128
+#line 3133
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3128
+#line 3133
 			status = lstatus;
-#line 3128
+#line 3133
 	}
-#line 3128
+#line 3133
 
-#line 3128
+#line 3133
 	*xpp = (const void *)xp;
-#line 3128
+#line 3133
 	return status;
-#line 3128
+#line 3133
 #endif
-#line 3128
+#line 3133
 }
-#line 3128
+#line 3133
 
 int
-#line 3129
+#line 3134
 ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
-#line 3129
+#line 3134
 {
-#line 3129
+#line 3134
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3129
+#line 3134
 
-#line 3129
+#line 3134
  /* basic algorithm is:
-#line 3129
+#line 3134
   *   - ensure sane alignment of input data
-#line 3129
+#line 3134
   *   - copy (conversion happens automatically) input data
-#line 3129
+#line 3134
   *     to output
-#line 3129
+#line 3134
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3129
+#line 3134
   *     at next location for converted output
-#line 3129
+#line 3134
   */
-#line 3129
+#line 3134
   long i, j, ni;
-#line 3129
+#line 3134
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3129
+#line 3134
   short *xp;
-#line 3129
+#line 3134
   int nrange = 0;         /* number of range errors */
-#line 3129
+#line 3134
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3129
+#line 3134
   long cxp = (long) *((char**)xpp);
-#line 3129
+#line 3134
 
-#line 3129
+#line 3134
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3129
+#line 3134
   /* sjl: manually stripmine so we can limit amount of
-#line 3129
+#line 3134
    * vector work space reserved to LOOPCNT elements. Also
-#line 3129
+#line 3134
    * makes vectorisation easy */
-#line 3129
+#line 3134
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3129
+#line 3134
     ni=Min(nelems-j,LOOPCNT);
-#line 3129
+#line 3134
     if (realign) {
-#line 3129
+#line 3134
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3129
+#line 3134
       xp = tmp;
-#line 3129
+#line 3134
     } else {
-#line 3129
+#line 3134
       xp = (short *) *xpp;
-#line 3129
+#line 3134
     }
-#line 3129
+#line 3134
    /* copy the next block */
-#line 3129
+#line 3134
 #pragma cdir loopcnt=LOOPCNT
-#line 3129
+#line 3134
 #pragma cdir shortloop
-#line 3129
+#line 3134
     for (i=0; i<ni; i++) {
-#line 3129
+#line 3134
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3129
+#line 3134
      /* test for range errors (not always needed but do it anyway) */
-#line 3129
+#line 3134
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3129
+#line 3134
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3129
+#line 3134
       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
-#line 3129
+#line 3134
     }
-#line 3129
+#line 3134
    /* update xpp and tp */
-#line 3129
+#line 3134
     if (realign) xp = (short *) *xpp;
-#line 3129
+#line 3134
     xp += ni;
-#line 3129
+#line 3134
     tp += ni;
-#line 3129
+#line 3134
     *xpp = (void*)xp;
-#line 3129
+#line 3134
   }
-#line 3129
+#line 3134
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3129
+#line 3134
 
-#line 3129
+#line 3134
 #else   /* not SX */
-#line 3129
+#line 3134
 	const char *xp = (const char *) *xpp;
-#line 3129
+#line 3134
 	int status = NC_NOERR;
-#line 3129
+#line 3134
 
-#line 3129
+#line 3134
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3129
+#line 3134
 	{
-#line 3129
+#line 3134
 		const int lstatus = ncx_get_short_long(xp, tp);
-#line 3129
+#line 3134
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3129
+#line 3134
 			status = lstatus;
-#line 3129
+#line 3134
 	}
-#line 3129
+#line 3134
 
-#line 3129
+#line 3134
 	*xpp = (const void *)xp;
-#line 3129
+#line 3134
 	return status;
-#line 3129
+#line 3134
 #endif
-#line 3129
+#line 3134
 }
-#line 3129
+#line 3134
 
 int
-#line 3130
+#line 3135
 ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
-#line 3130
+#line 3135
 {
-#line 3130
+#line 3135
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3130
+#line 3135
 
-#line 3130
+#line 3135
  /* basic algorithm is:
-#line 3130
+#line 3135
   *   - ensure sane alignment of input data
-#line 3130
+#line 3135
   *   - copy (conversion happens automatically) input data
-#line 3130
+#line 3135
   *     to output
-#line 3130
+#line 3135
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3130
+#line 3135
   *     at next location for converted output
-#line 3130
+#line 3135
   */
-#line 3130
+#line 3135
   long i, j, ni;
-#line 3130
+#line 3135
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3130
+#line 3135
   short *xp;
-#line 3130
+#line 3135
   int nrange = 0;         /* number of range errors */
-#line 3130
+#line 3135
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3130
+#line 3135
   long cxp = (long) *((char**)xpp);
-#line 3130
+#line 3135
 
-#line 3130
+#line 3135
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3130
+#line 3135
   /* sjl: manually stripmine so we can limit amount of
-#line 3130
+#line 3135
    * vector work space reserved to LOOPCNT elements. Also
-#line 3130
+#line 3135
    * makes vectorisation easy */
-#line 3130
+#line 3135
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3130
+#line 3135
     ni=Min(nelems-j,LOOPCNT);
-#line 3130
+#line 3135
     if (realign) {
-#line 3130
+#line 3135
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3130
+#line 3135
       xp = tmp;
-#line 3130
+#line 3135
     } else {
-#line 3130
+#line 3135
       xp = (short *) *xpp;
-#line 3130
+#line 3135
     }
-#line 3130
+#line 3135
    /* copy the next block */
-#line 3130
+#line 3135
 #pragma cdir loopcnt=LOOPCNT
-#line 3130
+#line 3135
 #pragma cdir shortloop
-#line 3130
+#line 3135
     for (i=0; i<ni; i++) {
-#line 3130
+#line 3135
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3130
+#line 3135
      /* test for range errors (not always needed but do it anyway) */
-#line 3130
+#line 3135
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3130
+#line 3135
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3130
+#line 3135
       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
-#line 3130
+#line 3135
     }
-#line 3130
+#line 3135
    /* update xpp and tp */
-#line 3130
+#line 3135
     if (realign) xp = (short *) *xpp;
-#line 3130
+#line 3135
     xp += ni;
-#line 3130
+#line 3135
     tp += ni;
-#line 3130
+#line 3135
     *xpp = (void*)xp;
-#line 3130
+#line 3135
   }
-#line 3130
+#line 3135
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3130
+#line 3135
 
-#line 3130
+#line 3135
 #else   /* not SX */
-#line 3130
+#line 3135
 	const char *xp = (const char *) *xpp;
-#line 3130
+#line 3135
 	int status = NC_NOERR;
-#line 3130
+#line 3135
 
-#line 3130
+#line 3135
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3130
+#line 3135
 	{
-#line 3130
+#line 3135
 		const int lstatus = ncx_get_short_float(xp, tp);
-#line 3130
+#line 3135
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3130
+#line 3135
 			status = lstatus;
-#line 3130
+#line 3135
 	}
-#line 3130
+#line 3135
 
-#line 3130
+#line 3135
 	*xpp = (const void *)xp;
-#line 3130
+#line 3135
 	return status;
-#line 3130
+#line 3135
 #endif
-#line 3130
+#line 3135
 }
-#line 3130
+#line 3135
 
 int
-#line 3131
+#line 3136
 ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
-#line 3131
+#line 3136
 {
-#line 3131
+#line 3136
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3131
+#line 3136
 
-#line 3131
+#line 3136
  /* basic algorithm is:
-#line 3131
+#line 3136
   *   - ensure sane alignment of input data
-#line 3131
+#line 3136
   *   - copy (conversion happens automatically) input data
-#line 3131
+#line 3136
   *     to output
-#line 3131
+#line 3136
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3131
+#line 3136
   *     at next location for converted output
-#line 3131
+#line 3136
   */
-#line 3131
+#line 3136
   long i, j, ni;
-#line 3131
+#line 3136
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3131
+#line 3136
   short *xp;
-#line 3131
+#line 3136
   int nrange = 0;         /* number of range errors */
-#line 3131
+#line 3136
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3131
+#line 3136
   long cxp = (long) *((char**)xpp);
-#line 3131
+#line 3136
 
-#line 3131
+#line 3136
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3131
+#line 3136
   /* sjl: manually stripmine so we can limit amount of
-#line 3131
+#line 3136
    * vector work space reserved to LOOPCNT elements. Also
-#line 3131
+#line 3136
    * makes vectorisation easy */
-#line 3131
+#line 3136
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3131
+#line 3136
     ni=Min(nelems-j,LOOPCNT);
-#line 3131
+#line 3136
     if (realign) {
-#line 3131
+#line 3136
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3131
+#line 3136
       xp = tmp;
-#line 3131
+#line 3136
     } else {
-#line 3131
+#line 3136
       xp = (short *) *xpp;
-#line 3131
+#line 3136
     }
-#line 3131
+#line 3136
    /* copy the next block */
-#line 3131
+#line 3136
 #pragma cdir loopcnt=LOOPCNT
-#line 3131
+#line 3136
 #pragma cdir shortloop
-#line 3131
+#line 3136
     for (i=0; i<ni; i++) {
-#line 3131
+#line 3136
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3131
+#line 3136
      /* test for range errors (not always needed but do it anyway) */
-#line 3131
+#line 3136
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3131
+#line 3136
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3131
+#line 3136
       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
-#line 3131
+#line 3136
     }
-#line 3131
+#line 3136
    /* update xpp and tp */
-#line 3131
+#line 3136
     if (realign) xp = (short *) *xpp;
-#line 3131
+#line 3136
     xp += ni;
-#line 3131
+#line 3136
     tp += ni;
-#line 3131
+#line 3136
     *xpp = (void*)xp;
-#line 3131
+#line 3136
   }
-#line 3131
+#line 3136
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3131
+#line 3136
 
-#line 3131
+#line 3136
 #else   /* not SX */
-#line 3131
+#line 3136
 	const char *xp = (const char *) *xpp;
-#line 3131
+#line 3136
 	int status = NC_NOERR;
-#line 3131
+#line 3136
 
-#line 3131
+#line 3136
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3131
+#line 3136
 	{
-#line 3131
+#line 3136
 		const int lstatus = ncx_get_short_double(xp, tp);
-#line 3131
+#line 3136
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3131
+#line 3136
 			status = lstatus;
-#line 3131
+#line 3136
 	}
-#line 3131
+#line 3136
 
-#line 3131
+#line 3136
 	*xpp = (const void *)xp;
-#line 3131
+#line 3136
 	return status;
-#line 3131
+#line 3136
 #endif
-#line 3131
+#line 3136
 }
-#line 3131
+#line 3136
 
 int
-#line 3132
+#line 3137
 ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3132
+#line 3137
 {
-#line 3132
+#line 3137
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3132
+#line 3137
 
-#line 3132
+#line 3137
  /* basic algorithm is:
-#line 3132
+#line 3137
   *   - ensure sane alignment of input data
-#line 3132
+#line 3137
   *   - copy (conversion happens automatically) input data
-#line 3132
+#line 3137
   *     to output
-#line 3132
+#line 3137
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3132
+#line 3137
   *     at next location for converted output
-#line 3132
+#line 3137
   */
-#line 3132
+#line 3137
   long i, j, ni;
-#line 3132
+#line 3137
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3132
+#line 3137
   short *xp;
-#line 3132
+#line 3137
   int nrange = 0;         /* number of range errors */
-#line 3132
+#line 3137
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3132
+#line 3137
   long cxp = (long) *((char**)xpp);
-#line 3132
+#line 3137
 
-#line 3132
+#line 3137
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3132
+#line 3137
   /* sjl: manually stripmine so we can limit amount of
-#line 3132
+#line 3137
    * vector work space reserved to LOOPCNT elements. Also
-#line 3132
+#line 3137
    * makes vectorisation easy */
-#line 3132
+#line 3137
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3132
+#line 3137
     ni=Min(nelems-j,LOOPCNT);
-#line 3132
+#line 3137
     if (realign) {
-#line 3132
+#line 3137
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3132
+#line 3137
       xp = tmp;
-#line 3132
+#line 3137
     } else {
-#line 3132
+#line 3137
       xp = (short *) *xpp;
-#line 3132
+#line 3137
     }
-#line 3132
+#line 3137
    /* copy the next block */
-#line 3132
+#line 3137
 #pragma cdir loopcnt=LOOPCNT
-#line 3132
+#line 3137
 #pragma cdir shortloop
-#line 3132
+#line 3137
     for (i=0; i<ni; i++) {
-#line 3132
+#line 3137
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3132
+#line 3137
      /* test for range errors (not always needed but do it anyway) */
-#line 3132
+#line 3137
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3132
+#line 3137
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3132
+#line 3137
       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
-#line 3132
+#line 3137
     }
-#line 3132
+#line 3137
    /* update xpp and tp */
-#line 3132
+#line 3137
     if (realign) xp = (short *) *xpp;
-#line 3132
+#line 3137
     xp += ni;
-#line 3132
+#line 3137
     tp += ni;
-#line 3132
+#line 3137
     *xpp = (void*)xp;
-#line 3132
+#line 3137
   }
-#line 3132
+#line 3137
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3132
+#line 3137
 
-#line 3132
+#line 3137
 #else   /* not SX */
-#line 3132
+#line 3137
 	const char *xp = (const char *) *xpp;
-#line 3132
+#line 3137
 	int status = NC_NOERR;
-#line 3132
+#line 3137
 
-#line 3132
+#line 3137
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3132
+#line 3137
 	{
-#line 3132
+#line 3137
 		const int lstatus = ncx_get_short_longlong(xp, tp);
-#line 3132
+#line 3137
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3132
+#line 3137
 			status = lstatus;
-#line 3132
+#line 3137
 	}
-#line 3132
+#line 3137
 
-#line 3132
+#line 3137
 	*xpp = (const void *)xp;
-#line 3132
+#line 3137
 	return status;
-#line 3132
+#line 3137
 #endif
-#line 3132
+#line 3137
 }
-#line 3132
+#line 3137
 
 int
-#line 3133
+#line 3138
 ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3133
+#line 3138
 {
-#line 3133
+#line 3138
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3133
+#line 3138
 
-#line 3133
+#line 3138
  /* basic algorithm is:
-#line 3133
+#line 3138
   *   - ensure sane alignment of input data
-#line 3133
+#line 3138
   *   - copy (conversion happens automatically) input data
-#line 3133
+#line 3138
   *     to output
-#line 3133
+#line 3138
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3133
+#line 3138
   *     at next location for converted output
-#line 3133
+#line 3138
   */
-#line 3133
+#line 3138
   long i, j, ni;
-#line 3133
+#line 3138
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3133
+#line 3138
   short *xp;
-#line 3133
+#line 3138
   int nrange = 0;         /* number of range errors */
-#line 3133
+#line 3138
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3133
+#line 3138
   long cxp = (long) *((char**)xpp);
-#line 3133
+#line 3138
 
-#line 3133
+#line 3138
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3133
+#line 3138
   /* sjl: manually stripmine so we can limit amount of
-#line 3133
+#line 3138
    * vector work space reserved to LOOPCNT elements. Also
-#line 3133
+#line 3138
    * makes vectorisation easy */
-#line 3133
+#line 3138
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3133
+#line 3138
     ni=Min(nelems-j,LOOPCNT);
-#line 3133
+#line 3138
     if (realign) {
-#line 3133
+#line 3138
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3133
+#line 3138
       xp = tmp;
-#line 3133
+#line 3138
     } else {
-#line 3133
+#line 3138
       xp = (short *) *xpp;
-#line 3133
+#line 3138
     }
-#line 3133
+#line 3138
    /* copy the next block */
-#line 3133
+#line 3138
 #pragma cdir loopcnt=LOOPCNT
-#line 3133
+#line 3138
 #pragma cdir shortloop
-#line 3133
+#line 3138
     for (i=0; i<ni; i++) {
-#line 3133
+#line 3138
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3133
+#line 3138
      /* test for range errors (not always needed but do it anyway) */
-#line 3133
+#line 3138
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3133
+#line 3138
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3133
+#line 3138
       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
-#line 3133
+#line 3138
     }
-#line 3133
+#line 3138
    /* update xpp and tp */
-#line 3133
+#line 3138
     if (realign) xp = (short *) *xpp;
-#line 3133
+#line 3138
     xp += ni;
-#line 3133
+#line 3138
     tp += ni;
-#line 3133
+#line 3138
     *xpp = (void*)xp;
-#line 3133
+#line 3138
   }
-#line 3133
+#line 3138
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3133
+#line 3138
 
-#line 3133
+#line 3138
 #else   /* not SX */
-#line 3133
+#line 3138
 	const char *xp = (const char *) *xpp;
-#line 3133
+#line 3138
 	int status = NC_NOERR;
-#line 3133
+#line 3138
 
-#line 3133
+#line 3138
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3133
+#line 3138
 	{
-#line 3133
+#line 3138
 		const int lstatus = ncx_get_short_uchar(xp, tp);
-#line 3133
+#line 3138
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3133
+#line 3138
 			status = lstatus;
-#line 3133
+#line 3138
 	}
-#line 3133
+#line 3138
 
-#line 3133
+#line 3138
 	*xpp = (const void *)xp;
-#line 3133
+#line 3138
 	return status;
-#line 3133
+#line 3138
 #endif
-#line 3133
+#line 3138
 }
-#line 3133
+#line 3138
 
 int
-#line 3134
+#line 3139
 ncx_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3134
+#line 3139
 {
-#line 3134
+#line 3139
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3134
+#line 3139
 
-#line 3134
+#line 3139
  /* basic algorithm is:
-#line 3134
+#line 3139
   *   - ensure sane alignment of input data
-#line 3134
+#line 3139
   *   - copy (conversion happens automatically) input data
-#line 3134
+#line 3139
   *     to output
-#line 3134
+#line 3139
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3134
+#line 3139
   *     at next location for converted output
-#line 3134
+#line 3139
   */
-#line 3134
+#line 3139
   long i, j, ni;
-#line 3134
+#line 3139
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3134
+#line 3139
   short *xp;
-#line 3134
+#line 3139
   int nrange = 0;         /* number of range errors */
-#line 3134
+#line 3139
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3134
+#line 3139
   long cxp = (long) *((char**)xpp);
-#line 3134
+#line 3139
 
-#line 3134
+#line 3139
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3134
+#line 3139
   /* sjl: manually stripmine so we can limit amount of
-#line 3134
+#line 3139
    * vector work space reserved to LOOPCNT elements. Also
-#line 3134
+#line 3139
    * makes vectorisation easy */
-#line 3134
+#line 3139
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3134
+#line 3139
     ni=Min(nelems-j,LOOPCNT);
-#line 3134
+#line 3139
     if (realign) {
-#line 3134
+#line 3139
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3134
+#line 3139
       xp = tmp;
-#line 3134
+#line 3139
     } else {
-#line 3134
+#line 3139
       xp = (short *) *xpp;
-#line 3134
+#line 3139
     }
-#line 3134
+#line 3139
    /* copy the next block */
-#line 3134
+#line 3139
 #pragma cdir loopcnt=LOOPCNT
-#line 3134
+#line 3139
 #pragma cdir shortloop
-#line 3134
+#line 3139
     for (i=0; i<ni; i++) {
-#line 3134
+#line 3139
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3134
+#line 3139
      /* test for range errors (not always needed but do it anyway) */
-#line 3134
+#line 3139
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3134
+#line 3139
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3134
+#line 3139
       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
-#line 3134
+#line 3139
     }
-#line 3134
+#line 3139
    /* update xpp and tp */
-#line 3134
+#line 3139
     if (realign) xp = (short *) *xpp;
-#line 3134
+#line 3139
     xp += ni;
-#line 3134
+#line 3139
     tp += ni;
-#line 3134
+#line 3139
     *xpp = (void*)xp;
-#line 3134
+#line 3139
   }
-#line 3134
+#line 3139
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3134
+#line 3139
 
-#line 3134
+#line 3139
 #else   /* not SX */
-#line 3134
+#line 3139
 	const char *xp = (const char *) *xpp;
-#line 3134
+#line 3139
 	int status = NC_NOERR;
-#line 3134
+#line 3139
 
-#line 3134
+#line 3139
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3134
+#line 3139
 	{
-#line 3134
+#line 3139
 		const int lstatus = ncx_get_short_ushort(xp, tp);
-#line 3134
+#line 3139
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3134
+#line 3139
 			status = lstatus;
-#line 3134
+#line 3139
 	}
-#line 3134
+#line 3139
 
-#line 3134
+#line 3139
 	*xpp = (const void *)xp;
-#line 3134
+#line 3139
 	return status;
-#line 3134
+#line 3139
 #endif
-#line 3134
+#line 3139
 }
-#line 3134
+#line 3139
 
 int
-#line 3135
+#line 3140
 ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3135
+#line 3140
 {
-#line 3135
+#line 3140
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3135
+#line 3140
 
-#line 3135
+#line 3140
  /* basic algorithm is:
-#line 3135
+#line 3140
   *   - ensure sane alignment of input data
-#line 3135
+#line 3140
   *   - copy (conversion happens automatically) input data
-#line 3135
+#line 3140
   *     to output
-#line 3135
+#line 3140
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3135
+#line 3140
   *     at next location for converted output
-#line 3135
+#line 3140
   */
-#line 3135
+#line 3140
   long i, j, ni;
-#line 3135
+#line 3140
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3135
+#line 3140
   short *xp;
-#line 3135
+#line 3140
   int nrange = 0;         /* number of range errors */
-#line 3135
+#line 3140
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3135
+#line 3140
   long cxp = (long) *((char**)xpp);
-#line 3135
+#line 3140
 
-#line 3135
+#line 3140
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3135
+#line 3140
   /* sjl: manually stripmine so we can limit amount of
-#line 3135
+#line 3140
    * vector work space reserved to LOOPCNT elements. Also
-#line 3135
+#line 3140
    * makes vectorisation easy */
-#line 3135
+#line 3140
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3135
+#line 3140
     ni=Min(nelems-j,LOOPCNT);
-#line 3135
+#line 3140
     if (realign) {
-#line 3135
+#line 3140
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3135
+#line 3140
       xp = tmp;
-#line 3135
+#line 3140
     } else {
-#line 3135
+#line 3140
       xp = (short *) *xpp;
-#line 3135
+#line 3140
     }
-#line 3135
+#line 3140
    /* copy the next block */
-#line 3135
+#line 3140
 #pragma cdir loopcnt=LOOPCNT
-#line 3135
+#line 3140
 #pragma cdir shortloop
-#line 3135
+#line 3140
     for (i=0; i<ni; i++) {
-#line 3135
+#line 3140
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3135
+#line 3140
      /* test for range errors (not always needed but do it anyway) */
-#line 3135
+#line 3140
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3135
+#line 3140
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3135
+#line 3140
       nrange += xp[i] > UINT_MAX || xp[i] < 0;
-#line 3135
+#line 3140
     }
-#line 3135
+#line 3140
    /* update xpp and tp */
-#line 3135
+#line 3140
     if (realign) xp = (short *) *xpp;
-#line 3135
+#line 3140
     xp += ni;
-#line 3135
+#line 3140
     tp += ni;
-#line 3135
+#line 3140
     *xpp = (void*)xp;
-#line 3135
+#line 3140
   }
-#line 3135
+#line 3140
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3135
+#line 3140
 
-#line 3135
+#line 3140
 #else   /* not SX */
-#line 3135
+#line 3140
 	const char *xp = (const char *) *xpp;
-#line 3135
+#line 3140
 	int status = NC_NOERR;
-#line 3135
+#line 3140
 
-#line 3135
+#line 3140
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3135
+#line 3140
 	{
-#line 3135
+#line 3140
 		const int lstatus = ncx_get_short_uint(xp, tp);
-#line 3135
+#line 3140
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3135
+#line 3140
 			status = lstatus;
-#line 3135
+#line 3140
 	}
-#line 3135
+#line 3140
 
-#line 3135
+#line 3140
 	*xpp = (const void *)xp;
-#line 3135
+#line 3140
 	return status;
-#line 3135
+#line 3140
 #endif
-#line 3135
+#line 3140
 }
-#line 3135
+#line 3140
 
 int
-#line 3136
+#line 3141
 ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3136
+#line 3141
 {
-#line 3136
+#line 3141
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3136
+#line 3141
 
-#line 3136
+#line 3141
  /* basic algorithm is:
-#line 3136
+#line 3141
   *   - ensure sane alignment of input data
-#line 3136
+#line 3141
   *   - copy (conversion happens automatically) input data
-#line 3136
+#line 3141
   *     to output
-#line 3136
+#line 3141
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3136
+#line 3141
   *     at next location for converted output
-#line 3136
+#line 3141
   */
-#line 3136
+#line 3141
   long i, j, ni;
-#line 3136
+#line 3141
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3136
+#line 3141
   short *xp;
-#line 3136
+#line 3141
   int nrange = 0;         /* number of range errors */
-#line 3136
+#line 3141
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3136
+#line 3141
   long cxp = (long) *((char**)xpp);
-#line 3136
+#line 3141
 
-#line 3136
+#line 3141
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3136
+#line 3141
   /* sjl: manually stripmine so we can limit amount of
-#line 3136
+#line 3141
    * vector work space reserved to LOOPCNT elements. Also
-#line 3136
+#line 3141
    * makes vectorisation easy */
-#line 3136
+#line 3141
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3136
+#line 3141
     ni=Min(nelems-j,LOOPCNT);
-#line 3136
+#line 3141
     if (realign) {
-#line 3136
+#line 3141
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
-#line 3136
+#line 3141
       xp = tmp;
-#line 3136
+#line 3141
     } else {
-#line 3136
+#line 3141
       xp = (short *) *xpp;
-#line 3136
+#line 3141
     }
-#line 3136
+#line 3141
    /* copy the next block */
-#line 3136
+#line 3141
 #pragma cdir loopcnt=LOOPCNT
-#line 3136
+#line 3141
 #pragma cdir shortloop
-#line 3136
+#line 3141
     for (i=0; i<ni; i++) {
-#line 3136
+#line 3141
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3136
+#line 3141
      /* test for range errors (not always needed but do it anyway) */
-#line 3136
+#line 3141
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3136
+#line 3141
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3136
+#line 3141
       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
-#line 3136
+#line 3141
     }
-#line 3136
+#line 3141
    /* update xpp and tp */
-#line 3136
+#line 3141
     if (realign) xp = (short *) *xpp;
-#line 3136
+#line 3141
     xp += ni;
-#line 3136
+#line 3141
     tp += ni;
-#line 3136
+#line 3141
     *xpp = (void*)xp;
-#line 3136
+#line 3141
   }
-#line 3136
+#line 3141
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3136
+#line 3141
 
-#line 3136
+#line 3141
 #else   /* not SX */
-#line 3136
+#line 3141
 	const char *xp = (const char *) *xpp;
-#line 3136
+#line 3141
 	int status = NC_NOERR;
-#line 3136
+#line 3141
 
-#line 3136
+#line 3141
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3136
+#line 3141
 	{
-#line 3136
+#line 3141
 		const int lstatus = ncx_get_short_ulonglong(xp, tp);
-#line 3136
+#line 3141
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3136
+#line 3141
 			status = lstatus;
-#line 3136
+#line 3141
 	}
-#line 3136
+#line 3141
 
-#line 3136
+#line 3141
 	*xpp = (const void *)xp;
-#line 3136
+#line 3141
 	return status;
-#line 3136
+#line 3141
 #endif
-#line 3136
+#line 3141
 }
-#line 3136
+#line 3141
 
 
 int
-#line 3138
+#line 3143
 ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3138
+#line 3143
 {
-#line 3138
+#line 3143
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3138
+#line 3143
 
-#line 3138
+#line 3143
 	const char *xp = (const char *) *xpp;
-#line 3138
+#line 3143
 	int status = NC_NOERR;
-#line 3138
+#line 3143
 
-#line 3138
+#line 3143
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3138
+#line 3143
 	{
-#line 3138
+#line 3143
 		const int lstatus = ncx_get_short_schar(xp, tp);
-#line 3138
+#line 3143
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3138
+#line 3143
 			status = lstatus;
-#line 3138
+#line 3143
 	}
-#line 3138
+#line 3143
 
-#line 3138
+#line 3143
 	if (rndup != 0)
-#line 3138
+#line 3143
 		xp += X_SIZEOF_SHORT;
-#line 3138
+#line 3143
 
-#line 3138
+#line 3143
 	*xpp = (void *)xp;
-#line 3138
+#line 3143
 	return status;
-#line 3138
+#line 3143
 }
-#line 3138
+#line 3143
 
 int
-#line 3139
+#line 3144
 ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3139
+#line 3144
 {
-#line 3139
+#line 3144
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3139
+#line 3144
 
-#line 3139
+#line 3144
 	const char *xp = (const char *) *xpp;
-#line 3139
+#line 3144
 	int status = NC_NOERR;
-#line 3139
+#line 3144
 
-#line 3139
+#line 3144
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3139
+#line 3144
 	{
-#line 3139
+#line 3144
 		const int lstatus = ncx_get_short_uchar(xp, tp);
-#line 3139
+#line 3144
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3139
+#line 3144
 			status = lstatus;
-#line 3139
+#line 3144
 	}
-#line 3139
+#line 3144
 
-#line 3139
+#line 3144
 	if (rndup != 0)
-#line 3139
+#line 3144
 		xp += X_SIZEOF_SHORT;
-#line 3139
+#line 3144
 
-#line 3139
+#line 3144
 	*xpp = (void *)xp;
-#line 3139
+#line 3144
 	return status;
-#line 3139
+#line 3144
 }
-#line 3139
+#line 3144
 
 int
-#line 3140
+#line 3145
 ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
-#line 3140
+#line 3145
 {
-#line 3140
+#line 3145
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3140
+#line 3145
 
-#line 3140
+#line 3145
 	const char *xp = (const char *) *xpp;
-#line 3140
+#line 3145
 	int status = NC_NOERR;
-#line 3140
+#line 3145
 
-#line 3140
+#line 3145
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3140
+#line 3145
 	{
-#line 3140
+#line 3145
 		const int lstatus = ncx_get_short_short(xp, tp);
-#line 3140
+#line 3145
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3140
+#line 3145
 			status = lstatus;
-#line 3140
+#line 3145
 	}
-#line 3140
+#line 3145
 
-#line 3140
+#line 3145
 	if (rndup != 0)
-#line 3140
+#line 3145
 		xp += X_SIZEOF_SHORT;
-#line 3140
+#line 3145
 
-#line 3140
+#line 3145
 	*xpp = (void *)xp;
-#line 3140
+#line 3145
 	return status;
-#line 3140
+#line 3145
 }
-#line 3140
+#line 3145
 
 int
-#line 3141
+#line 3146
 ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
-#line 3141
+#line 3146
 {
-#line 3141
+#line 3146
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3141
+#line 3146
 
-#line 3141
+#line 3146
 	const char *xp = (const char *) *xpp;
-#line 3141
+#line 3146
 	int status = NC_NOERR;
-#line 3141
+#line 3146
 
-#line 3141
+#line 3146
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3141
+#line 3146
 	{
-#line 3141
+#line 3146
 		const int lstatus = ncx_get_short_int(xp, tp);
-#line 3141
+#line 3146
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3141
+#line 3146
 			status = lstatus;
-#line 3141
+#line 3146
 	}
-#line 3141
+#line 3146
 
-#line 3141
+#line 3146
 	if (rndup != 0)
-#line 3141
+#line 3146
 		xp += X_SIZEOF_SHORT;
-#line 3141
+#line 3146
 
-#line 3141
+#line 3146
 	*xpp = (void *)xp;
-#line 3141
+#line 3146
 	return status;
-#line 3141
+#line 3146
 }
-#line 3141
+#line 3146
 
 int
-#line 3142
+#line 3147
 ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
-#line 3142
+#line 3147
 {
-#line 3142
+#line 3147
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3142
+#line 3147
 
-#line 3142
+#line 3147
 	const char *xp = (const char *) *xpp;
-#line 3142
+#line 3147
 	int status = NC_NOERR;
-#line 3142
+#line 3147
 
-#line 3142
+#line 3147
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3142
+#line 3147
 	{
-#line 3142
+#line 3147
 		const int lstatus = ncx_get_short_long(xp, tp);
-#line 3142
+#line 3147
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3142
+#line 3147
 			status = lstatus;
-#line 3142
+#line 3147
 	}
-#line 3142
+#line 3147
 
-#line 3142
+#line 3147
 	if (rndup != 0)
-#line 3142
+#line 3147
 		xp += X_SIZEOF_SHORT;
-#line 3142
+#line 3147
 
-#line 3142
+#line 3147
 	*xpp = (void *)xp;
-#line 3142
+#line 3147
 	return status;
-#line 3142
+#line 3147
 }
-#line 3142
+#line 3147
 
 int
-#line 3143
+#line 3148
 ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
-#line 3143
+#line 3148
 {
-#line 3143
+#line 3148
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3143
+#line 3148
 
-#line 3143
+#line 3148
 	const char *xp = (const char *) *xpp;
-#line 3143
+#line 3148
 	int status = NC_NOERR;
-#line 3143
+#line 3148
 
-#line 3143
+#line 3148
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3143
+#line 3148
 	{
-#line 3143
+#line 3148
 		const int lstatus = ncx_get_short_float(xp, tp);
-#line 3143
+#line 3148
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3143
+#line 3148
 			status = lstatus;
-#line 3143
+#line 3148
 	}
-#line 3143
+#line 3148
 
-#line 3143
+#line 3148
 	if (rndup != 0)
-#line 3143
+#line 3148
 		xp += X_SIZEOF_SHORT;
-#line 3143
+#line 3148
 
-#line 3143
+#line 3148
 	*xpp = (void *)xp;
-#line 3143
+#line 3148
 	return status;
-#line 3143
+#line 3148
 }
-#line 3143
+#line 3148
 
 int
-#line 3144
+#line 3149
 ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
-#line 3144
+#line 3149
 {
-#line 3144
+#line 3149
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3144
+#line 3149
 
-#line 3144
+#line 3149
 	const char *xp = (const char *) *xpp;
-#line 3144
+#line 3149
 	int status = NC_NOERR;
-#line 3144
+#line 3149
 
-#line 3144
+#line 3149
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3144
+#line 3149
 	{
-#line 3144
+#line 3149
 		const int lstatus = ncx_get_short_double(xp, tp);
-#line 3144
+#line 3149
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3144
+#line 3149
 			status = lstatus;
-#line 3144
+#line 3149
 	}
-#line 3144
+#line 3149
 
-#line 3144
+#line 3149
 	if (rndup != 0)
-#line 3144
+#line 3149
 		xp += X_SIZEOF_SHORT;
-#line 3144
+#line 3149
 
-#line 3144
+#line 3149
 	*xpp = (void *)xp;
-#line 3144
+#line 3149
 	return status;
-#line 3144
+#line 3149
 }
-#line 3144
+#line 3149
 
 int
-#line 3145
+#line 3150
 ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3145
+#line 3150
 {
-#line 3145
+#line 3150
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3145
+#line 3150
 
-#line 3145
+#line 3150
 	const char *xp = (const char *) *xpp;
-#line 3145
+#line 3150
 	int status = NC_NOERR;
-#line 3145
+#line 3150
 
-#line 3145
+#line 3150
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3145
+#line 3150
 	{
-#line 3145
+#line 3150
 		const int lstatus = ncx_get_short_uint(xp, tp);
-#line 3145
+#line 3150
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3145
+#line 3150
 			status = lstatus;
-#line 3145
+#line 3150
 	}
-#line 3145
+#line 3150
 
-#line 3145
+#line 3150
 	if (rndup != 0)
-#line 3145
+#line 3150
 		xp += X_SIZEOF_SHORT;
-#line 3145
+#line 3150
 
-#line 3145
+#line 3150
 	*xpp = (void *)xp;
-#line 3145
+#line 3150
 	return status;
-#line 3145
+#line 3150
 }
-#line 3145
+#line 3150
 
 int
-#line 3146
+#line 3151
 ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3146
+#line 3151
 {
-#line 3146
+#line 3151
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3146
+#line 3151
 
-#line 3146
+#line 3151
 	const char *xp = (const char *) *xpp;
-#line 3146
+#line 3151
 	int status = NC_NOERR;
-#line 3146
+#line 3151
 
-#line 3146
+#line 3151
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3146
+#line 3151
 	{
-#line 3146
+#line 3151
 		const int lstatus = ncx_get_short_longlong(xp, tp);
-#line 3146
+#line 3151
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3146
+#line 3151
 			status = lstatus;
-#line 3146
+#line 3151
 	}
-#line 3146
+#line 3151
 
-#line 3146
+#line 3151
 	if (rndup != 0)
-#line 3146
+#line 3151
 		xp += X_SIZEOF_SHORT;
-#line 3146
+#line 3151
 
-#line 3146
+#line 3151
 	*xpp = (void *)xp;
-#line 3146
+#line 3151
 	return status;
-#line 3146
+#line 3151
 }
-#line 3146
+#line 3151
 
 int
-#line 3147
+#line 3152
 ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3147
+#line 3152
 {
-#line 3147
+#line 3152
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3147
+#line 3152
 
-#line 3147
+#line 3152
 	const char *xp = (const char *) *xpp;
-#line 3147
+#line 3152
 	int status = NC_NOERR;
-#line 3147
+#line 3152
 
-#line 3147
+#line 3152
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3147
+#line 3152
 	{
-#line 3147
+#line 3152
 		const int lstatus = ncx_get_short_ulonglong(xp, tp);
-#line 3147
+#line 3152
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3147
+#line 3152
 			status = lstatus;
-#line 3147
+#line 3152
 	}
-#line 3147
+#line 3152
 
-#line 3147
+#line 3152
 	if (rndup != 0)
-#line 3147
+#line 3152
 		xp += X_SIZEOF_SHORT;
-#line 3147
+#line 3152
 
-#line 3147
+#line 3152
 	*xpp = (void *)xp;
-#line 3147
+#line 3152
 	return status;
-#line 3147
+#line 3152
 }
-#line 3147
+#line 3152
 
 int
-#line 3148
+#line 3153
 ncx_pad_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3148
+#line 3153
 {
-#line 3148
+#line 3153
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3148
+#line 3153
 
-#line 3148
+#line 3153
 	const char *xp = (const char *) *xpp;
-#line 3148
+#line 3153
 	int status = NC_NOERR;
-#line 3148
+#line 3153
 
-#line 3148
+#line 3153
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3148
+#line 3153
 	{
-#line 3148
+#line 3153
 		const int lstatus = ncx_get_short_ushort(xp, tp);
-#line 3148
+#line 3153
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3148
+#line 3153
 			status = lstatus;
-#line 3148
+#line 3153
 	}
-#line 3148
+#line 3153
 
-#line 3148
+#line 3153
 	if (rndup != 0)
-#line 3148
+#line 3153
 		xp += X_SIZEOF_SHORT;
-#line 3148
+#line 3153
 
-#line 3148
+#line 3153
 	*xpp = (void *)xp;
-#line 3148
+#line 3153
 	return status;
-#line 3148
+#line 3153
 }
-#line 3148
+#line 3153
 
 
 #if X_SIZEOF_SHORT == SIZEOF_SHORT
@@ -15420,2074 +15425,2074 @@ ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
 }
 #else
 int
-#line 3164
+#line 3169
 ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3164
+#line 3169
 {
-#line 3164
+#line 3169
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3164
+#line 3169
 
-#line 3164
+#line 3169
  /* basic algorithm is:
-#line 3164
+#line 3169
   *   - ensure sane alignment of output data
-#line 3164
+#line 3169
   *   - copy (conversion happens automatically) input data
-#line 3164
+#line 3169
   *     to output
-#line 3164
+#line 3169
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3164
+#line 3169
   *     at next location for converted output
-#line 3164
+#line 3169
   */
-#line 3164
+#line 3169
   long i, j, ni;
-#line 3164
+#line 3169
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3164
+#line 3169
   short *xp;
-#line 3164
+#line 3169
   int nrange = 0;         /* number of range errors */
-#line 3164
+#line 3169
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3164
+#line 3169
   long cxp = (long) *((char**)xpp);
-#line 3164
+#line 3169
 
-#line 3164
+#line 3169
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3164
+#line 3169
   /* sjl: manually stripmine so we can limit amount of
-#line 3164
+#line 3169
    * vector work space reserved to LOOPCNT elements. Also
-#line 3164
+#line 3169
    * makes vectorisation easy */
-#line 3164
+#line 3169
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3164
+#line 3169
     ni=Min(nelems-j,LOOPCNT);
-#line 3164
+#line 3169
     if (realign) {
-#line 3164
+#line 3169
       xp = tmp;
-#line 3164
+#line 3169
     } else {
-#line 3164
+#line 3169
       xp = (short *) *xpp;
-#line 3164
+#line 3169
     }
-#line 3164
+#line 3169
    /* copy the next block */
-#line 3164
+#line 3169
 #pragma cdir loopcnt=LOOPCNT
-#line 3164
+#line 3169
 #pragma cdir shortloop
-#line 3164
+#line 3169
     for (i=0; i<ni; i++) {
-#line 3164
+#line 3169
       /* the normal case: */
-#line 3164
+#line 3169
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3164
+#line 3169
      /* test for range errors (not always needed but do it anyway) */
-#line 3164
+#line 3169
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3164
+#line 3169
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3164
+#line 3169
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3164
+#line 3169
     }
-#line 3164
+#line 3169
    /* copy workspace back if necessary */
-#line 3164
+#line 3169
     if (realign) {
-#line 3164
+#line 3169
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3164
+#line 3169
       xp = (short *) *xpp;
-#line 3164
+#line 3169
     }
-#line 3164
+#line 3169
    /* update xpp and tp */
-#line 3164
+#line 3169
     xp += ni;
-#line 3164
+#line 3169
     tp += ni;
-#line 3164
+#line 3169
     *xpp = (void*)xp;
-#line 3164
+#line 3169
   }
-#line 3164
+#line 3169
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3164
+#line 3169
 
-#line 3164
+#line 3169
 #else   /* not SX */
-#line 3164
+#line 3169
 
-#line 3164
+#line 3169
 	char *xp = (char *) *xpp;
-#line 3164
+#line 3169
 	int status = NC_NOERR;
-#line 3164
+#line 3169
 
-#line 3164
+#line 3169
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3164
+#line 3169
 	{
-#line 3164
+#line 3169
 		int lstatus = ncx_put_short_short(xp, tp, fillp);
-#line 3164
+#line 3169
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3164
+#line 3169
 			status = lstatus;
-#line 3164
+#line 3169
 	}
-#line 3164
+#line 3169
 
-#line 3164
+#line 3169
 	*xpp = (void *)xp;
-#line 3164
+#line 3169
 	return status;
-#line 3164
+#line 3169
 #endif
-#line 3164
+#line 3169
 }
-#line 3164
+#line 3169
 
 #endif
 int
-#line 3166
+#line 3171
 ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3166
+#line 3171
 {
-#line 3166
+#line 3171
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3166
+#line 3171
 
-#line 3166
+#line 3171
  /* basic algorithm is:
-#line 3166
+#line 3171
   *   - ensure sane alignment of output data
-#line 3166
+#line 3171
   *   - copy (conversion happens automatically) input data
-#line 3166
+#line 3171
   *     to output
-#line 3166
+#line 3171
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3166
+#line 3171
   *     at next location for converted output
-#line 3166
+#line 3171
   */
-#line 3166
+#line 3171
   long i, j, ni;
-#line 3166
+#line 3171
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3166
+#line 3171
   short *xp;
-#line 3166
+#line 3171
   int nrange = 0;         /* number of range errors */
-#line 3166
+#line 3171
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3166
+#line 3171
   long cxp = (long) *((char**)xpp);
-#line 3166
+#line 3171
 
-#line 3166
+#line 3171
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3166
+#line 3171
   /* sjl: manually stripmine so we can limit amount of
-#line 3166
+#line 3171
    * vector work space reserved to LOOPCNT elements. Also
-#line 3166
+#line 3171
    * makes vectorisation easy */
-#line 3166
+#line 3171
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3166
+#line 3171
     ni=Min(nelems-j,LOOPCNT);
-#line 3166
+#line 3171
     if (realign) {
-#line 3166
+#line 3171
       xp = tmp;
-#line 3166
+#line 3171
     } else {
-#line 3166
+#line 3171
       xp = (short *) *xpp;
-#line 3166
+#line 3171
     }
-#line 3166
+#line 3171
    /* copy the next block */
-#line 3166
+#line 3171
 #pragma cdir loopcnt=LOOPCNT
-#line 3166
+#line 3171
 #pragma cdir shortloop
-#line 3166
+#line 3171
     for (i=0; i<ni; i++) {
-#line 3166
+#line 3171
       /* the normal case: */
-#line 3166
+#line 3171
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3166
+#line 3171
      /* test for range errors (not always needed but do it anyway) */
-#line 3166
+#line 3171
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3166
+#line 3171
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3166
+#line 3171
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3166
+#line 3171
     }
-#line 3166
+#line 3171
    /* copy workspace back if necessary */
-#line 3166
+#line 3171
     if (realign) {
-#line 3166
+#line 3171
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3166
+#line 3171
       xp = (short *) *xpp;
-#line 3166
+#line 3171
     }
-#line 3166
+#line 3171
    /* update xpp and tp */
-#line 3166
+#line 3171
     xp += ni;
-#line 3166
+#line 3171
     tp += ni;
-#line 3166
+#line 3171
     *xpp = (void*)xp;
-#line 3166
+#line 3171
   }
-#line 3166
+#line 3171
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3166
+#line 3171
 
-#line 3166
+#line 3171
 #else   /* not SX */
-#line 3166
+#line 3171
 
-#line 3166
+#line 3171
 	char *xp = (char *) *xpp;
-#line 3166
+#line 3171
 	int status = NC_NOERR;
-#line 3166
+#line 3171
 
-#line 3166
+#line 3171
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3166
+#line 3171
 	{
-#line 3166
+#line 3171
 		int lstatus = ncx_put_short_schar(xp, tp, fillp);
-#line 3166
+#line 3171
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3166
+#line 3171
 			status = lstatus;
-#line 3166
+#line 3171
 	}
-#line 3166
+#line 3171
 
-#line 3166
+#line 3171
 	*xpp = (void *)xp;
-#line 3166
+#line 3171
 	return status;
-#line 3166
+#line 3171
 #endif
-#line 3166
+#line 3171
 }
-#line 3166
+#line 3171
 
 int
-#line 3167
+#line 3172
 ncx_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3167
+#line 3172
 {
-#line 3167
+#line 3172
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3167
+#line 3172
 
-#line 3167
+#line 3172
  /* basic algorithm is:
-#line 3167
+#line 3172
   *   - ensure sane alignment of output data
-#line 3167
+#line 3172
   *   - copy (conversion happens automatically) input data
-#line 3167
+#line 3172
   *     to output
-#line 3167
+#line 3172
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3167
+#line 3172
   *     at next location for converted output
-#line 3167
+#line 3172
   */
-#line 3167
+#line 3172
   long i, j, ni;
-#line 3167
+#line 3172
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3167
+#line 3172
   short *xp;
-#line 3167
+#line 3172
   int nrange = 0;         /* number of range errors */
-#line 3167
+#line 3172
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3167
+#line 3172
   long cxp = (long) *((char**)xpp);
-#line 3167
+#line 3172
 
-#line 3167
+#line 3172
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3167
+#line 3172
   /* sjl: manually stripmine so we can limit amount of
-#line 3167
+#line 3172
    * vector work space reserved to LOOPCNT elements. Also
-#line 3167
+#line 3172
    * makes vectorisation easy */
-#line 3167
+#line 3172
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3167
+#line 3172
     ni=Min(nelems-j,LOOPCNT);
-#line 3167
+#line 3172
     if (realign) {
-#line 3167
+#line 3172
       xp = tmp;
-#line 3167
+#line 3172
     } else {
-#line 3167
+#line 3172
       xp = (short *) *xpp;
-#line 3167
+#line 3172
     }
-#line 3167
+#line 3172
    /* copy the next block */
-#line 3167
+#line 3172
 #pragma cdir loopcnt=LOOPCNT
-#line 3167
+#line 3172
 #pragma cdir shortloop
-#line 3167
+#line 3172
     for (i=0; i<ni; i++) {
-#line 3167
+#line 3172
       /* the normal case: */
-#line 3167
+#line 3172
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3167
+#line 3172
      /* test for range errors (not always needed but do it anyway) */
-#line 3167
+#line 3172
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3167
+#line 3172
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3167
+#line 3172
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3167
+#line 3172
     }
-#line 3167
+#line 3172
    /* copy workspace back if necessary */
-#line 3167
+#line 3172
     if (realign) {
-#line 3167
+#line 3172
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3167
+#line 3172
       xp = (short *) *xpp;
-#line 3167
+#line 3172
     }
-#line 3167
+#line 3172
    /* update xpp and tp */
-#line 3167
+#line 3172
     xp += ni;
-#line 3167
+#line 3172
     tp += ni;
-#line 3167
+#line 3172
     *xpp = (void*)xp;
-#line 3167
+#line 3172
   }
-#line 3167
+#line 3172
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3167
+#line 3172
 
-#line 3167
+#line 3172
 #else   /* not SX */
-#line 3167
+#line 3172
 
-#line 3167
+#line 3172
 	char *xp = (char *) *xpp;
-#line 3167
+#line 3172
 	int status = NC_NOERR;
-#line 3167
+#line 3172
 
-#line 3167
+#line 3172
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3167
+#line 3172
 	{
-#line 3167
+#line 3172
 		int lstatus = ncx_put_short_int(xp, tp, fillp);
-#line 3167
+#line 3172
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3167
+#line 3172
 			status = lstatus;
-#line 3167
+#line 3172
 	}
-#line 3167
+#line 3172
 
-#line 3167
+#line 3172
 	*xpp = (void *)xp;
-#line 3167
+#line 3172
 	return status;
-#line 3167
+#line 3172
 #endif
-#line 3167
+#line 3172
 }
-#line 3167
+#line 3172
 
 int
-#line 3168
+#line 3173
 ncx_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3168
+#line 3173
 {
-#line 3168
+#line 3173
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3168
+#line 3173
 
-#line 3168
+#line 3173
  /* basic algorithm is:
-#line 3168
+#line 3173
   *   - ensure sane alignment of output data
-#line 3168
+#line 3173
   *   - copy (conversion happens automatically) input data
-#line 3168
+#line 3173
   *     to output
-#line 3168
+#line 3173
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3168
+#line 3173
   *     at next location for converted output
-#line 3168
+#line 3173
   */
-#line 3168
+#line 3173
   long i, j, ni;
-#line 3168
+#line 3173
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3168
+#line 3173
   short *xp;
-#line 3168
+#line 3173
   int nrange = 0;         /* number of range errors */
-#line 3168
+#line 3173
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3168
+#line 3173
   long cxp = (long) *((char**)xpp);
-#line 3168
+#line 3173
 
-#line 3168
+#line 3173
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3168
+#line 3173
   /* sjl: manually stripmine so we can limit amount of
-#line 3168
+#line 3173
    * vector work space reserved to LOOPCNT elements. Also
-#line 3168
+#line 3173
    * makes vectorisation easy */
-#line 3168
+#line 3173
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3168
+#line 3173
     ni=Min(nelems-j,LOOPCNT);
-#line 3168
+#line 3173
     if (realign) {
-#line 3168
+#line 3173
       xp = tmp;
-#line 3168
+#line 3173
     } else {
-#line 3168
+#line 3173
       xp = (short *) *xpp;
-#line 3168
+#line 3173
     }
-#line 3168
+#line 3173
    /* copy the next block */
-#line 3168
+#line 3173
 #pragma cdir loopcnt=LOOPCNT
-#line 3168
+#line 3173
 #pragma cdir shortloop
-#line 3168
+#line 3173
     for (i=0; i<ni; i++) {
-#line 3168
+#line 3173
       /* the normal case: */
-#line 3168
+#line 3173
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3168
+#line 3173
      /* test for range errors (not always needed but do it anyway) */
-#line 3168
+#line 3173
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3168
+#line 3173
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3168
+#line 3173
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3168
+#line 3173
     }
-#line 3168
+#line 3173
    /* copy workspace back if necessary */
-#line 3168
+#line 3173
     if (realign) {
-#line 3168
+#line 3173
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3168
+#line 3173
       xp = (short *) *xpp;
-#line 3168
+#line 3173
     }
-#line 3168
+#line 3173
    /* update xpp and tp */
-#line 3168
+#line 3173
     xp += ni;
-#line 3168
+#line 3173
     tp += ni;
-#line 3168
+#line 3173
     *xpp = (void*)xp;
-#line 3168
+#line 3173
   }
-#line 3168
+#line 3173
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3168
+#line 3173
 
-#line 3168
+#line 3173
 #else   /* not SX */
-#line 3168
+#line 3173
 
-#line 3168
+#line 3173
 	char *xp = (char *) *xpp;
-#line 3168
+#line 3173
 	int status = NC_NOERR;
-#line 3168
+#line 3173
 
-#line 3168
+#line 3173
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3168
+#line 3173
 	{
-#line 3168
+#line 3173
 		int lstatus = ncx_put_short_long(xp, tp, fillp);
-#line 3168
+#line 3173
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3168
+#line 3173
 			status = lstatus;
-#line 3168
+#line 3173
 	}
-#line 3168
+#line 3173
 
-#line 3168
+#line 3173
 	*xpp = (void *)xp;
-#line 3168
+#line 3173
 	return status;
-#line 3168
+#line 3173
 #endif
-#line 3168
+#line 3173
 }
-#line 3168
+#line 3173
 
 int
-#line 3169
+#line 3174
 ncx_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3169
+#line 3174
 {
-#line 3169
+#line 3174
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3169
+#line 3174
 
-#line 3169
+#line 3174
  /* basic algorithm is:
-#line 3169
+#line 3174
   *   - ensure sane alignment of output data
-#line 3169
+#line 3174
   *   - copy (conversion happens automatically) input data
-#line 3169
+#line 3174
   *     to output
-#line 3169
+#line 3174
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3169
+#line 3174
   *     at next location for converted output
-#line 3169
+#line 3174
   */
-#line 3169
+#line 3174
   long i, j, ni;
-#line 3169
+#line 3174
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3169
+#line 3174
   short *xp;
-#line 3169
+#line 3174
   int nrange = 0;         /* number of range errors */
-#line 3169
+#line 3174
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3169
+#line 3174
   long cxp = (long) *((char**)xpp);
-#line 3169
+#line 3174
 
-#line 3169
+#line 3174
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3169
+#line 3174
   /* sjl: manually stripmine so we can limit amount of
-#line 3169
+#line 3174
    * vector work space reserved to LOOPCNT elements. Also
-#line 3169
+#line 3174
    * makes vectorisation easy */
-#line 3169
+#line 3174
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3169
+#line 3174
     ni=Min(nelems-j,LOOPCNT);
-#line 3169
+#line 3174
     if (realign) {
-#line 3169
+#line 3174
       xp = tmp;
-#line 3169
+#line 3174
     } else {
-#line 3169
+#line 3174
       xp = (short *) *xpp;
-#line 3169
+#line 3174
     }
-#line 3169
+#line 3174
    /* copy the next block */
-#line 3169
+#line 3174
 #pragma cdir loopcnt=LOOPCNT
-#line 3169
+#line 3174
 #pragma cdir shortloop
-#line 3169
+#line 3174
     for (i=0; i<ni; i++) {
-#line 3169
+#line 3174
       /* the normal case: */
-#line 3169
+#line 3174
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3169
+#line 3174
      /* test for range errors (not always needed but do it anyway) */
-#line 3169
+#line 3174
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3169
+#line 3174
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3169
+#line 3174
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3169
+#line 3174
     }
-#line 3169
+#line 3174
    /* copy workspace back if necessary */
-#line 3169
+#line 3174
     if (realign) {
-#line 3169
+#line 3174
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3169
+#line 3174
       xp = (short *) *xpp;
-#line 3169
+#line 3174
     }
-#line 3169
+#line 3174
    /* update xpp and tp */
-#line 3169
+#line 3174
     xp += ni;
-#line 3169
+#line 3174
     tp += ni;
-#line 3169
+#line 3174
     *xpp = (void*)xp;
-#line 3169
+#line 3174
   }
-#line 3169
+#line 3174
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3169
+#line 3174
 
-#line 3169
+#line 3174
 #else   /* not SX */
-#line 3169
+#line 3174
 
-#line 3169
+#line 3174
 	char *xp = (char *) *xpp;
-#line 3169
+#line 3174
 	int status = NC_NOERR;
-#line 3169
+#line 3174
 
-#line 3169
+#line 3174
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3169
+#line 3174
 	{
-#line 3169
+#line 3174
 		int lstatus = ncx_put_short_float(xp, tp, fillp);
-#line 3169
+#line 3174
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3169
+#line 3174
 			status = lstatus;
-#line 3169
+#line 3174
 	}
-#line 3169
+#line 3174
 
-#line 3169
+#line 3174
 	*xpp = (void *)xp;
-#line 3169
+#line 3174
 	return status;
-#line 3169
+#line 3174
 #endif
-#line 3169
+#line 3174
 }
-#line 3169
+#line 3174
 
 int
-#line 3170
+#line 3175
 ncx_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3170
+#line 3175
 {
-#line 3170
+#line 3175
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3170
+#line 3175
 
-#line 3170
+#line 3175
  /* basic algorithm is:
-#line 3170
+#line 3175
   *   - ensure sane alignment of output data
-#line 3170
+#line 3175
   *   - copy (conversion happens automatically) input data
-#line 3170
+#line 3175
   *     to output
-#line 3170
+#line 3175
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3170
+#line 3175
   *     at next location for converted output
-#line 3170
+#line 3175
   */
-#line 3170
+#line 3175
   long i, j, ni;
-#line 3170
+#line 3175
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3170
+#line 3175
   short *xp;
-#line 3170
+#line 3175
   int nrange = 0;         /* number of range errors */
-#line 3170
+#line 3175
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3170
+#line 3175
   long cxp = (long) *((char**)xpp);
-#line 3170
+#line 3175
 
-#line 3170
+#line 3175
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3170
+#line 3175
   /* sjl: manually stripmine so we can limit amount of
-#line 3170
+#line 3175
    * vector work space reserved to LOOPCNT elements. Also
-#line 3170
+#line 3175
    * makes vectorisation easy */
-#line 3170
+#line 3175
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3170
+#line 3175
     ni=Min(nelems-j,LOOPCNT);
-#line 3170
+#line 3175
     if (realign) {
-#line 3170
+#line 3175
       xp = tmp;
-#line 3170
+#line 3175
     } else {
-#line 3170
+#line 3175
       xp = (short *) *xpp;
-#line 3170
+#line 3175
     }
-#line 3170
+#line 3175
    /* copy the next block */
-#line 3170
+#line 3175
 #pragma cdir loopcnt=LOOPCNT
-#line 3170
+#line 3175
 #pragma cdir shortloop
-#line 3170
+#line 3175
     for (i=0; i<ni; i++) {
-#line 3170
+#line 3175
       /* the normal case: */
-#line 3170
+#line 3175
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3170
+#line 3175
      /* test for range errors (not always needed but do it anyway) */
-#line 3170
+#line 3175
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3170
+#line 3175
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3170
+#line 3175
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3170
+#line 3175
     }
-#line 3170
+#line 3175
    /* copy workspace back if necessary */
-#line 3170
+#line 3175
     if (realign) {
-#line 3170
+#line 3175
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3170
+#line 3175
       xp = (short *) *xpp;
-#line 3170
+#line 3175
     }
-#line 3170
+#line 3175
    /* update xpp and tp */
-#line 3170
+#line 3175
     xp += ni;
-#line 3170
+#line 3175
     tp += ni;
-#line 3170
+#line 3175
     *xpp = (void*)xp;
-#line 3170
+#line 3175
   }
-#line 3170
+#line 3175
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3170
+#line 3175
 
-#line 3170
+#line 3175
 #else   /* not SX */
-#line 3170
+#line 3175
 
-#line 3170
+#line 3175
 	char *xp = (char *) *xpp;
-#line 3170
+#line 3175
 	int status = NC_NOERR;
-#line 3170
+#line 3175
 
-#line 3170
+#line 3175
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3170
+#line 3175
 	{
-#line 3170
+#line 3175
 		int lstatus = ncx_put_short_double(xp, tp, fillp);
-#line 3170
+#line 3175
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3170
+#line 3175
 			status = lstatus;
-#line 3170
+#line 3175
 	}
-#line 3170
+#line 3175
 
-#line 3170
+#line 3175
 	*xpp = (void *)xp;
-#line 3170
+#line 3175
 	return status;
-#line 3170
+#line 3175
 #endif
-#line 3170
+#line 3175
 }
-#line 3170
+#line 3175
 
 int
-#line 3171
+#line 3176
 ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3171
+#line 3176
 {
-#line 3171
+#line 3176
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3171
+#line 3176
 
-#line 3171
+#line 3176
  /* basic algorithm is:
-#line 3171
+#line 3176
   *   - ensure sane alignment of output data
-#line 3171
+#line 3176
   *   - copy (conversion happens automatically) input data
-#line 3171
+#line 3176
   *     to output
-#line 3171
+#line 3176
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3171
+#line 3176
   *     at next location for converted output
-#line 3171
+#line 3176
   */
-#line 3171
+#line 3176
   long i, j, ni;
-#line 3171
+#line 3176
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3171
+#line 3176
   short *xp;
-#line 3171
+#line 3176
   int nrange = 0;         /* number of range errors */
-#line 3171
+#line 3176
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3171
+#line 3176
   long cxp = (long) *((char**)xpp);
-#line 3171
+#line 3176
 
-#line 3171
+#line 3176
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3171
+#line 3176
   /* sjl: manually stripmine so we can limit amount of
-#line 3171
+#line 3176
    * vector work space reserved to LOOPCNT elements. Also
-#line 3171
+#line 3176
    * makes vectorisation easy */
-#line 3171
+#line 3176
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3171
+#line 3176
     ni=Min(nelems-j,LOOPCNT);
-#line 3171
+#line 3176
     if (realign) {
-#line 3171
+#line 3176
       xp = tmp;
-#line 3171
+#line 3176
     } else {
-#line 3171
+#line 3176
       xp = (short *) *xpp;
-#line 3171
+#line 3176
     }
-#line 3171
+#line 3176
    /* copy the next block */
-#line 3171
+#line 3176
 #pragma cdir loopcnt=LOOPCNT
-#line 3171
+#line 3176
 #pragma cdir shortloop
-#line 3171
+#line 3176
     for (i=0; i<ni; i++) {
-#line 3171
+#line 3176
       /* the normal case: */
-#line 3171
+#line 3176
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3171
+#line 3176
      /* test for range errors (not always needed but do it anyway) */
-#line 3171
+#line 3176
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3171
+#line 3176
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3171
+#line 3176
       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
-#line 3171
+#line 3176
     }
-#line 3171
+#line 3176
    /* copy workspace back if necessary */
-#line 3171
+#line 3176
     if (realign) {
-#line 3171
+#line 3176
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3171
+#line 3176
       xp = (short *) *xpp;
-#line 3171
+#line 3176
     }
-#line 3171
+#line 3176
    /* update xpp and tp */
-#line 3171
+#line 3176
     xp += ni;
-#line 3171
+#line 3176
     tp += ni;
-#line 3171
+#line 3176
     *xpp = (void*)xp;
-#line 3171
+#line 3176
   }
-#line 3171
+#line 3176
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3171
+#line 3176
 
-#line 3171
+#line 3176
 #else   /* not SX */
-#line 3171
+#line 3176
 
-#line 3171
+#line 3176
 	char *xp = (char *) *xpp;
-#line 3171
+#line 3176
 	int status = NC_NOERR;
-#line 3171
+#line 3176
 
-#line 3171
+#line 3176
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3171
+#line 3176
 	{
-#line 3171
+#line 3176
 		int lstatus = ncx_put_short_longlong(xp, tp, fillp);
-#line 3171
+#line 3176
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3171
+#line 3176
 			status = lstatus;
-#line 3171
+#line 3176
 	}
-#line 3171
+#line 3176
 
-#line 3171
+#line 3176
 	*xpp = (void *)xp;
-#line 3171
+#line 3176
 	return status;
-#line 3171
+#line 3176
 #endif
-#line 3171
+#line 3176
 }
-#line 3171
+#line 3176
 
 int
-#line 3172
+#line 3177
 ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3172
+#line 3177
 {
-#line 3172
+#line 3177
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3172
+#line 3177
 
-#line 3172
+#line 3177
  /* basic algorithm is:
-#line 3172
+#line 3177
   *   - ensure sane alignment of output data
-#line 3172
+#line 3177
   *   - copy (conversion happens automatically) input data
-#line 3172
+#line 3177
   *     to output
-#line 3172
+#line 3177
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3172
+#line 3177
   *     at next location for converted output
-#line 3172
+#line 3177
   */
-#line 3172
+#line 3177
   long i, j, ni;
-#line 3172
+#line 3177
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3172
+#line 3177
   short *xp;
-#line 3172
+#line 3177
   int nrange = 0;         /* number of range errors */
-#line 3172
+#line 3177
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3172
+#line 3177
   long cxp = (long) *((char**)xpp);
-#line 3172
+#line 3177
 
-#line 3172
+#line 3177
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3172
+#line 3177
   /* sjl: manually stripmine so we can limit amount of
-#line 3172
+#line 3177
    * vector work space reserved to LOOPCNT elements. Also
-#line 3172
+#line 3177
    * makes vectorisation easy */
-#line 3172
+#line 3177
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3172
+#line 3177
     ni=Min(nelems-j,LOOPCNT);
-#line 3172
+#line 3177
     if (realign) {
-#line 3172
+#line 3177
       xp = tmp;
-#line 3172
+#line 3177
     } else {
-#line 3172
+#line 3177
       xp = (short *) *xpp;
-#line 3172
+#line 3177
     }
-#line 3172
+#line 3177
    /* copy the next block */
-#line 3172
+#line 3177
 #pragma cdir loopcnt=LOOPCNT
-#line 3172
+#line 3177
 #pragma cdir shortloop
-#line 3172
+#line 3177
     for (i=0; i<ni; i++) {
-#line 3172
+#line 3177
       /* the normal case: */
-#line 3172
+#line 3177
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3172
+#line 3177
      /* test for range errors (not always needed but do it anyway) */
-#line 3172
+#line 3177
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3172
+#line 3177
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3172
+#line 3177
       nrange += tp[i] > X_SHORT_MAX ;
-#line 3172
+#line 3177
     }
-#line 3172
+#line 3177
    /* copy workspace back if necessary */
-#line 3172
+#line 3177
     if (realign) {
-#line 3172
+#line 3177
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3172
+#line 3177
       xp = (short *) *xpp;
-#line 3172
+#line 3177
     }
-#line 3172
+#line 3177
    /* update xpp and tp */
-#line 3172
+#line 3177
     xp += ni;
-#line 3172
+#line 3177
     tp += ni;
-#line 3172
+#line 3177
     *xpp = (void*)xp;
-#line 3172
+#line 3177
   }
-#line 3172
+#line 3177
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3172
+#line 3177
 
-#line 3172
+#line 3177
 #else   /* not SX */
-#line 3172
+#line 3177
 
-#line 3172
+#line 3177
 	char *xp = (char *) *xpp;
-#line 3172
+#line 3177
 	int status = NC_NOERR;
-#line 3172
+#line 3177
 
-#line 3172
+#line 3177
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3172
+#line 3177
 	{
-#line 3172
+#line 3177
 		int lstatus = ncx_put_short_uchar(xp, tp, fillp);
-#line 3172
+#line 3177
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3172
+#line 3177
 			status = lstatus;
-#line 3172
+#line 3177
 	}
-#line 3172
+#line 3177
 
-#line 3172
+#line 3177
 	*xpp = (void *)xp;
-#line 3172
+#line 3177
 	return status;
-#line 3172
+#line 3177
 #endif
-#line 3172
+#line 3177
 }
-#line 3172
+#line 3177
 
 int
-#line 3173
+#line 3178
 ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3173
+#line 3178
 {
-#line 3173
+#line 3178
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3173
+#line 3178
 
-#line 3173
+#line 3178
  /* basic algorithm is:
-#line 3173
+#line 3178
   *   - ensure sane alignment of output data
-#line 3173
+#line 3178
   *   - copy (conversion happens automatically) input data
-#line 3173
+#line 3178
   *     to output
-#line 3173
+#line 3178
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3173
+#line 3178
   *     at next location for converted output
-#line 3173
+#line 3178
   */
-#line 3173
+#line 3178
   long i, j, ni;
-#line 3173
+#line 3178
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3173
+#line 3178
   short *xp;
-#line 3173
+#line 3178
   int nrange = 0;         /* number of range errors */
-#line 3173
+#line 3178
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3173
+#line 3178
   long cxp = (long) *((char**)xpp);
-#line 3173
+#line 3178
 
-#line 3173
+#line 3178
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3173
+#line 3178
   /* sjl: manually stripmine so we can limit amount of
-#line 3173
+#line 3178
    * vector work space reserved to LOOPCNT elements. Also
-#line 3173
+#line 3178
    * makes vectorisation easy */
-#line 3173
+#line 3178
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3173
+#line 3178
     ni=Min(nelems-j,LOOPCNT);
-#line 3173
+#line 3178
     if (realign) {
-#line 3173
+#line 3178
       xp = tmp;
-#line 3173
+#line 3178
     } else {
-#line 3173
+#line 3178
       xp = (short *) *xpp;
-#line 3173
+#line 3178
     }
-#line 3173
+#line 3178
    /* copy the next block */
-#line 3173
+#line 3178
 #pragma cdir loopcnt=LOOPCNT
-#line 3173
+#line 3178
 #pragma cdir shortloop
-#line 3173
+#line 3178
     for (i=0; i<ni; i++) {
-#line 3173
+#line 3178
       /* the normal case: */
-#line 3173
+#line 3178
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3173
+#line 3178
      /* test for range errors (not always needed but do it anyway) */
-#line 3173
+#line 3178
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3173
+#line 3178
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3173
+#line 3178
       nrange += tp[i] > X_SHORT_MAX ;
-#line 3173
+#line 3178
     }
-#line 3173
+#line 3178
    /* copy workspace back if necessary */
-#line 3173
+#line 3178
     if (realign) {
-#line 3173
+#line 3178
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3173
+#line 3178
       xp = (short *) *xpp;
-#line 3173
+#line 3178
     }
-#line 3173
+#line 3178
    /* update xpp and tp */
-#line 3173
+#line 3178
     xp += ni;
-#line 3173
+#line 3178
     tp += ni;
-#line 3173
+#line 3178
     *xpp = (void*)xp;
-#line 3173
+#line 3178
   }
-#line 3173
+#line 3178
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3173
+#line 3178
 
-#line 3173
+#line 3178
 #else   /* not SX */
-#line 3173
+#line 3178
 
-#line 3173
+#line 3178
 	char *xp = (char *) *xpp;
-#line 3173
+#line 3178
 	int status = NC_NOERR;
-#line 3173
+#line 3178
 
-#line 3173
+#line 3178
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3173
+#line 3178
 	{
-#line 3173
+#line 3178
 		int lstatus = ncx_put_short_uint(xp, tp, fillp);
-#line 3173
+#line 3178
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3173
+#line 3178
 			status = lstatus;
-#line 3173
+#line 3178
 	}
-#line 3173
+#line 3178
 
-#line 3173
+#line 3178
 	*xpp = (void *)xp;
-#line 3173
+#line 3178
 	return status;
-#line 3173
+#line 3178
 #endif
-#line 3173
+#line 3178
 }
-#line 3173
+#line 3178
 
 int
-#line 3174
+#line 3179
 ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3174
+#line 3179
 {
-#line 3174
+#line 3179
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3174
+#line 3179
 
-#line 3174
+#line 3179
  /* basic algorithm is:
-#line 3174
+#line 3179
   *   - ensure sane alignment of output data
-#line 3174
+#line 3179
   *   - copy (conversion happens automatically) input data
-#line 3174
+#line 3179
   *     to output
-#line 3174
+#line 3179
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3174
+#line 3179
   *     at next location for converted output
-#line 3174
+#line 3179
   */
-#line 3174
+#line 3179
   long i, j, ni;
-#line 3174
+#line 3179
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3174
+#line 3179
   short *xp;
-#line 3174
+#line 3179
   int nrange = 0;         /* number of range errors */
-#line 3174
+#line 3179
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3174
+#line 3179
   long cxp = (long) *((char**)xpp);
-#line 3174
+#line 3179
 
-#line 3174
+#line 3179
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3174
+#line 3179
   /* sjl: manually stripmine so we can limit amount of
-#line 3174
+#line 3179
    * vector work space reserved to LOOPCNT elements. Also
-#line 3174
+#line 3179
    * makes vectorisation easy */
-#line 3174
+#line 3179
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3174
+#line 3179
     ni=Min(nelems-j,LOOPCNT);
-#line 3174
+#line 3179
     if (realign) {
-#line 3174
+#line 3179
       xp = tmp;
-#line 3174
+#line 3179
     } else {
-#line 3174
+#line 3179
       xp = (short *) *xpp;
-#line 3174
+#line 3179
     }
-#line 3174
+#line 3179
    /* copy the next block */
-#line 3174
+#line 3179
 #pragma cdir loopcnt=LOOPCNT
-#line 3174
+#line 3179
 #pragma cdir shortloop
-#line 3174
+#line 3179
     for (i=0; i<ni; i++) {
-#line 3174
+#line 3179
       /* the normal case: */
-#line 3174
+#line 3179
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3174
+#line 3179
      /* test for range errors (not always needed but do it anyway) */
-#line 3174
+#line 3179
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3174
+#line 3179
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3174
+#line 3179
       nrange += tp[i] > X_SHORT_MAX ;
-#line 3174
+#line 3179
     }
-#line 3174
+#line 3179
    /* copy workspace back if necessary */
-#line 3174
+#line 3179
     if (realign) {
-#line 3174
+#line 3179
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3174
+#line 3179
       xp = (short *) *xpp;
-#line 3174
+#line 3179
     }
-#line 3174
+#line 3179
    /* update xpp and tp */
-#line 3174
+#line 3179
     xp += ni;
-#line 3174
+#line 3179
     tp += ni;
-#line 3174
+#line 3179
     *xpp = (void*)xp;
-#line 3174
+#line 3179
   }
-#line 3174
+#line 3179
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3174
+#line 3179
 
-#line 3174
+#line 3179
 #else   /* not SX */
-#line 3174
+#line 3179
 
-#line 3174
+#line 3179
 	char *xp = (char *) *xpp;
-#line 3174
+#line 3179
 	int status = NC_NOERR;
-#line 3174
+#line 3179
 
-#line 3174
+#line 3179
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3174
+#line 3179
 	{
-#line 3174
+#line 3179
 		int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
-#line 3174
+#line 3179
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3174
+#line 3179
 			status = lstatus;
-#line 3174
+#line 3179
 	}
-#line 3174
+#line 3179
 
-#line 3174
+#line 3179
 	*xpp = (void *)xp;
-#line 3174
+#line 3179
 	return status;
-#line 3174
+#line 3179
 #endif
-#line 3174
+#line 3179
 }
-#line 3174
+#line 3179
 
 int
-#line 3175
+#line 3180
 ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3175
+#line 3180
 {
-#line 3175
+#line 3180
 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
-#line 3175
+#line 3180
 
-#line 3175
+#line 3180
  /* basic algorithm is:
-#line 3175
+#line 3180
   *   - ensure sane alignment of output data
-#line 3175
+#line 3180
   *   - copy (conversion happens automatically) input data
-#line 3175
+#line 3180
   *     to output
-#line 3175
+#line 3180
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3175
+#line 3180
   *     at next location for converted output
-#line 3175
+#line 3180
   */
-#line 3175
+#line 3180
   long i, j, ni;
-#line 3175
+#line 3180
   short tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3175
+#line 3180
   short *xp;
-#line 3175
+#line 3180
   int nrange = 0;         /* number of range errors */
-#line 3175
+#line 3180
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3175
+#line 3180
   long cxp = (long) *((char**)xpp);
-#line 3175
+#line 3180
 
-#line 3175
+#line 3180
   realign = (cxp & 7) % SIZEOF_SHORT;
-#line 3175
+#line 3180
   /* sjl: manually stripmine so we can limit amount of
-#line 3175
+#line 3180
    * vector work space reserved to LOOPCNT elements. Also
-#line 3175
+#line 3180
    * makes vectorisation easy */
-#line 3175
+#line 3180
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3175
+#line 3180
     ni=Min(nelems-j,LOOPCNT);
-#line 3175
+#line 3180
     if (realign) {
-#line 3175
+#line 3180
       xp = tmp;
-#line 3175
+#line 3180
     } else {
-#line 3175
+#line 3180
       xp = (short *) *xpp;
-#line 3175
+#line 3180
     }
-#line 3175
+#line 3180
    /* copy the next block */
-#line 3175
+#line 3180
 #pragma cdir loopcnt=LOOPCNT
-#line 3175
+#line 3180
 #pragma cdir shortloop
-#line 3175
+#line 3180
     for (i=0; i<ni; i++) {
-#line 3175
+#line 3180
       /* the normal case: */
-#line 3175
+#line 3180
       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
-#line 3175
+#line 3180
      /* test for range errors (not always needed but do it anyway) */
-#line 3175
+#line 3180
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3175
+#line 3180
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3175
+#line 3180
       nrange += tp[i] > X_SHORT_MAX ;
-#line 3175
+#line 3180
     }
-#line 3175
+#line 3180
    /* copy workspace back if necessary */
-#line 3175
+#line 3180
     if (realign) {
-#line 3175
+#line 3180
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
-#line 3175
+#line 3180
       xp = (short *) *xpp;
-#line 3175
+#line 3180
     }
-#line 3175
+#line 3180
    /* update xpp and tp */
-#line 3175
+#line 3180
     xp += ni;
-#line 3175
+#line 3180
     tp += ni;
-#line 3175
+#line 3180
     *xpp = (void*)xp;
-#line 3175
+#line 3180
   }
-#line 3175
+#line 3180
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3175
+#line 3180
 
-#line 3175
+#line 3180
 #else   /* not SX */
-#line 3175
+#line 3180
 
-#line 3175
+#line 3180
 	char *xp = (char *) *xpp;
-#line 3175
+#line 3180
 	int status = NC_NOERR;
-#line 3175
+#line 3180
 
-#line 3175
+#line 3180
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3175
+#line 3180
 	{
-#line 3175
+#line 3180
 		int lstatus = ncx_put_short_ushort(xp, tp, fillp);
-#line 3175
+#line 3180
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3175
+#line 3180
 			status = lstatus;
-#line 3175
+#line 3180
 	}
-#line 3175
+#line 3180
 
-#line 3175
+#line 3180
 	*xpp = (void *)xp;
-#line 3175
+#line 3180
 	return status;
-#line 3175
+#line 3180
 #endif
-#line 3175
+#line 3180
 }
-#line 3175
+#line 3180
 
 
 int
-#line 3177
+#line 3182
 ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3177
+#line 3182
 {
-#line 3177
+#line 3182
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3177
+#line 3182
 
-#line 3177
+#line 3182
 	char *xp = (char *) *xpp;
-#line 3177
+#line 3182
 	int status = NC_NOERR;
-#line 3177
+#line 3182
 
-#line 3177
+#line 3182
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3177
+#line 3182
 	{
-#line 3177
+#line 3182
 		int lstatus = ncx_put_short_schar(xp, tp, fillp);
-#line 3177
+#line 3182
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3177
+#line 3182
 			status = lstatus;
-#line 3177
+#line 3182
 	}
-#line 3177
+#line 3182
 
-#line 3177
+#line 3182
 	if (rndup != 0)
-#line 3177
+#line 3182
 	{
-#line 3177
+#line 3182
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3177
+#line 3182
 		xp += X_SIZEOF_SHORT;
-#line 3177
+#line 3182
 	}
-#line 3177
+#line 3182
 
-#line 3177
+#line 3182
 	*xpp = (void *)xp;
-#line 3177
+#line 3182
 	return status;
-#line 3177
+#line 3182
 }
-#line 3177
+#line 3182
 
 int
-#line 3178
+#line 3183
 ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3178
+#line 3183
 {
-#line 3178
+#line 3183
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3178
+#line 3183
 
-#line 3178
+#line 3183
 	char *xp = (char *) *xpp;
-#line 3178
+#line 3183
 	int status = NC_NOERR;
-#line 3178
+#line 3183
 
-#line 3178
+#line 3183
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3178
+#line 3183
 	{
-#line 3178
+#line 3183
 		int lstatus = ncx_put_short_uchar(xp, tp, fillp);
-#line 3178
+#line 3183
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3178
+#line 3183
 			status = lstatus;
-#line 3178
+#line 3183
 	}
-#line 3178
+#line 3183
 
-#line 3178
+#line 3183
 	if (rndup != 0)
-#line 3178
+#line 3183
 	{
-#line 3178
+#line 3183
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3178
+#line 3183
 		xp += X_SIZEOF_SHORT;
-#line 3178
+#line 3183
 	}
-#line 3178
+#line 3183
 
-#line 3178
+#line 3183
 	*xpp = (void *)xp;
-#line 3178
+#line 3183
 	return status;
-#line 3178
+#line 3183
 }
-#line 3178
+#line 3183
 
 int
-#line 3179
+#line 3184
 ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3179
+#line 3184
 {
-#line 3179
+#line 3184
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3179
+#line 3184
 
-#line 3179
+#line 3184
 	char *xp = (char *) *xpp;
-#line 3179
+#line 3184
 	int status = NC_NOERR;
-#line 3179
+#line 3184
 
-#line 3179
+#line 3184
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3179
+#line 3184
 	{
-#line 3179
+#line 3184
 		int lstatus = ncx_put_short_short(xp, tp, fillp);
-#line 3179
+#line 3184
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3179
+#line 3184
 			status = lstatus;
-#line 3179
+#line 3184
 	}
-#line 3179
+#line 3184
 
-#line 3179
+#line 3184
 	if (rndup != 0)
-#line 3179
+#line 3184
 	{
-#line 3179
+#line 3184
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3179
+#line 3184
 		xp += X_SIZEOF_SHORT;
-#line 3179
+#line 3184
 	}
-#line 3179
+#line 3184
 
-#line 3179
+#line 3184
 	*xpp = (void *)xp;
-#line 3179
+#line 3184
 	return status;
-#line 3179
+#line 3184
 }
-#line 3179
+#line 3184
 
 int
-#line 3180
+#line 3185
 ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3180
+#line 3185
 {
-#line 3180
+#line 3185
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3180
+#line 3185
 
-#line 3180
+#line 3185
 	char *xp = (char *) *xpp;
-#line 3180
+#line 3185
 	int status = NC_NOERR;
-#line 3180
+#line 3185
 
-#line 3180
+#line 3185
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3180
+#line 3185
 	{
-#line 3180
+#line 3185
 		int lstatus = ncx_put_short_int(xp, tp, fillp);
-#line 3180
+#line 3185
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3180
+#line 3185
 			status = lstatus;
-#line 3180
+#line 3185
 	}
-#line 3180
+#line 3185
 
-#line 3180
+#line 3185
 	if (rndup != 0)
-#line 3180
+#line 3185
 	{
-#line 3180
+#line 3185
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3180
+#line 3185
 		xp += X_SIZEOF_SHORT;
-#line 3180
+#line 3185
 	}
-#line 3180
+#line 3185
 
-#line 3180
+#line 3185
 	*xpp = (void *)xp;
-#line 3180
+#line 3185
 	return status;
-#line 3180
+#line 3185
 }
-#line 3180
+#line 3185
 
 int
-#line 3181
+#line 3186
 ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3181
+#line 3186
 {
-#line 3181
+#line 3186
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3181
+#line 3186
 
-#line 3181
+#line 3186
 	char *xp = (char *) *xpp;
-#line 3181
+#line 3186
 	int status = NC_NOERR;
-#line 3181
+#line 3186
 
-#line 3181
+#line 3186
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3181
+#line 3186
 	{
-#line 3181
+#line 3186
 		int lstatus = ncx_put_short_long(xp, tp, fillp);
-#line 3181
+#line 3186
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3181
+#line 3186
 			status = lstatus;
-#line 3181
+#line 3186
 	}
-#line 3181
+#line 3186
 
-#line 3181
+#line 3186
 	if (rndup != 0)
-#line 3181
+#line 3186
 	{
-#line 3181
+#line 3186
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3181
+#line 3186
 		xp += X_SIZEOF_SHORT;
-#line 3181
+#line 3186
 	}
-#line 3181
+#line 3186
 
-#line 3181
+#line 3186
 	*xpp = (void *)xp;
-#line 3181
+#line 3186
 	return status;
-#line 3181
+#line 3186
 }
-#line 3181
+#line 3186
 
 int
-#line 3182
+#line 3187
 ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3182
+#line 3187
 {
-#line 3182
+#line 3187
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3182
+#line 3187
 
-#line 3182
+#line 3187
 	char *xp = (char *) *xpp;
-#line 3182
+#line 3187
 	int status = NC_NOERR;
-#line 3182
+#line 3187
 
-#line 3182
+#line 3187
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3182
+#line 3187
 	{
-#line 3182
+#line 3187
 		int lstatus = ncx_put_short_float(xp, tp, fillp);
-#line 3182
+#line 3187
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3182
+#line 3187
 			status = lstatus;
-#line 3182
+#line 3187
 	}
-#line 3182
+#line 3187
 
-#line 3182
+#line 3187
 	if (rndup != 0)
-#line 3182
+#line 3187
 	{
-#line 3182
+#line 3187
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3182
+#line 3187
 		xp += X_SIZEOF_SHORT;
-#line 3182
+#line 3187
 	}
-#line 3182
+#line 3187
 
-#line 3182
+#line 3187
 	*xpp = (void *)xp;
-#line 3182
+#line 3187
 	return status;
-#line 3182
+#line 3187
 }
-#line 3182
+#line 3187
 
 int
-#line 3183
+#line 3188
 ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3183
+#line 3188
 {
-#line 3183
+#line 3188
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3183
+#line 3188
 
-#line 3183
+#line 3188
 	char *xp = (char *) *xpp;
-#line 3183
+#line 3188
 	int status = NC_NOERR;
-#line 3183
+#line 3188
 
-#line 3183
+#line 3188
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3183
+#line 3188
 	{
-#line 3183
+#line 3188
 		int lstatus = ncx_put_short_double(xp, tp, fillp);
-#line 3183
+#line 3188
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3183
+#line 3188
 			status = lstatus;
-#line 3183
+#line 3188
 	}
-#line 3183
+#line 3188
 
-#line 3183
+#line 3188
 	if (rndup != 0)
-#line 3183
+#line 3188
 	{
-#line 3183
+#line 3188
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3183
+#line 3188
 		xp += X_SIZEOF_SHORT;
-#line 3183
+#line 3188
 	}
-#line 3183
+#line 3188
 
-#line 3183
+#line 3188
 	*xpp = (void *)xp;
-#line 3183
+#line 3188
 	return status;
-#line 3183
+#line 3188
 }
-#line 3183
+#line 3188
 
 int
-#line 3184
+#line 3189
 ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3184
+#line 3189
 {
-#line 3184
+#line 3189
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3184
+#line 3189
 
-#line 3184
+#line 3189
 	char *xp = (char *) *xpp;
-#line 3184
+#line 3189
 	int status = NC_NOERR;
-#line 3184
+#line 3189
 
-#line 3184
+#line 3189
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3184
+#line 3189
 	{
-#line 3184
+#line 3189
 		int lstatus = ncx_put_short_uint(xp, tp, fillp);
-#line 3184
+#line 3189
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3184
+#line 3189
 			status = lstatus;
-#line 3184
+#line 3189
 	}
-#line 3184
+#line 3189
 
-#line 3184
+#line 3189
 	if (rndup != 0)
-#line 3184
+#line 3189
 	{
-#line 3184
+#line 3189
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3184
+#line 3189
 		xp += X_SIZEOF_SHORT;
-#line 3184
+#line 3189
 	}
-#line 3184
+#line 3189
 
-#line 3184
+#line 3189
 	*xpp = (void *)xp;
-#line 3184
+#line 3189
 	return status;
-#line 3184
+#line 3189
 }
-#line 3184
+#line 3189
 
 int
-#line 3185
+#line 3190
 ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3185
+#line 3190
 {
-#line 3185
+#line 3190
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3185
+#line 3190
 
-#line 3185
+#line 3190
 	char *xp = (char *) *xpp;
-#line 3185
+#line 3190
 	int status = NC_NOERR;
-#line 3185
+#line 3190
 
-#line 3185
+#line 3190
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3185
+#line 3190
 	{
-#line 3185
+#line 3190
 		int lstatus = ncx_put_short_longlong(xp, tp, fillp);
-#line 3185
+#line 3190
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3185
+#line 3190
 			status = lstatus;
-#line 3185
+#line 3190
 	}
-#line 3185
+#line 3190
 
-#line 3185
+#line 3190
 	if (rndup != 0)
-#line 3185
+#line 3190
 	{
-#line 3185
+#line 3190
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3185
+#line 3190
 		xp += X_SIZEOF_SHORT;
-#line 3185
+#line 3190
 	}
-#line 3185
+#line 3190
 
-#line 3185
+#line 3190
 	*xpp = (void *)xp;
-#line 3185
+#line 3190
 	return status;
-#line 3185
+#line 3190
 }
-#line 3185
+#line 3190
 
 int
-#line 3186
+#line 3191
 ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3186
+#line 3191
 {
-#line 3186
+#line 3191
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3186
+#line 3191
 
-#line 3186
+#line 3191
 	char *xp = (char *) *xpp;
-#line 3186
+#line 3191
 	int status = NC_NOERR;
-#line 3186
+#line 3191
 
-#line 3186
+#line 3191
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3186
+#line 3191
 	{
-#line 3186
+#line 3191
 		int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
-#line 3186
+#line 3191
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3186
+#line 3191
 			status = lstatus;
-#line 3186
+#line 3191
 	}
-#line 3186
+#line 3191
 
-#line 3186
+#line 3191
 	if (rndup != 0)
-#line 3186
+#line 3191
 	{
-#line 3186
+#line 3191
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3186
+#line 3191
 		xp += X_SIZEOF_SHORT;
-#line 3186
+#line 3191
 	}
-#line 3186
+#line 3191
 
-#line 3186
+#line 3191
 	*xpp = (void *)xp;
-#line 3186
+#line 3191
 	return status;
-#line 3186
+#line 3191
 }
-#line 3186
+#line 3191
 
 int
-#line 3187
+#line 3192
 ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3187
+#line 3192
 {
-#line 3187
+#line 3192
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3187
+#line 3192
 
-#line 3187
+#line 3192
 	char *xp = (char *) *xpp;
-#line 3187
+#line 3192
 	int status = NC_NOERR;
-#line 3187
+#line 3192
 
-#line 3187
+#line 3192
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
-#line 3187
+#line 3192
 	{
-#line 3187
+#line 3192
 		int lstatus = ncx_put_short_ushort(xp, tp, fillp);
-#line 3187
+#line 3192
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3187
+#line 3192
 			status = lstatus;
-#line 3187
+#line 3192
 	}
-#line 3187
+#line 3192
 
-#line 3187
+#line 3192
 	if (rndup != 0)
-#line 3187
+#line 3192
 	{
-#line 3187
+#line 3192
 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
-#line 3187
+#line 3192
 		xp += X_SIZEOF_SHORT;
-#line 3187
+#line 3192
 	}
-#line 3187
+#line 3192
 
-#line 3187
+#line 3192
 	*xpp = (void *)xp;
-#line 3187
+#line 3192
 	return status;
-#line 3187
+#line 3192
 }
-#line 3187
+#line 3192
 
 
 
@@ -17508,1898 +17513,1898 @@ ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
 }
 #else
 int
-#line 3206
+#line 3211
 ncx_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3206
+#line 3211
 {
-#line 3206
+#line 3211
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3206
+#line 3211
 
-#line 3206
+#line 3211
  /* basic algorithm is:
-#line 3206
+#line 3211
   *   - ensure sane alignment of input data
-#line 3206
+#line 3211
   *   - copy (conversion happens automatically) input data
-#line 3206
+#line 3211
   *     to output
-#line 3206
+#line 3211
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3206
+#line 3211
   *     at next location for converted output
-#line 3206
+#line 3211
   */
-#line 3206
+#line 3211
   long i, j, ni;
-#line 3206
+#line 3211
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3206
+#line 3211
   ushort *xp;
-#line 3206
+#line 3211
   int nrange = 0;         /* number of range errors */
-#line 3206
+#line 3211
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3206
+#line 3211
   long cxp = (long) *((char**)xpp);
-#line 3206
+#line 3211
 
-#line 3206
+#line 3211
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3206
+#line 3211
   /* sjl: manually stripmine so we can limit amount of
-#line 3206
+#line 3211
    * vector work space reserved to LOOPCNT elements. Also
-#line 3206
+#line 3211
    * makes vectorisation easy */
-#line 3206
+#line 3211
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3206
+#line 3211
     ni=Min(nelems-j,LOOPCNT);
-#line 3206
+#line 3211
     if (realign) {
-#line 3206
+#line 3211
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3206
+#line 3211
       xp = tmp;
-#line 3206
+#line 3211
     } else {
-#line 3206
+#line 3211
       xp = (ushort *) *xpp;
-#line 3206
+#line 3211
     }
-#line 3206
+#line 3211
    /* copy the next block */
-#line 3206
+#line 3211
 #pragma cdir loopcnt=LOOPCNT
-#line 3206
+#line 3211
 #pragma cdir shortloop
-#line 3206
+#line 3211
     for (i=0; i<ni; i++) {
-#line 3206
+#line 3211
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3206
+#line 3211
      /* test for range errors (not always needed but do it anyway) */
-#line 3206
+#line 3211
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3206
+#line 3211
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3206
+#line 3211
       nrange += xp[i] > USHORT_MAX ;
-#line 3206
+#line 3211
     }
-#line 3206
+#line 3211
    /* update xpp and tp */
-#line 3206
+#line 3211
     if (realign) xp = (ushort *) *xpp;
-#line 3206
+#line 3211
     xp += ni;
-#line 3206
+#line 3211
     tp += ni;
-#line 3206
+#line 3211
     *xpp = (void*)xp;
-#line 3206
+#line 3211
   }
-#line 3206
+#line 3211
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3206
+#line 3211
 
-#line 3206
+#line 3211
 #else   /* not SX */
-#line 3206
+#line 3211
 	const char *xp = (const char *) *xpp;
-#line 3206
+#line 3211
 	int status = NC_NOERR;
-#line 3206
+#line 3211
 
-#line 3206
+#line 3211
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3206
+#line 3211
 	{
-#line 3206
+#line 3211
 		const int lstatus = ncx_get_ushort_ushort(xp, tp);
-#line 3206
+#line 3211
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3206
+#line 3211
 			status = lstatus;
-#line 3206
+#line 3211
 	}
-#line 3206
+#line 3211
 
-#line 3206
+#line 3211
 	*xpp = (const void *)xp;
-#line 3206
+#line 3211
 	return status;
-#line 3206
+#line 3211
 #endif
-#line 3206
+#line 3211
 }
-#line 3206
+#line 3211
 
 #endif
 int
-#line 3208
+#line 3213
 ncx_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3208
+#line 3213
 {
-#line 3208
+#line 3213
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3208
+#line 3213
 
-#line 3208
+#line 3213
  /* basic algorithm is:
-#line 3208
+#line 3213
   *   - ensure sane alignment of input data
-#line 3208
+#line 3213
   *   - copy (conversion happens automatically) input data
-#line 3208
+#line 3213
   *     to output
-#line 3208
+#line 3213
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3208
+#line 3213
   *     at next location for converted output
-#line 3208
+#line 3213
   */
-#line 3208
+#line 3213
   long i, j, ni;
-#line 3208
+#line 3213
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3208
+#line 3213
   ushort *xp;
-#line 3208
+#line 3213
   int nrange = 0;         /* number of range errors */
-#line 3208
+#line 3213
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3208
+#line 3213
   long cxp = (long) *((char**)xpp);
-#line 3208
+#line 3213
 
-#line 3208
+#line 3213
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3208
+#line 3213
   /* sjl: manually stripmine so we can limit amount of
-#line 3208
+#line 3213
    * vector work space reserved to LOOPCNT elements. Also
-#line 3208
+#line 3213
    * makes vectorisation easy */
-#line 3208
+#line 3213
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3208
+#line 3213
     ni=Min(nelems-j,LOOPCNT);
-#line 3208
+#line 3213
     if (realign) {
-#line 3208
+#line 3213
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3208
+#line 3213
       xp = tmp;
-#line 3208
+#line 3213
     } else {
-#line 3208
+#line 3213
       xp = (ushort *) *xpp;
-#line 3208
+#line 3213
     }
-#line 3208
+#line 3213
    /* copy the next block */
-#line 3208
+#line 3213
 #pragma cdir loopcnt=LOOPCNT
-#line 3208
+#line 3213
 #pragma cdir shortloop
-#line 3208
+#line 3213
     for (i=0; i<ni; i++) {
-#line 3208
+#line 3213
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3208
+#line 3213
      /* test for range errors (not always needed but do it anyway) */
-#line 3208
+#line 3213
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3208
+#line 3213
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3208
+#line 3213
       nrange += xp[i] > SCHAR_MAX ;
-#line 3208
+#line 3213
     }
-#line 3208
+#line 3213
    /* update xpp and tp */
-#line 3208
+#line 3213
     if (realign) xp = (ushort *) *xpp;
-#line 3208
+#line 3213
     xp += ni;
-#line 3208
+#line 3213
     tp += ni;
-#line 3208
+#line 3213
     *xpp = (void*)xp;
-#line 3208
+#line 3213
   }
-#line 3208
+#line 3213
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3208
+#line 3213
 
-#line 3208
+#line 3213
 #else   /* not SX */
-#line 3208
+#line 3213
 	const char *xp = (const char *) *xpp;
-#line 3208
+#line 3213
 	int status = NC_NOERR;
-#line 3208
+#line 3213
 
-#line 3208
+#line 3213
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3208
+#line 3213
 	{
-#line 3208
+#line 3213
 		const int lstatus = ncx_get_ushort_schar(xp, tp);
-#line 3208
+#line 3213
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3208
+#line 3213
 			status = lstatus;
-#line 3208
+#line 3213
 	}
-#line 3208
+#line 3213
 
-#line 3208
+#line 3213
 	*xpp = (const void *)xp;
-#line 3208
+#line 3213
 	return status;
-#line 3208
+#line 3213
 #endif
-#line 3208
+#line 3213
 }
-#line 3208
+#line 3213
 
 int
-#line 3209
+#line 3214
 ncx_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
-#line 3209
+#line 3214
 {
-#line 3209
+#line 3214
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3209
+#line 3214
 
-#line 3209
+#line 3214
  /* basic algorithm is:
-#line 3209
+#line 3214
   *   - ensure sane alignment of input data
-#line 3209
+#line 3214
   *   - copy (conversion happens automatically) input data
-#line 3209
+#line 3214
   *     to output
-#line 3209
+#line 3214
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3209
+#line 3214
   *     at next location for converted output
-#line 3209
+#line 3214
   */
-#line 3209
+#line 3214
   long i, j, ni;
-#line 3209
+#line 3214
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3209
+#line 3214
   ushort *xp;
-#line 3209
+#line 3214
   int nrange = 0;         /* number of range errors */
-#line 3209
+#line 3214
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3209
+#line 3214
   long cxp = (long) *((char**)xpp);
-#line 3209
+#line 3214
 
-#line 3209
+#line 3214
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3209
+#line 3214
   /* sjl: manually stripmine so we can limit amount of
-#line 3209
+#line 3214
    * vector work space reserved to LOOPCNT elements. Also
-#line 3209
+#line 3214
    * makes vectorisation easy */
-#line 3209
+#line 3214
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3209
+#line 3214
     ni=Min(nelems-j,LOOPCNT);
-#line 3209
+#line 3214
     if (realign) {
-#line 3209
+#line 3214
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3209
+#line 3214
       xp = tmp;
-#line 3209
+#line 3214
     } else {
-#line 3209
+#line 3214
       xp = (ushort *) *xpp;
-#line 3209
+#line 3214
     }
-#line 3209
+#line 3214
    /* copy the next block */
-#line 3209
+#line 3214
 #pragma cdir loopcnt=LOOPCNT
-#line 3209
+#line 3214
 #pragma cdir shortloop
-#line 3209
+#line 3214
     for (i=0; i<ni; i++) {
-#line 3209
+#line 3214
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3209
+#line 3214
      /* test for range errors (not always needed but do it anyway) */
-#line 3209
+#line 3214
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3209
+#line 3214
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3209
+#line 3214
       nrange += xp[i] > SHORT_MAX ;
-#line 3209
+#line 3214
     }
-#line 3209
+#line 3214
    /* update xpp and tp */
-#line 3209
+#line 3214
     if (realign) xp = (ushort *) *xpp;
-#line 3209
+#line 3214
     xp += ni;
-#line 3209
+#line 3214
     tp += ni;
-#line 3209
+#line 3214
     *xpp = (void*)xp;
-#line 3209
+#line 3214
   }
-#line 3209
+#line 3214
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3209
+#line 3214
 
-#line 3209
+#line 3214
 #else   /* not SX */
-#line 3209
+#line 3214
 	const char *xp = (const char *) *xpp;
-#line 3209
+#line 3214
 	int status = NC_NOERR;
-#line 3209
+#line 3214
 
-#line 3209
+#line 3214
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3209
+#line 3214
 	{
-#line 3209
+#line 3214
 		const int lstatus = ncx_get_ushort_short(xp, tp);
-#line 3209
+#line 3214
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3209
+#line 3214
 			status = lstatus;
-#line 3209
+#line 3214
 	}
-#line 3209
+#line 3214
 
-#line 3209
+#line 3214
 	*xpp = (const void *)xp;
-#line 3209
+#line 3214
 	return status;
-#line 3209
+#line 3214
 #endif
-#line 3209
+#line 3214
 }
-#line 3209
+#line 3214
 
 int
-#line 3210
+#line 3215
 ncx_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
-#line 3210
+#line 3215
 {
-#line 3210
+#line 3215
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3210
+#line 3215
 
-#line 3210
+#line 3215
  /* basic algorithm is:
-#line 3210
+#line 3215
   *   - ensure sane alignment of input data
-#line 3210
+#line 3215
   *   - copy (conversion happens automatically) input data
-#line 3210
+#line 3215
   *     to output
-#line 3210
+#line 3215
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3210
+#line 3215
   *     at next location for converted output
-#line 3210
+#line 3215
   */
-#line 3210
+#line 3215
   long i, j, ni;
-#line 3210
+#line 3215
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3210
+#line 3215
   ushort *xp;
-#line 3210
+#line 3215
   int nrange = 0;         /* number of range errors */
-#line 3210
+#line 3215
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3210
+#line 3215
   long cxp = (long) *((char**)xpp);
-#line 3210
+#line 3215
 
-#line 3210
+#line 3215
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3210
+#line 3215
   /* sjl: manually stripmine so we can limit amount of
-#line 3210
+#line 3215
    * vector work space reserved to LOOPCNT elements. Also
-#line 3210
+#line 3215
    * makes vectorisation easy */
-#line 3210
+#line 3215
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3210
+#line 3215
     ni=Min(nelems-j,LOOPCNT);
-#line 3210
+#line 3215
     if (realign) {
-#line 3210
+#line 3215
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3210
+#line 3215
       xp = tmp;
-#line 3210
+#line 3215
     } else {
-#line 3210
+#line 3215
       xp = (ushort *) *xpp;
-#line 3210
+#line 3215
     }
-#line 3210
+#line 3215
    /* copy the next block */
-#line 3210
+#line 3215
 #pragma cdir loopcnt=LOOPCNT
-#line 3210
+#line 3215
 #pragma cdir shortloop
-#line 3210
+#line 3215
     for (i=0; i<ni; i++) {
-#line 3210
+#line 3215
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3210
+#line 3215
      /* test for range errors (not always needed but do it anyway) */
-#line 3210
+#line 3215
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3210
+#line 3215
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3210
+#line 3215
       nrange += xp[i] > INT_MAX ;
-#line 3210
+#line 3215
     }
-#line 3210
+#line 3215
    /* update xpp and tp */
-#line 3210
+#line 3215
     if (realign) xp = (ushort *) *xpp;
-#line 3210
+#line 3215
     xp += ni;
-#line 3210
+#line 3215
     tp += ni;
-#line 3210
+#line 3215
     *xpp = (void*)xp;
-#line 3210
+#line 3215
   }
-#line 3210
+#line 3215
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3210
+#line 3215
 
-#line 3210
+#line 3215
 #else   /* not SX */
-#line 3210
+#line 3215
 	const char *xp = (const char *) *xpp;
-#line 3210
+#line 3215
 	int status = NC_NOERR;
-#line 3210
+#line 3215
 
-#line 3210
+#line 3215
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3210
+#line 3215
 	{
-#line 3210
+#line 3215
 		const int lstatus = ncx_get_ushort_int(xp, tp);
-#line 3210
+#line 3215
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3210
+#line 3215
 			status = lstatus;
-#line 3210
+#line 3215
 	}
-#line 3210
+#line 3215
 
-#line 3210
+#line 3215
 	*xpp = (const void *)xp;
-#line 3210
+#line 3215
 	return status;
-#line 3210
+#line 3215
 #endif
-#line 3210
+#line 3215
 }
-#line 3210
+#line 3215
 
 int
-#line 3211
+#line 3216
 ncx_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
-#line 3211
+#line 3216
 {
-#line 3211
+#line 3216
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3211
+#line 3216
 
-#line 3211
+#line 3216
  /* basic algorithm is:
-#line 3211
+#line 3216
   *   - ensure sane alignment of input data
-#line 3211
+#line 3216
   *   - copy (conversion happens automatically) input data
-#line 3211
+#line 3216
   *     to output
-#line 3211
+#line 3216
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3211
+#line 3216
   *     at next location for converted output
-#line 3211
+#line 3216
   */
-#line 3211
+#line 3216
   long i, j, ni;
-#line 3211
+#line 3216
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3211
+#line 3216
   ushort *xp;
-#line 3211
+#line 3216
   int nrange = 0;         /* number of range errors */
-#line 3211
+#line 3216
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3211
+#line 3216
   long cxp = (long) *((char**)xpp);
-#line 3211
+#line 3216
 
-#line 3211
+#line 3216
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3211
+#line 3216
   /* sjl: manually stripmine so we can limit amount of
-#line 3211
+#line 3216
    * vector work space reserved to LOOPCNT elements. Also
-#line 3211
+#line 3216
    * makes vectorisation easy */
-#line 3211
+#line 3216
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3211
+#line 3216
     ni=Min(nelems-j,LOOPCNT);
-#line 3211
+#line 3216
     if (realign) {
-#line 3211
+#line 3216
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3211
+#line 3216
       xp = tmp;
-#line 3211
+#line 3216
     } else {
-#line 3211
+#line 3216
       xp = (ushort *) *xpp;
-#line 3211
+#line 3216
     }
-#line 3211
+#line 3216
    /* copy the next block */
-#line 3211
+#line 3216
 #pragma cdir loopcnt=LOOPCNT
-#line 3211
+#line 3216
 #pragma cdir shortloop
-#line 3211
+#line 3216
     for (i=0; i<ni; i++) {
-#line 3211
+#line 3216
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3211
+#line 3216
      /* test for range errors (not always needed but do it anyway) */
-#line 3211
+#line 3216
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3211
+#line 3216
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3211
+#line 3216
       nrange += xp[i] > LONG_MAX ;
-#line 3211
+#line 3216
     }
-#line 3211
+#line 3216
    /* update xpp and tp */
-#line 3211
+#line 3216
     if (realign) xp = (ushort *) *xpp;
-#line 3211
+#line 3216
     xp += ni;
-#line 3211
+#line 3216
     tp += ni;
-#line 3211
+#line 3216
     *xpp = (void*)xp;
-#line 3211
+#line 3216
   }
-#line 3211
+#line 3216
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3211
+#line 3216
 
-#line 3211
+#line 3216
 #else   /* not SX */
-#line 3211
+#line 3216
 	const char *xp = (const char *) *xpp;
-#line 3211
+#line 3216
 	int status = NC_NOERR;
-#line 3211
+#line 3216
 
-#line 3211
+#line 3216
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3211
+#line 3216
 	{
-#line 3211
+#line 3216
 		const int lstatus = ncx_get_ushort_long(xp, tp);
-#line 3211
+#line 3216
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3211
+#line 3216
 			status = lstatus;
-#line 3211
+#line 3216
 	}
-#line 3211
+#line 3216
 
-#line 3211
+#line 3216
 	*xpp = (const void *)xp;
-#line 3211
+#line 3216
 	return status;
-#line 3211
+#line 3216
 #endif
-#line 3211
+#line 3216
 }
-#line 3211
+#line 3216
 
 int
-#line 3212
+#line 3217
 ncx_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
-#line 3212
+#line 3217
 {
-#line 3212
+#line 3217
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3212
+#line 3217
 
-#line 3212
+#line 3217
  /* basic algorithm is:
-#line 3212
+#line 3217
   *   - ensure sane alignment of input data
-#line 3212
+#line 3217
   *   - copy (conversion happens automatically) input data
-#line 3212
+#line 3217
   *     to output
-#line 3212
+#line 3217
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3212
+#line 3217
   *     at next location for converted output
-#line 3212
+#line 3217
   */
-#line 3212
+#line 3217
   long i, j, ni;
-#line 3212
+#line 3217
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3212
+#line 3217
   ushort *xp;
-#line 3212
+#line 3217
   int nrange = 0;         /* number of range errors */
-#line 3212
+#line 3217
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3212
+#line 3217
   long cxp = (long) *((char**)xpp);
-#line 3212
+#line 3217
 
-#line 3212
+#line 3217
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3212
+#line 3217
   /* sjl: manually stripmine so we can limit amount of
-#line 3212
+#line 3217
    * vector work space reserved to LOOPCNT elements. Also
-#line 3212
+#line 3217
    * makes vectorisation easy */
-#line 3212
+#line 3217
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3212
+#line 3217
     ni=Min(nelems-j,LOOPCNT);
-#line 3212
+#line 3217
     if (realign) {
-#line 3212
+#line 3217
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3212
+#line 3217
       xp = tmp;
-#line 3212
+#line 3217
     } else {
-#line 3212
+#line 3217
       xp = (ushort *) *xpp;
-#line 3212
+#line 3217
     }
-#line 3212
+#line 3217
    /* copy the next block */
-#line 3212
+#line 3217
 #pragma cdir loopcnt=LOOPCNT
-#line 3212
+#line 3217
 #pragma cdir shortloop
-#line 3212
+#line 3217
     for (i=0; i<ni; i++) {
-#line 3212
+#line 3217
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3212
+#line 3217
      /* test for range errors (not always needed but do it anyway) */
-#line 3212
+#line 3217
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3212
+#line 3217
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3212
+#line 3217
       nrange += xp[i] > FLOAT_MAX ;
-#line 3212
+#line 3217
     }
-#line 3212
+#line 3217
    /* update xpp and tp */
-#line 3212
+#line 3217
     if (realign) xp = (ushort *) *xpp;
-#line 3212
+#line 3217
     xp += ni;
-#line 3212
+#line 3217
     tp += ni;
-#line 3212
+#line 3217
     *xpp = (void*)xp;
-#line 3212
+#line 3217
   }
-#line 3212
+#line 3217
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3212
+#line 3217
 
-#line 3212
+#line 3217
 #else   /* not SX */
-#line 3212
+#line 3217
 	const char *xp = (const char *) *xpp;
-#line 3212
+#line 3217
 	int status = NC_NOERR;
-#line 3212
+#line 3217
 
-#line 3212
+#line 3217
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3212
+#line 3217
 	{
-#line 3212
+#line 3217
 		const int lstatus = ncx_get_ushort_float(xp, tp);
-#line 3212
+#line 3217
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3212
+#line 3217
 			status = lstatus;
-#line 3212
+#line 3217
 	}
-#line 3212
+#line 3217
 
-#line 3212
+#line 3217
 	*xpp = (const void *)xp;
-#line 3212
+#line 3217
 	return status;
-#line 3212
+#line 3217
 #endif
-#line 3212
+#line 3217
 }
-#line 3212
+#line 3217
 
 int
-#line 3213
+#line 3218
 ncx_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
-#line 3213
+#line 3218
 {
-#line 3213
+#line 3218
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3213
+#line 3218
 
-#line 3213
+#line 3218
  /* basic algorithm is:
-#line 3213
+#line 3218
   *   - ensure sane alignment of input data
-#line 3213
+#line 3218
   *   - copy (conversion happens automatically) input data
-#line 3213
+#line 3218
   *     to output
-#line 3213
+#line 3218
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3213
+#line 3218
   *     at next location for converted output
-#line 3213
+#line 3218
   */
-#line 3213
+#line 3218
   long i, j, ni;
-#line 3213
+#line 3218
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3213
+#line 3218
   ushort *xp;
-#line 3213
+#line 3218
   int nrange = 0;         /* number of range errors */
-#line 3213
+#line 3218
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3213
+#line 3218
   long cxp = (long) *((char**)xpp);
-#line 3213
+#line 3218
 
-#line 3213
+#line 3218
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3213
+#line 3218
   /* sjl: manually stripmine so we can limit amount of
-#line 3213
+#line 3218
    * vector work space reserved to LOOPCNT elements. Also
-#line 3213
+#line 3218
    * makes vectorisation easy */
-#line 3213
+#line 3218
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3213
+#line 3218
     ni=Min(nelems-j,LOOPCNT);
-#line 3213
+#line 3218
     if (realign) {
-#line 3213
+#line 3218
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3213
+#line 3218
       xp = tmp;
-#line 3213
+#line 3218
     } else {
-#line 3213
+#line 3218
       xp = (ushort *) *xpp;
-#line 3213
+#line 3218
     }
-#line 3213
+#line 3218
    /* copy the next block */
-#line 3213
+#line 3218
 #pragma cdir loopcnt=LOOPCNT
-#line 3213
+#line 3218
 #pragma cdir shortloop
-#line 3213
+#line 3218
     for (i=0; i<ni; i++) {
-#line 3213
+#line 3218
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3213
+#line 3218
      /* test for range errors (not always needed but do it anyway) */
-#line 3213
+#line 3218
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3213
+#line 3218
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3213
+#line 3218
       nrange += xp[i] > DOUBLE_MAX ;
-#line 3213
+#line 3218
     }
-#line 3213
+#line 3218
    /* update xpp and tp */
-#line 3213
+#line 3218
     if (realign) xp = (ushort *) *xpp;
-#line 3213
+#line 3218
     xp += ni;
-#line 3213
+#line 3218
     tp += ni;
-#line 3213
+#line 3218
     *xpp = (void*)xp;
-#line 3213
+#line 3218
   }
-#line 3213
+#line 3218
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3213
+#line 3218
 
-#line 3213
+#line 3218
 #else   /* not SX */
-#line 3213
+#line 3218
 	const char *xp = (const char *) *xpp;
-#line 3213
+#line 3218
 	int status = NC_NOERR;
-#line 3213
+#line 3218
 
-#line 3213
+#line 3218
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3213
+#line 3218
 	{
-#line 3213
+#line 3218
 		const int lstatus = ncx_get_ushort_double(xp, tp);
-#line 3213
+#line 3218
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3213
+#line 3218
 			status = lstatus;
-#line 3213
+#line 3218
 	}
-#line 3213
+#line 3218
 
-#line 3213
+#line 3218
 	*xpp = (const void *)xp;
-#line 3213
+#line 3218
 	return status;
-#line 3213
+#line 3218
 #endif
-#line 3213
+#line 3218
 }
-#line 3213
+#line 3218
 
 int
-#line 3214
+#line 3219
 ncx_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3214
+#line 3219
 {
-#line 3214
+#line 3219
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3214
+#line 3219
 
-#line 3214
+#line 3219
  /* basic algorithm is:
-#line 3214
+#line 3219
   *   - ensure sane alignment of input data
-#line 3214
+#line 3219
   *   - copy (conversion happens automatically) input data
-#line 3214
+#line 3219
   *     to output
-#line 3214
+#line 3219
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3214
+#line 3219
   *     at next location for converted output
-#line 3214
+#line 3219
   */
-#line 3214
+#line 3219
   long i, j, ni;
-#line 3214
+#line 3219
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3214
+#line 3219
   ushort *xp;
-#line 3214
+#line 3219
   int nrange = 0;         /* number of range errors */
-#line 3214
+#line 3219
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3214
+#line 3219
   long cxp = (long) *((char**)xpp);
-#line 3214
+#line 3219
 
-#line 3214
+#line 3219
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3214
+#line 3219
   /* sjl: manually stripmine so we can limit amount of
-#line 3214
+#line 3219
    * vector work space reserved to LOOPCNT elements. Also
-#line 3214
+#line 3219
    * makes vectorisation easy */
-#line 3214
+#line 3219
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3214
+#line 3219
     ni=Min(nelems-j,LOOPCNT);
-#line 3214
+#line 3219
     if (realign) {
-#line 3214
+#line 3219
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3214
+#line 3219
       xp = tmp;
-#line 3214
+#line 3219
     } else {
-#line 3214
+#line 3219
       xp = (ushort *) *xpp;
-#line 3214
+#line 3219
     }
-#line 3214
+#line 3219
    /* copy the next block */
-#line 3214
+#line 3219
 #pragma cdir loopcnt=LOOPCNT
-#line 3214
+#line 3219
 #pragma cdir shortloop
-#line 3214
+#line 3219
     for (i=0; i<ni; i++) {
-#line 3214
+#line 3219
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3214
+#line 3219
      /* test for range errors (not always needed but do it anyway) */
-#line 3214
+#line 3219
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3214
+#line 3219
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3214
+#line 3219
       nrange += xp[i] > LONGLONG_MAX ;
-#line 3214
+#line 3219
     }
-#line 3214
+#line 3219
    /* update xpp and tp */
-#line 3214
+#line 3219
     if (realign) xp = (ushort *) *xpp;
-#line 3214
+#line 3219
     xp += ni;
-#line 3214
+#line 3219
     tp += ni;
-#line 3214
+#line 3219
     *xpp = (void*)xp;
-#line 3214
+#line 3219
   }
-#line 3214
+#line 3219
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3214
+#line 3219
 
-#line 3214
+#line 3219
 #else   /* not SX */
-#line 3214
+#line 3219
 	const char *xp = (const char *) *xpp;
-#line 3214
+#line 3219
 	int status = NC_NOERR;
-#line 3214
+#line 3219
 
-#line 3214
+#line 3219
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3214
+#line 3219
 	{
-#line 3214
+#line 3219
 		const int lstatus = ncx_get_ushort_longlong(xp, tp);
-#line 3214
+#line 3219
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3214
+#line 3219
 			status = lstatus;
-#line 3214
+#line 3219
 	}
-#line 3214
+#line 3219
 
-#line 3214
+#line 3219
 	*xpp = (const void *)xp;
-#line 3214
+#line 3219
 	return status;
-#line 3214
+#line 3219
 #endif
-#line 3214
+#line 3219
 }
-#line 3214
+#line 3219
 
 int
-#line 3215
+#line 3220
 ncx_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3215
+#line 3220
 {
-#line 3215
+#line 3220
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3215
+#line 3220
 
-#line 3215
+#line 3220
  /* basic algorithm is:
-#line 3215
+#line 3220
   *   - ensure sane alignment of input data
-#line 3215
+#line 3220
   *   - copy (conversion happens automatically) input data
-#line 3215
+#line 3220
   *     to output
-#line 3215
+#line 3220
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3215
+#line 3220
   *     at next location for converted output
-#line 3215
+#line 3220
   */
-#line 3215
+#line 3220
   long i, j, ni;
-#line 3215
+#line 3220
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3215
+#line 3220
   ushort *xp;
-#line 3215
+#line 3220
   int nrange = 0;         /* number of range errors */
-#line 3215
+#line 3220
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3215
+#line 3220
   long cxp = (long) *((char**)xpp);
-#line 3215
+#line 3220
 
-#line 3215
+#line 3220
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3215
+#line 3220
   /* sjl: manually stripmine so we can limit amount of
-#line 3215
+#line 3220
    * vector work space reserved to LOOPCNT elements. Also
-#line 3215
+#line 3220
    * makes vectorisation easy */
-#line 3215
+#line 3220
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3215
+#line 3220
     ni=Min(nelems-j,LOOPCNT);
-#line 3215
+#line 3220
     if (realign) {
-#line 3215
+#line 3220
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3215
+#line 3220
       xp = tmp;
-#line 3215
+#line 3220
     } else {
-#line 3215
+#line 3220
       xp = (ushort *) *xpp;
-#line 3215
+#line 3220
     }
-#line 3215
+#line 3220
    /* copy the next block */
-#line 3215
+#line 3220
 #pragma cdir loopcnt=LOOPCNT
-#line 3215
+#line 3220
 #pragma cdir shortloop
-#line 3215
+#line 3220
     for (i=0; i<ni; i++) {
-#line 3215
+#line 3220
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3215
+#line 3220
      /* test for range errors (not always needed but do it anyway) */
-#line 3215
+#line 3220
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3215
+#line 3220
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3215
+#line 3220
       nrange += xp[i] > UCHAR_MAX ;
-#line 3215
+#line 3220
     }
-#line 3215
+#line 3220
    /* update xpp and tp */
-#line 3215
+#line 3220
     if (realign) xp = (ushort *) *xpp;
-#line 3215
+#line 3220
     xp += ni;
-#line 3215
+#line 3220
     tp += ni;
-#line 3215
+#line 3220
     *xpp = (void*)xp;
-#line 3215
+#line 3220
   }
-#line 3215
+#line 3220
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3215
+#line 3220
 
-#line 3215
+#line 3220
 #else   /* not SX */
-#line 3215
+#line 3220
 	const char *xp = (const char *) *xpp;
-#line 3215
+#line 3220
 	int status = NC_NOERR;
-#line 3215
+#line 3220
 
-#line 3215
+#line 3220
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3215
+#line 3220
 	{
-#line 3215
+#line 3220
 		const int lstatus = ncx_get_ushort_uchar(xp, tp);
-#line 3215
+#line 3220
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3215
+#line 3220
 			status = lstatus;
-#line 3215
+#line 3220
 	}
-#line 3215
+#line 3220
 
-#line 3215
+#line 3220
 	*xpp = (const void *)xp;
-#line 3215
+#line 3220
 	return status;
-#line 3215
+#line 3220
 #endif
-#line 3215
+#line 3220
 }
-#line 3215
+#line 3220
 
 int
-#line 3216
+#line 3221
 ncx_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3216
+#line 3221
 {
-#line 3216
+#line 3221
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3216
+#line 3221
 
-#line 3216
+#line 3221
  /* basic algorithm is:
-#line 3216
+#line 3221
   *   - ensure sane alignment of input data
-#line 3216
+#line 3221
   *   - copy (conversion happens automatically) input data
-#line 3216
+#line 3221
   *     to output
-#line 3216
+#line 3221
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3216
+#line 3221
   *     at next location for converted output
-#line 3216
+#line 3221
   */
-#line 3216
+#line 3221
   long i, j, ni;
-#line 3216
+#line 3221
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3216
+#line 3221
   ushort *xp;
-#line 3216
+#line 3221
   int nrange = 0;         /* number of range errors */
-#line 3216
+#line 3221
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3216
+#line 3221
   long cxp = (long) *((char**)xpp);
-#line 3216
+#line 3221
 
-#line 3216
+#line 3221
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3216
+#line 3221
   /* sjl: manually stripmine so we can limit amount of
-#line 3216
+#line 3221
    * vector work space reserved to LOOPCNT elements. Also
-#line 3216
+#line 3221
    * makes vectorisation easy */
-#line 3216
+#line 3221
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3216
+#line 3221
     ni=Min(nelems-j,LOOPCNT);
-#line 3216
+#line 3221
     if (realign) {
-#line 3216
+#line 3221
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3216
+#line 3221
       xp = tmp;
-#line 3216
+#line 3221
     } else {
-#line 3216
+#line 3221
       xp = (ushort *) *xpp;
-#line 3216
+#line 3221
     }
-#line 3216
+#line 3221
    /* copy the next block */
-#line 3216
+#line 3221
 #pragma cdir loopcnt=LOOPCNT
-#line 3216
+#line 3221
 #pragma cdir shortloop
-#line 3216
+#line 3221
     for (i=0; i<ni; i++) {
-#line 3216
+#line 3221
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3216
+#line 3221
      /* test for range errors (not always needed but do it anyway) */
-#line 3216
+#line 3221
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3216
+#line 3221
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3216
+#line 3221
       nrange += xp[i] > UINT_MAX ;
-#line 3216
+#line 3221
     }
-#line 3216
+#line 3221
    /* update xpp and tp */
-#line 3216
+#line 3221
     if (realign) xp = (ushort *) *xpp;
-#line 3216
+#line 3221
     xp += ni;
-#line 3216
+#line 3221
     tp += ni;
-#line 3216
+#line 3221
     *xpp = (void*)xp;
-#line 3216
+#line 3221
   }
-#line 3216
+#line 3221
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3216
+#line 3221
 
-#line 3216
+#line 3221
 #else   /* not SX */
-#line 3216
+#line 3221
 	const char *xp = (const char *) *xpp;
-#line 3216
+#line 3221
 	int status = NC_NOERR;
-#line 3216
+#line 3221
 
-#line 3216
+#line 3221
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3216
+#line 3221
 	{
-#line 3216
+#line 3221
 		const int lstatus = ncx_get_ushort_uint(xp, tp);
-#line 3216
+#line 3221
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3216
+#line 3221
 			status = lstatus;
-#line 3216
+#line 3221
 	}
-#line 3216
+#line 3221
 
-#line 3216
+#line 3221
 	*xpp = (const void *)xp;
-#line 3216
+#line 3221
 	return status;
-#line 3216
+#line 3221
 #endif
-#line 3216
+#line 3221
 }
-#line 3216
+#line 3221
 
 int
-#line 3217
+#line 3222
 ncx_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3217
+#line 3222
 {
-#line 3217
+#line 3222
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3217
+#line 3222
 
-#line 3217
+#line 3222
  /* basic algorithm is:
-#line 3217
+#line 3222
   *   - ensure sane alignment of input data
-#line 3217
+#line 3222
   *   - copy (conversion happens automatically) input data
-#line 3217
+#line 3222
   *     to output
-#line 3217
+#line 3222
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3217
+#line 3222
   *     at next location for converted output
-#line 3217
+#line 3222
   */
-#line 3217
+#line 3222
   long i, j, ni;
-#line 3217
+#line 3222
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3217
+#line 3222
   ushort *xp;
-#line 3217
+#line 3222
   int nrange = 0;         /* number of range errors */
-#line 3217
+#line 3222
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3217
+#line 3222
   long cxp = (long) *((char**)xpp);
-#line 3217
+#line 3222
 
-#line 3217
+#line 3222
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3217
+#line 3222
   /* sjl: manually stripmine so we can limit amount of
-#line 3217
+#line 3222
    * vector work space reserved to LOOPCNT elements. Also
-#line 3217
+#line 3222
    * makes vectorisation easy */
-#line 3217
+#line 3222
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3217
+#line 3222
     ni=Min(nelems-j,LOOPCNT);
-#line 3217
+#line 3222
     if (realign) {
-#line 3217
+#line 3222
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
-#line 3217
+#line 3222
       xp = tmp;
-#line 3217
+#line 3222
     } else {
-#line 3217
+#line 3222
       xp = (ushort *) *xpp;
-#line 3217
+#line 3222
     }
-#line 3217
+#line 3222
    /* copy the next block */
-#line 3217
+#line 3222
 #pragma cdir loopcnt=LOOPCNT
-#line 3217
+#line 3222
 #pragma cdir shortloop
-#line 3217
+#line 3222
     for (i=0; i<ni; i++) {
-#line 3217
+#line 3222
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3217
+#line 3222
      /* test for range errors (not always needed but do it anyway) */
-#line 3217
+#line 3222
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3217
+#line 3222
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3217
+#line 3222
       nrange += xp[i] > ULONGLONG_MAX ;
-#line 3217
+#line 3222
     }
-#line 3217
+#line 3222
    /* update xpp and tp */
-#line 3217
+#line 3222
     if (realign) xp = (ushort *) *xpp;
-#line 3217
+#line 3222
     xp += ni;
-#line 3217
+#line 3222
     tp += ni;
-#line 3217
+#line 3222
     *xpp = (void*)xp;
-#line 3217
+#line 3222
   }
-#line 3217
+#line 3222
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3217
+#line 3222
 
-#line 3217
+#line 3222
 #else   /* not SX */
-#line 3217
+#line 3222
 	const char *xp = (const char *) *xpp;
-#line 3217
+#line 3222
 	int status = NC_NOERR;
-#line 3217
+#line 3222
 
-#line 3217
+#line 3222
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3217
+#line 3222
 	{
-#line 3217
+#line 3222
 		const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
-#line 3217
+#line 3222
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3217
+#line 3222
 			status = lstatus;
-#line 3217
+#line 3222
 	}
-#line 3217
+#line 3222
 
-#line 3217
+#line 3222
 	*xpp = (const void *)xp;
-#line 3217
+#line 3222
 	return status;
-#line 3217
+#line 3222
 #endif
-#line 3217
+#line 3222
 }
-#line 3217
+#line 3222
 
 
 int
-#line 3219
+#line 3224
 ncx_pad_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3219
+#line 3224
 {
-#line 3219
+#line 3224
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3219
+#line 3224
 
-#line 3219
+#line 3224
 	const char *xp = (const char *) *xpp;
-#line 3219
+#line 3224
 	int status = NC_NOERR;
-#line 3219
+#line 3224
 
-#line 3219
+#line 3224
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3219
+#line 3224
 	{
-#line 3219
+#line 3224
 		const int lstatus = ncx_get_ushort_schar(xp, tp);
-#line 3219
+#line 3224
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3219
+#line 3224
 			status = lstatus;
-#line 3219
+#line 3224
 	}
-#line 3219
+#line 3224
 
-#line 3219
+#line 3224
 	if (rndup != 0)
-#line 3219
+#line 3224
 		xp += X_SIZEOF_USHORT;
-#line 3219
+#line 3224
 
-#line 3219
+#line 3224
 	*xpp = (void *)xp;
-#line 3219
+#line 3224
 	return status;
-#line 3219
+#line 3224
 }
-#line 3219
+#line 3224
 
 int
-#line 3220
+#line 3225
 ncx_pad_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
-#line 3220
+#line 3225
 {
-#line 3220
+#line 3225
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3220
+#line 3225
 
-#line 3220
+#line 3225
 	const char *xp = (const char *) *xpp;
-#line 3220
+#line 3225
 	int status = NC_NOERR;
-#line 3220
+#line 3225
 
-#line 3220
+#line 3225
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3220
+#line 3225
 	{
-#line 3220
+#line 3225
 		const int lstatus = ncx_get_ushort_short(xp, tp);
-#line 3220
+#line 3225
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3220
+#line 3225
 			status = lstatus;
-#line 3220
+#line 3225
 	}
-#line 3220
+#line 3225
 
-#line 3220
+#line 3225
 	if (rndup != 0)
-#line 3220
+#line 3225
 		xp += X_SIZEOF_USHORT;
-#line 3220
+#line 3225
 
-#line 3220
+#line 3225
 	*xpp = (void *)xp;
-#line 3220
+#line 3225
 	return status;
-#line 3220
+#line 3225
 }
-#line 3220
+#line 3225
 
 int
-#line 3221
+#line 3226
 ncx_pad_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
-#line 3221
+#line 3226
 {
-#line 3221
+#line 3226
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3221
+#line 3226
 
-#line 3221
+#line 3226
 	const char *xp = (const char *) *xpp;
-#line 3221
+#line 3226
 	int status = NC_NOERR;
-#line 3221
+#line 3226
 
-#line 3221
+#line 3226
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3221
+#line 3226
 	{
-#line 3221
+#line 3226
 		const int lstatus = ncx_get_ushort_int(xp, tp);
-#line 3221
+#line 3226
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3221
+#line 3226
 			status = lstatus;
-#line 3221
+#line 3226
 	}
-#line 3221
+#line 3226
 
-#line 3221
+#line 3226
 	if (rndup != 0)
-#line 3221
+#line 3226
 		xp += X_SIZEOF_USHORT;
-#line 3221
+#line 3226
 
-#line 3221
+#line 3226
 	*xpp = (void *)xp;
-#line 3221
+#line 3226
 	return status;
-#line 3221
+#line 3226
 }
-#line 3221
+#line 3226
 
 int
-#line 3222
+#line 3227
 ncx_pad_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
-#line 3222
+#line 3227
 {
-#line 3222
+#line 3227
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3222
+#line 3227
 
-#line 3222
+#line 3227
 	const char *xp = (const char *) *xpp;
-#line 3222
+#line 3227
 	int status = NC_NOERR;
-#line 3222
+#line 3227
 
-#line 3222
+#line 3227
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3222
+#line 3227
 	{
-#line 3222
+#line 3227
 		const int lstatus = ncx_get_ushort_long(xp, tp);
-#line 3222
+#line 3227
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3222
+#line 3227
 			status = lstatus;
-#line 3222
+#line 3227
 	}
-#line 3222
+#line 3227
 
-#line 3222
+#line 3227
 	if (rndup != 0)
-#line 3222
+#line 3227
 		xp += X_SIZEOF_USHORT;
-#line 3222
+#line 3227
 
-#line 3222
+#line 3227
 	*xpp = (void *)xp;
-#line 3222
+#line 3227
 	return status;
-#line 3222
+#line 3227
 }
-#line 3222
+#line 3227
 
 int
-#line 3223
+#line 3228
 ncx_pad_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
-#line 3223
+#line 3228
 {
-#line 3223
+#line 3228
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3223
+#line 3228
 
-#line 3223
+#line 3228
 	const char *xp = (const char *) *xpp;
-#line 3223
+#line 3228
 	int status = NC_NOERR;
-#line 3223
+#line 3228
 
-#line 3223
+#line 3228
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3223
+#line 3228
 	{
-#line 3223
+#line 3228
 		const int lstatus = ncx_get_ushort_float(xp, tp);
-#line 3223
+#line 3228
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3223
+#line 3228
 			status = lstatus;
-#line 3223
+#line 3228
 	}
-#line 3223
+#line 3228
 
-#line 3223
+#line 3228
 	if (rndup != 0)
-#line 3223
+#line 3228
 		xp += X_SIZEOF_USHORT;
-#line 3223
+#line 3228
 
-#line 3223
+#line 3228
 	*xpp = (void *)xp;
-#line 3223
+#line 3228
 	return status;
-#line 3223
+#line 3228
 }
-#line 3223
+#line 3228
 
 int
-#line 3224
+#line 3229
 ncx_pad_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
-#line 3224
+#line 3229
 {
-#line 3224
+#line 3229
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3224
+#line 3229
 
-#line 3224
+#line 3229
 	const char *xp = (const char *) *xpp;
-#line 3224
+#line 3229
 	int status = NC_NOERR;
-#line 3224
+#line 3229
 
-#line 3224
+#line 3229
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3224
+#line 3229
 	{
-#line 3224
+#line 3229
 		const int lstatus = ncx_get_ushort_double(xp, tp);
-#line 3224
+#line 3229
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3224
+#line 3229
 			status = lstatus;
-#line 3224
+#line 3229
 	}
-#line 3224
+#line 3229
 
-#line 3224
+#line 3229
 	if (rndup != 0)
-#line 3224
+#line 3229
 		xp += X_SIZEOF_USHORT;
-#line 3224
+#line 3229
 
-#line 3224
+#line 3229
 	*xpp = (void *)xp;
-#line 3224
+#line 3229
 	return status;
-#line 3224
+#line 3229
 }
-#line 3224
+#line 3229
 
 int
-#line 3225
+#line 3230
 ncx_pad_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3225
+#line 3230
 {
-#line 3225
+#line 3230
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3225
+#line 3230
 
-#line 3225
+#line 3230
 	const char *xp = (const char *) *xpp;
-#line 3225
+#line 3230
 	int status = NC_NOERR;
-#line 3225
+#line 3230
 
-#line 3225
+#line 3230
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3225
+#line 3230
 	{
-#line 3225
+#line 3230
 		const int lstatus = ncx_get_ushort_uchar(xp, tp);
-#line 3225
+#line 3230
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3225
+#line 3230
 			status = lstatus;
-#line 3225
+#line 3230
 	}
-#line 3225
+#line 3230
 
-#line 3225
+#line 3230
 	if (rndup != 0)
-#line 3225
+#line 3230
 		xp += X_SIZEOF_USHORT;
-#line 3225
+#line 3230
 
-#line 3225
+#line 3230
 	*xpp = (void *)xp;
-#line 3225
+#line 3230
 	return status;
-#line 3225
+#line 3230
 }
-#line 3225
+#line 3230
 
 int
-#line 3226
+#line 3231
 ncx_pad_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3226
+#line 3231
 {
-#line 3226
+#line 3231
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3226
+#line 3231
 
-#line 3226
+#line 3231
 	const char *xp = (const char *) *xpp;
-#line 3226
+#line 3231
 	int status = NC_NOERR;
-#line 3226
+#line 3231
 
-#line 3226
+#line 3231
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3226
+#line 3231
 	{
-#line 3226
+#line 3231
 		const int lstatus = ncx_get_ushort_ushort(xp, tp);
-#line 3226
+#line 3231
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3226
+#line 3231
 			status = lstatus;
-#line 3226
+#line 3231
 	}
-#line 3226
+#line 3231
 
-#line 3226
+#line 3231
 	if (rndup != 0)
-#line 3226
+#line 3231
 		xp += X_SIZEOF_USHORT;
-#line 3226
+#line 3231
 
-#line 3226
+#line 3231
 	*xpp = (void *)xp;
-#line 3226
+#line 3231
 	return status;
-#line 3226
+#line 3231
 }
-#line 3226
+#line 3231
 
 int
-#line 3227
+#line 3232
 ncx_pad_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3227
+#line 3232
 {
-#line 3227
+#line 3232
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3227
+#line 3232
 
-#line 3227
+#line 3232
 	const char *xp = (const char *) *xpp;
-#line 3227
+#line 3232
 	int status = NC_NOERR;
-#line 3227
+#line 3232
 
-#line 3227
+#line 3232
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3227
+#line 3232
 	{
-#line 3227
+#line 3232
 		const int lstatus = ncx_get_ushort_uint(xp, tp);
-#line 3227
+#line 3232
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3227
+#line 3232
 			status = lstatus;
-#line 3227
+#line 3232
 	}
-#line 3227
+#line 3232
 
-#line 3227
+#line 3232
 	if (rndup != 0)
-#line 3227
+#line 3232
 		xp += X_SIZEOF_USHORT;
-#line 3227
+#line 3232
 
-#line 3227
+#line 3232
 	*xpp = (void *)xp;
-#line 3227
+#line 3232
 	return status;
-#line 3227
+#line 3232
 }
-#line 3227
+#line 3232
 
 int
-#line 3228
+#line 3233
 ncx_pad_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3228
+#line 3233
 {
-#line 3228
+#line 3233
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3228
+#line 3233
 
-#line 3228
+#line 3233
 	const char *xp = (const char *) *xpp;
-#line 3228
+#line 3233
 	int status = NC_NOERR;
-#line 3228
+#line 3233
 
-#line 3228
+#line 3233
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3228
+#line 3233
 	{
-#line 3228
+#line 3233
 		const int lstatus = ncx_get_ushort_longlong(xp, tp);
-#line 3228
+#line 3233
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3228
+#line 3233
 			status = lstatus;
-#line 3228
+#line 3233
 	}
-#line 3228
+#line 3233
 
-#line 3228
+#line 3233
 	if (rndup != 0)
-#line 3228
+#line 3233
 		xp += X_SIZEOF_USHORT;
-#line 3228
+#line 3233
 
-#line 3228
+#line 3233
 	*xpp = (void *)xp;
-#line 3228
+#line 3233
 	return status;
-#line 3228
+#line 3233
 }
-#line 3228
+#line 3233
 
 int
-#line 3229
+#line 3234
 ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3229
+#line 3234
 {
-#line 3229
+#line 3234
 	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3229
+#line 3234
 
-#line 3229
+#line 3234
 	const char *xp = (const char *) *xpp;
-#line 3229
+#line 3234
 	int status = NC_NOERR;
-#line 3229
+#line 3234
 
-#line 3229
+#line 3234
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3229
+#line 3234
 	{
-#line 3229
+#line 3234
 		const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
-#line 3229
+#line 3234
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3229
+#line 3234
 			status = lstatus;
-#line 3229
+#line 3234
 	}
-#line 3229
+#line 3234
 
-#line 3229
+#line 3234
 	if (rndup != 0)
-#line 3229
+#line 3234
 		xp += X_SIZEOF_USHORT;
-#line 3229
+#line 3234
 
-#line 3229
+#line 3234
 	*xpp = (void *)xp;
-#line 3229
+#line 3234
 	return status;
-#line 3229
+#line 3234
 }
-#line 3229
+#line 3234
 
 
 #if X_SIZEOF_USHORT == SIZEOF_USHORT
@@ -19417,1592 +19422,1225 @@ ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp, void
 }
 #else
 int
-#line 3245
+#line 3250
 ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3245
+#line 3250
 {
-#line 3245
+#line 3250
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3245
+#line 3250
 
-#line 3245
+#line 3250
  /* basic algorithm is:
-#line 3245
+#line 3250
   *   - ensure sane alignment of output data
-#line 3245
+#line 3250
   *   - copy (conversion happens automatically) input data
-#line 3245
+#line 3250
   *     to output
-#line 3245
+#line 3250
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3245
+#line 3250
   *     at next location for converted output
-#line 3245
+#line 3250
   */
-#line 3245
+#line 3250
   long i, j, ni;
-#line 3245
+#line 3250
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3245
+#line 3250
   ushort *xp;
-#line 3245
+#line 3250
   int nrange = 0;         /* number of range errors */
-#line 3245
+#line 3250
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3245
+#line 3250
   long cxp = (long) *((char**)xpp);
-#line 3245
+#line 3250
 
-#line 3245
+#line 3250
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3245
+#line 3250
   /* sjl: manually stripmine so we can limit amount of
-#line 3245
+#line 3250
    * vector work space reserved to LOOPCNT elements. Also
-#line 3245
+#line 3250
    * makes vectorisation easy */
-#line 3245
+#line 3250
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3245
+#line 3250
     ni=Min(nelems-j,LOOPCNT);
-#line 3245
+#line 3250
     if (realign) {
-#line 3245
+#line 3250
       xp = tmp;
-#line 3245
+#line 3250
     } else {
-#line 3245
+#line 3250
       xp = (ushort *) *xpp;
-#line 3245
+#line 3250
     }
-#line 3245
+#line 3250
    /* copy the next block */
-#line 3245
+#line 3250
 #pragma cdir loopcnt=LOOPCNT
-#line 3245
+#line 3250
 #pragma cdir shortloop
-#line 3245
+#line 3250
     for (i=0; i<ni; i++) {
-#line 3245
+#line 3250
       /* the normal case: */
-#line 3245
+#line 3250
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3245
+#line 3250
      /* test for range errors (not always needed but do it anyway) */
-#line 3245
+#line 3250
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3245
+#line 3250
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3245
+#line 3250
       nrange += tp[i] > X_USHORT_MAX ;
-#line 3245
+#line 3250
     }
-#line 3245
+#line 3250
    /* copy workspace back if necessary */
-#line 3245
+#line 3250
     if (realign) {
-#line 3245
+#line 3250
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3245
+#line 3250
       xp = (ushort *) *xpp;
-#line 3245
+#line 3250
     }
-#line 3245
+#line 3250
    /* update xpp and tp */
-#line 3245
+#line 3250
     xp += ni;
-#line 3245
+#line 3250
     tp += ni;
-#line 3245
+#line 3250
     *xpp = (void*)xp;
-#line 3245
+#line 3250
   }
-#line 3245
+#line 3250
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3245
+#line 3250
 
-#line 3245
+#line 3250
 #else   /* not SX */
-#line 3245
+#line 3250
 
-#line 3245
+#line 3250
 	char *xp = (char *) *xpp;
-#line 3245
+#line 3250
 	int status = NC_NOERR;
-#line 3245
+#line 3250
 
-#line 3245
+#line 3250
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3245
+#line 3250
 	{
-#line 3245
+#line 3250
 		int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
-#line 3245
+#line 3250
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3245
+#line 3250
 			status = lstatus;
-#line 3245
+#line 3250
 	}
-#line 3245
+#line 3250
 
-#line 3245
+#line 3250
 	*xpp = (void *)xp;
-#line 3245
+#line 3250
 	return status;
-#line 3245
+#line 3250
 #endif
-#line 3245
+#line 3250
 }
-#line 3245
+#line 3250
 
 #endif
 int
-#line 3247
+#line 3252
 ncx_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3247
+#line 3252
 {
-#line 3247
+#line 3252
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3247
+#line 3252
 
-#line 3247
+#line 3252
  /* basic algorithm is:
-#line 3247
+#line 3252
   *   - ensure sane alignment of output data
-#line 3247
+#line 3252
   *   - copy (conversion happens automatically) input data
-#line 3247
+#line 3252
   *     to output
-#line 3247
+#line 3252
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3247
+#line 3252
   *     at next location for converted output
-#line 3247
+#line 3252
   */
-#line 3247
+#line 3252
   long i, j, ni;
-#line 3247
+#line 3252
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3247
+#line 3252
   ushort *xp;
-#line 3247
+#line 3252
   int nrange = 0;         /* number of range errors */
-#line 3247
+#line 3252
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3247
+#line 3252
   long cxp = (long) *((char**)xpp);
-#line 3247
+#line 3252
 
-#line 3247
+#line 3252
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3247
+#line 3252
   /* sjl: manually stripmine so we can limit amount of
-#line 3247
+#line 3252
    * vector work space reserved to LOOPCNT elements. Also
-#line 3247
+#line 3252
    * makes vectorisation easy */
-#line 3247
+#line 3252
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3247
+#line 3252
     ni=Min(nelems-j,LOOPCNT);
-#line 3247
+#line 3252
     if (realign) {
-#line 3247
+#line 3252
       xp = tmp;
-#line 3247
+#line 3252
     } else {
-#line 3247
+#line 3252
       xp = (ushort *) *xpp;
-#line 3247
+#line 3252
     }
-#line 3247
+#line 3252
    /* copy the next block */
-#line 3247
+#line 3252
 #pragma cdir loopcnt=LOOPCNT
-#line 3247
+#line 3252
 #pragma cdir shortloop
-#line 3247
+#line 3252
     for (i=0; i<ni; i++) {
-#line 3247
+#line 3252
       /* the normal case: */
-#line 3247
+#line 3252
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3247
+#line 3252
      /* test for range errors (not always needed but do it anyway) */
-#line 3247
+#line 3252
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3247
+#line 3252
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3247
+#line 3252
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3247
+#line 3252
     }
-#line 3247
+#line 3252
    /* copy workspace back if necessary */
-#line 3247
+#line 3252
     if (realign) {
-#line 3247
+#line 3252
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3247
+#line 3252
       xp = (ushort *) *xpp;
-#line 3247
+#line 3252
     }
-#line 3247
+#line 3252
    /* update xpp and tp */
-#line 3247
+#line 3252
     xp += ni;
-#line 3247
+#line 3252
     tp += ni;
-#line 3247
+#line 3252
     *xpp = (void*)xp;
-#line 3247
+#line 3252
   }
-#line 3247
+#line 3252
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3247
+#line 3252
 
-#line 3247
+#line 3252
 #else   /* not SX */
-#line 3247
+#line 3252
 
-#line 3247
+#line 3252
 	char *xp = (char *) *xpp;
-#line 3247
+#line 3252
 	int status = NC_NOERR;
-#line 3247
+#line 3252
 
-#line 3247
+#line 3252
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3247
+#line 3252
 	{
-#line 3247
+#line 3252
 		int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
-#line 3247
+#line 3252
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3247
+#line 3252
 			status = lstatus;
-#line 3247
+#line 3252
 	}
-#line 3247
+#line 3252
 
-#line 3247
+#line 3252
 	*xpp = (void *)xp;
-#line 3247
+#line 3252
 	return status;
-#line 3247
+#line 3252
 #endif
-#line 3247
+#line 3252
 }
-#line 3247
+#line 3252
 
 int
-#line 3248
+#line 3253
 ncx_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3248
+#line 3253
 {
-#line 3248
+#line 3253
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3248
+#line 3253
 
-#line 3248
+#line 3253
  /* basic algorithm is:
-#line 3248
+#line 3253
   *   - ensure sane alignment of output data
-#line 3248
+#line 3253
   *   - copy (conversion happens automatically) input data
-#line 3248
+#line 3253
   *     to output
-#line 3248
+#line 3253
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3248
+#line 3253
   *     at next location for converted output
-#line 3248
+#line 3253
   */
-#line 3248
+#line 3253
   long i, j, ni;
-#line 3248
+#line 3253
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3248
+#line 3253
   ushort *xp;
-#line 3248
+#line 3253
   int nrange = 0;         /* number of range errors */
-#line 3248
+#line 3253
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3248
+#line 3253
   long cxp = (long) *((char**)xpp);
-#line 3248
+#line 3253
 
-#line 3248
+#line 3253
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3248
+#line 3253
   /* sjl: manually stripmine so we can limit amount of
-#line 3248
+#line 3253
    * vector work space reserved to LOOPCNT elements. Also
-#line 3248
+#line 3253
    * makes vectorisation easy */
-#line 3248
+#line 3253
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3248
+#line 3253
     ni=Min(nelems-j,LOOPCNT);
-#line 3248
+#line 3253
     if (realign) {
-#line 3248
+#line 3253
       xp = tmp;
-#line 3248
+#line 3253
     } else {
-#line 3248
+#line 3253
       xp = (ushort *) *xpp;
-#line 3248
+#line 3253
     }
-#line 3248
+#line 3253
    /* copy the next block */
-#line 3248
+#line 3253
 #pragma cdir loopcnt=LOOPCNT
-#line 3248
+#line 3253
 #pragma cdir shortloop
-#line 3248
+#line 3253
     for (i=0; i<ni; i++) {
-#line 3248
+#line 3253
       /* the normal case: */
-#line 3248
+#line 3253
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3248
+#line 3253
      /* test for range errors (not always needed but do it anyway) */
-#line 3248
+#line 3253
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3248
+#line 3253
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3248
+#line 3253
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3248
+#line 3253
     }
-#line 3248
+#line 3253
    /* copy workspace back if necessary */
-#line 3248
+#line 3253
     if (realign) {
-#line 3248
+#line 3253
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3248
+#line 3253
       xp = (ushort *) *xpp;
-#line 3248
+#line 3253
     }
-#line 3248
+#line 3253
    /* update xpp and tp */
-#line 3248
+#line 3253
     xp += ni;
-#line 3248
+#line 3253
     tp += ni;
-#line 3248
+#line 3253
     *xpp = (void*)xp;
-#line 3248
+#line 3253
   }
-#line 3248
+#line 3253
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3248
+#line 3253
 
-#line 3248
+#line 3253
 #else   /* not SX */
-#line 3248
+#line 3253
 
-#line 3248
+#line 3253
 	char *xp = (char *) *xpp;
-#line 3248
+#line 3253
 	int status = NC_NOERR;
-#line 3248
+#line 3253
 
-#line 3248
+#line 3253
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3248
+#line 3253
 	{
-#line 3248
+#line 3253
 		int lstatus = ncx_put_ushort_short(xp, tp, fillp);
-#line 3248
+#line 3253
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3248
+#line 3253
 			status = lstatus;
-#line 3248
+#line 3253
 	}
-#line 3248
+#line 3253
 
-#line 3248
+#line 3253
 	*xpp = (void *)xp;
-#line 3248
+#line 3253
 	return status;
-#line 3248
+#line 3253
 #endif
-#line 3248
+#line 3253
 }
-#line 3248
+#line 3253
 
 int
-#line 3249
+#line 3254
 ncx_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3249
+#line 3254
 {
-#line 3249
+#line 3254
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3249
+#line 3254
 
-#line 3249
+#line 3254
  /* basic algorithm is:
-#line 3249
+#line 3254
   *   - ensure sane alignment of output data
-#line 3249
+#line 3254
   *   - copy (conversion happens automatically) input data
-#line 3249
+#line 3254
   *     to output
-#line 3249
+#line 3254
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3249
+#line 3254
   *     at next location for converted output
-#line 3249
+#line 3254
   */
-#line 3249
+#line 3254
   long i, j, ni;
-#line 3249
+#line 3254
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3249
+#line 3254
   ushort *xp;
-#line 3249
+#line 3254
   int nrange = 0;         /* number of range errors */
-#line 3249
+#line 3254
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3249
+#line 3254
   long cxp = (long) *((char**)xpp);
-#line 3249
+#line 3254
 
-#line 3249
+#line 3254
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3249
+#line 3254
   /* sjl: manually stripmine so we can limit amount of
-#line 3249
+#line 3254
    * vector work space reserved to LOOPCNT elements. Also
-#line 3249
+#line 3254
    * makes vectorisation easy */
-#line 3249
+#line 3254
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3249
+#line 3254
     ni=Min(nelems-j,LOOPCNT);
-#line 3249
+#line 3254
     if (realign) {
-#line 3249
+#line 3254
       xp = tmp;
-#line 3249
+#line 3254
     } else {
-#line 3249
+#line 3254
       xp = (ushort *) *xpp;
-#line 3249
+#line 3254
     }
-#line 3249
+#line 3254
    /* copy the next block */
-#line 3249
+#line 3254
 #pragma cdir loopcnt=LOOPCNT
-#line 3249
+#line 3254
 #pragma cdir shortloop
-#line 3249
+#line 3254
     for (i=0; i<ni; i++) {
-#line 3249
+#line 3254
       /* the normal case: */
-#line 3249
+#line 3254
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3249
+#line 3254
      /* test for range errors (not always needed but do it anyway) */
-#line 3249
+#line 3254
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3249
+#line 3254
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3249
+#line 3254
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3249
+#line 3254
     }
-#line 3249
+#line 3254
    /* copy workspace back if necessary */
-#line 3249
+#line 3254
     if (realign) {
-#line 3249
+#line 3254
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3249
+#line 3254
       xp = (ushort *) *xpp;
-#line 3249
+#line 3254
     }
-#line 3249
+#line 3254
    /* update xpp and tp */
-#line 3249
+#line 3254
     xp += ni;
-#line 3249
+#line 3254
     tp += ni;
-#line 3249
+#line 3254
     *xpp = (void*)xp;
-#line 3249
+#line 3254
   }
-#line 3249
+#line 3254
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3249
+#line 3254
 
-#line 3249
+#line 3254
 #else   /* not SX */
-#line 3249
+#line 3254
 
-#line 3249
+#line 3254
 	char *xp = (char *) *xpp;
-#line 3249
+#line 3254
 	int status = NC_NOERR;
-#line 3249
+#line 3254
 
-#line 3249
+#line 3254
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3249
+#line 3254
 	{
-#line 3249
+#line 3254
 		int lstatus = ncx_put_ushort_int(xp, tp, fillp);
-#line 3249
+#line 3254
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3249
+#line 3254
 			status = lstatus;
-#line 3249
+#line 3254
 	}
-#line 3249
+#line 3254
 
-#line 3249
+#line 3254
 	*xpp = (void *)xp;
-#line 3249
+#line 3254
 	return status;
-#line 3249
+#line 3254
 #endif
-#line 3249
+#line 3254
 }
-#line 3249
+#line 3254
 
 int
-#line 3250
+#line 3255
 ncx_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3250
+#line 3255
 {
-#line 3250
+#line 3255
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3250
+#line 3255
 
-#line 3250
+#line 3255
  /* basic algorithm is:
-#line 3250
+#line 3255
   *   - ensure sane alignment of output data
-#line 3250
+#line 3255
   *   - copy (conversion happens automatically) input data
-#line 3250
+#line 3255
   *     to output
-#line 3250
+#line 3255
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3250
+#line 3255
   *     at next location for converted output
-#line 3250
+#line 3255
   */
-#line 3250
+#line 3255
   long i, j, ni;
-#line 3250
+#line 3255
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3250
+#line 3255
   ushort *xp;
-#line 3250
+#line 3255
   int nrange = 0;         /* number of range errors */
-#line 3250
+#line 3255
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3250
+#line 3255
   long cxp = (long) *((char**)xpp);
-#line 3250
+#line 3255
 
-#line 3250
+#line 3255
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3250
+#line 3255
   /* sjl: manually stripmine so we can limit amount of
-#line 3250
+#line 3255
    * vector work space reserved to LOOPCNT elements. Also
-#line 3250
+#line 3255
    * makes vectorisation easy */
-#line 3250
+#line 3255
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3250
+#line 3255
     ni=Min(nelems-j,LOOPCNT);
-#line 3250
+#line 3255
     if (realign) {
-#line 3250
+#line 3255
       xp = tmp;
-#line 3250
+#line 3255
     } else {
-#line 3250
+#line 3255
       xp = (ushort *) *xpp;
-#line 3250
+#line 3255
     }
-#line 3250
+#line 3255
    /* copy the next block */
-#line 3250
+#line 3255
 #pragma cdir loopcnt=LOOPCNT
-#line 3250
+#line 3255
 #pragma cdir shortloop
-#line 3250
+#line 3255
     for (i=0; i<ni; i++) {
-#line 3250
+#line 3255
       /* the normal case: */
-#line 3250
+#line 3255
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3250
+#line 3255
      /* test for range errors (not always needed but do it anyway) */
-#line 3250
+#line 3255
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3250
+#line 3255
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3250
+#line 3255
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3250
+#line 3255
     }
-#line 3250
+#line 3255
    /* copy workspace back if necessary */
-#line 3250
+#line 3255
     if (realign) {
-#line 3250
+#line 3255
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3250
+#line 3255
       xp = (ushort *) *xpp;
-#line 3250
+#line 3255
     }
-#line 3250
+#line 3255
    /* update xpp and tp */
-#line 3250
+#line 3255
     xp += ni;
-#line 3250
+#line 3255
     tp += ni;
-#line 3250
+#line 3255
     *xpp = (void*)xp;
-#line 3250
+#line 3255
   }
-#line 3250
+#line 3255
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3250
+#line 3255
 
-#line 3250
+#line 3255
 #else   /* not SX */
-#line 3250
+#line 3255
 
-#line 3250
+#line 3255
 	char *xp = (char *) *xpp;
-#line 3250
+#line 3255
 	int status = NC_NOERR;
-#line 3250
+#line 3255
 
-#line 3250
+#line 3255
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3250
+#line 3255
 	{
-#line 3250
+#line 3255
 		int lstatus = ncx_put_ushort_long(xp, tp, fillp);
-#line 3250
+#line 3255
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3250
+#line 3255
 			status = lstatus;
-#line 3250
+#line 3255
 	}
-#line 3250
+#line 3255
 
-#line 3250
+#line 3255
 	*xpp = (void *)xp;
-#line 3250
+#line 3255
 	return status;
-#line 3250
+#line 3255
 #endif
-#line 3250
+#line 3255
 }
-#line 3250
+#line 3255
 
 int
-#line 3251
+#line 3256
 ncx_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3251
+#line 3256
 {
-#line 3251
+#line 3256
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3251
+#line 3256
 
-#line 3251
+#line 3256
  /* basic algorithm is:
-#line 3251
+#line 3256
   *   - ensure sane alignment of output data
-#line 3251
+#line 3256
   *   - copy (conversion happens automatically) input data
-#line 3251
+#line 3256
   *     to output
-#line 3251
+#line 3256
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3251
+#line 3256
   *     at next location for converted output
-#line 3251
+#line 3256
   */
-#line 3251
+#line 3256
   long i, j, ni;
-#line 3251
+#line 3256
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3251
+#line 3256
   ushort *xp;
-#line 3251
+#line 3256
   int nrange = 0;         /* number of range errors */
-#line 3251
+#line 3256
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3251
+#line 3256
   long cxp = (long) *((char**)xpp);
-#line 3251
+#line 3256
 
-#line 3251
+#line 3256
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3251
+#line 3256
   /* sjl: manually stripmine so we can limit amount of
-#line 3251
+#line 3256
    * vector work space reserved to LOOPCNT elements. Also
-#line 3251
+#line 3256
    * makes vectorisation easy */
-#line 3251
+#line 3256
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3251
+#line 3256
     ni=Min(nelems-j,LOOPCNT);
-#line 3251
+#line 3256
     if (realign) {
-#line 3251
+#line 3256
       xp = tmp;
-#line 3251
+#line 3256
     } else {
-#line 3251
+#line 3256
       xp = (ushort *) *xpp;
-#line 3251
+#line 3256
     }
-#line 3251
+#line 3256
    /* copy the next block */
-#line 3251
+#line 3256
 #pragma cdir loopcnt=LOOPCNT
-#line 3251
+#line 3256
 #pragma cdir shortloop
-#line 3251
+#line 3256
     for (i=0; i<ni; i++) {
-#line 3251
+#line 3256
       /* the normal case: */
-#line 3251
+#line 3256
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3251
+#line 3256
      /* test for range errors (not always needed but do it anyway) */
-#line 3251
+#line 3256
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3251
+#line 3256
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3251
+#line 3256
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3251
+#line 3256
     }
-#line 3251
+#line 3256
    /* copy workspace back if necessary */
-#line 3251
+#line 3256
     if (realign) {
-#line 3251
+#line 3256
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3251
+#line 3256
       xp = (ushort *) *xpp;
-#line 3251
+#line 3256
     }
-#line 3251
+#line 3256
    /* update xpp and tp */
-#line 3251
+#line 3256
     xp += ni;
-#line 3251
+#line 3256
     tp += ni;
-#line 3251
+#line 3256
     *xpp = (void*)xp;
-#line 3251
+#line 3256
   }
-#line 3251
+#line 3256
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3251
+#line 3256
 
-#line 3251
+#line 3256
 #else   /* not SX */
-#line 3251
+#line 3256
 
-#line 3251
+#line 3256
 	char *xp = (char *) *xpp;
-#line 3251
+#line 3256
 	int status = NC_NOERR;
-#line 3251
+#line 3256
 
-#line 3251
+#line 3256
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3251
+#line 3256
 	{
-#line 3251
+#line 3256
 		int lstatus = ncx_put_ushort_float(xp, tp, fillp);
-#line 3251
+#line 3256
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3251
+#line 3256
 			status = lstatus;
-#line 3251
+#line 3256
 	}
-#line 3251
+#line 3256
 
-#line 3251
+#line 3256
 	*xpp = (void *)xp;
-#line 3251
+#line 3256
 	return status;
-#line 3251
+#line 3256
 #endif
-#line 3251
+#line 3256
 }
-#line 3251
+#line 3256
 
 int
-#line 3252
+#line 3257
 ncx_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3252
+#line 3257
 {
-#line 3252
+#line 3257
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3252
+#line 3257
 
-#line 3252
+#line 3257
  /* basic algorithm is:
-#line 3252
+#line 3257
   *   - ensure sane alignment of output data
-#line 3252
+#line 3257
   *   - copy (conversion happens automatically) input data
-#line 3252
+#line 3257
   *     to output
-#line 3252
+#line 3257
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3252
+#line 3257
   *     at next location for converted output
-#line 3252
+#line 3257
   */
-#line 3252
+#line 3257
   long i, j, ni;
-#line 3252
+#line 3257
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3252
+#line 3257
   ushort *xp;
-#line 3252
+#line 3257
   int nrange = 0;         /* number of range errors */
-#line 3252
+#line 3257
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3252
+#line 3257
   long cxp = (long) *((char**)xpp);
-#line 3252
+#line 3257
 
-#line 3252
+#line 3257
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3252
+#line 3257
   /* sjl: manually stripmine so we can limit amount of
-#line 3252
+#line 3257
    * vector work space reserved to LOOPCNT elements. Also
-#line 3252
+#line 3257
    * makes vectorisation easy */
-#line 3252
+#line 3257
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3252
+#line 3257
     ni=Min(nelems-j,LOOPCNT);
-#line 3252
+#line 3257
     if (realign) {
-#line 3252
+#line 3257
       xp = tmp;
-#line 3252
+#line 3257
     } else {
-#line 3252
+#line 3257
       xp = (ushort *) *xpp;
-#line 3252
+#line 3257
     }
-#line 3252
+#line 3257
    /* copy the next block */
-#line 3252
+#line 3257
 #pragma cdir loopcnt=LOOPCNT
-#line 3252
+#line 3257
 #pragma cdir shortloop
-#line 3252
+#line 3257
     for (i=0; i<ni; i++) {
-#line 3252
+#line 3257
       /* the normal case: */
-#line 3252
+#line 3257
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3252
+#line 3257
      /* test for range errors (not always needed but do it anyway) */
-#line 3252
+#line 3257
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3252
+#line 3257
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3252
+#line 3257
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3252
+#line 3257
     }
-#line 3252
+#line 3257
    /* copy workspace back if necessary */
-#line 3252
+#line 3257
     if (realign) {
-#line 3252
+#line 3257
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3252
+#line 3257
       xp = (ushort *) *xpp;
-#line 3252
+#line 3257
     }
-#line 3252
+#line 3257
    /* update xpp and tp */
-#line 3252
+#line 3257
     xp += ni;
-#line 3252
+#line 3257
     tp += ni;
-#line 3252
+#line 3257
     *xpp = (void*)xp;
-#line 3252
+#line 3257
   }
-#line 3252
+#line 3257
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3252
+#line 3257
 
-#line 3252
+#line 3257
 #else   /* not SX */
-#line 3252
+#line 3257
 
-#line 3252
+#line 3257
 	char *xp = (char *) *xpp;
-#line 3252
+#line 3257
 	int status = NC_NOERR;
-#line 3252
+#line 3257
 
-#line 3252
+#line 3257
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3252
+#line 3257
 	{
-#line 3252
+#line 3257
 		int lstatus = ncx_put_ushort_double(xp, tp, fillp);
-#line 3252
+#line 3257
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3252
+#line 3257
 			status = lstatus;
-#line 3252
+#line 3257
 	}
-#line 3252
+#line 3257
 
-#line 3252
+#line 3257
 	*xpp = (void *)xp;
-#line 3252
+#line 3257
 	return status;
-#line 3252
+#line 3257
 #endif
-#line 3252
+#line 3257
 }
-#line 3252
+#line 3257
 
 int
-#line 3253
+#line 3258
 ncx_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3253
+#line 3258
 {
-#line 3253
+#line 3258
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3253
+#line 3258
 
-#line 3253
+#line 3258
  /* basic algorithm is:
-#line 3253
+#line 3258
   *   - ensure sane alignment of output data
-#line 3253
+#line 3258
   *   - copy (conversion happens automatically) input data
-#line 3253
+#line 3258
   *     to output
-#line 3253
+#line 3258
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3253
+#line 3258
   *     at next location for converted output
-#line 3253
+#line 3258
   */
-#line 3253
+#line 3258
   long i, j, ni;
-#line 3253
+#line 3258
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3253
+#line 3258
   ushort *xp;
-#line 3253
+#line 3258
   int nrange = 0;         /* number of range errors */
-#line 3253
+#line 3258
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3253
+#line 3258
   long cxp = (long) *((char**)xpp);
-#line 3253
+#line 3258
 
-#line 3253
+#line 3258
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3253
+#line 3258
   /* sjl: manually stripmine so we can limit amount of
-#line 3253
+#line 3258
    * vector work space reserved to LOOPCNT elements. Also
-#line 3253
+#line 3258
    * makes vectorisation easy */
-#line 3253
+#line 3258
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3253
+#line 3258
     ni=Min(nelems-j,LOOPCNT);
-#line 3253
+#line 3258
     if (realign) {
-#line 3253
+#line 3258
       xp = tmp;
-#line 3253
+#line 3258
     } else {
-#line 3253
+#line 3258
       xp = (ushort *) *xpp;
-#line 3253
+#line 3258
     }
-#line 3253
+#line 3258
    /* copy the next block */
-#line 3253
+#line 3258
 #pragma cdir loopcnt=LOOPCNT
-#line 3253
+#line 3258
 #pragma cdir shortloop
-#line 3253
+#line 3258
     for (i=0; i<ni; i++) {
-#line 3253
+#line 3258
       /* the normal case: */
-#line 3253
+#line 3258
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3253
+#line 3258
      /* test for range errors (not always needed but do it anyway) */
-#line 3253
+#line 3258
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3253
+#line 3258
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3253
+#line 3258
       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
-#line 3253
+#line 3258
     }
-#line 3253
+#line 3258
    /* copy workspace back if necessary */
-#line 3253
+#line 3258
     if (realign) {
-#line 3253
+#line 3258
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3253
+#line 3258
       xp = (ushort *) *xpp;
-#line 3253
+#line 3258
     }
-#line 3253
+#line 3258
    /* update xpp and tp */
-#line 3253
+#line 3258
     xp += ni;
-#line 3253
+#line 3258
     tp += ni;
-#line 3253
+#line 3258
     *xpp = (void*)xp;
-#line 3253
+#line 3258
   }
-#line 3253
+#line 3258
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3253
+#line 3258
 
-#line 3253
+#line 3258
 #else   /* not SX */
-#line 3253
+#line 3258
 
-#line 3253
+#line 3258
 	char *xp = (char *) *xpp;
-#line 3253
+#line 3258
 	int status = NC_NOERR;
-#line 3253
+#line 3258
 
-#line 3253
+#line 3258
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3253
+#line 3258
 	{
-#line 3253
+#line 3258
 		int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
-#line 3253
+#line 3258
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3253
+#line 3258
 			status = lstatus;
-#line 3253
+#line 3258
 	}
-#line 3253
+#line 3258
 
-#line 3253
+#line 3258
 	*xpp = (void *)xp;
-#line 3253
+#line 3258
 	return status;
-#line 3253
+#line 3258
 #endif
-#line 3253
+#line 3258
 }
-#line 3253
+#line 3258
 
 int
-#line 3254
+#line 3259
 ncx_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3254
+#line 3259
 {
-#line 3254
+#line 3259
 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3254
+#line 3259
 
-#line 3254
+#line 3259
  /* basic algorithm is:
-#line 3254
+#line 3259
   *   - ensure sane alignment of output data
-#line 3254
+#line 3259
   *   - copy (conversion happens automatically) input data
-#line 3254
+#line 3259
   *     to output
-#line 3254
+#line 3259
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3254
+#line 3259
   *     at next location for converted output
-#line 3254
+#line 3259
   */
-#line 3254
+#line 3259
   long i, j, ni;
-#line 3254
+#line 3259
   ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3254
+#line 3259
   ushort *xp;
-#line 3254
+#line 3259
   int nrange = 0;         /* number of range errors */
-#line 3254
+#line 3259
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3254
+#line 3259
   long cxp = (long) *((char**)xpp);
-#line 3254
+#line 3259
 
-#line 3254
+#line 3259
   realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3254
+#line 3259
   /* sjl: manually stripmine so we can limit amount of
-#line 3254
+#line 3259
    * vector work space reserved to LOOPCNT elements. Also
-#line 3254
+#line 3259
    * makes vectorisation easy */
-#line 3254
+#line 3259
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3254
+#line 3259
     ni=Min(nelems-j,LOOPCNT);
-#line 3254
+#line 3259
     if (realign) {
-#line 3254
+#line 3259
       xp = tmp;
-#line 3254
+#line 3259
     } else {
-#line 3254
+#line 3259
       xp = (ushort *) *xpp;
-#line 3254
+#line 3259
     }
-#line 3254
+#line 3259
    /* copy the next block */
-#line 3254
+#line 3259
 #pragma cdir loopcnt=LOOPCNT
-#line 3254
+#line 3259
 #pragma cdir shortloop
-#line 3254
+#line 3259
     for (i=0; i<ni; i++) {
-#line 3254
-      /* the normal case: */
-#line 3254
-      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3254
-     /* test for range errors (not always needed but do it anyway) */
-#line 3254
-     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3254
-     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3254
-      nrange += tp[i] > X_USHORT_MAX ;
-#line 3254
-    }
-#line 3254
-   /* copy workspace back if necessary */
-#line 3254
-    if (realign) {
-#line 3254
-      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3254
-      xp = (ushort *) *xpp;
-#line 3254
-    }
-#line 3254
-   /* update xpp and tp */
-#line 3254
-    xp += ni;
-#line 3254
-    tp += ni;
-#line 3254
-    *xpp = (void*)xp;
-#line 3254
-  }
-#line 3254
-  return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3254
-
-#line 3254
-#else   /* not SX */
-#line 3254
-
-#line 3254
-	char *xp = (char *) *xpp;
-#line 3254
-	int status = NC_NOERR;
-#line 3254
-
-#line 3254
-	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3254
-	{
-#line 3254
-		int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
-#line 3254
-		if (status == NC_NOERR) /* report the first encountered error */
-#line 3254
-			status = lstatus;
-#line 3254
-	}
-#line 3254
-
-#line 3254
-	*xpp = (void *)xp;
-#line 3254
-	return status;
-#line 3254
-#endif
-#line 3254
-}
-#line 3254
-
-int
-#line 3255
-ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3255
-{
-#line 3255
-#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3255
-
-#line 3255
- /* basic algorithm is:
-#line 3255
-  *   - ensure sane alignment of output data
-#line 3255
-  *   - copy (conversion happens automatically) input data
-#line 3255
-  *     to output
-#line 3255
-  *   - update tp to point at next unconverted input, and xpp to point
-#line 3255
-  *     at next location for converted output
-#line 3255
-  */
-#line 3255
-  long i, j, ni;
-#line 3255
-  ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3255
-  ushort *xp;
-#line 3255
-  int nrange = 0;         /* number of range errors */
-#line 3255
-  int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3255
-  long cxp = (long) *((char**)xpp);
-#line 3255
-
-#line 3255
-  realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3255
-  /* sjl: manually stripmine so we can limit amount of
-#line 3255
-   * vector work space reserved to LOOPCNT elements. Also
-#line 3255
-   * makes vectorisation easy */
-#line 3255
-  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3255
-    ni=Min(nelems-j,LOOPCNT);
-#line 3255
-    if (realign) {
-#line 3255
-      xp = tmp;
-#line 3255
-    } else {
-#line 3255
-      xp = (ushort *) *xpp;
-#line 3255
-    }
-#line 3255
-   /* copy the next block */
-#line 3255
-#pragma cdir loopcnt=LOOPCNT
-#line 3255
-#pragma cdir shortloop
-#line 3255
-    for (i=0; i<ni; i++) {
-#line 3255
-      /* the normal case: */
-#line 3255
-      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3255
-     /* test for range errors (not always needed but do it anyway) */
-#line 3255
-     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3255
-     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3255
-      nrange += tp[i] > X_USHORT_MAX ;
-#line 3255
-    }
-#line 3255
-   /* copy workspace back if necessary */
-#line 3255
-    if (realign) {
-#line 3255
-      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3255
-      xp = (ushort *) *xpp;
-#line 3255
-    }
-#line 3255
-   /* update xpp and tp */
-#line 3255
-    xp += ni;
-#line 3255
-    tp += ni;
-#line 3255
-    *xpp = (void*)xp;
-#line 3255
-  }
-#line 3255
-  return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3255
-
-#line 3255
-#else   /* not SX */
-#line 3255
-
-#line 3255
-	char *xp = (char *) *xpp;
-#line 3255
-	int status = NC_NOERR;
-#line 3255
-
-#line 3255
-	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3255
-	{
-#line 3255
-		int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
-#line 3255
-		if (status == NC_NOERR) /* report the first encountered error */
-#line 3255
-			status = lstatus;
-#line 3255
-	}
-#line 3255
-
-#line 3255
-	*xpp = (void *)xp;
-#line 3255
-	return status;
-#line 3255
-#endif
-#line 3255
-}
-#line 3255
-
-int
-#line 3256
-ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3256
-{
-#line 3256
-#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
-#line 3256
-
-#line 3256
- /* basic algorithm is:
-#line 3256
-  *   - ensure sane alignment of output data
-#line 3256
-  *   - copy (conversion happens automatically) input data
-#line 3256
-  *     to output
-#line 3256
-  *   - update tp to point at next unconverted input, and xpp to point
-#line 3256
-  *     at next location for converted output
-#line 3256
-  */
-#line 3256
-  long i, j, ni;
-#line 3256
-  ushort tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3256
-  ushort *xp;
-#line 3256
-  int nrange = 0;         /* number of range errors */
-#line 3256
-  int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3256
-  long cxp = (long) *((char**)xpp);
-#line 3256
-
-#line 3256
-  realign = (cxp & 7) % SIZEOF_USHORT;
-#line 3256
-  /* sjl: manually stripmine so we can limit amount of
-#line 3256
-   * vector work space reserved to LOOPCNT elements. Also
-#line 3256
-   * makes vectorisation easy */
-#line 3256
-  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3256
-    ni=Min(nelems-j,LOOPCNT);
-#line 3256
-    if (realign) {
-#line 3256
-      xp = tmp;
-#line 3256
-    } else {
-#line 3256
-      xp = (ushort *) *xpp;
-#line 3256
-    }
-#line 3256
-   /* copy the next block */
-#line 3256
-#pragma cdir loopcnt=LOOPCNT
-#line 3256
-#pragma cdir shortloop
-#line 3256
-    for (i=0; i<ni; i++) {
-#line 3256
+#line 3259
       /* the normal case: */
-#line 3256
+#line 3259
       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
-#line 3256
+#line 3259
      /* test for range errors (not always needed but do it anyway) */
-#line 3256
+#line 3259
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3256
+#line 3259
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3256
+#line 3259
       nrange += tp[i] > X_USHORT_MAX ;
-#line 3256
+#line 3259
     }
-#line 3256
+#line 3259
    /* copy workspace back if necessary */
-#line 3256
-    if (realign) {
-#line 3256
-      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
-#line 3256
-      xp = (ushort *) *xpp;
-#line 3256
-    }
-#line 3256
-   /* update xpp and tp */
-#line 3256
-    xp += ni;
-#line 3256
-    tp += ni;
-#line 3256
-    *xpp = (void*)xp;
-#line 3256
-  }
-#line 3256
-  return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3256
-
-#line 3256
-#else   /* not SX */
-#line 3256
-
-#line 3256
-	char *xp = (char *) *xpp;
-#line 3256
-	int status = NC_NOERR;
-#line 3256
-
-#line 3256
-	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3256
-	{
-#line 3256
-		int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
-#line 3256
-		if (status == NC_NOERR) /* report the first encountered error */
-#line 3256
-			status = lstatus;
-#line 3256
-	}
-#line 3256
-
-#line 3256
-	*xpp = (void *)xp;
-#line 3256
-	return status;
-#line 3256
-#endif
-#line 3256
-}
-#line 3256
-
-
-int
-#line 3258
-ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3258
-{
-#line 3258
-	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3258
-
-#line 3258
-	char *xp = (char *) *xpp;
-#line 3258
-	int status = NC_NOERR;
-#line 3258
-
-#line 3258
-	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3258
-	{
-#line 3258
-		int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
-#line 3258
-		if (status == NC_NOERR) /* report the first encountered error */
-#line 3258
-			status = lstatus;
-#line 3258
-	}
-#line 3258
-
-#line 3258
-	if (rndup != 0)
-#line 3258
-	{
-#line 3258
-		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
-#line 3258
-		xp += X_SIZEOF_USHORT;
-#line 3258
-	}
-#line 3258
-
-#line 3258
-	*xpp = (void *)xp;
-#line 3258
-	return status;
-#line 3258
-}
-#line 3258
-
-int
 #line 3259
-ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
+    if (realign) {
+#line 3259
+      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
 #line 3259
-{
+      xp = (ushort *) *xpp;
 #line 3259
-	const size_t rndup = nelems % X_SIZEOF_SHORT;
+    }
+#line 3259
+   /* update xpp and tp */
+#line 3259
+    xp += ni;
+#line 3259
+    tp += ni;
+#line 3259
+    *xpp = (void*)xp;
+#line 3259
+  }
+#line 3259
+  return nrange == 0 ? NC_NOERR : NC_ERANGE;
+#line 3259
+
+#line 3259
+#else   /* not SX */
 #line 3259
 
 #line 3259
@@ -21026,62 +20664,140 @@ ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fill
 #line 3259
 
 #line 3259
-	if (rndup != 0)
-#line 3259
-	{
-#line 3259
-		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
-#line 3259
-		xp += X_SIZEOF_USHORT;
-#line 3259
-	}
-#line 3259
-
-#line 3259
 	*xpp = (void *)xp;
 #line 3259
 	return status;
 #line 3259
+#endif
+#line 3259
 }
 #line 3259
 
 int
 #line 3260
-ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
+ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 #line 3260
 {
 #line 3260
-	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
 #line 3260
 
 #line 3260
-	char *xp = (char *) *xpp;
+ /* basic algorithm is:
 #line 3260
-	int status = NC_NOERR;
+  *   - ensure sane alignment of output data
+#line 3260
+  *   - copy (conversion happens automatically) input data
+#line 3260
+  *     to output
+#line 3260
+  *   - update tp to point at next unconverted input, and xpp to point
+#line 3260
+  *     at next location for converted output
+#line 3260
+  */
+#line 3260
+  long i, j, ni;
+#line 3260
+  ushort tmp[LOOPCNT];        /* in case input is misaligned */
+#line 3260
+  ushort *xp;
+#line 3260
+  int nrange = 0;         /* number of range errors */
+#line 3260
+  int realign = 0;        /* "do we need to fix input data alignment?" */
+#line 3260
+  long cxp = (long) *((char**)xpp);
 #line 3260
 
 #line 3260
-	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+  realign = (cxp & 7) % SIZEOF_USHORT;
 #line 3260
-	{
+  /* sjl: manually stripmine so we can limit amount of
 #line 3260
-		int lstatus = ncx_put_ushort_short(xp, tp, fillp);
+   * vector work space reserved to LOOPCNT elements. Also
 #line 3260
-		if (status == NC_NOERR) /* report the first encountered error */
+   * makes vectorisation easy */
 #line 3260
-			status = lstatus;
+  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
 #line 3260
-	}
+    ni=Min(nelems-j,LOOPCNT);
+#line 3260
+    if (realign) {
+#line 3260
+      xp = tmp;
+#line 3260
+    } else {
+#line 3260
+      xp = (ushort *) *xpp;
+#line 3260
+    }
+#line 3260
+   /* copy the next block */
+#line 3260
+#pragma cdir loopcnt=LOOPCNT
+#line 3260
+#pragma cdir shortloop
+#line 3260
+    for (i=0; i<ni; i++) {
+#line 3260
+      /* the normal case: */
+#line 3260
+      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
+#line 3260
+     /* test for range errors (not always needed but do it anyway) */
+#line 3260
+     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
+#line 3260
+     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
+#line 3260
+      nrange += tp[i] > X_USHORT_MAX ;
+#line 3260
+    }
+#line 3260
+   /* copy workspace back if necessary */
+#line 3260
+    if (realign) {
+#line 3260
+      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
+#line 3260
+      xp = (ushort *) *xpp;
+#line 3260
+    }
+#line 3260
+   /* update xpp and tp */
+#line 3260
+    xp += ni;
+#line 3260
+    tp += ni;
+#line 3260
+    *xpp = (void*)xp;
+#line 3260
+  }
+#line 3260
+  return nrange == 0 ? NC_NOERR : NC_ERANGE;
 #line 3260
 
 #line 3260
-	if (rndup != 0)
+#else   /* not SX */
+#line 3260
+
+#line 3260
+	char *xp = (char *) *xpp;
+#line 3260
+	int status = NC_NOERR;
+#line 3260
+
+#line 3260
+	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
 #line 3260
 	{
 #line 3260
-		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+		int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
 #line 3260
-		xp += X_SIZEOF_USHORT;
+		if (status == NC_NOERR) /* report the first encountered error */
+#line 3260
+			status = lstatus;
 #line 3260
 	}
 #line 3260
@@ -21091,110 +20807,154 @@ ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fill
 #line 3260
 	return status;
 #line 3260
+#endif
+#line 3260
 }
 #line 3260
 
 int
 #line 3261
-ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
+ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
 #line 3261
 {
 #line 3261
-	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
 #line 3261
 
 #line 3261
-	char *xp = (char *) *xpp;
+ /* basic algorithm is:
 #line 3261
-	int status = NC_NOERR;
+  *   - ensure sane alignment of output data
 #line 3261
-
+  *   - copy (conversion happens automatically) input data
 #line 3261
-	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+  *     to output
 #line 3261
-	{
+  *   - update tp to point at next unconverted input, and xpp to point
 #line 3261
-		int lstatus = ncx_put_ushort_int(xp, tp, fillp);
+  *     at next location for converted output
 #line 3261
-		if (status == NC_NOERR) /* report the first encountered error */
+  */
 #line 3261
-			status = lstatus;
+  long i, j, ni;
 #line 3261
-	}
+  ushort tmp[LOOPCNT];        /* in case input is misaligned */
+#line 3261
+  ushort *xp;
+#line 3261
+  int nrange = 0;         /* number of range errors */
+#line 3261
+  int realign = 0;        /* "do we need to fix input data alignment?" */
+#line 3261
+  long cxp = (long) *((char**)xpp);
 #line 3261
 
 #line 3261
-	if (rndup != 0)
+  realign = (cxp & 7) % SIZEOF_USHORT;
 #line 3261
-	{
+  /* sjl: manually stripmine so we can limit amount of
 #line 3261
-		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+   * vector work space reserved to LOOPCNT elements. Also
 #line 3261
-		xp += X_SIZEOF_USHORT;
+   * makes vectorisation easy */
 #line 3261
-	}
+  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
 #line 3261
-
+    ni=Min(nelems-j,LOOPCNT);
 #line 3261
-	*xpp = (void *)xp;
+    if (realign) {
 #line 3261
-	return status;
+      xp = tmp;
 #line 3261
-}
+    } else {
+#line 3261
+      xp = (ushort *) *xpp;
+#line 3261
+    }
+#line 3261
+   /* copy the next block */
+#line 3261
+#pragma cdir loopcnt=LOOPCNT
+#line 3261
+#pragma cdir shortloop
+#line 3261
+    for (i=0; i<ni; i++) {
+#line 3261
+      /* the normal case: */
+#line 3261
+      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
+#line 3261
+     /* test for range errors (not always needed but do it anyway) */
+#line 3261
+     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
+#line 3261
+     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
+#line 3261
+      nrange += tp[i] > X_USHORT_MAX ;
+#line 3261
+    }
+#line 3261
+   /* copy workspace back if necessary */
+#line 3261
+    if (realign) {
+#line 3261
+      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
+#line 3261
+      xp = (ushort *) *xpp;
+#line 3261
+    }
+#line 3261
+   /* update xpp and tp */
+#line 3261
+    xp += ni;
+#line 3261
+    tp += ni;
+#line 3261
+    *xpp = (void*)xp;
+#line 3261
+  }
+#line 3261
+  return nrange == 0 ? NC_NOERR : NC_ERANGE;
 #line 3261
 
-int
-#line 3262
-ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3262
-{
-#line 3262
-	const size_t rndup = nelems % X_SIZEOF_SHORT;
-#line 3262
+#line 3261
+#else   /* not SX */
+#line 3261
 
-#line 3262
+#line 3261
 	char *xp = (char *) *xpp;
-#line 3262
+#line 3261
 	int status = NC_NOERR;
-#line 3262
+#line 3261
 
-#line 3262
+#line 3261
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
-#line 3262
+#line 3261
 	{
-#line 3262
-		int lstatus = ncx_put_ushort_long(xp, tp, fillp);
-#line 3262
+#line 3261
+		int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
+#line 3261
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3262
+#line 3261
 			status = lstatus;
-#line 3262
-	}
-#line 3262
-
-#line 3262
-	if (rndup != 0)
-#line 3262
-	{
-#line 3262
-		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
-#line 3262
-		xp += X_SIZEOF_USHORT;
-#line 3262
+#line 3261
 	}
-#line 3262
+#line 3261
 
-#line 3262
+#line 3261
 	*xpp = (void *)xp;
-#line 3262
+#line 3261
 	return status;
-#line 3262
+#line 3261
+#endif
+#line 3261
 }
-#line 3262
+#line 3261
+
 
 int
 #line 3263
-ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
+ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
 #line 3263
 {
 #line 3263
@@ -21212,7 +20972,7 @@ ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fill
 #line 3263
 	{
 #line 3263
-		int lstatus = ncx_put_ushort_float(xp, tp, fillp);
+		int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
 #line 3263
 		if (status == NC_NOERR) /* report the first encountered error */
 #line 3263
@@ -21243,7 +21003,7 @@ ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fill
 
 int
 #line 3264
-ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
+ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
 #line 3264
 {
 #line 3264
@@ -21261,7 +21021,7 @@ ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fi
 #line 3264
 	{
 #line 3264
-		int lstatus = ncx_put_ushort_double(xp, tp, fillp);
+		int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
 #line 3264
 		if (status == NC_NOERR) /* report the first encountered error */
 #line 3264
@@ -21292,7 +21052,7 @@ ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fi
 
 int
 #line 3265
-ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
+ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
 #line 3265
 {
 #line 3265
@@ -21310,7 +21070,7 @@ ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 #line 3265
 	{
 #line 3265
-		int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
+		int lstatus = ncx_put_ushort_short(xp, tp, fillp);
 #line 3265
 		if (status == NC_NOERR) /* report the first encountered error */
 #line 3265
@@ -21341,7 +21101,7 @@ ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
 
 int
 #line 3266
-ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
+ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
 #line 3266
 {
 #line 3266
@@ -21359,7 +21119,7 @@ ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void
 #line 3266
 	{
 #line 3266
-		int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
+		int lstatus = ncx_put_ushort_int(xp, tp, fillp);
 #line 3266
 		if (status == NC_NOERR) /* report the first encountered error */
 #line 3266
@@ -21390,7 +21150,7 @@ ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void
 
 int
 #line 3267
-ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
+ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
 #line 3267
 {
 #line 3267
@@ -21408,7 +21168,7 @@ ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, vo
 #line 3267
 	{
 #line 3267
-		int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
+		int lstatus = ncx_put_ushort_long(xp, tp, fillp);
 #line 3267
 		if (status == NC_NOERR) /* report the first encountered error */
 #line 3267
@@ -21439,7 +21199,7 @@ ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, vo
 
 int
 #line 3268
-ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
+ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
 #line 3268
 {
 #line 3268
@@ -21457,7 +21217,7 @@ ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fi
 #line 3268
 	{
 #line 3268
-		int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
+		int lstatus = ncx_put_ushort_float(xp, tp, fillp);
 #line 3268
 		if (status == NC_NOERR) /* report the first encountered error */
 #line 3268
@@ -21486,6 +21246,251 @@ ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fi
 }
 #line 3268
 
+int
+#line 3269
+ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
+#line 3269
+{
+#line 3269
+	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#line 3269
+
+#line 3269
+	char *xp = (char *) *xpp;
+#line 3269
+	int status = NC_NOERR;
+#line 3269
+
+#line 3269
+	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+#line 3269
+	{
+#line 3269
+		int lstatus = ncx_put_ushort_double(xp, tp, fillp);
+#line 3269
+		if (status == NC_NOERR) /* report the first encountered error */
+#line 3269
+			status = lstatus;
+#line 3269
+	}
+#line 3269
+
+#line 3269
+	if (rndup != 0)
+#line 3269
+	{
+#line 3269
+		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+#line 3269
+		xp += X_SIZEOF_USHORT;
+#line 3269
+	}
+#line 3269
+
+#line 3269
+	*xpp = (void *)xp;
+#line 3269
+	return status;
+#line 3269
+}
+#line 3269
+
+int
+#line 3270
+ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
+#line 3270
+{
+#line 3270
+	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#line 3270
+
+#line 3270
+	char *xp = (char *) *xpp;
+#line 3270
+	int status = NC_NOERR;
+#line 3270
+
+#line 3270
+	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+#line 3270
+	{
+#line 3270
+		int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
+#line 3270
+		if (status == NC_NOERR) /* report the first encountered error */
+#line 3270
+			status = lstatus;
+#line 3270
+	}
+#line 3270
+
+#line 3270
+	if (rndup != 0)
+#line 3270
+	{
+#line 3270
+		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+#line 3270
+		xp += X_SIZEOF_USHORT;
+#line 3270
+	}
+#line 3270
+
+#line 3270
+	*xpp = (void *)xp;
+#line 3270
+	return status;
+#line 3270
+}
+#line 3270
+
+int
+#line 3271
+ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
+#line 3271
+{
+#line 3271
+	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#line 3271
+
+#line 3271
+	char *xp = (char *) *xpp;
+#line 3271
+	int status = NC_NOERR;
+#line 3271
+
+#line 3271
+	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+#line 3271
+	{
+#line 3271
+		int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
+#line 3271
+		if (status == NC_NOERR) /* report the first encountered error */
+#line 3271
+			status = lstatus;
+#line 3271
+	}
+#line 3271
+
+#line 3271
+	if (rndup != 0)
+#line 3271
+	{
+#line 3271
+		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+#line 3271
+		xp += X_SIZEOF_USHORT;
+#line 3271
+	}
+#line 3271
+
+#line 3271
+	*xpp = (void *)xp;
+#line 3271
+	return status;
+#line 3271
+}
+#line 3271
+
+int
+#line 3272
+ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
+#line 3272
+{
+#line 3272
+	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#line 3272
+
+#line 3272
+	char *xp = (char *) *xpp;
+#line 3272
+	int status = NC_NOERR;
+#line 3272
+
+#line 3272
+	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+#line 3272
+	{
+#line 3272
+		int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
+#line 3272
+		if (status == NC_NOERR) /* report the first encountered error */
+#line 3272
+			status = lstatus;
+#line 3272
+	}
+#line 3272
+
+#line 3272
+	if (rndup != 0)
+#line 3272
+	{
+#line 3272
+		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+#line 3272
+		xp += X_SIZEOF_USHORT;
+#line 3272
+	}
+#line 3272
+
+#line 3272
+	*xpp = (void *)xp;
+#line 3272
+	return status;
+#line 3272
+}
+#line 3272
+
+int
+#line 3273
+ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
+#line 3273
+{
+#line 3273
+	const size_t rndup = nelems % X_SIZEOF_SHORT;
+#line 3273
+
+#line 3273
+	char *xp = (char *) *xpp;
+#line 3273
+	int status = NC_NOERR;
+#line 3273
+
+#line 3273
+	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
+#line 3273
+	{
+#line 3273
+		int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
+#line 3273
+		if (status == NC_NOERR) /* report the first encountered error */
+#line 3273
+			status = lstatus;
+#line 3273
+	}
+#line 3273
+
+#line 3273
+	if (rndup != 0)
+#line 3273
+	{
+#line 3273
+		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
+#line 3273
+		xp += X_SIZEOF_USHORT;
+#line 3273
+	}
+#line 3273
+
+#line 3273
+	*xpp = (void *)xp;
+#line 3273
+	return status;
+#line 3273
+}
+#line 3273
+
 
 
 /* int -----------------------------------------------------------------------*/
@@ -21505,1424 +21510,1424 @@ ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
 }
 #else
 int
-#line 3287
+#line 3292
 ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
-#line 3287
+#line 3292
 {
-#line 3287
+#line 3292
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3287
+#line 3292
 
-#line 3287
+#line 3292
  /* basic algorithm is:
-#line 3287
+#line 3292
   *   - ensure sane alignment of input data
-#line 3287
+#line 3292
   *   - copy (conversion happens automatically) input data
-#line 3287
+#line 3292
   *     to output
-#line 3287
+#line 3292
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3287
+#line 3292
   *     at next location for converted output
-#line 3287
+#line 3292
   */
-#line 3287
+#line 3292
   long i, j, ni;
-#line 3287
+#line 3292
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3287
+#line 3292
   int *xp;
-#line 3287
+#line 3292
   int nrange = 0;         /* number of range errors */
-#line 3287
+#line 3292
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3287
+#line 3292
   long cxp = (long) *((char**)xpp);
-#line 3287
+#line 3292
 
-#line 3287
+#line 3292
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3287
+#line 3292
   /* sjl: manually stripmine so we can limit amount of
-#line 3287
+#line 3292
    * vector work space reserved to LOOPCNT elements. Also
-#line 3287
+#line 3292
    * makes vectorisation easy */
-#line 3287
+#line 3292
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3287
+#line 3292
     ni=Min(nelems-j,LOOPCNT);
-#line 3287
+#line 3292
     if (realign) {
-#line 3287
+#line 3292
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3287
+#line 3292
       xp = tmp;
-#line 3287
+#line 3292
     } else {
-#line 3287
+#line 3292
       xp = (int *) *xpp;
-#line 3287
+#line 3292
     }
-#line 3287
+#line 3292
    /* copy the next block */
-#line 3287
+#line 3292
 #pragma cdir loopcnt=LOOPCNT
-#line 3287
+#line 3292
 #pragma cdir shortloop
-#line 3287
+#line 3292
     for (i=0; i<ni; i++) {
-#line 3287
+#line 3292
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3287
+#line 3292
      /* test for range errors (not always needed but do it anyway) */
-#line 3287
+#line 3292
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3287
+#line 3292
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3287
+#line 3292
       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
-#line 3287
+#line 3292
     }
-#line 3287
+#line 3292
    /* update xpp and tp */
-#line 3287
+#line 3292
     if (realign) xp = (int *) *xpp;
-#line 3287
+#line 3292
     xp += ni;
-#line 3287
+#line 3292
     tp += ni;
-#line 3287
+#line 3292
     *xpp = (void*)xp;
-#line 3287
+#line 3292
   }
-#line 3287
+#line 3292
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3287
+#line 3292
 
-#line 3287
+#line 3292
 #else   /* not SX */
-#line 3287
+#line 3292
 	const char *xp = (const char *) *xpp;
-#line 3287
+#line 3292
 	int status = NC_NOERR;
-#line 3287
+#line 3292
 
-#line 3287
+#line 3292
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3287
+#line 3292
 	{
-#line 3287
+#line 3292
 		const int lstatus = ncx_get_int_int(xp, tp);
-#line 3287
+#line 3292
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3287
+#line 3292
 			status = lstatus;
-#line 3287
+#line 3292
 	}
-#line 3287
+#line 3292
 
-#line 3287
+#line 3292
 	*xpp = (const void *)xp;
-#line 3287
+#line 3292
 	return status;
-#line 3287
+#line 3292
 #endif
-#line 3287
+#line 3292
 }
-#line 3287
+#line 3292
 
 #endif
 int
-#line 3289
+#line 3294
 ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3289
+#line 3294
 {
-#line 3289
+#line 3294
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3289
+#line 3294
 
-#line 3289
+#line 3294
  /* basic algorithm is:
-#line 3289
+#line 3294
   *   - ensure sane alignment of input data
-#line 3289
+#line 3294
   *   - copy (conversion happens automatically) input data
-#line 3289
+#line 3294
   *     to output
-#line 3289
+#line 3294
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3289
+#line 3294
   *     at next location for converted output
-#line 3289
+#line 3294
   */
-#line 3289
+#line 3294
   long i, j, ni;
-#line 3289
+#line 3294
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3289
+#line 3294
   int *xp;
-#line 3289
+#line 3294
   int nrange = 0;         /* number of range errors */
-#line 3289
+#line 3294
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3289
+#line 3294
   long cxp = (long) *((char**)xpp);
-#line 3289
+#line 3294
 
-#line 3289
+#line 3294
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3289
+#line 3294
   /* sjl: manually stripmine so we can limit amount of
-#line 3289
+#line 3294
    * vector work space reserved to LOOPCNT elements. Also
-#line 3289
+#line 3294
    * makes vectorisation easy */
-#line 3289
+#line 3294
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3289
+#line 3294
     ni=Min(nelems-j,LOOPCNT);
-#line 3289
+#line 3294
     if (realign) {
-#line 3289
+#line 3294
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3289
+#line 3294
       xp = tmp;
-#line 3289
+#line 3294
     } else {
-#line 3289
+#line 3294
       xp = (int *) *xpp;
-#line 3289
+#line 3294
     }
-#line 3289
+#line 3294
    /* copy the next block */
-#line 3289
+#line 3294
 #pragma cdir loopcnt=LOOPCNT
-#line 3289
+#line 3294
 #pragma cdir shortloop
-#line 3289
+#line 3294
     for (i=0; i<ni; i++) {
-#line 3289
+#line 3294
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3289
+#line 3294
      /* test for range errors (not always needed but do it anyway) */
-#line 3289
+#line 3294
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3289
+#line 3294
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3289
+#line 3294
       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
-#line 3289
+#line 3294
     }
-#line 3289
+#line 3294
    /* update xpp and tp */
-#line 3289
+#line 3294
     if (realign) xp = (int *) *xpp;
-#line 3289
+#line 3294
     xp += ni;
-#line 3289
+#line 3294
     tp += ni;
-#line 3289
+#line 3294
     *xpp = (void*)xp;
-#line 3289
+#line 3294
   }
-#line 3289
+#line 3294
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3289
+#line 3294
 
-#line 3289
+#line 3294
 #else   /* not SX */
-#line 3289
+#line 3294
 	const char *xp = (const char *) *xpp;
-#line 3289
+#line 3294
 	int status = NC_NOERR;
-#line 3289
+#line 3294
 
-#line 3289
+#line 3294
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3289
+#line 3294
 	{
-#line 3289
+#line 3294
 		const int lstatus = ncx_get_int_schar(xp, tp);
-#line 3289
+#line 3294
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3289
+#line 3294
 			status = lstatus;
-#line 3289
+#line 3294
 	}
-#line 3289
+#line 3294
 
-#line 3289
+#line 3294
 	*xpp = (const void *)xp;
-#line 3289
+#line 3294
 	return status;
-#line 3289
+#line 3294
 #endif
-#line 3289
+#line 3294
 }
-#line 3289
+#line 3294
 
 int
-#line 3290
+#line 3295
 ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
-#line 3290
+#line 3295
 {
-#line 3290
+#line 3295
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3290
+#line 3295
 
-#line 3290
+#line 3295
  /* basic algorithm is:
-#line 3290
+#line 3295
   *   - ensure sane alignment of input data
-#line 3290
+#line 3295
   *   - copy (conversion happens automatically) input data
-#line 3290
+#line 3295
   *     to output
-#line 3290
+#line 3295
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3290
+#line 3295
   *     at next location for converted output
-#line 3290
+#line 3295
   */
-#line 3290
+#line 3295
   long i, j, ni;
-#line 3290
+#line 3295
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3290
+#line 3295
   int *xp;
-#line 3290
+#line 3295
   int nrange = 0;         /* number of range errors */
-#line 3290
+#line 3295
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3290
+#line 3295
   long cxp = (long) *((char**)xpp);
-#line 3290
+#line 3295
 
-#line 3290
+#line 3295
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3290
+#line 3295
   /* sjl: manually stripmine so we can limit amount of
-#line 3290
+#line 3295
    * vector work space reserved to LOOPCNT elements. Also
-#line 3290
+#line 3295
    * makes vectorisation easy */
-#line 3290
+#line 3295
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3290
+#line 3295
     ni=Min(nelems-j,LOOPCNT);
-#line 3290
+#line 3295
     if (realign) {
-#line 3290
+#line 3295
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3290
+#line 3295
       xp = tmp;
-#line 3290
+#line 3295
     } else {
-#line 3290
+#line 3295
       xp = (int *) *xpp;
-#line 3290
+#line 3295
     }
-#line 3290
+#line 3295
    /* copy the next block */
-#line 3290
+#line 3295
 #pragma cdir loopcnt=LOOPCNT
-#line 3290
+#line 3295
 #pragma cdir shortloop
-#line 3290
+#line 3295
     for (i=0; i<ni; i++) {
-#line 3290
+#line 3295
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3290
+#line 3295
      /* test for range errors (not always needed but do it anyway) */
-#line 3290
+#line 3295
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3290
+#line 3295
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3290
+#line 3295
       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
-#line 3290
+#line 3295
     }
-#line 3290
+#line 3295
    /* update xpp and tp */
-#line 3290
+#line 3295
     if (realign) xp = (int *) *xpp;
-#line 3290
+#line 3295
     xp += ni;
-#line 3290
+#line 3295
     tp += ni;
-#line 3290
+#line 3295
     *xpp = (void*)xp;
-#line 3290
+#line 3295
   }
-#line 3290
+#line 3295
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3290
+#line 3295
 
-#line 3290
+#line 3295
 #else   /* not SX */
-#line 3290
+#line 3295
 	const char *xp = (const char *) *xpp;
-#line 3290
+#line 3295
 	int status = NC_NOERR;
-#line 3290
+#line 3295
 
-#line 3290
+#line 3295
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3290
+#line 3295
 	{
-#line 3290
+#line 3295
 		const int lstatus = ncx_get_int_short(xp, tp);
-#line 3290
+#line 3295
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3290
+#line 3295
 			status = lstatus;
-#line 3290
+#line 3295
 	}
-#line 3290
+#line 3295
 
-#line 3290
+#line 3295
 	*xpp = (const void *)xp;
-#line 3290
+#line 3295
 	return status;
-#line 3290
+#line 3295
 #endif
-#line 3290
+#line 3295
 }
-#line 3290
+#line 3295
 
 int
-#line 3291
+#line 3296
 ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
-#line 3291
+#line 3296
 {
-#line 3291
+#line 3296
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3291
+#line 3296
 
-#line 3291
+#line 3296
  /* basic algorithm is:
-#line 3291
+#line 3296
   *   - ensure sane alignment of input data
-#line 3291
+#line 3296
   *   - copy (conversion happens automatically) input data
-#line 3291
+#line 3296
   *     to output
-#line 3291
+#line 3296
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3291
+#line 3296
   *     at next location for converted output
-#line 3291
+#line 3296
   */
-#line 3291
+#line 3296
   long i, j, ni;
-#line 3291
+#line 3296
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3291
+#line 3296
   int *xp;
-#line 3291
+#line 3296
   int nrange = 0;         /* number of range errors */
-#line 3291
+#line 3296
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3291
+#line 3296
   long cxp = (long) *((char**)xpp);
-#line 3291
+#line 3296
 
-#line 3291
+#line 3296
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3291
+#line 3296
   /* sjl: manually stripmine so we can limit amount of
-#line 3291
+#line 3296
    * vector work space reserved to LOOPCNT elements. Also
-#line 3291
+#line 3296
    * makes vectorisation easy */
-#line 3291
+#line 3296
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3291
+#line 3296
     ni=Min(nelems-j,LOOPCNT);
-#line 3291
+#line 3296
     if (realign) {
-#line 3291
+#line 3296
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3291
+#line 3296
       xp = tmp;
-#line 3291
+#line 3296
     } else {
-#line 3291
+#line 3296
       xp = (int *) *xpp;
-#line 3291
+#line 3296
     }
-#line 3291
+#line 3296
    /* copy the next block */
-#line 3291
+#line 3296
 #pragma cdir loopcnt=LOOPCNT
-#line 3291
+#line 3296
 #pragma cdir shortloop
-#line 3291
+#line 3296
     for (i=0; i<ni; i++) {
-#line 3291
+#line 3296
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3291
+#line 3296
      /* test for range errors (not always needed but do it anyway) */
-#line 3291
+#line 3296
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3291
+#line 3296
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3291
+#line 3296
       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
-#line 3291
+#line 3296
     }
-#line 3291
+#line 3296
    /* update xpp and tp */
-#line 3291
+#line 3296
     if (realign) xp = (int *) *xpp;
-#line 3291
+#line 3296
     xp += ni;
-#line 3291
+#line 3296
     tp += ni;
-#line 3291
+#line 3296
     *xpp = (void*)xp;
-#line 3291
+#line 3296
   }
-#line 3291
+#line 3296
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3291
+#line 3296
 
-#line 3291
+#line 3296
 #else   /* not SX */
-#line 3291
+#line 3296
 	const char *xp = (const char *) *xpp;
-#line 3291
+#line 3296
 	int status = NC_NOERR;
-#line 3291
+#line 3296
 
-#line 3291
+#line 3296
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3291
+#line 3296
 	{
-#line 3291
+#line 3296
 		const int lstatus = ncx_get_int_long(xp, tp);
-#line 3291
+#line 3296
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3291
+#line 3296
 			status = lstatus;
-#line 3291
+#line 3296
 	}
-#line 3291
+#line 3296
 
-#line 3291
+#line 3296
 	*xpp = (const void *)xp;
-#line 3291
+#line 3296
 	return status;
-#line 3291
+#line 3296
 #endif
-#line 3291
+#line 3296
 }
-#line 3291
+#line 3296
 
 int
-#line 3292
+#line 3297
 ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
-#line 3292
+#line 3297
 {
-#line 3292
+#line 3297
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3292
+#line 3297
 
-#line 3292
+#line 3297
  /* basic algorithm is:
-#line 3292
+#line 3297
   *   - ensure sane alignment of input data
-#line 3292
+#line 3297
   *   - copy (conversion happens automatically) input data
-#line 3292
+#line 3297
   *     to output
-#line 3292
+#line 3297
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3292
+#line 3297
   *     at next location for converted output
-#line 3292
+#line 3297
   */
-#line 3292
+#line 3297
   long i, j, ni;
-#line 3292
+#line 3297
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3292
+#line 3297
   int *xp;
-#line 3292
+#line 3297
   int nrange = 0;         /* number of range errors */
-#line 3292
+#line 3297
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3292
+#line 3297
   long cxp = (long) *((char**)xpp);
-#line 3292
+#line 3297
 
-#line 3292
+#line 3297
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3292
+#line 3297
   /* sjl: manually stripmine so we can limit amount of
-#line 3292
+#line 3297
    * vector work space reserved to LOOPCNT elements. Also
-#line 3292
+#line 3297
    * makes vectorisation easy */
-#line 3292
+#line 3297
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3292
+#line 3297
     ni=Min(nelems-j,LOOPCNT);
-#line 3292
+#line 3297
     if (realign) {
-#line 3292
+#line 3297
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3292
+#line 3297
       xp = tmp;
-#line 3292
+#line 3297
     } else {
-#line 3292
+#line 3297
       xp = (int *) *xpp;
-#line 3292
+#line 3297
     }
-#line 3292
+#line 3297
    /* copy the next block */
-#line 3292
+#line 3297
 #pragma cdir loopcnt=LOOPCNT
-#line 3292
+#line 3297
 #pragma cdir shortloop
-#line 3292
+#line 3297
     for (i=0; i<ni; i++) {
-#line 3292
+#line 3297
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3292
+#line 3297
      /* test for range errors (not always needed but do it anyway) */
-#line 3292
+#line 3297
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3292
+#line 3297
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3292
+#line 3297
       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
-#line 3292
+#line 3297
     }
-#line 3292
+#line 3297
    /* update xpp and tp */
-#line 3292
+#line 3297
     if (realign) xp = (int *) *xpp;
-#line 3292
+#line 3297
     xp += ni;
-#line 3292
+#line 3297
     tp += ni;
-#line 3292
+#line 3297
     *xpp = (void*)xp;
-#line 3292
+#line 3297
   }
-#line 3292
+#line 3297
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3292
+#line 3297
 
-#line 3292
+#line 3297
 #else   /* not SX */
-#line 3292
+#line 3297
 	const char *xp = (const char *) *xpp;
-#line 3292
+#line 3297
 	int status = NC_NOERR;
-#line 3292
+#line 3297
 
-#line 3292
+#line 3297
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3292
+#line 3297
 	{
-#line 3292
+#line 3297
 		const int lstatus = ncx_get_int_float(xp, tp);
-#line 3292
+#line 3297
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3292
+#line 3297
 			status = lstatus;
-#line 3292
+#line 3297
 	}
-#line 3292
+#line 3297
 
-#line 3292
+#line 3297
 	*xpp = (const void *)xp;
-#line 3292
+#line 3297
 	return status;
-#line 3292
+#line 3297
 #endif
-#line 3292
+#line 3297
 }
-#line 3292
+#line 3297
 
 int
-#line 3293
+#line 3298
 ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
-#line 3293
+#line 3298
 {
-#line 3293
+#line 3298
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3293
+#line 3298
 
-#line 3293
+#line 3298
  /* basic algorithm is:
-#line 3293
+#line 3298
   *   - ensure sane alignment of input data
-#line 3293
+#line 3298
   *   - copy (conversion happens automatically) input data
-#line 3293
+#line 3298
   *     to output
-#line 3293
+#line 3298
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3293
+#line 3298
   *     at next location for converted output
-#line 3293
+#line 3298
   */
-#line 3293
+#line 3298
   long i, j, ni;
-#line 3293
+#line 3298
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3293
+#line 3298
   int *xp;
-#line 3293
+#line 3298
   int nrange = 0;         /* number of range errors */
-#line 3293
+#line 3298
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3293
+#line 3298
   long cxp = (long) *((char**)xpp);
-#line 3293
+#line 3298
 
-#line 3293
+#line 3298
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3293
+#line 3298
   /* sjl: manually stripmine so we can limit amount of
-#line 3293
+#line 3298
    * vector work space reserved to LOOPCNT elements. Also
-#line 3293
+#line 3298
    * makes vectorisation easy */
-#line 3293
+#line 3298
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3293
+#line 3298
     ni=Min(nelems-j,LOOPCNT);
-#line 3293
+#line 3298
     if (realign) {
-#line 3293
+#line 3298
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3293
+#line 3298
       xp = tmp;
-#line 3293
+#line 3298
     } else {
-#line 3293
+#line 3298
       xp = (int *) *xpp;
-#line 3293
+#line 3298
     }
-#line 3293
+#line 3298
    /* copy the next block */
-#line 3293
+#line 3298
 #pragma cdir loopcnt=LOOPCNT
-#line 3293
+#line 3298
 #pragma cdir shortloop
-#line 3293
+#line 3298
     for (i=0; i<ni; i++) {
-#line 3293
+#line 3298
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3293
+#line 3298
      /* test for range errors (not always needed but do it anyway) */
-#line 3293
+#line 3298
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3293
+#line 3298
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3293
+#line 3298
       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
-#line 3293
+#line 3298
     }
-#line 3293
+#line 3298
    /* update xpp and tp */
-#line 3293
+#line 3298
     if (realign) xp = (int *) *xpp;
-#line 3293
+#line 3298
     xp += ni;
-#line 3293
+#line 3298
     tp += ni;
-#line 3293
+#line 3298
     *xpp = (void*)xp;
-#line 3293
+#line 3298
   }
-#line 3293
+#line 3298
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3293
+#line 3298
 
-#line 3293
+#line 3298
 #else   /* not SX */
-#line 3293
+#line 3298
 	const char *xp = (const char *) *xpp;
-#line 3293
+#line 3298
 	int status = NC_NOERR;
-#line 3293
+#line 3298
 
-#line 3293
+#line 3298
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3293
+#line 3298
 	{
-#line 3293
+#line 3298
 		const int lstatus = ncx_get_int_double(xp, tp);
-#line 3293
+#line 3298
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3293
+#line 3298
 			status = lstatus;
-#line 3293
+#line 3298
 	}
-#line 3293
+#line 3298
 
-#line 3293
+#line 3298
 	*xpp = (const void *)xp;
-#line 3293
+#line 3298
 	return status;
-#line 3293
+#line 3298
 #endif
-#line 3293
+#line 3298
 }
-#line 3293
+#line 3298
 
 int
-#line 3294
+#line 3299
 ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3294
+#line 3299
 {
-#line 3294
+#line 3299
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3294
+#line 3299
 
-#line 3294
+#line 3299
  /* basic algorithm is:
-#line 3294
+#line 3299
   *   - ensure sane alignment of input data
-#line 3294
+#line 3299
   *   - copy (conversion happens automatically) input data
-#line 3294
+#line 3299
   *     to output
-#line 3294
+#line 3299
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3294
+#line 3299
   *     at next location for converted output
-#line 3294
+#line 3299
   */
-#line 3294
+#line 3299
   long i, j, ni;
-#line 3294
+#line 3299
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3294
+#line 3299
   int *xp;
-#line 3294
+#line 3299
   int nrange = 0;         /* number of range errors */
-#line 3294
+#line 3299
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3294
+#line 3299
   long cxp = (long) *((char**)xpp);
-#line 3294
+#line 3299
 
-#line 3294
+#line 3299
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3294
+#line 3299
   /* sjl: manually stripmine so we can limit amount of
-#line 3294
+#line 3299
    * vector work space reserved to LOOPCNT elements. Also
-#line 3294
+#line 3299
    * makes vectorisation easy */
-#line 3294
+#line 3299
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3294
+#line 3299
     ni=Min(nelems-j,LOOPCNT);
-#line 3294
+#line 3299
     if (realign) {
-#line 3294
+#line 3299
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3294
+#line 3299
       xp = tmp;
-#line 3294
+#line 3299
     } else {
-#line 3294
+#line 3299
       xp = (int *) *xpp;
-#line 3294
+#line 3299
     }
-#line 3294
+#line 3299
    /* copy the next block */
-#line 3294
+#line 3299
 #pragma cdir loopcnt=LOOPCNT
-#line 3294
+#line 3299
 #pragma cdir shortloop
-#line 3294
+#line 3299
     for (i=0; i<ni; i++) {
-#line 3294
+#line 3299
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3294
+#line 3299
      /* test for range errors (not always needed but do it anyway) */
-#line 3294
+#line 3299
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3294
+#line 3299
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3294
+#line 3299
       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
-#line 3294
+#line 3299
     }
-#line 3294
+#line 3299
    /* update xpp and tp */
-#line 3294
+#line 3299
     if (realign) xp = (int *) *xpp;
-#line 3294
+#line 3299
     xp += ni;
-#line 3294
+#line 3299
     tp += ni;
-#line 3294
+#line 3299
     *xpp = (void*)xp;
-#line 3294
+#line 3299
   }
-#line 3294
+#line 3299
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3294
+#line 3299
 
-#line 3294
+#line 3299
 #else   /* not SX */
-#line 3294
+#line 3299
 	const char *xp = (const char *) *xpp;
-#line 3294
+#line 3299
 	int status = NC_NOERR;
-#line 3294
+#line 3299
 
-#line 3294
+#line 3299
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3294
+#line 3299
 	{
-#line 3294
+#line 3299
 		const int lstatus = ncx_get_int_longlong(xp, tp);
-#line 3294
+#line 3299
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3294
+#line 3299
 			status = lstatus;
-#line 3294
+#line 3299
 	}
-#line 3294
+#line 3299
 
-#line 3294
+#line 3299
 	*xpp = (const void *)xp;
-#line 3294
+#line 3299
 	return status;
-#line 3294
+#line 3299
 #endif
-#line 3294
+#line 3299
 }
-#line 3294
+#line 3299
 
 int
-#line 3295
+#line 3300
 ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3295
+#line 3300
 {
-#line 3295
+#line 3300
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3295
+#line 3300
 
-#line 3295
+#line 3300
  /* basic algorithm is:
-#line 3295
+#line 3300
   *   - ensure sane alignment of input data
-#line 3295
+#line 3300
   *   - copy (conversion happens automatically) input data
-#line 3295
+#line 3300
   *     to output
-#line 3295
+#line 3300
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3295
+#line 3300
   *     at next location for converted output
-#line 3295
+#line 3300
   */
-#line 3295
+#line 3300
   long i, j, ni;
-#line 3295
+#line 3300
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3295
+#line 3300
   int *xp;
-#line 3295
+#line 3300
   int nrange = 0;         /* number of range errors */
-#line 3295
+#line 3300
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3295
+#line 3300
   long cxp = (long) *((char**)xpp);
-#line 3295
+#line 3300
 
-#line 3295
+#line 3300
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3295
+#line 3300
   /* sjl: manually stripmine so we can limit amount of
-#line 3295
+#line 3300
    * vector work space reserved to LOOPCNT elements. Also
-#line 3295
+#line 3300
    * makes vectorisation easy */
-#line 3295
+#line 3300
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3295
+#line 3300
     ni=Min(nelems-j,LOOPCNT);
-#line 3295
+#line 3300
     if (realign) {
-#line 3295
+#line 3300
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3295
+#line 3300
       xp = tmp;
-#line 3295
+#line 3300
     } else {
-#line 3295
+#line 3300
       xp = (int *) *xpp;
-#line 3295
+#line 3300
     }
-#line 3295
+#line 3300
    /* copy the next block */
-#line 3295
+#line 3300
 #pragma cdir loopcnt=LOOPCNT
-#line 3295
+#line 3300
 #pragma cdir shortloop
-#line 3295
+#line 3300
     for (i=0; i<ni; i++) {
-#line 3295
+#line 3300
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3295
+#line 3300
      /* test for range errors (not always needed but do it anyway) */
-#line 3295
+#line 3300
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3295
+#line 3300
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3295
+#line 3300
       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
-#line 3295
+#line 3300
     }
-#line 3295
+#line 3300
    /* update xpp and tp */
-#line 3295
+#line 3300
     if (realign) xp = (int *) *xpp;
-#line 3295
+#line 3300
     xp += ni;
-#line 3295
+#line 3300
     tp += ni;
-#line 3295
+#line 3300
     *xpp = (void*)xp;
-#line 3295
+#line 3300
   }
-#line 3295
+#line 3300
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3295
+#line 3300
 
-#line 3295
+#line 3300
 #else   /* not SX */
-#line 3295
+#line 3300
 	const char *xp = (const char *) *xpp;
-#line 3295
+#line 3300
 	int status = NC_NOERR;
-#line 3295
+#line 3300
 
-#line 3295
+#line 3300
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3295
+#line 3300
 	{
-#line 3295
+#line 3300
 		const int lstatus = ncx_get_int_uchar(xp, tp);
-#line 3295
+#line 3300
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3295
+#line 3300
 			status = lstatus;
-#line 3295
+#line 3300
 	}
-#line 3295
+#line 3300
 
-#line 3295
+#line 3300
 	*xpp = (const void *)xp;
-#line 3295
+#line 3300
 	return status;
-#line 3295
+#line 3300
 #endif
-#line 3295
+#line 3300
 }
-#line 3295
+#line 3300
 
 int
-#line 3296
+#line 3301
 ncx_getn_int_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3296
+#line 3301
 {
-#line 3296
+#line 3301
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3296
+#line 3301
 
-#line 3296
+#line 3301
  /* basic algorithm is:
-#line 3296
+#line 3301
   *   - ensure sane alignment of input data
-#line 3296
+#line 3301
   *   - copy (conversion happens automatically) input data
-#line 3296
+#line 3301
   *     to output
-#line 3296
+#line 3301
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3296
+#line 3301
   *     at next location for converted output
-#line 3296
+#line 3301
   */
-#line 3296
+#line 3301
   long i, j, ni;
-#line 3296
+#line 3301
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3296
+#line 3301
   int *xp;
-#line 3296
+#line 3301
   int nrange = 0;         /* number of range errors */
-#line 3296
+#line 3301
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3296
+#line 3301
   long cxp = (long) *((char**)xpp);
-#line 3296
+#line 3301
 
-#line 3296
+#line 3301
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3296
+#line 3301
   /* sjl: manually stripmine so we can limit amount of
-#line 3296
+#line 3301
    * vector work space reserved to LOOPCNT elements. Also
-#line 3296
+#line 3301
    * makes vectorisation easy */
-#line 3296
+#line 3301
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3296
+#line 3301
     ni=Min(nelems-j,LOOPCNT);
-#line 3296
+#line 3301
     if (realign) {
-#line 3296
+#line 3301
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3296
+#line 3301
       xp = tmp;
-#line 3296
+#line 3301
     } else {
-#line 3296
+#line 3301
       xp = (int *) *xpp;
-#line 3296
+#line 3301
     }
-#line 3296
+#line 3301
    /* copy the next block */
-#line 3296
+#line 3301
 #pragma cdir loopcnt=LOOPCNT
-#line 3296
+#line 3301
 #pragma cdir shortloop
-#line 3296
+#line 3301
     for (i=0; i<ni; i++) {
-#line 3296
+#line 3301
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3296
+#line 3301
      /* test for range errors (not always needed but do it anyway) */
-#line 3296
+#line 3301
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3296
+#line 3301
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3296
+#line 3301
       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
-#line 3296
+#line 3301
     }
-#line 3296
+#line 3301
    /* update xpp and tp */
-#line 3296
+#line 3301
     if (realign) xp = (int *) *xpp;
-#line 3296
+#line 3301
     xp += ni;
-#line 3296
+#line 3301
     tp += ni;
-#line 3296
+#line 3301
     *xpp = (void*)xp;
-#line 3296
+#line 3301
   }
-#line 3296
+#line 3301
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3296
+#line 3301
 
-#line 3296
+#line 3301
 #else   /* not SX */
-#line 3296
+#line 3301
 	const char *xp = (const char *) *xpp;
-#line 3296
+#line 3301
 	int status = NC_NOERR;
-#line 3296
+#line 3301
 
-#line 3296
+#line 3301
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3296
+#line 3301
 	{
-#line 3296
+#line 3301
 		const int lstatus = ncx_get_int_ushort(xp, tp);
-#line 3296
+#line 3301
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3296
+#line 3301
 			status = lstatus;
-#line 3296
+#line 3301
 	}
-#line 3296
+#line 3301
 
-#line 3296
+#line 3301
 	*xpp = (const void *)xp;
-#line 3296
+#line 3301
 	return status;
-#line 3296
+#line 3301
 #endif
-#line 3296
+#line 3301
 }
-#line 3296
+#line 3301
 
 int
-#line 3297
+#line 3302
 ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3297
+#line 3302
 {
-#line 3297
+#line 3302
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3297
+#line 3302
 
-#line 3297
+#line 3302
  /* basic algorithm is:
-#line 3297
+#line 3302
   *   - ensure sane alignment of input data
-#line 3297
+#line 3302
   *   - copy (conversion happens automatically) input data
-#line 3297
+#line 3302
   *     to output
-#line 3297
+#line 3302
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3297
+#line 3302
   *     at next location for converted output
-#line 3297
+#line 3302
   */
-#line 3297
+#line 3302
   long i, j, ni;
-#line 3297
+#line 3302
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3297
+#line 3302
   int *xp;
-#line 3297
+#line 3302
   int nrange = 0;         /* number of range errors */
-#line 3297
+#line 3302
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3297
+#line 3302
   long cxp = (long) *((char**)xpp);
-#line 3297
+#line 3302
 
-#line 3297
+#line 3302
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3297
+#line 3302
   /* sjl: manually stripmine so we can limit amount of
-#line 3297
+#line 3302
    * vector work space reserved to LOOPCNT elements. Also
-#line 3297
+#line 3302
    * makes vectorisation easy */
-#line 3297
+#line 3302
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3297
+#line 3302
     ni=Min(nelems-j,LOOPCNT);
-#line 3297
+#line 3302
     if (realign) {
-#line 3297
+#line 3302
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3297
+#line 3302
       xp = tmp;
-#line 3297
+#line 3302
     } else {
-#line 3297
+#line 3302
       xp = (int *) *xpp;
-#line 3297
+#line 3302
     }
-#line 3297
+#line 3302
    /* copy the next block */
-#line 3297
+#line 3302
 #pragma cdir loopcnt=LOOPCNT
-#line 3297
+#line 3302
 #pragma cdir shortloop
-#line 3297
+#line 3302
     for (i=0; i<ni; i++) {
-#line 3297
+#line 3302
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3297
+#line 3302
      /* test for range errors (not always needed but do it anyway) */
-#line 3297
+#line 3302
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3297
+#line 3302
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3297
+#line 3302
       nrange += xp[i] > UINT_MAX || xp[i] < 0;
-#line 3297
+#line 3302
     }
-#line 3297
+#line 3302
    /* update xpp and tp */
-#line 3297
+#line 3302
     if (realign) xp = (int *) *xpp;
-#line 3297
+#line 3302
     xp += ni;
-#line 3297
+#line 3302
     tp += ni;
-#line 3297
+#line 3302
     *xpp = (void*)xp;
-#line 3297
+#line 3302
   }
-#line 3297
+#line 3302
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3297
+#line 3302
 
-#line 3297
+#line 3302
 #else   /* not SX */
-#line 3297
+#line 3302
 	const char *xp = (const char *) *xpp;
-#line 3297
+#line 3302
 	int status = NC_NOERR;
-#line 3297
+#line 3302
 
-#line 3297
+#line 3302
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3297
+#line 3302
 	{
-#line 3297
+#line 3302
 		const int lstatus = ncx_get_int_uint(xp, tp);
-#line 3297
+#line 3302
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3297
+#line 3302
 			status = lstatus;
-#line 3297
+#line 3302
 	}
-#line 3297
+#line 3302
 
-#line 3297
+#line 3302
 	*xpp = (const void *)xp;
-#line 3297
+#line 3302
 	return status;
-#line 3297
+#line 3302
 #endif
-#line 3297
+#line 3302
 }
-#line 3297
+#line 3302
 
 int
-#line 3298
+#line 3303
 ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3298
+#line 3303
 {
-#line 3298
+#line 3303
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3298
+#line 3303
 
-#line 3298
+#line 3303
  /* basic algorithm is:
-#line 3298
+#line 3303
   *   - ensure sane alignment of input data
-#line 3298
+#line 3303
   *   - copy (conversion happens automatically) input data
-#line 3298
+#line 3303
   *     to output
-#line 3298
+#line 3303
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3298
+#line 3303
   *     at next location for converted output
-#line 3298
+#line 3303
   */
-#line 3298
+#line 3303
   long i, j, ni;
-#line 3298
+#line 3303
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3298
+#line 3303
   int *xp;
-#line 3298
+#line 3303
   int nrange = 0;         /* number of range errors */
-#line 3298
+#line 3303
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3298
+#line 3303
   long cxp = (long) *((char**)xpp);
-#line 3298
+#line 3303
 
-#line 3298
+#line 3303
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3298
+#line 3303
   /* sjl: manually stripmine so we can limit amount of
-#line 3298
+#line 3303
    * vector work space reserved to LOOPCNT elements. Also
-#line 3298
+#line 3303
    * makes vectorisation easy */
-#line 3298
+#line 3303
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3298
+#line 3303
     ni=Min(nelems-j,LOOPCNT);
-#line 3298
+#line 3303
     if (realign) {
-#line 3298
+#line 3303
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
-#line 3298
+#line 3303
       xp = tmp;
-#line 3298
+#line 3303
     } else {
-#line 3298
+#line 3303
       xp = (int *) *xpp;
-#line 3298
+#line 3303
     }
-#line 3298
+#line 3303
    /* copy the next block */
-#line 3298
+#line 3303
 #pragma cdir loopcnt=LOOPCNT
-#line 3298
+#line 3303
 #pragma cdir shortloop
-#line 3298
+#line 3303
     for (i=0; i<ni; i++) {
-#line 3298
+#line 3303
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3298
+#line 3303
      /* test for range errors (not always needed but do it anyway) */
-#line 3298
+#line 3303
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3298
+#line 3303
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3298
+#line 3303
       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
-#line 3298
+#line 3303
     }
-#line 3298
+#line 3303
    /* update xpp and tp */
-#line 3298
+#line 3303
     if (realign) xp = (int *) *xpp;
-#line 3298
+#line 3303
     xp += ni;
-#line 3298
+#line 3303
     tp += ni;
-#line 3298
+#line 3303
     *xpp = (void*)xp;
-#line 3298
+#line 3303
   }
-#line 3298
+#line 3303
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3298
+#line 3303
 
-#line 3298
+#line 3303
 #else   /* not SX */
-#line 3298
+#line 3303
 	const char *xp = (const char *) *xpp;
-#line 3298
+#line 3303
 	int status = NC_NOERR;
-#line 3298
+#line 3303
 
-#line 3298
+#line 3303
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3298
+#line 3303
 	{
-#line 3298
+#line 3303
 		const int lstatus = ncx_get_int_ulonglong(xp, tp);
-#line 3298
+#line 3303
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3298
+#line 3303
 			status = lstatus;
-#line 3298
+#line 3303
 	}
-#line 3298
+#line 3303
 
-#line 3298
+#line 3303
 	*xpp = (const void *)xp;
-#line 3298
+#line 3303
 	return status;
-#line 3298
+#line 3303
 #endif
-#line 3298
+#line 3303
 }
-#line 3298
+#line 3303
 
 
 #if X_SIZEOF_INT == SIZEOF_INT
@@ -22940,1532 +22945,1532 @@ ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
 }
 #else
 int
-#line 3314
+#line 3319
 ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3314
+#line 3319
 {
-#line 3314
+#line 3319
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3314
+#line 3319
 
-#line 3314
+#line 3319
  /* basic algorithm is:
-#line 3314
+#line 3319
   *   - ensure sane alignment of output data
-#line 3314
+#line 3319
   *   - copy (conversion happens automatically) input data
-#line 3314
+#line 3319
   *     to output
-#line 3314
+#line 3319
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3314
+#line 3319
   *     at next location for converted output
-#line 3314
+#line 3319
   */
-#line 3314
+#line 3319
   long i, j, ni;
-#line 3314
+#line 3319
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3314
+#line 3319
   int *xp;
-#line 3314
+#line 3319
   int nrange = 0;         /* number of range errors */
-#line 3314
+#line 3319
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3314
+#line 3319
   long cxp = (long) *((char**)xpp);
-#line 3314
+#line 3319
 
-#line 3314
+#line 3319
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3314
+#line 3319
   /* sjl: manually stripmine so we can limit amount of
-#line 3314
+#line 3319
    * vector work space reserved to LOOPCNT elements. Also
-#line 3314
+#line 3319
    * makes vectorisation easy */
-#line 3314
+#line 3319
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3314
+#line 3319
     ni=Min(nelems-j,LOOPCNT);
-#line 3314
+#line 3319
     if (realign) {
-#line 3314
+#line 3319
       xp = tmp;
-#line 3314
+#line 3319
     } else {
-#line 3314
+#line 3319
       xp = (int *) *xpp;
-#line 3314
+#line 3319
     }
-#line 3314
+#line 3319
    /* copy the next block */
-#line 3314
+#line 3319
 #pragma cdir loopcnt=LOOPCNT
-#line 3314
+#line 3319
 #pragma cdir shortloop
-#line 3314
+#line 3319
     for (i=0; i<ni; i++) {
-#line 3314
+#line 3319
       /* the normal case: */
-#line 3314
+#line 3319
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3314
+#line 3319
      /* test for range errors (not always needed but do it anyway) */
-#line 3314
+#line 3319
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3314
+#line 3319
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3314
+#line 3319
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3314
+#line 3319
     }
-#line 3314
+#line 3319
    /* copy workspace back if necessary */
-#line 3314
+#line 3319
     if (realign) {
-#line 3314
+#line 3319
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3314
+#line 3319
       xp = (int *) *xpp;
-#line 3314
+#line 3319
     }
-#line 3314
+#line 3319
    /* update xpp and tp */
-#line 3314
+#line 3319
     xp += ni;
-#line 3314
+#line 3319
     tp += ni;
-#line 3314
+#line 3319
     *xpp = (void*)xp;
-#line 3314
+#line 3319
   }
-#line 3314
+#line 3319
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3314
+#line 3319
 
-#line 3314
+#line 3319
 #else   /* not SX */
-#line 3314
+#line 3319
 
-#line 3314
+#line 3319
 	char *xp = (char *) *xpp;
-#line 3314
+#line 3319
 	int status = NC_NOERR;
-#line 3314
+#line 3319
 
-#line 3314
+#line 3319
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3314
+#line 3319
 	{
-#line 3314
+#line 3319
 		int lstatus = ncx_put_int_int(xp, tp, fillp);
-#line 3314
+#line 3319
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3314
+#line 3319
 			status = lstatus;
-#line 3314
+#line 3319
 	}
-#line 3314
+#line 3319
 
-#line 3314
+#line 3319
 	*xpp = (void *)xp;
-#line 3314
+#line 3319
 	return status;
-#line 3314
+#line 3319
 #endif
-#line 3314
+#line 3319
 }
-#line 3314
+#line 3319
 
 #endif
 int
-#line 3316
+#line 3321
 ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3316
+#line 3321
 {
-#line 3316
+#line 3321
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3316
+#line 3321
 
-#line 3316
+#line 3321
  /* basic algorithm is:
-#line 3316
+#line 3321
   *   - ensure sane alignment of output data
-#line 3316
+#line 3321
   *   - copy (conversion happens automatically) input data
-#line 3316
+#line 3321
   *     to output
-#line 3316
+#line 3321
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3316
+#line 3321
   *     at next location for converted output
-#line 3316
+#line 3321
   */
-#line 3316
+#line 3321
   long i, j, ni;
-#line 3316
+#line 3321
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3316
+#line 3321
   int *xp;
-#line 3316
+#line 3321
   int nrange = 0;         /* number of range errors */
-#line 3316
+#line 3321
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3316
+#line 3321
   long cxp = (long) *((char**)xpp);
-#line 3316
+#line 3321
 
-#line 3316
+#line 3321
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3316
+#line 3321
   /* sjl: manually stripmine so we can limit amount of
-#line 3316
+#line 3321
    * vector work space reserved to LOOPCNT elements. Also
-#line 3316
+#line 3321
    * makes vectorisation easy */
-#line 3316
+#line 3321
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3316
+#line 3321
     ni=Min(nelems-j,LOOPCNT);
-#line 3316
+#line 3321
     if (realign) {
-#line 3316
+#line 3321
       xp = tmp;
-#line 3316
+#line 3321
     } else {
-#line 3316
+#line 3321
       xp = (int *) *xpp;
-#line 3316
+#line 3321
     }
-#line 3316
+#line 3321
    /* copy the next block */
-#line 3316
+#line 3321
 #pragma cdir loopcnt=LOOPCNT
-#line 3316
+#line 3321
 #pragma cdir shortloop
-#line 3316
+#line 3321
     for (i=0; i<ni; i++) {
-#line 3316
+#line 3321
       /* the normal case: */
-#line 3316
+#line 3321
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3316
+#line 3321
      /* test for range errors (not always needed but do it anyway) */
-#line 3316
+#line 3321
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3316
+#line 3321
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3316
+#line 3321
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3316
+#line 3321
     }
-#line 3316
+#line 3321
    /* copy workspace back if necessary */
-#line 3316
+#line 3321
     if (realign) {
-#line 3316
+#line 3321
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3316
+#line 3321
       xp = (int *) *xpp;
-#line 3316
+#line 3321
     }
-#line 3316
+#line 3321
    /* update xpp and tp */
-#line 3316
+#line 3321
     xp += ni;
-#line 3316
+#line 3321
     tp += ni;
-#line 3316
+#line 3321
     *xpp = (void*)xp;
-#line 3316
+#line 3321
   }
-#line 3316
+#line 3321
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3316
+#line 3321
 
-#line 3316
+#line 3321
 #else   /* not SX */
-#line 3316
+#line 3321
 
-#line 3316
+#line 3321
 	char *xp = (char *) *xpp;
-#line 3316
+#line 3321
 	int status = NC_NOERR;
-#line 3316
+#line 3321
 
-#line 3316
+#line 3321
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3316
+#line 3321
 	{
-#line 3316
+#line 3321
 		int lstatus = ncx_put_int_schar(xp, tp, fillp);
-#line 3316
+#line 3321
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3316
+#line 3321
 			status = lstatus;
-#line 3316
+#line 3321
 	}
-#line 3316
+#line 3321
 
-#line 3316
+#line 3321
 	*xpp = (void *)xp;
-#line 3316
+#line 3321
 	return status;
-#line 3316
+#line 3321
 #endif
-#line 3316
+#line 3321
 }
-#line 3316
+#line 3321
 
 int
-#line 3317
+#line 3322
 ncx_putn_int_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3317
+#line 3322
 {
-#line 3317
+#line 3322
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3317
+#line 3322
 
-#line 3317
+#line 3322
  /* basic algorithm is:
-#line 3317
+#line 3322
   *   - ensure sane alignment of output data
-#line 3317
+#line 3322
   *   - copy (conversion happens automatically) input data
-#line 3317
+#line 3322
   *     to output
-#line 3317
+#line 3322
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3317
+#line 3322
   *     at next location for converted output
-#line 3317
+#line 3322
   */
-#line 3317
+#line 3322
   long i, j, ni;
-#line 3317
+#line 3322
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3317
+#line 3322
   int *xp;
-#line 3317
+#line 3322
   int nrange = 0;         /* number of range errors */
-#line 3317
+#line 3322
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3317
+#line 3322
   long cxp = (long) *((char**)xpp);
-#line 3317
+#line 3322
 
-#line 3317
+#line 3322
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3317
+#line 3322
   /* sjl: manually stripmine so we can limit amount of
-#line 3317
+#line 3322
    * vector work space reserved to LOOPCNT elements. Also
-#line 3317
+#line 3322
    * makes vectorisation easy */
-#line 3317
+#line 3322
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3317
+#line 3322
     ni=Min(nelems-j,LOOPCNT);
-#line 3317
+#line 3322
     if (realign) {
-#line 3317
+#line 3322
       xp = tmp;
-#line 3317
+#line 3322
     } else {
-#line 3317
+#line 3322
       xp = (int *) *xpp;
-#line 3317
+#line 3322
     }
-#line 3317
+#line 3322
    /* copy the next block */
-#line 3317
+#line 3322
 #pragma cdir loopcnt=LOOPCNT
-#line 3317
+#line 3322
 #pragma cdir shortloop
-#line 3317
+#line 3322
     for (i=0; i<ni; i++) {
-#line 3317
+#line 3322
       /* the normal case: */
-#line 3317
+#line 3322
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3317
+#line 3322
      /* test for range errors (not always needed but do it anyway) */
-#line 3317
+#line 3322
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3317
+#line 3322
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3317
+#line 3322
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3317
+#line 3322
     }
-#line 3317
+#line 3322
    /* copy workspace back if necessary */
-#line 3317
+#line 3322
     if (realign) {
-#line 3317
+#line 3322
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3317
+#line 3322
       xp = (int *) *xpp;
-#line 3317
+#line 3322
     }
-#line 3317
+#line 3322
    /* update xpp and tp */
-#line 3317
+#line 3322
     xp += ni;
-#line 3317
+#line 3322
     tp += ni;
-#line 3317
+#line 3322
     *xpp = (void*)xp;
-#line 3317
+#line 3322
   }
-#line 3317
+#line 3322
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3317
+#line 3322
 
-#line 3317
+#line 3322
 #else   /* not SX */
-#line 3317
+#line 3322
 
-#line 3317
+#line 3322
 	char *xp = (char *) *xpp;
-#line 3317
+#line 3322
 	int status = NC_NOERR;
-#line 3317
+#line 3322
 
-#line 3317
+#line 3322
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3317
+#line 3322
 	{
-#line 3317
+#line 3322
 		int lstatus = ncx_put_int_short(xp, tp, fillp);
-#line 3317
+#line 3322
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3317
+#line 3322
 			status = lstatus;
-#line 3317
+#line 3322
 	}
-#line 3317
+#line 3322
 
-#line 3317
+#line 3322
 	*xpp = (void *)xp;
-#line 3317
+#line 3322
 	return status;
-#line 3317
+#line 3322
 #endif
-#line 3317
+#line 3322
 }
-#line 3317
+#line 3322
 
 int
-#line 3318
+#line 3323
 ncx_putn_int_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3318
+#line 3323
 {
-#line 3318
+#line 3323
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3318
+#line 3323
 
-#line 3318
+#line 3323
  /* basic algorithm is:
-#line 3318
+#line 3323
   *   - ensure sane alignment of output data
-#line 3318
+#line 3323
   *   - copy (conversion happens automatically) input data
-#line 3318
+#line 3323
   *     to output
-#line 3318
+#line 3323
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3318
+#line 3323
   *     at next location for converted output
-#line 3318
+#line 3323
   */
-#line 3318
+#line 3323
   long i, j, ni;
-#line 3318
+#line 3323
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3318
+#line 3323
   int *xp;
-#line 3318
+#line 3323
   int nrange = 0;         /* number of range errors */
-#line 3318
+#line 3323
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3318
+#line 3323
   long cxp = (long) *((char**)xpp);
-#line 3318
+#line 3323
 
-#line 3318
+#line 3323
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3318
+#line 3323
   /* sjl: manually stripmine so we can limit amount of
-#line 3318
+#line 3323
    * vector work space reserved to LOOPCNT elements. Also
-#line 3318
+#line 3323
    * makes vectorisation easy */
-#line 3318
+#line 3323
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3318
+#line 3323
     ni=Min(nelems-j,LOOPCNT);
-#line 3318
+#line 3323
     if (realign) {
-#line 3318
+#line 3323
       xp = tmp;
-#line 3318
+#line 3323
     } else {
-#line 3318
+#line 3323
       xp = (int *) *xpp;
-#line 3318
+#line 3323
     }
-#line 3318
+#line 3323
    /* copy the next block */
-#line 3318
+#line 3323
 #pragma cdir loopcnt=LOOPCNT
-#line 3318
+#line 3323
 #pragma cdir shortloop
-#line 3318
+#line 3323
     for (i=0; i<ni; i++) {
-#line 3318
+#line 3323
       /* the normal case: */
-#line 3318
+#line 3323
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3318
+#line 3323
      /* test for range errors (not always needed but do it anyway) */
-#line 3318
+#line 3323
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3318
+#line 3323
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3318
+#line 3323
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3318
+#line 3323
     }
-#line 3318
+#line 3323
    /* copy workspace back if necessary */
-#line 3318
+#line 3323
     if (realign) {
-#line 3318
+#line 3323
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3318
+#line 3323
       xp = (int *) *xpp;
-#line 3318
+#line 3323
     }
-#line 3318
+#line 3323
    /* update xpp and tp */
-#line 3318
+#line 3323
     xp += ni;
-#line 3318
+#line 3323
     tp += ni;
-#line 3318
+#line 3323
     *xpp = (void*)xp;
-#line 3318
+#line 3323
   }
-#line 3318
+#line 3323
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3318
+#line 3323
 
-#line 3318
+#line 3323
 #else   /* not SX */
-#line 3318
+#line 3323
 
-#line 3318
+#line 3323
 	char *xp = (char *) *xpp;
-#line 3318
+#line 3323
 	int status = NC_NOERR;
-#line 3318
+#line 3323
 
-#line 3318
+#line 3323
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3318
+#line 3323
 	{
-#line 3318
+#line 3323
 		int lstatus = ncx_put_int_long(xp, tp, fillp);
-#line 3318
+#line 3323
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3318
+#line 3323
 			status = lstatus;
-#line 3318
+#line 3323
 	}
-#line 3318
+#line 3323
 
-#line 3318
+#line 3323
 	*xpp = (void *)xp;
-#line 3318
+#line 3323
 	return status;
-#line 3318
+#line 3323
 #endif
-#line 3318
+#line 3323
 }
-#line 3318
+#line 3323
 
 int
-#line 3319
+#line 3324
 ncx_putn_int_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3319
+#line 3324
 {
-#line 3319
+#line 3324
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3319
+#line 3324
 
-#line 3319
+#line 3324
  /* basic algorithm is:
-#line 3319
+#line 3324
   *   - ensure sane alignment of output data
-#line 3319
+#line 3324
   *   - copy (conversion happens automatically) input data
-#line 3319
+#line 3324
   *     to output
-#line 3319
+#line 3324
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3319
+#line 3324
   *     at next location for converted output
-#line 3319
+#line 3324
   */
-#line 3319
+#line 3324
   long i, j, ni;
-#line 3319
+#line 3324
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3319
+#line 3324
   int *xp;
-#line 3319
+#line 3324
   double d;               /* special case for ncx_putn_int_float */
-#line 3319
+#line 3324
   int nrange = 0;         /* number of range errors */
-#line 3319
+#line 3324
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3319
+#line 3324
   long cxp = (long) *((char**)xpp);
-#line 3319
+#line 3324
 
-#line 3319
+#line 3324
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3319
+#line 3324
   /* sjl: manually stripmine so we can limit amount of
-#line 3319
+#line 3324
    * vector work space reserved to LOOPCNT elements. Also
-#line 3319
+#line 3324
    * makes vectorisation easy */
-#line 3319
+#line 3324
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3319
+#line 3324
     ni=Min(nelems-j,LOOPCNT);
-#line 3319
+#line 3324
     if (realign) {
-#line 3319
+#line 3324
       xp = tmp;
-#line 3319
+#line 3324
     } else {
-#line 3319
+#line 3324
       xp = (int *) *xpp;
-#line 3319
+#line 3324
     }
-#line 3319
+#line 3324
    /* copy the next block */
-#line 3319
+#line 3324
 #pragma cdir loopcnt=LOOPCNT
-#line 3319
+#line 3324
 #pragma cdir shortloop
-#line 3319
+#line 3324
     for (i=0; i<ni; i++) {
-#line 3319
+#line 3324
       /* for some reason int to float, for putn, requires a special case */
-#line 3319
+#line 3324
       d = tp[i];
-#line 3319
+#line 3324
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
-#line 3319
+#line 3324
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3319
+#line 3324
     }
-#line 3319
+#line 3324
    /* copy workspace back if necessary */
-#line 3319
+#line 3324
     if (realign) {
-#line 3319
+#line 3324
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3319
+#line 3324
       xp = (int *) *xpp;
-#line 3319
+#line 3324
     }
-#line 3319
+#line 3324
    /* update xpp and tp */
-#line 3319
+#line 3324
     xp += ni;
-#line 3319
+#line 3324
     tp += ni;
-#line 3319
+#line 3324
     *xpp = (void*)xp;
-#line 3319
+#line 3324
   }
-#line 3319
+#line 3324
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3319
+#line 3324
 
-#line 3319
+#line 3324
 #else   /* not SX */
-#line 3319
+#line 3324
 
-#line 3319
+#line 3324
 	char *xp = (char *) *xpp;
-#line 3319
+#line 3324
 	int status = NC_NOERR;
-#line 3319
+#line 3324
 
-#line 3319
+#line 3324
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3319
+#line 3324
 	{
-#line 3319
+#line 3324
 		int lstatus = ncx_put_int_float(xp, tp, fillp);
-#line 3319
+#line 3324
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3319
+#line 3324
 			status = lstatus;
-#line 3319
+#line 3324
 	}
-#line 3319
+#line 3324
 
-#line 3319
+#line 3324
 	*xpp = (void *)xp;
-#line 3319
+#line 3324
 	return status;
-#line 3319
+#line 3324
 #endif
-#line 3319
+#line 3324
 }
-#line 3319
+#line 3324
 
 int
-#line 3320
+#line 3325
 ncx_putn_int_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3320
+#line 3325
 {
-#line 3320
+#line 3325
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3320
+#line 3325
 
-#line 3320
+#line 3325
  /* basic algorithm is:
-#line 3320
+#line 3325
   *   - ensure sane alignment of output data
-#line 3320
+#line 3325
   *   - copy (conversion happens automatically) input data
-#line 3320
+#line 3325
   *     to output
-#line 3320
+#line 3325
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3320
+#line 3325
   *     at next location for converted output
-#line 3320
+#line 3325
   */
-#line 3320
+#line 3325
   long i, j, ni;
-#line 3320
+#line 3325
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3320
+#line 3325
   int *xp;
-#line 3320
+#line 3325
   int nrange = 0;         /* number of range errors */
-#line 3320
+#line 3325
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3320
+#line 3325
   long cxp = (long) *((char**)xpp);
-#line 3320
+#line 3325
 
-#line 3320
+#line 3325
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3320
+#line 3325
   /* sjl: manually stripmine so we can limit amount of
-#line 3320
+#line 3325
    * vector work space reserved to LOOPCNT elements. Also
-#line 3320
+#line 3325
    * makes vectorisation easy */
-#line 3320
+#line 3325
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3320
+#line 3325
     ni=Min(nelems-j,LOOPCNT);
-#line 3320
+#line 3325
     if (realign) {
-#line 3320
+#line 3325
       xp = tmp;
-#line 3320
+#line 3325
     } else {
-#line 3320
+#line 3325
       xp = (int *) *xpp;
-#line 3320
+#line 3325
     }
-#line 3320
+#line 3325
    /* copy the next block */
-#line 3320
+#line 3325
 #pragma cdir loopcnt=LOOPCNT
-#line 3320
+#line 3325
 #pragma cdir shortloop
-#line 3320
+#line 3325
     for (i=0; i<ni; i++) {
-#line 3320
+#line 3325
       /* the normal case: */
-#line 3320
+#line 3325
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3320
+#line 3325
      /* test for range errors (not always needed but do it anyway) */
-#line 3320
+#line 3325
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3320
+#line 3325
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3320
+#line 3325
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3320
+#line 3325
     }
-#line 3320
+#line 3325
    /* copy workspace back if necessary */
-#line 3320
+#line 3325
     if (realign) {
-#line 3320
+#line 3325
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3320
+#line 3325
       xp = (int *) *xpp;
-#line 3320
+#line 3325
     }
-#line 3320
+#line 3325
    /* update xpp and tp */
-#line 3320
+#line 3325
     xp += ni;
-#line 3320
+#line 3325
     tp += ni;
-#line 3320
+#line 3325
     *xpp = (void*)xp;
-#line 3320
+#line 3325
   }
-#line 3320
+#line 3325
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3320
+#line 3325
 
-#line 3320
+#line 3325
 #else   /* not SX */
-#line 3320
+#line 3325
 
-#line 3320
+#line 3325
 	char *xp = (char *) *xpp;
-#line 3320
+#line 3325
 	int status = NC_NOERR;
-#line 3320
+#line 3325
 
-#line 3320
+#line 3325
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3320
+#line 3325
 	{
-#line 3320
+#line 3325
 		int lstatus = ncx_put_int_double(xp, tp, fillp);
-#line 3320
+#line 3325
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3320
+#line 3325
 			status = lstatus;
-#line 3320
+#line 3325
 	}
-#line 3320
+#line 3325
 
-#line 3320
+#line 3325
 	*xpp = (void *)xp;
-#line 3320
+#line 3325
 	return status;
-#line 3320
+#line 3325
 #endif
-#line 3320
+#line 3325
 }
-#line 3320
+#line 3325
 
 int
-#line 3321
+#line 3326
 ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3321
+#line 3326
 {
-#line 3321
+#line 3326
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3321
+#line 3326
 
-#line 3321
+#line 3326
  /* basic algorithm is:
-#line 3321
+#line 3326
   *   - ensure sane alignment of output data
-#line 3321
+#line 3326
   *   - copy (conversion happens automatically) input data
-#line 3321
+#line 3326
   *     to output
-#line 3321
+#line 3326
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3321
+#line 3326
   *     at next location for converted output
-#line 3321
+#line 3326
   */
-#line 3321
+#line 3326
   long i, j, ni;
-#line 3321
+#line 3326
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3321
+#line 3326
   int *xp;
-#line 3321
+#line 3326
   int nrange = 0;         /* number of range errors */
-#line 3321
+#line 3326
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3321
+#line 3326
   long cxp = (long) *((char**)xpp);
-#line 3321
+#line 3326
 
-#line 3321
+#line 3326
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3321
+#line 3326
   /* sjl: manually stripmine so we can limit amount of
-#line 3321
+#line 3326
    * vector work space reserved to LOOPCNT elements. Also
-#line 3321
+#line 3326
    * makes vectorisation easy */
-#line 3321
+#line 3326
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3321
+#line 3326
     ni=Min(nelems-j,LOOPCNT);
-#line 3321
+#line 3326
     if (realign) {
-#line 3321
+#line 3326
       xp = tmp;
-#line 3321
+#line 3326
     } else {
-#line 3321
+#line 3326
       xp = (int *) *xpp;
-#line 3321
+#line 3326
     }
-#line 3321
+#line 3326
    /* copy the next block */
-#line 3321
+#line 3326
 #pragma cdir loopcnt=LOOPCNT
-#line 3321
+#line 3326
 #pragma cdir shortloop
-#line 3321
+#line 3326
     for (i=0; i<ni; i++) {
-#line 3321
+#line 3326
       /* the normal case: */
-#line 3321
+#line 3326
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3321
+#line 3326
      /* test for range errors (not always needed but do it anyway) */
-#line 3321
+#line 3326
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3321
+#line 3326
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3321
+#line 3326
       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
-#line 3321
+#line 3326
     }
-#line 3321
+#line 3326
    /* copy workspace back if necessary */
-#line 3321
+#line 3326
     if (realign) {
-#line 3321
+#line 3326
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3321
+#line 3326
       xp = (int *) *xpp;
-#line 3321
+#line 3326
     }
-#line 3321
+#line 3326
    /* update xpp and tp */
-#line 3321
+#line 3326
     xp += ni;
-#line 3321
+#line 3326
     tp += ni;
-#line 3321
+#line 3326
     *xpp = (void*)xp;
-#line 3321
+#line 3326
   }
-#line 3321
+#line 3326
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3321
+#line 3326
 
-#line 3321
+#line 3326
 #else   /* not SX */
-#line 3321
+#line 3326
 
-#line 3321
+#line 3326
 	char *xp = (char *) *xpp;
-#line 3321
+#line 3326
 	int status = NC_NOERR;
-#line 3321
+#line 3326
 
-#line 3321
+#line 3326
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3321
+#line 3326
 	{
-#line 3321
+#line 3326
 		int lstatus = ncx_put_int_longlong(xp, tp, fillp);
-#line 3321
+#line 3326
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3321
+#line 3326
 			status = lstatus;
-#line 3321
+#line 3326
 	}
-#line 3321
+#line 3326
 
-#line 3321
+#line 3326
 	*xpp = (void *)xp;
-#line 3321
+#line 3326
 	return status;
-#line 3321
+#line 3326
 #endif
-#line 3321
+#line 3326
 }
-#line 3321
+#line 3326
 
 int
-#line 3322
+#line 3327
 ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3322
+#line 3327
 {
-#line 3322
+#line 3327
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3322
+#line 3327
 
-#line 3322
+#line 3327
  /* basic algorithm is:
-#line 3322
+#line 3327
   *   - ensure sane alignment of output data
-#line 3322
+#line 3327
   *   - copy (conversion happens automatically) input data
-#line 3322
+#line 3327
   *     to output
-#line 3322
+#line 3327
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3322
+#line 3327
   *     at next location for converted output
-#line 3322
+#line 3327
   */
-#line 3322
+#line 3327
   long i, j, ni;
-#line 3322
+#line 3327
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3322
+#line 3327
   int *xp;
-#line 3322
+#line 3327
   int nrange = 0;         /* number of range errors */
-#line 3322
+#line 3327
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3322
+#line 3327
   long cxp = (long) *((char**)xpp);
-#line 3322
+#line 3327
 
-#line 3322
+#line 3327
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3322
+#line 3327
   /* sjl: manually stripmine so we can limit amount of
-#line 3322
+#line 3327
    * vector work space reserved to LOOPCNT elements. Also
-#line 3322
+#line 3327
    * makes vectorisation easy */
-#line 3322
+#line 3327
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3322
+#line 3327
     ni=Min(nelems-j,LOOPCNT);
-#line 3322
+#line 3327
     if (realign) {
-#line 3322
+#line 3327
       xp = tmp;
-#line 3322
+#line 3327
     } else {
-#line 3322
+#line 3327
       xp = (int *) *xpp;
-#line 3322
+#line 3327
     }
-#line 3322
+#line 3327
    /* copy the next block */
-#line 3322
+#line 3327
 #pragma cdir loopcnt=LOOPCNT
-#line 3322
+#line 3327
 #pragma cdir shortloop
-#line 3322
+#line 3327
     for (i=0; i<ni; i++) {
-#line 3322
+#line 3327
       /* the normal case: */
-#line 3322
+#line 3327
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3322
+#line 3327
      /* test for range errors (not always needed but do it anyway) */
-#line 3322
+#line 3327
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3322
+#line 3327
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3322
+#line 3327
       nrange += tp[i] > X_INT_MAX ;
-#line 3322
+#line 3327
     }
-#line 3322
+#line 3327
    /* copy workspace back if necessary */
-#line 3322
+#line 3327
     if (realign) {
-#line 3322
+#line 3327
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3322
+#line 3327
       xp = (int *) *xpp;
-#line 3322
+#line 3327
     }
-#line 3322
+#line 3327
    /* update xpp and tp */
-#line 3322
+#line 3327
     xp += ni;
-#line 3322
+#line 3327
     tp += ni;
-#line 3322
+#line 3327
     *xpp = (void*)xp;
-#line 3322
+#line 3327
   }
-#line 3322
+#line 3327
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3322
+#line 3327
 
-#line 3322
+#line 3327
 #else   /* not SX */
-#line 3322
+#line 3327
 
-#line 3322
+#line 3327
 	char *xp = (char *) *xpp;
-#line 3322
+#line 3327
 	int status = NC_NOERR;
-#line 3322
+#line 3327
 
-#line 3322
+#line 3327
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3322
+#line 3327
 	{
-#line 3322
+#line 3327
 		int lstatus = ncx_put_int_uchar(xp, tp, fillp);
-#line 3322
+#line 3327
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3322
+#line 3327
 			status = lstatus;
-#line 3322
+#line 3327
 	}
-#line 3322
+#line 3327
 
-#line 3322
+#line 3327
 	*xpp = (void *)xp;
-#line 3322
+#line 3327
 	return status;
-#line 3322
+#line 3327
 #endif
-#line 3322
+#line 3327
 }
-#line 3322
+#line 3327
 
 int
-#line 3323
+#line 3328
 ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3323
+#line 3328
 {
-#line 3323
+#line 3328
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3323
+#line 3328
 
-#line 3323
+#line 3328
  /* basic algorithm is:
-#line 3323
+#line 3328
   *   - ensure sane alignment of output data
-#line 3323
+#line 3328
   *   - copy (conversion happens automatically) input data
-#line 3323
+#line 3328
   *     to output
-#line 3323
+#line 3328
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3323
+#line 3328
   *     at next location for converted output
-#line 3323
+#line 3328
   */
-#line 3323
+#line 3328
   long i, j, ni;
-#line 3323
+#line 3328
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3323
+#line 3328
   int *xp;
-#line 3323
+#line 3328
   int nrange = 0;         /* number of range errors */
-#line 3323
+#line 3328
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3323
+#line 3328
   long cxp = (long) *((char**)xpp);
-#line 3323
+#line 3328
 
-#line 3323
+#line 3328
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3323
+#line 3328
   /* sjl: manually stripmine so we can limit amount of
-#line 3323
+#line 3328
    * vector work space reserved to LOOPCNT elements. Also
-#line 3323
+#line 3328
    * makes vectorisation easy */
-#line 3323
+#line 3328
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3323
+#line 3328
     ni=Min(nelems-j,LOOPCNT);
-#line 3323
+#line 3328
     if (realign) {
-#line 3323
+#line 3328
       xp = tmp;
-#line 3323
+#line 3328
     } else {
-#line 3323
+#line 3328
       xp = (int *) *xpp;
-#line 3323
+#line 3328
     }
-#line 3323
+#line 3328
    /* copy the next block */
-#line 3323
+#line 3328
 #pragma cdir loopcnt=LOOPCNT
-#line 3323
+#line 3328
 #pragma cdir shortloop
-#line 3323
+#line 3328
     for (i=0; i<ni; i++) {
-#line 3323
+#line 3328
       /* the normal case: */
-#line 3323
+#line 3328
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3323
+#line 3328
      /* test for range errors (not always needed but do it anyway) */
-#line 3323
+#line 3328
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3323
+#line 3328
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3323
+#line 3328
       nrange += tp[i] > X_INT_MAX ;
-#line 3323
+#line 3328
     }
-#line 3323
+#line 3328
    /* copy workspace back if necessary */
-#line 3323
+#line 3328
     if (realign) {
-#line 3323
+#line 3328
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3323
+#line 3328
       xp = (int *) *xpp;
-#line 3323
+#line 3328
     }
-#line 3323
+#line 3328
    /* update xpp and tp */
-#line 3323
+#line 3328
     xp += ni;
-#line 3323
+#line 3328
     tp += ni;
-#line 3323
+#line 3328
     *xpp = (void*)xp;
-#line 3323
+#line 3328
   }
-#line 3323
+#line 3328
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3323
+#line 3328
 
-#line 3323
+#line 3328
 #else   /* not SX */
-#line 3323
+#line 3328
 
-#line 3323
+#line 3328
 	char *xp = (char *) *xpp;
-#line 3323
+#line 3328
 	int status = NC_NOERR;
-#line 3323
+#line 3328
 
-#line 3323
+#line 3328
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3323
+#line 3328
 	{
-#line 3323
+#line 3328
 		int lstatus = ncx_put_int_ushort(xp, tp, fillp);
-#line 3323
+#line 3328
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3323
+#line 3328
 			status = lstatus;
-#line 3323
+#line 3328
 	}
-#line 3323
+#line 3328
 
-#line 3323
+#line 3328
 	*xpp = (void *)xp;
-#line 3323
+#line 3328
 	return status;
-#line 3323
+#line 3328
 #endif
-#line 3323
+#line 3328
 }
-#line 3323
+#line 3328
 
 int
-#line 3324
+#line 3329
 ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3324
+#line 3329
 {
-#line 3324
+#line 3329
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3324
+#line 3329
 
-#line 3324
+#line 3329
  /* basic algorithm is:
-#line 3324
+#line 3329
   *   - ensure sane alignment of output data
-#line 3324
+#line 3329
   *   - copy (conversion happens automatically) input data
-#line 3324
+#line 3329
   *     to output
-#line 3324
+#line 3329
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3324
+#line 3329
   *     at next location for converted output
-#line 3324
+#line 3329
   */
-#line 3324
+#line 3329
   long i, j, ni;
-#line 3324
+#line 3329
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3324
+#line 3329
   int *xp;
-#line 3324
+#line 3329
   int nrange = 0;         /* number of range errors */
-#line 3324
+#line 3329
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3324
+#line 3329
   long cxp = (long) *((char**)xpp);
-#line 3324
+#line 3329
 
-#line 3324
+#line 3329
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3324
+#line 3329
   /* sjl: manually stripmine so we can limit amount of
-#line 3324
+#line 3329
    * vector work space reserved to LOOPCNT elements. Also
-#line 3324
+#line 3329
    * makes vectorisation easy */
-#line 3324
+#line 3329
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3324
+#line 3329
     ni=Min(nelems-j,LOOPCNT);
-#line 3324
+#line 3329
     if (realign) {
-#line 3324
+#line 3329
       xp = tmp;
-#line 3324
+#line 3329
     } else {
-#line 3324
+#line 3329
       xp = (int *) *xpp;
-#line 3324
+#line 3329
     }
-#line 3324
+#line 3329
    /* copy the next block */
-#line 3324
+#line 3329
 #pragma cdir loopcnt=LOOPCNT
-#line 3324
+#line 3329
 #pragma cdir shortloop
-#line 3324
+#line 3329
     for (i=0; i<ni; i++) {
-#line 3324
+#line 3329
       /* the normal case: */
-#line 3324
+#line 3329
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3324
+#line 3329
      /* test for range errors (not always needed but do it anyway) */
-#line 3324
+#line 3329
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3324
+#line 3329
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3324
+#line 3329
       nrange += tp[i] > X_INT_MAX ;
-#line 3324
+#line 3329
     }
-#line 3324
+#line 3329
    /* copy workspace back if necessary */
-#line 3324
+#line 3329
     if (realign) {
-#line 3324
+#line 3329
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3324
+#line 3329
       xp = (int *) *xpp;
-#line 3324
+#line 3329
     }
-#line 3324
+#line 3329
    /* update xpp and tp */
-#line 3324
+#line 3329
     xp += ni;
-#line 3324
+#line 3329
     tp += ni;
-#line 3324
+#line 3329
     *xpp = (void*)xp;
-#line 3324
+#line 3329
   }
-#line 3324
+#line 3329
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3324
+#line 3329
 
-#line 3324
+#line 3329
 #else   /* not SX */
-#line 3324
+#line 3329
 
-#line 3324
+#line 3329
 	char *xp = (char *) *xpp;
-#line 3324
+#line 3329
 	int status = NC_NOERR;
-#line 3324
+#line 3329
 
-#line 3324
+#line 3329
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3324
+#line 3329
 	{
-#line 3324
+#line 3329
 		int lstatus = ncx_put_int_uint(xp, tp, fillp);
-#line 3324
+#line 3329
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3324
+#line 3329
 			status = lstatus;
-#line 3324
+#line 3329
 	}
-#line 3324
+#line 3329
 
-#line 3324
+#line 3329
 	*xpp = (void *)xp;
-#line 3324
+#line 3329
 	return status;
-#line 3324
+#line 3329
 #endif
-#line 3324
+#line 3329
 }
-#line 3324
+#line 3329
 
 int
-#line 3325
+#line 3330
 ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3325
+#line 3330
 {
-#line 3325
+#line 3330
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
-#line 3325
+#line 3330
 
-#line 3325
+#line 3330
  /* basic algorithm is:
-#line 3325
+#line 3330
   *   - ensure sane alignment of output data
-#line 3325
+#line 3330
   *   - copy (conversion happens automatically) input data
-#line 3325
+#line 3330
   *     to output
-#line 3325
+#line 3330
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3325
+#line 3330
   *     at next location for converted output
-#line 3325
+#line 3330
   */
-#line 3325
+#line 3330
   long i, j, ni;
-#line 3325
+#line 3330
   int tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3325
+#line 3330
   int *xp;
-#line 3325
+#line 3330
   int nrange = 0;         /* number of range errors */
-#line 3325
+#line 3330
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3325
+#line 3330
   long cxp = (long) *((char**)xpp);
-#line 3325
+#line 3330
 
-#line 3325
+#line 3330
   realign = (cxp & 7) % SIZEOF_INT;
-#line 3325
+#line 3330
   /* sjl: manually stripmine so we can limit amount of
-#line 3325
+#line 3330
    * vector work space reserved to LOOPCNT elements. Also
-#line 3325
+#line 3330
    * makes vectorisation easy */
-#line 3325
+#line 3330
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3325
+#line 3330
     ni=Min(nelems-j,LOOPCNT);
-#line 3325
+#line 3330
     if (realign) {
-#line 3325
+#line 3330
       xp = tmp;
-#line 3325
+#line 3330
     } else {
-#line 3325
+#line 3330
       xp = (int *) *xpp;
-#line 3325
+#line 3330
     }
-#line 3325
+#line 3330
    /* copy the next block */
-#line 3325
+#line 3330
 #pragma cdir loopcnt=LOOPCNT
-#line 3325
+#line 3330
 #pragma cdir shortloop
-#line 3325
+#line 3330
     for (i=0; i<ni; i++) {
-#line 3325
+#line 3330
       /* the normal case: */
-#line 3325
+#line 3330
       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
-#line 3325
+#line 3330
      /* test for range errors (not always needed but do it anyway) */
-#line 3325
+#line 3330
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3325
+#line 3330
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3325
+#line 3330
       nrange += tp[i] > X_INT_MAX ;
-#line 3325
+#line 3330
     }
-#line 3325
+#line 3330
    /* copy workspace back if necessary */
-#line 3325
+#line 3330
     if (realign) {
-#line 3325
+#line 3330
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
-#line 3325
+#line 3330
       xp = (int *) *xpp;
-#line 3325
+#line 3330
     }
-#line 3325
+#line 3330
    /* update xpp and tp */
-#line 3325
+#line 3330
     xp += ni;
-#line 3325
+#line 3330
     tp += ni;
-#line 3325
+#line 3330
     *xpp = (void*)xp;
-#line 3325
+#line 3330
   }
-#line 3325
+#line 3330
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3325
+#line 3330
 
-#line 3325
+#line 3330
 #else   /* not SX */
-#line 3325
+#line 3330
 
-#line 3325
+#line 3330
 	char *xp = (char *) *xpp;
-#line 3325
+#line 3330
 	int status = NC_NOERR;
-#line 3325
+#line 3330
 
-#line 3325
+#line 3330
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
-#line 3325
+#line 3330
 	{
-#line 3325
+#line 3330
 		int lstatus = ncx_put_int_ulonglong(xp, tp, fillp);
-#line 3325
+#line 3330
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3325
+#line 3330
 			status = lstatus;
-#line 3325
+#line 3330
 	}
-#line 3325
+#line 3330
 
-#line 3325
+#line 3330
 	*xpp = (void *)xp;
-#line 3325
+#line 3330
 	return status;
-#line 3325
+#line 3330
 #endif
-#line 3325
+#line 3330
 }
-#line 3325
+#line 3330
 
 
 /* uint ----------------------------------------------------------------------*/
@@ -24485,1424 +24490,1424 @@ ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
 }
 #else
 int
-#line 3343
+#line 3348
 ncx_getn_uint_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3343
+#line 3348
 {
-#line 3343
+#line 3348
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3343
+#line 3348
 
-#line 3343
+#line 3348
  /* basic algorithm is:
-#line 3343
+#line 3348
   *   - ensure sane alignment of input data
-#line 3343
+#line 3348
   *   - copy (conversion happens automatically) input data
-#line 3343
+#line 3348
   *     to output
-#line 3343
+#line 3348
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3343
+#line 3348
   *     at next location for converted output
-#line 3343
+#line 3348
   */
-#line 3343
+#line 3348
   long i, j, ni;
-#line 3343
+#line 3348
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3343
+#line 3348
   uint *xp;
-#line 3343
+#line 3348
   int nrange = 0;         /* number of range errors */
-#line 3343
+#line 3348
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3343
+#line 3348
   long cxp = (long) *((char**)xpp);
-#line 3343
+#line 3348
 
-#line 3343
+#line 3348
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3343
+#line 3348
   /* sjl: manually stripmine so we can limit amount of
-#line 3343
+#line 3348
    * vector work space reserved to LOOPCNT elements. Also
-#line 3343
+#line 3348
    * makes vectorisation easy */
-#line 3343
+#line 3348
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3343
+#line 3348
     ni=Min(nelems-j,LOOPCNT);
-#line 3343
+#line 3348
     if (realign) {
-#line 3343
+#line 3348
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3343
+#line 3348
       xp = tmp;
-#line 3343
+#line 3348
     } else {
-#line 3343
+#line 3348
       xp = (uint *) *xpp;
-#line 3343
+#line 3348
     }
-#line 3343
+#line 3348
    /* copy the next block */
-#line 3343
+#line 3348
 #pragma cdir loopcnt=LOOPCNT
-#line 3343
+#line 3348
 #pragma cdir shortloop
-#line 3343
+#line 3348
     for (i=0; i<ni; i++) {
-#line 3343
+#line 3348
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3343
+#line 3348
      /* test for range errors (not always needed but do it anyway) */
-#line 3343
+#line 3348
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3343
+#line 3348
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3343
+#line 3348
       nrange += xp[i] > UINT_MAX ;
-#line 3343
+#line 3348
     }
-#line 3343
+#line 3348
    /* update xpp and tp */
-#line 3343
+#line 3348
     if (realign) xp = (uint *) *xpp;
-#line 3343
+#line 3348
     xp += ni;
-#line 3343
+#line 3348
     tp += ni;
-#line 3343
+#line 3348
     *xpp = (void*)xp;
-#line 3343
+#line 3348
   }
-#line 3343
+#line 3348
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3343
+#line 3348
 
-#line 3343
+#line 3348
 #else   /* not SX */
-#line 3343
+#line 3348
 	const char *xp = (const char *) *xpp;
-#line 3343
+#line 3348
 	int status = NC_NOERR;
-#line 3343
+#line 3348
 
-#line 3343
+#line 3348
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3343
+#line 3348
 	{
-#line 3343
+#line 3348
 		const int lstatus = ncx_get_uint_uint(xp, tp);
-#line 3343
+#line 3348
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3343
+#line 3348
 			status = lstatus;
-#line 3343
+#line 3348
 	}
-#line 3343
+#line 3348
 
-#line 3343
+#line 3348
 	*xpp = (const void *)xp;
-#line 3343
+#line 3348
 	return status;
-#line 3343
+#line 3348
 #endif
-#line 3343
+#line 3348
 }
-#line 3343
+#line 3348
 
 #endif
 int
-#line 3345
+#line 3350
 ncx_getn_uint_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3345
+#line 3350
 {
-#line 3345
+#line 3350
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3345
+#line 3350
 
-#line 3345
+#line 3350
  /* basic algorithm is:
-#line 3345
+#line 3350
   *   - ensure sane alignment of input data
-#line 3345
+#line 3350
   *   - copy (conversion happens automatically) input data
-#line 3345
+#line 3350
   *     to output
-#line 3345
+#line 3350
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3345
+#line 3350
   *     at next location for converted output
-#line 3345
+#line 3350
   */
-#line 3345
+#line 3350
   long i, j, ni;
-#line 3345
+#line 3350
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3345
+#line 3350
   uint *xp;
-#line 3345
+#line 3350
   int nrange = 0;         /* number of range errors */
-#line 3345
+#line 3350
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3345
+#line 3350
   long cxp = (long) *((char**)xpp);
-#line 3345
+#line 3350
 
-#line 3345
+#line 3350
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3345
+#line 3350
   /* sjl: manually stripmine so we can limit amount of
-#line 3345
+#line 3350
    * vector work space reserved to LOOPCNT elements. Also
-#line 3345
+#line 3350
    * makes vectorisation easy */
-#line 3345
+#line 3350
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3345
+#line 3350
     ni=Min(nelems-j,LOOPCNT);
-#line 3345
+#line 3350
     if (realign) {
-#line 3345
+#line 3350
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3345
+#line 3350
       xp = tmp;
-#line 3345
+#line 3350
     } else {
-#line 3345
+#line 3350
       xp = (uint *) *xpp;
-#line 3345
+#line 3350
     }
-#line 3345
+#line 3350
    /* copy the next block */
-#line 3345
+#line 3350
 #pragma cdir loopcnt=LOOPCNT
-#line 3345
+#line 3350
 #pragma cdir shortloop
-#line 3345
+#line 3350
     for (i=0; i<ni; i++) {
-#line 3345
+#line 3350
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3345
+#line 3350
      /* test for range errors (not always needed but do it anyway) */
-#line 3345
+#line 3350
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3345
+#line 3350
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3345
+#line 3350
       nrange += xp[i] > SCHAR_MAX ;
-#line 3345
+#line 3350
     }
-#line 3345
+#line 3350
    /* update xpp and tp */
-#line 3345
+#line 3350
     if (realign) xp = (uint *) *xpp;
-#line 3345
+#line 3350
     xp += ni;
-#line 3345
+#line 3350
     tp += ni;
-#line 3345
+#line 3350
     *xpp = (void*)xp;
-#line 3345
+#line 3350
   }
-#line 3345
+#line 3350
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3345
+#line 3350
 
-#line 3345
+#line 3350
 #else   /* not SX */
-#line 3345
+#line 3350
 	const char *xp = (const char *) *xpp;
-#line 3345
+#line 3350
 	int status = NC_NOERR;
-#line 3345
+#line 3350
 
-#line 3345
+#line 3350
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3345
+#line 3350
 	{
-#line 3345
+#line 3350
 		const int lstatus = ncx_get_uint_schar(xp, tp);
-#line 3345
+#line 3350
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3345
+#line 3350
 			status = lstatus;
-#line 3345
+#line 3350
 	}
-#line 3345
+#line 3350
 
-#line 3345
+#line 3350
 	*xpp = (const void *)xp;
-#line 3345
+#line 3350
 	return status;
-#line 3345
+#line 3350
 #endif
-#line 3345
+#line 3350
 }
-#line 3345
+#line 3350
 
 int
-#line 3346
+#line 3351
 ncx_getn_uint_short(const void **xpp, size_t nelems, short *tp)
-#line 3346
+#line 3351
 {
-#line 3346
+#line 3351
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3346
+#line 3351
 
-#line 3346
+#line 3351
  /* basic algorithm is:
-#line 3346
+#line 3351
   *   - ensure sane alignment of input data
-#line 3346
+#line 3351
   *   - copy (conversion happens automatically) input data
-#line 3346
+#line 3351
   *     to output
-#line 3346
+#line 3351
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3346
+#line 3351
   *     at next location for converted output
-#line 3346
+#line 3351
   */
-#line 3346
+#line 3351
   long i, j, ni;
-#line 3346
+#line 3351
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3346
+#line 3351
   uint *xp;
-#line 3346
+#line 3351
   int nrange = 0;         /* number of range errors */
-#line 3346
+#line 3351
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3346
+#line 3351
   long cxp = (long) *((char**)xpp);
-#line 3346
+#line 3351
 
-#line 3346
+#line 3351
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3346
+#line 3351
   /* sjl: manually stripmine so we can limit amount of
-#line 3346
+#line 3351
    * vector work space reserved to LOOPCNT elements. Also
-#line 3346
+#line 3351
    * makes vectorisation easy */
-#line 3346
+#line 3351
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3346
+#line 3351
     ni=Min(nelems-j,LOOPCNT);
-#line 3346
+#line 3351
     if (realign) {
-#line 3346
+#line 3351
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3346
+#line 3351
       xp = tmp;
-#line 3346
+#line 3351
     } else {
-#line 3346
+#line 3351
       xp = (uint *) *xpp;
-#line 3346
+#line 3351
     }
-#line 3346
+#line 3351
    /* copy the next block */
-#line 3346
+#line 3351
 #pragma cdir loopcnt=LOOPCNT
-#line 3346
+#line 3351
 #pragma cdir shortloop
-#line 3346
+#line 3351
     for (i=0; i<ni; i++) {
-#line 3346
+#line 3351
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3346
+#line 3351
      /* test for range errors (not always needed but do it anyway) */
-#line 3346
+#line 3351
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3346
+#line 3351
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3346
+#line 3351
       nrange += xp[i] > SHORT_MAX ;
-#line 3346
+#line 3351
     }
-#line 3346
+#line 3351
    /* update xpp and tp */
-#line 3346
+#line 3351
     if (realign) xp = (uint *) *xpp;
-#line 3346
+#line 3351
     xp += ni;
-#line 3346
+#line 3351
     tp += ni;
-#line 3346
+#line 3351
     *xpp = (void*)xp;
-#line 3346
+#line 3351
   }
-#line 3346
+#line 3351
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3346
+#line 3351
 
-#line 3346
+#line 3351
 #else   /* not SX */
-#line 3346
+#line 3351
 	const char *xp = (const char *) *xpp;
-#line 3346
+#line 3351
 	int status = NC_NOERR;
-#line 3346
+#line 3351
 
-#line 3346
+#line 3351
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3346
+#line 3351
 	{
-#line 3346
+#line 3351
 		const int lstatus = ncx_get_uint_short(xp, tp);
-#line 3346
+#line 3351
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3346
+#line 3351
 			status = lstatus;
-#line 3346
+#line 3351
 	}
-#line 3346
+#line 3351
 
-#line 3346
+#line 3351
 	*xpp = (const void *)xp;
-#line 3346
+#line 3351
 	return status;
-#line 3346
+#line 3351
 #endif
-#line 3346
+#line 3351
 }
-#line 3346
+#line 3351
 
 int
-#line 3347
+#line 3352
 ncx_getn_uint_int(const void **xpp, size_t nelems, int *tp)
-#line 3347
+#line 3352
 {
-#line 3347
+#line 3352
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3347
+#line 3352
 
-#line 3347
+#line 3352
  /* basic algorithm is:
-#line 3347
+#line 3352
   *   - ensure sane alignment of input data
-#line 3347
+#line 3352
   *   - copy (conversion happens automatically) input data
-#line 3347
+#line 3352
   *     to output
-#line 3347
+#line 3352
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3347
+#line 3352
   *     at next location for converted output
-#line 3347
+#line 3352
   */
-#line 3347
+#line 3352
   long i, j, ni;
-#line 3347
+#line 3352
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3347
+#line 3352
   uint *xp;
-#line 3347
+#line 3352
   int nrange = 0;         /* number of range errors */
-#line 3347
+#line 3352
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3347
+#line 3352
   long cxp = (long) *((char**)xpp);
-#line 3347
+#line 3352
 
-#line 3347
+#line 3352
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3347
+#line 3352
   /* sjl: manually stripmine so we can limit amount of
-#line 3347
+#line 3352
    * vector work space reserved to LOOPCNT elements. Also
-#line 3347
+#line 3352
    * makes vectorisation easy */
-#line 3347
+#line 3352
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3347
+#line 3352
     ni=Min(nelems-j,LOOPCNT);
-#line 3347
+#line 3352
     if (realign) {
-#line 3347
+#line 3352
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3347
+#line 3352
       xp = tmp;
-#line 3347
+#line 3352
     } else {
-#line 3347
+#line 3352
       xp = (uint *) *xpp;
-#line 3347
+#line 3352
     }
-#line 3347
+#line 3352
    /* copy the next block */
-#line 3347
+#line 3352
 #pragma cdir loopcnt=LOOPCNT
-#line 3347
+#line 3352
 #pragma cdir shortloop
-#line 3347
+#line 3352
     for (i=0; i<ni; i++) {
-#line 3347
+#line 3352
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3347
+#line 3352
      /* test for range errors (not always needed but do it anyway) */
-#line 3347
+#line 3352
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3347
+#line 3352
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3347
+#line 3352
       nrange += xp[i] > INT_MAX ;
-#line 3347
+#line 3352
     }
-#line 3347
+#line 3352
    /* update xpp and tp */
-#line 3347
+#line 3352
     if (realign) xp = (uint *) *xpp;
-#line 3347
+#line 3352
     xp += ni;
-#line 3347
+#line 3352
     tp += ni;
-#line 3347
+#line 3352
     *xpp = (void*)xp;
-#line 3347
+#line 3352
   }
-#line 3347
+#line 3352
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3347
+#line 3352
 
-#line 3347
+#line 3352
 #else   /* not SX */
-#line 3347
+#line 3352
 	const char *xp = (const char *) *xpp;
-#line 3347
+#line 3352
 	int status = NC_NOERR;
-#line 3347
+#line 3352
 
-#line 3347
+#line 3352
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3347
+#line 3352
 	{
-#line 3347
+#line 3352
 		const int lstatus = ncx_get_uint_int(xp, tp);
-#line 3347
+#line 3352
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3347
+#line 3352
 			status = lstatus;
-#line 3347
+#line 3352
 	}
-#line 3347
+#line 3352
 
-#line 3347
+#line 3352
 	*xpp = (const void *)xp;
-#line 3347
+#line 3352
 	return status;
-#line 3347
+#line 3352
 #endif
-#line 3347
+#line 3352
 }
-#line 3347
+#line 3352
 
 int
-#line 3348
+#line 3353
 ncx_getn_uint_long(const void **xpp, size_t nelems, long *tp)
-#line 3348
+#line 3353
 {
-#line 3348
+#line 3353
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3348
+#line 3353
 
-#line 3348
+#line 3353
  /* basic algorithm is:
-#line 3348
+#line 3353
   *   - ensure sane alignment of input data
-#line 3348
+#line 3353
   *   - copy (conversion happens automatically) input data
-#line 3348
+#line 3353
   *     to output
-#line 3348
+#line 3353
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3348
+#line 3353
   *     at next location for converted output
-#line 3348
+#line 3353
   */
-#line 3348
+#line 3353
   long i, j, ni;
-#line 3348
+#line 3353
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3348
+#line 3353
   uint *xp;
-#line 3348
+#line 3353
   int nrange = 0;         /* number of range errors */
-#line 3348
+#line 3353
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3348
+#line 3353
   long cxp = (long) *((char**)xpp);
-#line 3348
+#line 3353
 
-#line 3348
+#line 3353
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3348
+#line 3353
   /* sjl: manually stripmine so we can limit amount of
-#line 3348
+#line 3353
    * vector work space reserved to LOOPCNT elements. Also
-#line 3348
+#line 3353
    * makes vectorisation easy */
-#line 3348
+#line 3353
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3348
+#line 3353
     ni=Min(nelems-j,LOOPCNT);
-#line 3348
+#line 3353
     if (realign) {
-#line 3348
+#line 3353
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3348
+#line 3353
       xp = tmp;
-#line 3348
+#line 3353
     } else {
-#line 3348
+#line 3353
       xp = (uint *) *xpp;
-#line 3348
+#line 3353
     }
-#line 3348
+#line 3353
    /* copy the next block */
-#line 3348
+#line 3353
 #pragma cdir loopcnt=LOOPCNT
-#line 3348
+#line 3353
 #pragma cdir shortloop
-#line 3348
+#line 3353
     for (i=0; i<ni; i++) {
-#line 3348
+#line 3353
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3348
+#line 3353
      /* test for range errors (not always needed but do it anyway) */
-#line 3348
+#line 3353
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3348
+#line 3353
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3348
+#line 3353
       nrange += xp[i] > LONG_MAX ;
-#line 3348
+#line 3353
     }
-#line 3348
+#line 3353
    /* update xpp and tp */
-#line 3348
+#line 3353
     if (realign) xp = (uint *) *xpp;
-#line 3348
+#line 3353
     xp += ni;
-#line 3348
+#line 3353
     tp += ni;
-#line 3348
+#line 3353
     *xpp = (void*)xp;
-#line 3348
+#line 3353
   }
-#line 3348
+#line 3353
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3348
+#line 3353
 
-#line 3348
+#line 3353
 #else   /* not SX */
-#line 3348
+#line 3353
 	const char *xp = (const char *) *xpp;
-#line 3348
+#line 3353
 	int status = NC_NOERR;
-#line 3348
+#line 3353
 
-#line 3348
+#line 3353
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3348
+#line 3353
 	{
-#line 3348
+#line 3353
 		const int lstatus = ncx_get_uint_long(xp, tp);
-#line 3348
+#line 3353
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3348
+#line 3353
 			status = lstatus;
-#line 3348
+#line 3353
 	}
-#line 3348
+#line 3353
 
-#line 3348
+#line 3353
 	*xpp = (const void *)xp;
-#line 3348
+#line 3353
 	return status;
-#line 3348
+#line 3353
 #endif
-#line 3348
+#line 3353
 }
-#line 3348
+#line 3353
 
 int
-#line 3349
+#line 3354
 ncx_getn_uint_float(const void **xpp, size_t nelems, float *tp)
-#line 3349
+#line 3354
 {
-#line 3349
+#line 3354
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3349
+#line 3354
 
-#line 3349
+#line 3354
  /* basic algorithm is:
-#line 3349
+#line 3354
   *   - ensure sane alignment of input data
-#line 3349
+#line 3354
   *   - copy (conversion happens automatically) input data
-#line 3349
+#line 3354
   *     to output
-#line 3349
+#line 3354
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3349
+#line 3354
   *     at next location for converted output
-#line 3349
+#line 3354
   */
-#line 3349
+#line 3354
   long i, j, ni;
-#line 3349
+#line 3354
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3349
+#line 3354
   uint *xp;
-#line 3349
+#line 3354
   int nrange = 0;         /* number of range errors */
-#line 3349
+#line 3354
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3349
+#line 3354
   long cxp = (long) *((char**)xpp);
-#line 3349
+#line 3354
 
-#line 3349
+#line 3354
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3349
+#line 3354
   /* sjl: manually stripmine so we can limit amount of
-#line 3349
+#line 3354
    * vector work space reserved to LOOPCNT elements. Also
-#line 3349
+#line 3354
    * makes vectorisation easy */
-#line 3349
+#line 3354
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3349
+#line 3354
     ni=Min(nelems-j,LOOPCNT);
-#line 3349
+#line 3354
     if (realign) {
-#line 3349
+#line 3354
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3349
+#line 3354
       xp = tmp;
-#line 3349
+#line 3354
     } else {
-#line 3349
+#line 3354
       xp = (uint *) *xpp;
-#line 3349
+#line 3354
     }
-#line 3349
+#line 3354
    /* copy the next block */
-#line 3349
+#line 3354
 #pragma cdir loopcnt=LOOPCNT
-#line 3349
+#line 3354
 #pragma cdir shortloop
-#line 3349
+#line 3354
     for (i=0; i<ni; i++) {
-#line 3349
+#line 3354
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3349
+#line 3354
      /* test for range errors (not always needed but do it anyway) */
-#line 3349
+#line 3354
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3349
+#line 3354
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3349
+#line 3354
       nrange += xp[i] > FLOAT_MAX ;
-#line 3349
+#line 3354
     }
-#line 3349
+#line 3354
    /* update xpp and tp */
-#line 3349
+#line 3354
     if (realign) xp = (uint *) *xpp;
-#line 3349
+#line 3354
     xp += ni;
-#line 3349
+#line 3354
     tp += ni;
-#line 3349
+#line 3354
     *xpp = (void*)xp;
-#line 3349
+#line 3354
   }
-#line 3349
+#line 3354
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3349
+#line 3354
 
-#line 3349
+#line 3354
 #else   /* not SX */
-#line 3349
+#line 3354
 	const char *xp = (const char *) *xpp;
-#line 3349
+#line 3354
 	int status = NC_NOERR;
-#line 3349
+#line 3354
 
-#line 3349
+#line 3354
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3349
+#line 3354
 	{
-#line 3349
+#line 3354
 		const int lstatus = ncx_get_uint_float(xp, tp);
-#line 3349
+#line 3354
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3349
+#line 3354
 			status = lstatus;
-#line 3349
+#line 3354
 	}
-#line 3349
+#line 3354
 
-#line 3349
+#line 3354
 	*xpp = (const void *)xp;
-#line 3349
+#line 3354
 	return status;
-#line 3349
+#line 3354
 #endif
-#line 3349
+#line 3354
 }
-#line 3349
+#line 3354
 
 int
-#line 3350
+#line 3355
 ncx_getn_uint_double(const void **xpp, size_t nelems, double *tp)
-#line 3350
+#line 3355
 {
-#line 3350
+#line 3355
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3350
+#line 3355
 
-#line 3350
+#line 3355
  /* basic algorithm is:
-#line 3350
+#line 3355
   *   - ensure sane alignment of input data
-#line 3350
+#line 3355
   *   - copy (conversion happens automatically) input data
-#line 3350
+#line 3355
   *     to output
-#line 3350
+#line 3355
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3350
+#line 3355
   *     at next location for converted output
-#line 3350
+#line 3355
   */
-#line 3350
+#line 3355
   long i, j, ni;
-#line 3350
+#line 3355
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3350
+#line 3355
   uint *xp;
-#line 3350
+#line 3355
   int nrange = 0;         /* number of range errors */
-#line 3350
+#line 3355
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3350
+#line 3355
   long cxp = (long) *((char**)xpp);
-#line 3350
+#line 3355
 
-#line 3350
+#line 3355
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3350
+#line 3355
   /* sjl: manually stripmine so we can limit amount of
-#line 3350
+#line 3355
    * vector work space reserved to LOOPCNT elements. Also
-#line 3350
+#line 3355
    * makes vectorisation easy */
-#line 3350
+#line 3355
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3350
+#line 3355
     ni=Min(nelems-j,LOOPCNT);
-#line 3350
+#line 3355
     if (realign) {
-#line 3350
+#line 3355
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3350
+#line 3355
       xp = tmp;
-#line 3350
+#line 3355
     } else {
-#line 3350
+#line 3355
       xp = (uint *) *xpp;
-#line 3350
+#line 3355
     }
-#line 3350
+#line 3355
    /* copy the next block */
-#line 3350
+#line 3355
 #pragma cdir loopcnt=LOOPCNT
-#line 3350
+#line 3355
 #pragma cdir shortloop
-#line 3350
+#line 3355
     for (i=0; i<ni; i++) {
-#line 3350
+#line 3355
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3350
+#line 3355
      /* test for range errors (not always needed but do it anyway) */
-#line 3350
+#line 3355
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3350
+#line 3355
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3350
+#line 3355
       nrange += xp[i] > DOUBLE_MAX ;
-#line 3350
+#line 3355
     }
-#line 3350
+#line 3355
    /* update xpp and tp */
-#line 3350
+#line 3355
     if (realign) xp = (uint *) *xpp;
-#line 3350
+#line 3355
     xp += ni;
-#line 3350
+#line 3355
     tp += ni;
-#line 3350
+#line 3355
     *xpp = (void*)xp;
-#line 3350
+#line 3355
   }
-#line 3350
+#line 3355
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3350
+#line 3355
 
-#line 3350
+#line 3355
 #else   /* not SX */
-#line 3350
+#line 3355
 	const char *xp = (const char *) *xpp;
-#line 3350
+#line 3355
 	int status = NC_NOERR;
-#line 3350
+#line 3355
 
-#line 3350
+#line 3355
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3350
+#line 3355
 	{
-#line 3350
+#line 3355
 		const int lstatus = ncx_get_uint_double(xp, tp);
-#line 3350
+#line 3355
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3350
+#line 3355
 			status = lstatus;
-#line 3350
+#line 3355
 	}
-#line 3350
+#line 3355
 
-#line 3350
+#line 3355
 	*xpp = (const void *)xp;
-#line 3350
+#line 3355
 	return status;
-#line 3350
+#line 3355
 #endif
-#line 3350
+#line 3355
 }
-#line 3350
+#line 3355
 
 int
-#line 3351
+#line 3356
 ncx_getn_uint_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3351
+#line 3356
 {
-#line 3351
+#line 3356
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3351
+#line 3356
 
-#line 3351
+#line 3356
  /* basic algorithm is:
-#line 3351
+#line 3356
   *   - ensure sane alignment of input data
-#line 3351
+#line 3356
   *   - copy (conversion happens automatically) input data
-#line 3351
+#line 3356
   *     to output
-#line 3351
+#line 3356
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3351
+#line 3356
   *     at next location for converted output
-#line 3351
+#line 3356
   */
-#line 3351
+#line 3356
   long i, j, ni;
-#line 3351
+#line 3356
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3351
+#line 3356
   uint *xp;
-#line 3351
+#line 3356
   int nrange = 0;         /* number of range errors */
-#line 3351
+#line 3356
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3351
+#line 3356
   long cxp = (long) *((char**)xpp);
-#line 3351
+#line 3356
 
-#line 3351
+#line 3356
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3351
+#line 3356
   /* sjl: manually stripmine so we can limit amount of
-#line 3351
+#line 3356
    * vector work space reserved to LOOPCNT elements. Also
-#line 3351
+#line 3356
    * makes vectorisation easy */
-#line 3351
+#line 3356
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3351
+#line 3356
     ni=Min(nelems-j,LOOPCNT);
-#line 3351
+#line 3356
     if (realign) {
-#line 3351
+#line 3356
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3351
+#line 3356
       xp = tmp;
-#line 3351
+#line 3356
     } else {
-#line 3351
+#line 3356
       xp = (uint *) *xpp;
-#line 3351
+#line 3356
     }
-#line 3351
+#line 3356
    /* copy the next block */
-#line 3351
+#line 3356
 #pragma cdir loopcnt=LOOPCNT
-#line 3351
+#line 3356
 #pragma cdir shortloop
-#line 3351
+#line 3356
     for (i=0; i<ni; i++) {
-#line 3351
+#line 3356
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3351
+#line 3356
      /* test for range errors (not always needed but do it anyway) */
-#line 3351
+#line 3356
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3351
+#line 3356
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3351
+#line 3356
       nrange += xp[i] > LONGLONG_MAX ;
-#line 3351
+#line 3356
     }
-#line 3351
+#line 3356
    /* update xpp and tp */
-#line 3351
+#line 3356
     if (realign) xp = (uint *) *xpp;
-#line 3351
+#line 3356
     xp += ni;
-#line 3351
+#line 3356
     tp += ni;
-#line 3351
+#line 3356
     *xpp = (void*)xp;
-#line 3351
+#line 3356
   }
-#line 3351
+#line 3356
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3351
+#line 3356
 
-#line 3351
+#line 3356
 #else   /* not SX */
-#line 3351
+#line 3356
 	const char *xp = (const char *) *xpp;
-#line 3351
+#line 3356
 	int status = NC_NOERR;
-#line 3351
+#line 3356
 
-#line 3351
+#line 3356
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3351
+#line 3356
 	{
-#line 3351
+#line 3356
 		const int lstatus = ncx_get_uint_longlong(xp, tp);
-#line 3351
+#line 3356
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3351
+#line 3356
 			status = lstatus;
-#line 3351
+#line 3356
 	}
-#line 3351
+#line 3356
 
-#line 3351
+#line 3356
 	*xpp = (const void *)xp;
-#line 3351
+#line 3356
 	return status;
-#line 3351
+#line 3356
 #endif
-#line 3351
+#line 3356
 }
-#line 3351
+#line 3356
 
 int
-#line 3352
+#line 3357
 ncx_getn_uint_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3352
+#line 3357
 {
-#line 3352
+#line 3357
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3352
+#line 3357
 
-#line 3352
+#line 3357
  /* basic algorithm is:
-#line 3352
+#line 3357
   *   - ensure sane alignment of input data
-#line 3352
+#line 3357
   *   - copy (conversion happens automatically) input data
-#line 3352
+#line 3357
   *     to output
-#line 3352
+#line 3357
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3352
+#line 3357
   *     at next location for converted output
-#line 3352
+#line 3357
   */
-#line 3352
+#line 3357
   long i, j, ni;
-#line 3352
+#line 3357
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3352
+#line 3357
   uint *xp;
-#line 3352
+#line 3357
   int nrange = 0;         /* number of range errors */
-#line 3352
+#line 3357
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3352
+#line 3357
   long cxp = (long) *((char**)xpp);
-#line 3352
+#line 3357
 
-#line 3352
+#line 3357
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3352
+#line 3357
   /* sjl: manually stripmine so we can limit amount of
-#line 3352
+#line 3357
    * vector work space reserved to LOOPCNT elements. Also
-#line 3352
+#line 3357
    * makes vectorisation easy */
-#line 3352
+#line 3357
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3352
+#line 3357
     ni=Min(nelems-j,LOOPCNT);
-#line 3352
+#line 3357
     if (realign) {
-#line 3352
+#line 3357
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3352
+#line 3357
       xp = tmp;
-#line 3352
+#line 3357
     } else {
-#line 3352
+#line 3357
       xp = (uint *) *xpp;
-#line 3352
+#line 3357
     }
-#line 3352
+#line 3357
    /* copy the next block */
-#line 3352
+#line 3357
 #pragma cdir loopcnt=LOOPCNT
-#line 3352
+#line 3357
 #pragma cdir shortloop
-#line 3352
+#line 3357
     for (i=0; i<ni; i++) {
-#line 3352
+#line 3357
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3352
+#line 3357
      /* test for range errors (not always needed but do it anyway) */
-#line 3352
+#line 3357
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3352
+#line 3357
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3352
+#line 3357
       nrange += xp[i] > UCHAR_MAX ;
-#line 3352
+#line 3357
     }
-#line 3352
+#line 3357
    /* update xpp and tp */
-#line 3352
+#line 3357
     if (realign) xp = (uint *) *xpp;
-#line 3352
+#line 3357
     xp += ni;
-#line 3352
+#line 3357
     tp += ni;
-#line 3352
+#line 3357
     *xpp = (void*)xp;
-#line 3352
+#line 3357
   }
-#line 3352
+#line 3357
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3352
+#line 3357
 
-#line 3352
+#line 3357
 #else   /* not SX */
-#line 3352
+#line 3357
 	const char *xp = (const char *) *xpp;
-#line 3352
+#line 3357
 	int status = NC_NOERR;
-#line 3352
+#line 3357
 
-#line 3352
+#line 3357
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3352
+#line 3357
 	{
-#line 3352
+#line 3357
 		const int lstatus = ncx_get_uint_uchar(xp, tp);
-#line 3352
+#line 3357
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3352
+#line 3357
 			status = lstatus;
-#line 3352
+#line 3357
 	}
-#line 3352
+#line 3357
 
-#line 3352
+#line 3357
 	*xpp = (const void *)xp;
-#line 3352
+#line 3357
 	return status;
-#line 3352
+#line 3357
 #endif
-#line 3352
+#line 3357
 }
-#line 3352
+#line 3357
 
 int
-#line 3353
+#line 3358
 ncx_getn_uint_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3353
+#line 3358
 {
-#line 3353
+#line 3358
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3353
+#line 3358
 
-#line 3353
+#line 3358
  /* basic algorithm is:
-#line 3353
+#line 3358
   *   - ensure sane alignment of input data
-#line 3353
+#line 3358
   *   - copy (conversion happens automatically) input data
-#line 3353
+#line 3358
   *     to output
-#line 3353
+#line 3358
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3353
+#line 3358
   *     at next location for converted output
-#line 3353
+#line 3358
   */
-#line 3353
+#line 3358
   long i, j, ni;
-#line 3353
+#line 3358
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3353
+#line 3358
   uint *xp;
-#line 3353
+#line 3358
   int nrange = 0;         /* number of range errors */
-#line 3353
+#line 3358
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3353
+#line 3358
   long cxp = (long) *((char**)xpp);
-#line 3353
+#line 3358
 
-#line 3353
+#line 3358
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3353
+#line 3358
   /* sjl: manually stripmine so we can limit amount of
-#line 3353
+#line 3358
    * vector work space reserved to LOOPCNT elements. Also
-#line 3353
+#line 3358
    * makes vectorisation easy */
-#line 3353
+#line 3358
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3353
+#line 3358
     ni=Min(nelems-j,LOOPCNT);
-#line 3353
+#line 3358
     if (realign) {
-#line 3353
+#line 3358
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3353
+#line 3358
       xp = tmp;
-#line 3353
+#line 3358
     } else {
-#line 3353
+#line 3358
       xp = (uint *) *xpp;
-#line 3353
+#line 3358
     }
-#line 3353
+#line 3358
    /* copy the next block */
-#line 3353
+#line 3358
 #pragma cdir loopcnt=LOOPCNT
-#line 3353
+#line 3358
 #pragma cdir shortloop
-#line 3353
+#line 3358
     for (i=0; i<ni; i++) {
-#line 3353
+#line 3358
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3353
+#line 3358
      /* test for range errors (not always needed but do it anyway) */
-#line 3353
+#line 3358
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3353
+#line 3358
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3353
+#line 3358
       nrange += xp[i] > USHORT_MAX ;
-#line 3353
+#line 3358
     }
-#line 3353
+#line 3358
    /* update xpp and tp */
-#line 3353
+#line 3358
     if (realign) xp = (uint *) *xpp;
-#line 3353
+#line 3358
     xp += ni;
-#line 3353
+#line 3358
     tp += ni;
-#line 3353
+#line 3358
     *xpp = (void*)xp;
-#line 3353
+#line 3358
   }
-#line 3353
+#line 3358
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3353
+#line 3358
 
-#line 3353
+#line 3358
 #else   /* not SX */
-#line 3353
+#line 3358
 	const char *xp = (const char *) *xpp;
-#line 3353
+#line 3358
 	int status = NC_NOERR;
-#line 3353
+#line 3358
 
-#line 3353
+#line 3358
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3353
+#line 3358
 	{
-#line 3353
+#line 3358
 		const int lstatus = ncx_get_uint_ushort(xp, tp);
-#line 3353
+#line 3358
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3353
+#line 3358
 			status = lstatus;
-#line 3353
+#line 3358
 	}
-#line 3353
+#line 3358
 
-#line 3353
+#line 3358
 	*xpp = (const void *)xp;
-#line 3353
+#line 3358
 	return status;
-#line 3353
+#line 3358
 #endif
-#line 3353
+#line 3358
 }
-#line 3353
+#line 3358
 
 int
-#line 3354
+#line 3359
 ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3354
+#line 3359
 {
-#line 3354
+#line 3359
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3354
+#line 3359
 
-#line 3354
+#line 3359
  /* basic algorithm is:
-#line 3354
+#line 3359
   *   - ensure sane alignment of input data
-#line 3354
+#line 3359
   *   - copy (conversion happens automatically) input data
-#line 3354
+#line 3359
   *     to output
-#line 3354
+#line 3359
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3354
+#line 3359
   *     at next location for converted output
-#line 3354
+#line 3359
   */
-#line 3354
+#line 3359
   long i, j, ni;
-#line 3354
+#line 3359
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3354
+#line 3359
   uint *xp;
-#line 3354
+#line 3359
   int nrange = 0;         /* number of range errors */
-#line 3354
+#line 3359
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3354
+#line 3359
   long cxp = (long) *((char**)xpp);
-#line 3354
+#line 3359
 
-#line 3354
+#line 3359
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3354
+#line 3359
   /* sjl: manually stripmine so we can limit amount of
-#line 3354
+#line 3359
    * vector work space reserved to LOOPCNT elements. Also
-#line 3354
+#line 3359
    * makes vectorisation easy */
-#line 3354
+#line 3359
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3354
+#line 3359
     ni=Min(nelems-j,LOOPCNT);
-#line 3354
+#line 3359
     if (realign) {
-#line 3354
+#line 3359
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
-#line 3354
+#line 3359
       xp = tmp;
-#line 3354
+#line 3359
     } else {
-#line 3354
+#line 3359
       xp = (uint *) *xpp;
-#line 3354
+#line 3359
     }
-#line 3354
+#line 3359
    /* copy the next block */
-#line 3354
+#line 3359
 #pragma cdir loopcnt=LOOPCNT
-#line 3354
+#line 3359
 #pragma cdir shortloop
-#line 3354
+#line 3359
     for (i=0; i<ni; i++) {
-#line 3354
+#line 3359
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3354
+#line 3359
      /* test for range errors (not always needed but do it anyway) */
-#line 3354
+#line 3359
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3354
+#line 3359
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3354
+#line 3359
       nrange += xp[i] > ULONGLONG_MAX ;
-#line 3354
+#line 3359
     }
-#line 3354
+#line 3359
    /* update xpp and tp */
-#line 3354
+#line 3359
     if (realign) xp = (uint *) *xpp;
-#line 3354
+#line 3359
     xp += ni;
-#line 3354
+#line 3359
     tp += ni;
-#line 3354
+#line 3359
     *xpp = (void*)xp;
-#line 3354
+#line 3359
   }
-#line 3354
+#line 3359
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3354
+#line 3359
 
-#line 3354
+#line 3359
 #else   /* not SX */
-#line 3354
+#line 3359
 	const char *xp = (const char *) *xpp;
-#line 3354
+#line 3359
 	int status = NC_NOERR;
-#line 3354
+#line 3359
 
-#line 3354
+#line 3359
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3354
+#line 3359
 	{
-#line 3354
+#line 3359
 		const int lstatus = ncx_get_uint_ulonglong(xp, tp);
-#line 3354
+#line 3359
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3354
+#line 3359
 			status = lstatus;
-#line 3354
+#line 3359
 	}
-#line 3354
+#line 3359
 
-#line 3354
+#line 3359
 	*xpp = (const void *)xp;
-#line 3354
+#line 3359
 	return status;
-#line 3354
+#line 3359
 #endif
-#line 3354
+#line 3359
 }
-#line 3354
+#line 3359
 
 
 #if X_SIZEOF_UINT == SIZEOF_UINT
@@ -25920,1534 +25925,1534 @@ ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp, void *fill
 }
 #else
 int
-#line 3370
+#line 3375
 ncx_putn_uint_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3370
+#line 3375
 {
-#line 3370
+#line 3375
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3370
+#line 3375
 
-#line 3370
+#line 3375
  /* basic algorithm is:
-#line 3370
+#line 3375
   *   - ensure sane alignment of output data
-#line 3370
+#line 3375
   *   - copy (conversion happens automatically) input data
-#line 3370
+#line 3375
   *     to output
-#line 3370
+#line 3375
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3370
+#line 3375
   *     at next location for converted output
-#line 3370
+#line 3375
   */
-#line 3370
+#line 3375
   long i, j, ni;
-#line 3370
+#line 3375
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3370
+#line 3375
   uint *xp;
-#line 3370
+#line 3375
   int nrange = 0;         /* number of range errors */
-#line 3370
+#line 3375
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3370
+#line 3375
   long cxp = (long) *((char**)xpp);
-#line 3370
+#line 3375
 
-#line 3370
+#line 3375
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3370
+#line 3375
   /* sjl: manually stripmine so we can limit amount of
-#line 3370
+#line 3375
    * vector work space reserved to LOOPCNT elements. Also
-#line 3370
+#line 3375
    * makes vectorisation easy */
-#line 3370
+#line 3375
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3370
+#line 3375
     ni=Min(nelems-j,LOOPCNT);
-#line 3370
+#line 3375
     if (realign) {
-#line 3370
+#line 3375
       xp = tmp;
-#line 3370
+#line 3375
     } else {
-#line 3370
+#line 3375
       xp = (uint *) *xpp;
-#line 3370
+#line 3375
     }
-#line 3370
+#line 3375
    /* copy the next block */
-#line 3370
+#line 3375
 #pragma cdir loopcnt=LOOPCNT
-#line 3370
+#line 3375
 #pragma cdir shortloop
-#line 3370
+#line 3375
     for (i=0; i<ni; i++) {
-#line 3370
+#line 3375
       /* the normal case: */
-#line 3370
+#line 3375
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3370
+#line 3375
      /* test for range errors (not always needed but do it anyway) */
-#line 3370
+#line 3375
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3370
+#line 3375
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3370
+#line 3375
       nrange += tp[i] > X_UINT_MAX ;
-#line 3370
+#line 3375
     }
-#line 3370
+#line 3375
    /* copy workspace back if necessary */
-#line 3370
+#line 3375
     if (realign) {
-#line 3370
+#line 3375
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3370
+#line 3375
       xp = (uint *) *xpp;
-#line 3370
+#line 3375
     }
-#line 3370
+#line 3375
    /* update xpp and tp */
-#line 3370
+#line 3375
     xp += ni;
-#line 3370
+#line 3375
     tp += ni;
-#line 3370
+#line 3375
     *xpp = (void*)xp;
-#line 3370
+#line 3375
   }
-#line 3370
+#line 3375
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3370
+#line 3375
 
-#line 3370
+#line 3375
 #else   /* not SX */
-#line 3370
+#line 3375
 
-#line 3370
+#line 3375
 	char *xp = (char *) *xpp;
-#line 3370
+#line 3375
 	int status = NC_NOERR;
-#line 3370
+#line 3375
 
-#line 3370
+#line 3375
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3370
+#line 3375
 	{
-#line 3370
+#line 3375
 		int lstatus = ncx_put_uint_uint(xp, tp, fillp);
-#line 3370
+#line 3375
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3370
+#line 3375
 			status = lstatus;
-#line 3370
+#line 3375
 	}
-#line 3370
+#line 3375
 
-#line 3370
+#line 3375
 	*xpp = (void *)xp;
-#line 3370
+#line 3375
 	return status;
-#line 3370
+#line 3375
 #endif
-#line 3370
+#line 3375
 }
-#line 3370
+#line 3375
 
 #endif
 int
-#line 3372
+#line 3377
 ncx_putn_uint_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3372
+#line 3377
 {
-#line 3372
+#line 3377
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3372
+#line 3377
 
-#line 3372
+#line 3377
  /* basic algorithm is:
-#line 3372
+#line 3377
   *   - ensure sane alignment of output data
-#line 3372
+#line 3377
   *   - copy (conversion happens automatically) input data
-#line 3372
+#line 3377
   *     to output
-#line 3372
+#line 3377
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3372
+#line 3377
   *     at next location for converted output
-#line 3372
+#line 3377
   */
-#line 3372
+#line 3377
   long i, j, ni;
-#line 3372
+#line 3377
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3372
+#line 3377
   uint *xp;
-#line 3372
+#line 3377
   int nrange = 0;         /* number of range errors */
-#line 3372
+#line 3377
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3372
+#line 3377
   long cxp = (long) *((char**)xpp);
-#line 3372
+#line 3377
 
-#line 3372
+#line 3377
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3372
+#line 3377
   /* sjl: manually stripmine so we can limit amount of
-#line 3372
+#line 3377
    * vector work space reserved to LOOPCNT elements. Also
-#line 3372
+#line 3377
    * makes vectorisation easy */
-#line 3372
+#line 3377
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3372
+#line 3377
     ni=Min(nelems-j,LOOPCNT);
-#line 3372
+#line 3377
     if (realign) {
-#line 3372
+#line 3377
       xp = tmp;
-#line 3372
+#line 3377
     } else {
-#line 3372
+#line 3377
       xp = (uint *) *xpp;
-#line 3372
+#line 3377
     }
-#line 3372
+#line 3377
    /* copy the next block */
-#line 3372
+#line 3377
 #pragma cdir loopcnt=LOOPCNT
-#line 3372
+#line 3377
 #pragma cdir shortloop
-#line 3372
+#line 3377
     for (i=0; i<ni; i++) {
-#line 3372
+#line 3377
       /* the normal case: */
-#line 3372
+#line 3377
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3372
+#line 3377
      /* test for range errors (not always needed but do it anyway) */
-#line 3372
+#line 3377
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3372
+#line 3377
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3372
+#line 3377
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3372
+#line 3377
     }
-#line 3372
+#line 3377
    /* copy workspace back if necessary */
-#line 3372
+#line 3377
     if (realign) {
-#line 3372
+#line 3377
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3372
+#line 3377
       xp = (uint *) *xpp;
-#line 3372
+#line 3377
     }
-#line 3372
+#line 3377
    /* update xpp and tp */
-#line 3372
+#line 3377
     xp += ni;
-#line 3372
+#line 3377
     tp += ni;
-#line 3372
+#line 3377
     *xpp = (void*)xp;
-#line 3372
+#line 3377
   }
-#line 3372
+#line 3377
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3372
+#line 3377
 
-#line 3372
+#line 3377
 #else   /* not SX */
-#line 3372
+#line 3377
 
-#line 3372
+#line 3377
 	char *xp = (char *) *xpp;
-#line 3372
+#line 3377
 	int status = NC_NOERR;
-#line 3372
+#line 3377
 
-#line 3372
+#line 3377
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3372
+#line 3377
 	{
-#line 3372
+#line 3377
 		int lstatus = ncx_put_uint_schar(xp, tp, fillp);
-#line 3372
+#line 3377
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3372
+#line 3377
 			status = lstatus;
-#line 3372
+#line 3377
 	}
-#line 3372
+#line 3377
 
-#line 3372
+#line 3377
 	*xpp = (void *)xp;
-#line 3372
+#line 3377
 	return status;
-#line 3372
+#line 3377
 #endif
-#line 3372
+#line 3377
 }
-#line 3372
+#line 3377
 
 int
-#line 3373
+#line 3378
 ncx_putn_uint_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3373
+#line 3378
 {
-#line 3373
+#line 3378
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3373
+#line 3378
 
-#line 3373
+#line 3378
  /* basic algorithm is:
-#line 3373
+#line 3378
   *   - ensure sane alignment of output data
-#line 3373
+#line 3378
   *   - copy (conversion happens automatically) input data
-#line 3373
+#line 3378
   *     to output
-#line 3373
+#line 3378
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3373
+#line 3378
   *     at next location for converted output
-#line 3373
+#line 3378
   */
-#line 3373
+#line 3378
   long i, j, ni;
-#line 3373
+#line 3378
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3373
+#line 3378
   uint *xp;
-#line 3373
+#line 3378
   int nrange = 0;         /* number of range errors */
-#line 3373
+#line 3378
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3373
+#line 3378
   long cxp = (long) *((char**)xpp);
-#line 3373
+#line 3378
 
-#line 3373
+#line 3378
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3373
+#line 3378
   /* sjl: manually stripmine so we can limit amount of
-#line 3373
+#line 3378
    * vector work space reserved to LOOPCNT elements. Also
-#line 3373
+#line 3378
    * makes vectorisation easy */
-#line 3373
+#line 3378
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3373
+#line 3378
     ni=Min(nelems-j,LOOPCNT);
-#line 3373
+#line 3378
     if (realign) {
-#line 3373
+#line 3378
       xp = tmp;
-#line 3373
+#line 3378
     } else {
-#line 3373
+#line 3378
       xp = (uint *) *xpp;
-#line 3373
+#line 3378
     }
-#line 3373
+#line 3378
    /* copy the next block */
-#line 3373
+#line 3378
 #pragma cdir loopcnt=LOOPCNT
-#line 3373
+#line 3378
 #pragma cdir shortloop
-#line 3373
+#line 3378
     for (i=0; i<ni; i++) {
-#line 3373
+#line 3378
       /* the normal case: */
-#line 3373
+#line 3378
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3373
+#line 3378
      /* test for range errors (not always needed but do it anyway) */
-#line 3373
+#line 3378
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3373
+#line 3378
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3373
+#line 3378
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3373
+#line 3378
     }
-#line 3373
+#line 3378
    /* copy workspace back if necessary */
-#line 3373
+#line 3378
     if (realign) {
-#line 3373
+#line 3378
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3373
+#line 3378
       xp = (uint *) *xpp;
-#line 3373
+#line 3378
     }
-#line 3373
+#line 3378
    /* update xpp and tp */
-#line 3373
+#line 3378
     xp += ni;
-#line 3373
+#line 3378
     tp += ni;
-#line 3373
+#line 3378
     *xpp = (void*)xp;
-#line 3373
+#line 3378
   }
-#line 3373
+#line 3378
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3373
+#line 3378
 
-#line 3373
+#line 3378
 #else   /* not SX */
-#line 3373
+#line 3378
 
-#line 3373
+#line 3378
 	char *xp = (char *) *xpp;
-#line 3373
+#line 3378
 	int status = NC_NOERR;
-#line 3373
+#line 3378
 
-#line 3373
+#line 3378
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3373
+#line 3378
 	{
-#line 3373
+#line 3378
 		int lstatus = ncx_put_uint_short(xp, tp, fillp);
-#line 3373
+#line 3378
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3373
+#line 3378
 			status = lstatus;
-#line 3373
+#line 3378
 	}
-#line 3373
+#line 3378
 
-#line 3373
+#line 3378
 	*xpp = (void *)xp;
-#line 3373
+#line 3378
 	return status;
-#line 3373
+#line 3378
 #endif
-#line 3373
+#line 3378
 }
-#line 3373
+#line 3378
 
 int
-#line 3374
+#line 3379
 ncx_putn_uint_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3374
+#line 3379
 {
-#line 3374
+#line 3379
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3374
+#line 3379
 
-#line 3374
+#line 3379
  /* basic algorithm is:
-#line 3374
+#line 3379
   *   - ensure sane alignment of output data
-#line 3374
+#line 3379
   *   - copy (conversion happens automatically) input data
-#line 3374
+#line 3379
   *     to output
-#line 3374
+#line 3379
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3374
+#line 3379
   *     at next location for converted output
-#line 3374
+#line 3379
   */
-#line 3374
+#line 3379
   long i, j, ni;
-#line 3374
+#line 3379
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3374
+#line 3379
   uint *xp;
-#line 3374
+#line 3379
   int nrange = 0;         /* number of range errors */
-#line 3374
+#line 3379
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3374
+#line 3379
   long cxp = (long) *((char**)xpp);
-#line 3374
+#line 3379
 
-#line 3374
+#line 3379
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3374
+#line 3379
   /* sjl: manually stripmine so we can limit amount of
-#line 3374
+#line 3379
    * vector work space reserved to LOOPCNT elements. Also
-#line 3374
+#line 3379
    * makes vectorisation easy */
-#line 3374
+#line 3379
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3374
+#line 3379
     ni=Min(nelems-j,LOOPCNT);
-#line 3374
+#line 3379
     if (realign) {
-#line 3374
+#line 3379
       xp = tmp;
-#line 3374
+#line 3379
     } else {
-#line 3374
+#line 3379
       xp = (uint *) *xpp;
-#line 3374
+#line 3379
     }
-#line 3374
+#line 3379
    /* copy the next block */
-#line 3374
+#line 3379
 #pragma cdir loopcnt=LOOPCNT
-#line 3374
+#line 3379
 #pragma cdir shortloop
-#line 3374
+#line 3379
     for (i=0; i<ni; i++) {
-#line 3374
+#line 3379
       /* the normal case: */
-#line 3374
+#line 3379
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3374
+#line 3379
      /* test for range errors (not always needed but do it anyway) */
-#line 3374
+#line 3379
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3374
+#line 3379
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3374
+#line 3379
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3374
+#line 3379
     }
-#line 3374
+#line 3379
    /* copy workspace back if necessary */
-#line 3374
+#line 3379
     if (realign) {
-#line 3374
+#line 3379
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3374
+#line 3379
       xp = (uint *) *xpp;
-#line 3374
+#line 3379
     }
-#line 3374
+#line 3379
    /* update xpp and tp */
-#line 3374
+#line 3379
     xp += ni;
-#line 3374
+#line 3379
     tp += ni;
-#line 3374
+#line 3379
     *xpp = (void*)xp;
-#line 3374
+#line 3379
   }
-#line 3374
+#line 3379
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3374
+#line 3379
 
-#line 3374
+#line 3379
 #else   /* not SX */
-#line 3374
+#line 3379
 
-#line 3374
+#line 3379
 	char *xp = (char *) *xpp;
-#line 3374
+#line 3379
 	int status = NC_NOERR;
-#line 3374
+#line 3379
 
-#line 3374
+#line 3379
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3374
+#line 3379
 	{
-#line 3374
+#line 3379
 		int lstatus = ncx_put_uint_int(xp, tp, fillp);
-#line 3374
+#line 3379
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3374
+#line 3379
 			status = lstatus;
-#line 3374
+#line 3379
 	}
-#line 3374
+#line 3379
 
-#line 3374
+#line 3379
 	*xpp = (void *)xp;
-#line 3374
+#line 3379
 	return status;
-#line 3374
+#line 3379
 #endif
-#line 3374
+#line 3379
 }
-#line 3374
+#line 3379
 
 int
-#line 3375
+#line 3380
 ncx_putn_uint_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3375
+#line 3380
 {
-#line 3375
+#line 3380
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3375
+#line 3380
 
-#line 3375
+#line 3380
  /* basic algorithm is:
-#line 3375
+#line 3380
   *   - ensure sane alignment of output data
-#line 3375
+#line 3380
   *   - copy (conversion happens automatically) input data
-#line 3375
+#line 3380
   *     to output
-#line 3375
+#line 3380
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3375
+#line 3380
   *     at next location for converted output
-#line 3375
+#line 3380
   */
-#line 3375
+#line 3380
   long i, j, ni;
-#line 3375
+#line 3380
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3375
+#line 3380
   uint *xp;
-#line 3375
+#line 3380
   int nrange = 0;         /* number of range errors */
-#line 3375
+#line 3380
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3375
+#line 3380
   long cxp = (long) *((char**)xpp);
-#line 3375
+#line 3380
 
-#line 3375
+#line 3380
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3375
+#line 3380
   /* sjl: manually stripmine so we can limit amount of
-#line 3375
+#line 3380
    * vector work space reserved to LOOPCNT elements. Also
-#line 3375
+#line 3380
    * makes vectorisation easy */
-#line 3375
+#line 3380
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3375
+#line 3380
     ni=Min(nelems-j,LOOPCNT);
-#line 3375
+#line 3380
     if (realign) {
-#line 3375
+#line 3380
       xp = tmp;
-#line 3375
+#line 3380
     } else {
-#line 3375
+#line 3380
       xp = (uint *) *xpp;
-#line 3375
+#line 3380
     }
-#line 3375
+#line 3380
    /* copy the next block */
-#line 3375
+#line 3380
 #pragma cdir loopcnt=LOOPCNT
-#line 3375
+#line 3380
 #pragma cdir shortloop
-#line 3375
+#line 3380
     for (i=0; i<ni; i++) {
-#line 3375
+#line 3380
       /* the normal case: */
-#line 3375
+#line 3380
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3375
+#line 3380
      /* test for range errors (not always needed but do it anyway) */
-#line 3375
+#line 3380
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3375
+#line 3380
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3375
+#line 3380
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3375
+#line 3380
     }
-#line 3375
+#line 3380
    /* copy workspace back if necessary */
-#line 3375
+#line 3380
     if (realign) {
-#line 3375
+#line 3380
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3375
+#line 3380
       xp = (uint *) *xpp;
-#line 3375
+#line 3380
     }
-#line 3375
+#line 3380
    /* update xpp and tp */
-#line 3375
+#line 3380
     xp += ni;
-#line 3375
+#line 3380
     tp += ni;
-#line 3375
+#line 3380
     *xpp = (void*)xp;
-#line 3375
+#line 3380
   }
-#line 3375
+#line 3380
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3375
+#line 3380
 
-#line 3375
+#line 3380
 #else   /* not SX */
-#line 3375
+#line 3380
 
-#line 3375
+#line 3380
 	char *xp = (char *) *xpp;
-#line 3375
+#line 3380
 	int status = NC_NOERR;
-#line 3375
+#line 3380
 
-#line 3375
+#line 3380
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3375
+#line 3380
 	{
-#line 3375
+#line 3380
 		int lstatus = ncx_put_uint_long(xp, tp, fillp);
-#line 3375
+#line 3380
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3375
+#line 3380
 			status = lstatus;
-#line 3375
+#line 3380
 	}
-#line 3375
+#line 3380
 
-#line 3375
+#line 3380
 	*xpp = (void *)xp;
-#line 3375
+#line 3380
 	return status;
-#line 3375
+#line 3380
 #endif
-#line 3375
+#line 3380
 }
-#line 3375
+#line 3380
 
 int
-#line 3376
+#line 3381
 ncx_putn_uint_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3376
+#line 3381
 {
-#line 3376
+#line 3381
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3376
+#line 3381
 
-#line 3376
+#line 3381
  /* basic algorithm is:
-#line 3376
+#line 3381
   *   - ensure sane alignment of output data
-#line 3376
+#line 3381
   *   - copy (conversion happens automatically) input data
-#line 3376
+#line 3381
   *     to output
-#line 3376
+#line 3381
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3376
+#line 3381
   *     at next location for converted output
-#line 3376
+#line 3381
   */
-#line 3376
+#line 3381
   long i, j, ni;
-#line 3376
+#line 3381
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3376
+#line 3381
   uint *xp;
-#line 3376
+#line 3381
   int nrange = 0;         /* number of range errors */
-#line 3376
+#line 3381
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3376
+#line 3381
   long cxp = (long) *((char**)xpp);
-#line 3376
+#line 3381
 
-#line 3376
+#line 3381
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3376
+#line 3381
   /* sjl: manually stripmine so we can limit amount of
-#line 3376
+#line 3381
    * vector work space reserved to LOOPCNT elements. Also
-#line 3376
+#line 3381
    * makes vectorisation easy */
-#line 3376
+#line 3381
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3376
+#line 3381
     ni=Min(nelems-j,LOOPCNT);
-#line 3376
+#line 3381
     if (realign) {
-#line 3376
+#line 3381
       xp = tmp;
-#line 3376
+#line 3381
     } else {
-#line 3376
+#line 3381
       xp = (uint *) *xpp;
-#line 3376
+#line 3381
     }
-#line 3376
+#line 3381
    /* copy the next block */
-#line 3376
+#line 3381
 #pragma cdir loopcnt=LOOPCNT
-#line 3376
+#line 3381
 #pragma cdir shortloop
-#line 3376
+#line 3381
     for (i=0; i<ni; i++) {
-#line 3376
+#line 3381
       /* the normal case: */
-#line 3376
+#line 3381
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3376
+#line 3381
      /* test for range errors (not always needed but do it anyway) */
-#line 3376
+#line 3381
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3376
+#line 3381
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3376
+#line 3381
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3376
+#line 3381
     }
-#line 3376
+#line 3381
    /* copy workspace back if necessary */
-#line 3376
+#line 3381
     if (realign) {
-#line 3376
+#line 3381
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3376
+#line 3381
       xp = (uint *) *xpp;
-#line 3376
+#line 3381
     }
-#line 3376
+#line 3381
    /* update xpp and tp */
-#line 3376
+#line 3381
     xp += ni;
-#line 3376
+#line 3381
     tp += ni;
-#line 3376
+#line 3381
     *xpp = (void*)xp;
-#line 3376
+#line 3381
   }
-#line 3376
+#line 3381
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3376
+#line 3381
 
-#line 3376
+#line 3381
 #else   /* not SX */
-#line 3376
+#line 3381
 
-#line 3376
+#line 3381
 	char *xp = (char *) *xpp;
-#line 3376
+#line 3381
 	int status = NC_NOERR;
-#line 3376
+#line 3381
 
-#line 3376
+#line 3381
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3376
+#line 3381
 	{
-#line 3376
+#line 3381
 		int lstatus = ncx_put_uint_float(xp, tp, fillp);
-#line 3376
+#line 3381
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3376
+#line 3381
 			status = lstatus;
-#line 3376
+#line 3381
 	}
-#line 3376
+#line 3381
 
-#line 3376
+#line 3381
 	*xpp = (void *)xp;
-#line 3376
+#line 3381
 	return status;
-#line 3376
+#line 3381
 #endif
-#line 3376
+#line 3381
 }
-#line 3376
+#line 3381
 
 int
-#line 3377
+#line 3382
 ncx_putn_uint_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3377
+#line 3382
 {
-#line 3377
+#line 3382
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3377
+#line 3382
 
-#line 3377
+#line 3382
  /* basic algorithm is:
-#line 3377
+#line 3382
   *   - ensure sane alignment of output data
-#line 3377
+#line 3382
   *   - copy (conversion happens automatically) input data
-#line 3377
+#line 3382
   *     to output
-#line 3377
+#line 3382
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3377
+#line 3382
   *     at next location for converted output
-#line 3377
+#line 3382
   */
-#line 3377
+#line 3382
   long i, j, ni;
-#line 3377
+#line 3382
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3377
+#line 3382
   uint *xp;
-#line 3377
+#line 3382
   int nrange = 0;         /* number of range errors */
-#line 3377
+#line 3382
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3377
+#line 3382
   long cxp = (long) *((char**)xpp);
-#line 3377
+#line 3382
 
-#line 3377
+#line 3382
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3377
+#line 3382
   /* sjl: manually stripmine so we can limit amount of
-#line 3377
+#line 3382
    * vector work space reserved to LOOPCNT elements. Also
-#line 3377
+#line 3382
    * makes vectorisation easy */
-#line 3377
+#line 3382
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3377
+#line 3382
     ni=Min(nelems-j,LOOPCNT);
-#line 3377
+#line 3382
     if (realign) {
-#line 3377
+#line 3382
       xp = tmp;
-#line 3377
+#line 3382
     } else {
-#line 3377
+#line 3382
       xp = (uint *) *xpp;
-#line 3377
+#line 3382
     }
-#line 3377
+#line 3382
    /* copy the next block */
-#line 3377
+#line 3382
 #pragma cdir loopcnt=LOOPCNT
-#line 3377
+#line 3382
 #pragma cdir shortloop
-#line 3377
+#line 3382
     for (i=0; i<ni; i++) {
-#line 3377
+#line 3382
       /* the normal case: */
-#line 3377
+#line 3382
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3377
+#line 3382
      /* test for range errors (not always needed but do it anyway) */
-#line 3377
+#line 3382
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3377
+#line 3382
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3377
+#line 3382
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3377
+#line 3382
     }
-#line 3377
+#line 3382
    /* copy workspace back if necessary */
-#line 3377
+#line 3382
     if (realign) {
-#line 3377
+#line 3382
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3377
+#line 3382
       xp = (uint *) *xpp;
-#line 3377
+#line 3382
     }
-#line 3377
+#line 3382
    /* update xpp and tp */
-#line 3377
+#line 3382
     xp += ni;
-#line 3377
+#line 3382
     tp += ni;
-#line 3377
+#line 3382
     *xpp = (void*)xp;
-#line 3377
+#line 3382
   }
-#line 3377
+#line 3382
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3377
+#line 3382
 
-#line 3377
+#line 3382
 #else   /* not SX */
-#line 3377
+#line 3382
 
-#line 3377
+#line 3382
 	char *xp = (char *) *xpp;
-#line 3377
+#line 3382
 	int status = NC_NOERR;
-#line 3377
+#line 3382
 
-#line 3377
+#line 3382
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3377
+#line 3382
 	{
-#line 3377
+#line 3382
 		int lstatus = ncx_put_uint_double(xp, tp, fillp);
-#line 3377
+#line 3382
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3377
+#line 3382
 			status = lstatus;
-#line 3377
+#line 3382
 	}
-#line 3377
+#line 3382
 
-#line 3377
+#line 3382
 	*xpp = (void *)xp;
-#line 3377
+#line 3382
 	return status;
-#line 3377
+#line 3382
 #endif
-#line 3377
+#line 3382
 }
-#line 3377
+#line 3382
 
 int
-#line 3378
+#line 3383
 ncx_putn_uint_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3378
+#line 3383
 {
-#line 3378
+#line 3383
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3378
+#line 3383
 
-#line 3378
+#line 3383
  /* basic algorithm is:
-#line 3378
+#line 3383
   *   - ensure sane alignment of output data
-#line 3378
+#line 3383
   *   - copy (conversion happens automatically) input data
-#line 3378
+#line 3383
   *     to output
-#line 3378
+#line 3383
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3378
+#line 3383
   *     at next location for converted output
-#line 3378
+#line 3383
   */
-#line 3378
+#line 3383
   long i, j, ni;
-#line 3378
+#line 3383
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3378
+#line 3383
   uint *xp;
-#line 3378
+#line 3383
   int nrange = 0;         /* number of range errors */
-#line 3378
+#line 3383
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3378
+#line 3383
   long cxp = (long) *((char**)xpp);
-#line 3378
+#line 3383
 
-#line 3378
+#line 3383
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3378
+#line 3383
   /* sjl: manually stripmine so we can limit amount of
-#line 3378
+#line 3383
    * vector work space reserved to LOOPCNT elements. Also
-#line 3378
+#line 3383
    * makes vectorisation easy */
-#line 3378
+#line 3383
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3378
+#line 3383
     ni=Min(nelems-j,LOOPCNT);
-#line 3378
+#line 3383
     if (realign) {
-#line 3378
+#line 3383
       xp = tmp;
-#line 3378
+#line 3383
     } else {
-#line 3378
+#line 3383
       xp = (uint *) *xpp;
-#line 3378
+#line 3383
     }
-#line 3378
+#line 3383
    /* copy the next block */
-#line 3378
+#line 3383
 #pragma cdir loopcnt=LOOPCNT
-#line 3378
+#line 3383
 #pragma cdir shortloop
-#line 3378
+#line 3383
     for (i=0; i<ni; i++) {
-#line 3378
+#line 3383
       /* the normal case: */
-#line 3378
+#line 3383
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3378
+#line 3383
      /* test for range errors (not always needed but do it anyway) */
-#line 3378
+#line 3383
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3378
+#line 3383
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3378
+#line 3383
       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
-#line 3378
+#line 3383
     }
-#line 3378
+#line 3383
    /* copy workspace back if necessary */
-#line 3378
+#line 3383
     if (realign) {
-#line 3378
+#line 3383
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3378
+#line 3383
       xp = (uint *) *xpp;
-#line 3378
+#line 3383
     }
-#line 3378
+#line 3383
    /* update xpp and tp */
-#line 3378
+#line 3383
     xp += ni;
-#line 3378
+#line 3383
     tp += ni;
-#line 3378
+#line 3383
     *xpp = (void*)xp;
-#line 3378
+#line 3383
   }
-#line 3378
+#line 3383
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3378
+#line 3383
 
-#line 3378
+#line 3383
 #else   /* not SX */
-#line 3378
+#line 3383
 
-#line 3378
+#line 3383
 	char *xp = (char *) *xpp;
-#line 3378
+#line 3383
 	int status = NC_NOERR;
-#line 3378
+#line 3383
 
-#line 3378
+#line 3383
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3378
+#line 3383
 	{
-#line 3378
+#line 3383
 		int lstatus = ncx_put_uint_longlong(xp, tp, fillp);
-#line 3378
+#line 3383
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3378
+#line 3383
 			status = lstatus;
-#line 3378
+#line 3383
 	}
-#line 3378
+#line 3383
 
-#line 3378
+#line 3383
 	*xpp = (void *)xp;
-#line 3378
+#line 3383
 	return status;
-#line 3378
+#line 3383
 #endif
-#line 3378
+#line 3383
 }
-#line 3378
+#line 3383
 
 int
-#line 3379
+#line 3384
 ncx_putn_uint_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3379
+#line 3384
 {
-#line 3379
+#line 3384
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3379
+#line 3384
 
-#line 3379
+#line 3384
  /* basic algorithm is:
-#line 3379
+#line 3384
   *   - ensure sane alignment of output data
-#line 3379
+#line 3384
   *   - copy (conversion happens automatically) input data
-#line 3379
+#line 3384
   *     to output
-#line 3379
+#line 3384
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3379
+#line 3384
   *     at next location for converted output
-#line 3379
+#line 3384
   */
-#line 3379
+#line 3384
   long i, j, ni;
-#line 3379
+#line 3384
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3379
+#line 3384
   uint *xp;
-#line 3379
+#line 3384
   int nrange = 0;         /* number of range errors */
-#line 3379
+#line 3384
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3379
+#line 3384
   long cxp = (long) *((char**)xpp);
-#line 3379
+#line 3384
 
-#line 3379
+#line 3384
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3379
+#line 3384
   /* sjl: manually stripmine so we can limit amount of
-#line 3379
+#line 3384
    * vector work space reserved to LOOPCNT elements. Also
-#line 3379
+#line 3384
    * makes vectorisation easy */
-#line 3379
+#line 3384
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3379
+#line 3384
     ni=Min(nelems-j,LOOPCNT);
-#line 3379
+#line 3384
     if (realign) {
-#line 3379
+#line 3384
       xp = tmp;
-#line 3379
+#line 3384
     } else {
-#line 3379
+#line 3384
       xp = (uint *) *xpp;
-#line 3379
+#line 3384
     }
-#line 3379
+#line 3384
    /* copy the next block */
-#line 3379
+#line 3384
 #pragma cdir loopcnt=LOOPCNT
-#line 3379
+#line 3384
 #pragma cdir shortloop
-#line 3379
+#line 3384
     for (i=0; i<ni; i++) {
-#line 3379
+#line 3384
       /* the normal case: */
-#line 3379
+#line 3384
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3379
+#line 3384
      /* test for range errors (not always needed but do it anyway) */
-#line 3379
+#line 3384
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3379
+#line 3384
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3379
+#line 3384
       nrange += tp[i] > X_UINT_MAX ;
-#line 3379
+#line 3384
     }
-#line 3379
+#line 3384
    /* copy workspace back if necessary */
-#line 3379
+#line 3384
     if (realign) {
-#line 3379
+#line 3384
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3379
+#line 3384
       xp = (uint *) *xpp;
-#line 3379
+#line 3384
     }
-#line 3379
+#line 3384
    /* update xpp and tp */
-#line 3379
+#line 3384
     xp += ni;
-#line 3379
+#line 3384
     tp += ni;
-#line 3379
+#line 3384
     *xpp = (void*)xp;
-#line 3379
+#line 3384
   }
-#line 3379
+#line 3384
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3379
+#line 3384
 
-#line 3379
+#line 3384
 #else   /* not SX */
-#line 3379
+#line 3384
 
-#line 3379
+#line 3384
 	char *xp = (char *) *xpp;
-#line 3379
+#line 3384
 	int status = NC_NOERR;
-#line 3379
+#line 3384
 
-#line 3379
+#line 3384
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3379
+#line 3384
 	{
-#line 3379
+#line 3384
 		int lstatus = ncx_put_uint_uchar(xp, tp, fillp);
-#line 3379
+#line 3384
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3379
+#line 3384
 			status = lstatus;
-#line 3379
+#line 3384
 	}
-#line 3379
+#line 3384
 
-#line 3379
+#line 3384
 	*xpp = (void *)xp;
-#line 3379
+#line 3384
 	return status;
-#line 3379
+#line 3384
 #endif
-#line 3379
+#line 3384
 }
-#line 3379
+#line 3384
 
 int
-#line 3380
+#line 3385
 ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3380
+#line 3385
 {
-#line 3380
+#line 3385
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3380
+#line 3385
 
-#line 3380
+#line 3385
  /* basic algorithm is:
-#line 3380
+#line 3385
   *   - ensure sane alignment of output data
-#line 3380
+#line 3385
   *   - copy (conversion happens automatically) input data
-#line 3380
+#line 3385
   *     to output
-#line 3380
+#line 3385
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3380
+#line 3385
   *     at next location for converted output
-#line 3380
+#line 3385
   */
-#line 3380
+#line 3385
   long i, j, ni;
-#line 3380
+#line 3385
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3380
+#line 3385
   uint *xp;
-#line 3380
+#line 3385
   int nrange = 0;         /* number of range errors */
-#line 3380
+#line 3385
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3380
+#line 3385
   long cxp = (long) *((char**)xpp);
-#line 3380
+#line 3385
 
-#line 3380
+#line 3385
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3380
+#line 3385
   /* sjl: manually stripmine so we can limit amount of
-#line 3380
+#line 3385
    * vector work space reserved to LOOPCNT elements. Also
-#line 3380
+#line 3385
    * makes vectorisation easy */
-#line 3380
+#line 3385
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3380
+#line 3385
     ni=Min(nelems-j,LOOPCNT);
-#line 3380
+#line 3385
     if (realign) {
-#line 3380
+#line 3385
       xp = tmp;
-#line 3380
+#line 3385
     } else {
-#line 3380
+#line 3385
       xp = (uint *) *xpp;
-#line 3380
+#line 3385
     }
-#line 3380
+#line 3385
    /* copy the next block */
-#line 3380
+#line 3385
 #pragma cdir loopcnt=LOOPCNT
-#line 3380
+#line 3385
 #pragma cdir shortloop
-#line 3380
+#line 3385
     for (i=0; i<ni; i++) {
-#line 3380
+#line 3385
       /* the normal case: */
-#line 3380
+#line 3385
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3380
+#line 3385
      /* test for range errors (not always needed but do it anyway) */
-#line 3380
+#line 3385
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3380
+#line 3385
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3380
+#line 3385
       nrange += tp[i] > X_UINT_MAX ;
-#line 3380
+#line 3385
     }
-#line 3380
+#line 3385
    /* copy workspace back if necessary */
-#line 3380
+#line 3385
     if (realign) {
-#line 3380
+#line 3385
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3380
+#line 3385
       xp = (uint *) *xpp;
-#line 3380
+#line 3385
     }
-#line 3380
+#line 3385
    /* update xpp and tp */
-#line 3380
+#line 3385
     xp += ni;
-#line 3380
+#line 3385
     tp += ni;
-#line 3380
+#line 3385
     *xpp = (void*)xp;
-#line 3380
+#line 3385
   }
-#line 3380
+#line 3385
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3380
+#line 3385
 
-#line 3380
+#line 3385
 #else   /* not SX */
-#line 3380
+#line 3385
 
-#line 3380
+#line 3385
 	char *xp = (char *) *xpp;
-#line 3380
+#line 3385
 	int status = NC_NOERR;
-#line 3380
+#line 3385
 
-#line 3380
+#line 3385
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3380
+#line 3385
 	{
-#line 3380
+#line 3385
 		int lstatus = ncx_put_uint_ushort(xp, tp, fillp);
-#line 3380
+#line 3385
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3380
+#line 3385
 			status = lstatus;
-#line 3380
+#line 3385
 	}
-#line 3380
+#line 3385
 
-#line 3380
+#line 3385
 	*xpp = (void *)xp;
-#line 3380
+#line 3385
 	return status;
-#line 3380
+#line 3385
 #endif
-#line 3380
+#line 3385
 }
-#line 3380
+#line 3385
 
 int
-#line 3381
+#line 3386
 ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3381
+#line 3386
 {
-#line 3381
+#line 3386
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
-#line 3381
+#line 3386
 
-#line 3381
+#line 3386
  /* basic algorithm is:
-#line 3381
+#line 3386
   *   - ensure sane alignment of output data
-#line 3381
+#line 3386
   *   - copy (conversion happens automatically) input data
-#line 3381
+#line 3386
   *     to output
-#line 3381
+#line 3386
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3381
+#line 3386
   *     at next location for converted output
-#line 3381
+#line 3386
   */
-#line 3381
+#line 3386
   long i, j, ni;
-#line 3381
+#line 3386
   uint tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3381
+#line 3386
   uint *xp;
-#line 3381
+#line 3386
   int nrange = 0;         /* number of range errors */
-#line 3381
+#line 3386
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3381
+#line 3386
   long cxp = (long) *((char**)xpp);
-#line 3381
+#line 3386
 
-#line 3381
+#line 3386
   realign = (cxp & 7) % SIZEOF_UINT;
-#line 3381
+#line 3386
   /* sjl: manually stripmine so we can limit amount of
-#line 3381
+#line 3386
    * vector work space reserved to LOOPCNT elements. Also
-#line 3381
+#line 3386
    * makes vectorisation easy */
-#line 3381
+#line 3386
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3381
+#line 3386
     ni=Min(nelems-j,LOOPCNT);
-#line 3381
+#line 3386
     if (realign) {
-#line 3381
+#line 3386
       xp = tmp;
-#line 3381
+#line 3386
     } else {
-#line 3381
+#line 3386
       xp = (uint *) *xpp;
-#line 3381
+#line 3386
     }
-#line 3381
+#line 3386
    /* copy the next block */
-#line 3381
+#line 3386
 #pragma cdir loopcnt=LOOPCNT
-#line 3381
+#line 3386
 #pragma cdir shortloop
-#line 3381
+#line 3386
     for (i=0; i<ni; i++) {
-#line 3381
+#line 3386
       /* the normal case: */
-#line 3381
+#line 3386
       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
-#line 3381
+#line 3386
      /* test for range errors (not always needed but do it anyway) */
-#line 3381
+#line 3386
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3381
+#line 3386
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3381
+#line 3386
       nrange += tp[i] > X_UINT_MAX ;
-#line 3381
+#line 3386
     }
-#line 3381
+#line 3386
    /* copy workspace back if necessary */
-#line 3381
+#line 3386
     if (realign) {
-#line 3381
+#line 3386
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
-#line 3381
+#line 3386
       xp = (uint *) *xpp;
-#line 3381
+#line 3386
     }
-#line 3381
+#line 3386
    /* update xpp and tp */
-#line 3381
+#line 3386
     xp += ni;
-#line 3381
+#line 3386
     tp += ni;
-#line 3381
+#line 3386
     *xpp = (void*)xp;
-#line 3381
+#line 3386
   }
-#line 3381
+#line 3386
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3381
+#line 3386
 
-#line 3381
+#line 3386
 #else   /* not SX */
-#line 3381
+#line 3386
 
-#line 3381
+#line 3386
 	char *xp = (char *) *xpp;
-#line 3381
+#line 3386
 	int status = NC_NOERR;
-#line 3381
+#line 3386
 
-#line 3381
+#line 3386
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
-#line 3381
+#line 3386
 	{
-#line 3381
+#line 3386
 		int lstatus = ncx_put_uint_ulonglong(xp, tp, fillp);
-#line 3381
+#line 3386
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3381
+#line 3386
 			status = lstatus;
-#line 3381
+#line 3386
 	}
-#line 3381
+#line 3386
 
-#line 3381
+#line 3386
 	*xpp = (void *)xp;
-#line 3381
+#line 3386
 	return status;
-#line 3381
+#line 3386
 #endif
-#line 3381
+#line 3386
 }
-#line 3381
+#line 3386
 
 
 
@@ -27475,95 +27480,95 @@ ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
 	while (ip < end)
 	{
 		struct vax_single *const vsp = (struct vax_single *) ip;
-#line 3407
+#line 3412
 		const struct ieee_single *const isp =
-#line 3407
+#line 3412
 			 (const struct ieee_single *) (*xpp);
-#line 3407
+#line 3412
 		unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
-#line 3407
+#line 3412
 
-#line 3407
+#line 3412
 		switch(exp) {
-#line 3407
+#line 3412
 		case 0 :
-#line 3407
+#line 3412
 			/* ieee subnormal */
-#line 3407
+#line 3412
 			if (isp->mant_hi == min.ieee.mant_hi
-#line 3407
+#line 3412
 				&& isp->mant_lo_hi == min.ieee.mant_lo_hi
-#line 3407
+#line 3412
 				&& isp->mant_lo_lo == min.ieee.mant_lo_lo)
-#line 3407
+#line 3412
 			{
-#line 3407
+#line 3412
 				*vsp = min.s;
-#line 3407
+#line 3412
 			}
-#line 3407
+#line 3412
 			else
-#line 3407
+#line 3412
 			{
-#line 3407
+#line 3412
 				unsigned mantissa = (isp->mant_hi << 16)
-#line 3407
+#line 3412
 					 | isp->mant_lo_hi << 8
-#line 3407
+#line 3412
 					 | isp->mant_lo_lo;
-#line 3407
+#line 3412
 				unsigned tmp = mantissa >> 20;
-#line 3407
+#line 3412
 				if (tmp >= 4) {
-#line 3407
+#line 3412
 					vsp->exp = 2;
-#line 3407
+#line 3412
 				} else if (tmp >= 2) {
-#line 3407
+#line 3412
 					vsp->exp = 1;
-#line 3407
+#line 3412
 				} else {
-#line 3407
+#line 3412
 					*vsp = min.s;
-#line 3407
+#line 3412
 					break;
-#line 3407
+#line 3412
 				} /* else */
-#line 3407
+#line 3412
 				tmp = mantissa - (1 << (20 + vsp->exp ));
-#line 3407
+#line 3412
 				tmp <<= 3 - vsp->exp;
-#line 3407
+#line 3412
 				vsp->mantissa2 = tmp;
-#line 3407
+#line 3412
 				vsp->mantissa1 = (tmp >> 16);
-#line 3407
+#line 3412
 			}
-#line 3407
+#line 3412
 			break;
-#line 3407
+#line 3412
 		case 0xfe :
-#line 3407
+#line 3412
 		case 0xff :
-#line 3407
+#line 3412
 			*vsp = max.s;
-#line 3407
+#line 3412
 			break;
-#line 3407
+#line 3412
 		default :
-#line 3407
+#line 3412
 			vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
-#line 3407
+#line 3412
 			vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
-#line 3407
+#line 3412
 			vsp->mantissa1 = isp->mant_hi;
-#line 3407
+#line 3412
 		}
-#line 3407
+#line 3412
 
-#line 3407
+#line 3412
 		vsp->sign = isp->sign;
-#line 3407
+#line 3412
 
 
 		ip++;
@@ -27591,1294 +27596,1294 @@ ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
 
 #endif
 int
-#line 3433
+#line 3438
 ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3433
+#line 3438
 {
-#line 3433
+#line 3438
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3433
+#line 3438
 
-#line 3433
+#line 3438
  /* basic algorithm is:
-#line 3433
+#line 3438
   *   - ensure sane alignment of input data
-#line 3433
+#line 3438
   *   - copy (conversion happens automatically) input data
-#line 3433
+#line 3438
   *     to output
-#line 3433
+#line 3438
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3433
+#line 3438
   *     at next location for converted output
-#line 3433
+#line 3438
   */
-#line 3433
+#line 3438
   long i, j, ni;
-#line 3433
+#line 3438
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3433
+#line 3438
   float *xp;
-#line 3433
+#line 3438
   int nrange = 0;         /* number of range errors */
-#line 3433
+#line 3438
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3433
+#line 3438
   long cxp = (long) *((char**)xpp);
-#line 3433
+#line 3438
 
-#line 3433
+#line 3438
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3433
+#line 3438
   /* sjl: manually stripmine so we can limit amount of
-#line 3433
+#line 3438
    * vector work space reserved to LOOPCNT elements. Also
-#line 3433
+#line 3438
    * makes vectorisation easy */
-#line 3433
+#line 3438
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3433
+#line 3438
     ni=Min(nelems-j,LOOPCNT);
-#line 3433
+#line 3438
     if (realign) {
-#line 3433
+#line 3438
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3433
+#line 3438
       xp = tmp;
-#line 3433
+#line 3438
     } else {
-#line 3433
+#line 3438
       xp = (float *) *xpp;
-#line 3433
+#line 3438
     }
-#line 3433
+#line 3438
    /* copy the next block */
-#line 3433
+#line 3438
 #pragma cdir loopcnt=LOOPCNT
-#line 3433
+#line 3438
 #pragma cdir shortloop
-#line 3433
+#line 3438
     for (i=0; i<ni; i++) {
-#line 3433
+#line 3438
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3433
+#line 3438
      /* test for range errors (not always needed but do it anyway) */
-#line 3433
+#line 3438
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3433
+#line 3438
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3433
+#line 3438
       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
-#line 3433
+#line 3438
     }
-#line 3433
+#line 3438
    /* update xpp and tp */
-#line 3433
+#line 3438
     if (realign) xp = (float *) *xpp;
-#line 3433
+#line 3438
     xp += ni;
-#line 3433
+#line 3438
     tp += ni;
-#line 3433
+#line 3438
     *xpp = (void*)xp;
-#line 3433
+#line 3438
   }
-#line 3433
+#line 3438
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3433
+#line 3438
 
-#line 3433
+#line 3438
 #else   /* not SX */
-#line 3433
+#line 3438
 	const char *xp = (const char *) *xpp;
-#line 3433
+#line 3438
 	int status = NC_NOERR;
-#line 3433
+#line 3438
 
-#line 3433
+#line 3438
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3433
+#line 3438
 	{
-#line 3433
+#line 3438
 		const int lstatus = ncx_get_float_schar(xp, tp);
-#line 3433
+#line 3438
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3433
+#line 3438
 			status = lstatus;
-#line 3433
+#line 3438
 	}
-#line 3433
+#line 3438
 
-#line 3433
+#line 3438
 	*xpp = (const void *)xp;
-#line 3433
+#line 3438
 	return status;
-#line 3433
+#line 3438
 #endif
-#line 3433
+#line 3438
 }
-#line 3433
+#line 3438
 
 int
-#line 3434
+#line 3439
 ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
-#line 3434
+#line 3439
 {
-#line 3434
+#line 3439
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3434
+#line 3439
 
-#line 3434
+#line 3439
  /* basic algorithm is:
-#line 3434
+#line 3439
   *   - ensure sane alignment of input data
-#line 3434
+#line 3439
   *   - copy (conversion happens automatically) input data
-#line 3434
+#line 3439
   *     to output
-#line 3434
+#line 3439
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3434
+#line 3439
   *     at next location for converted output
-#line 3434
+#line 3439
   */
-#line 3434
+#line 3439
   long i, j, ni;
-#line 3434
+#line 3439
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3434
+#line 3439
   float *xp;
-#line 3434
+#line 3439
   int nrange = 0;         /* number of range errors */
-#line 3434
+#line 3439
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3434
+#line 3439
   long cxp = (long) *((char**)xpp);
-#line 3434
+#line 3439
 
-#line 3434
+#line 3439
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3434
+#line 3439
   /* sjl: manually stripmine so we can limit amount of
-#line 3434
+#line 3439
    * vector work space reserved to LOOPCNT elements. Also
-#line 3434
+#line 3439
    * makes vectorisation easy */
-#line 3434
+#line 3439
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3434
+#line 3439
     ni=Min(nelems-j,LOOPCNT);
-#line 3434
+#line 3439
     if (realign) {
-#line 3434
+#line 3439
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3434
+#line 3439
       xp = tmp;
-#line 3434
+#line 3439
     } else {
-#line 3434
+#line 3439
       xp = (float *) *xpp;
-#line 3434
+#line 3439
     }
-#line 3434
+#line 3439
    /* copy the next block */
-#line 3434
+#line 3439
 #pragma cdir loopcnt=LOOPCNT
-#line 3434
+#line 3439
 #pragma cdir shortloop
-#line 3434
+#line 3439
     for (i=0; i<ni; i++) {
-#line 3434
+#line 3439
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3434
+#line 3439
      /* test for range errors (not always needed but do it anyway) */
-#line 3434
+#line 3439
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3434
+#line 3439
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3434
+#line 3439
       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
-#line 3434
+#line 3439
     }
-#line 3434
+#line 3439
    /* update xpp and tp */
-#line 3434
+#line 3439
     if (realign) xp = (float *) *xpp;
-#line 3434
+#line 3439
     xp += ni;
-#line 3434
+#line 3439
     tp += ni;
-#line 3434
+#line 3439
     *xpp = (void*)xp;
-#line 3434
+#line 3439
   }
-#line 3434
+#line 3439
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3434
+#line 3439
 
-#line 3434
+#line 3439
 #else   /* not SX */
-#line 3434
+#line 3439
 	const char *xp = (const char *) *xpp;
-#line 3434
+#line 3439
 	int status = NC_NOERR;
-#line 3434
+#line 3439
 
-#line 3434
+#line 3439
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3434
+#line 3439
 	{
-#line 3434
+#line 3439
 		const int lstatus = ncx_get_float_short(xp, tp);
-#line 3434
+#line 3439
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3434
+#line 3439
 			status = lstatus;
-#line 3434
+#line 3439
 	}
-#line 3434
+#line 3439
 
-#line 3434
+#line 3439
 	*xpp = (const void *)xp;
-#line 3434
+#line 3439
 	return status;
-#line 3434
+#line 3439
 #endif
-#line 3434
+#line 3439
 }
-#line 3434
+#line 3439
 
 int
-#line 3435
+#line 3440
 ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
-#line 3435
+#line 3440
 {
-#line 3435
+#line 3440
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3435
+#line 3440
 
-#line 3435
+#line 3440
  /* basic algorithm is:
-#line 3435
+#line 3440
   *   - ensure sane alignment of input data
-#line 3435
+#line 3440
   *   - copy (conversion happens automatically) input data
-#line 3435
+#line 3440
   *     to output
-#line 3435
+#line 3440
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3435
+#line 3440
   *     at next location for converted output
-#line 3435
+#line 3440
   */
-#line 3435
+#line 3440
   long i, j, ni;
-#line 3435
+#line 3440
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3435
+#line 3440
   float *xp;
-#line 3435
+#line 3440
   int nrange = 0;         /* number of range errors */
-#line 3435
+#line 3440
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3435
+#line 3440
   long cxp = (long) *((char**)xpp);
-#line 3435
+#line 3440
 
-#line 3435
+#line 3440
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3435
+#line 3440
   /* sjl: manually stripmine so we can limit amount of
-#line 3435
+#line 3440
    * vector work space reserved to LOOPCNT elements. Also
-#line 3435
+#line 3440
    * makes vectorisation easy */
-#line 3435
+#line 3440
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3435
+#line 3440
     ni=Min(nelems-j,LOOPCNT);
-#line 3435
+#line 3440
     if (realign) {
-#line 3435
+#line 3440
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3435
+#line 3440
       xp = tmp;
-#line 3435
+#line 3440
     } else {
-#line 3435
+#line 3440
       xp = (float *) *xpp;
-#line 3435
+#line 3440
     }
-#line 3435
+#line 3440
    /* copy the next block */
-#line 3435
+#line 3440
 #pragma cdir loopcnt=LOOPCNT
-#line 3435
+#line 3440
 #pragma cdir shortloop
-#line 3435
+#line 3440
     for (i=0; i<ni; i++) {
-#line 3435
+#line 3440
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3435
+#line 3440
      /* test for range errors (not always needed but do it anyway) */
-#line 3435
+#line 3440
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3435
+#line 3440
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3435
+#line 3440
       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
-#line 3435
+#line 3440
     }
-#line 3435
+#line 3440
    /* update xpp and tp */
-#line 3435
+#line 3440
     if (realign) xp = (float *) *xpp;
-#line 3435
+#line 3440
     xp += ni;
-#line 3435
+#line 3440
     tp += ni;
-#line 3435
+#line 3440
     *xpp = (void*)xp;
-#line 3435
+#line 3440
   }
-#line 3435
+#line 3440
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3435
+#line 3440
 
-#line 3435
+#line 3440
 #else   /* not SX */
-#line 3435
+#line 3440
 	const char *xp = (const char *) *xpp;
-#line 3435
+#line 3440
 	int status = NC_NOERR;
-#line 3435
+#line 3440
 
-#line 3435
+#line 3440
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3435
+#line 3440
 	{
-#line 3435
+#line 3440
 		const int lstatus = ncx_get_float_int(xp, tp);
-#line 3435
+#line 3440
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3435
+#line 3440
 			status = lstatus;
-#line 3435
+#line 3440
 	}
-#line 3435
+#line 3440
 
-#line 3435
+#line 3440
 	*xpp = (const void *)xp;
-#line 3435
+#line 3440
 	return status;
-#line 3435
+#line 3440
 #endif
-#line 3435
+#line 3440
 }
-#line 3435
+#line 3440
 
 int
-#line 3436
+#line 3441
 ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
-#line 3436
+#line 3441
 {
-#line 3436
+#line 3441
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3436
+#line 3441
 
-#line 3436
+#line 3441
  /* basic algorithm is:
-#line 3436
+#line 3441
   *   - ensure sane alignment of input data
-#line 3436
+#line 3441
   *   - copy (conversion happens automatically) input data
-#line 3436
+#line 3441
   *     to output
-#line 3436
+#line 3441
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3436
+#line 3441
   *     at next location for converted output
-#line 3436
+#line 3441
   */
-#line 3436
+#line 3441
   long i, j, ni;
-#line 3436
+#line 3441
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3436
+#line 3441
   float *xp;
-#line 3436
+#line 3441
   int nrange = 0;         /* number of range errors */
-#line 3436
+#line 3441
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3436
+#line 3441
   long cxp = (long) *((char**)xpp);
-#line 3436
+#line 3441
 
-#line 3436
+#line 3441
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3436
+#line 3441
   /* sjl: manually stripmine so we can limit amount of
-#line 3436
+#line 3441
    * vector work space reserved to LOOPCNT elements. Also
-#line 3436
+#line 3441
    * makes vectorisation easy */
-#line 3436
+#line 3441
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3436
+#line 3441
     ni=Min(nelems-j,LOOPCNT);
-#line 3436
+#line 3441
     if (realign) {
-#line 3436
+#line 3441
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3436
+#line 3441
       xp = tmp;
-#line 3436
+#line 3441
     } else {
-#line 3436
+#line 3441
       xp = (float *) *xpp;
-#line 3436
+#line 3441
     }
-#line 3436
+#line 3441
    /* copy the next block */
-#line 3436
+#line 3441
 #pragma cdir loopcnt=LOOPCNT
-#line 3436
+#line 3441
 #pragma cdir shortloop
-#line 3436
+#line 3441
     for (i=0; i<ni; i++) {
-#line 3436
+#line 3441
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3436
+#line 3441
      /* test for range errors (not always needed but do it anyway) */
-#line 3436
+#line 3441
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3436
+#line 3441
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3436
+#line 3441
       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
-#line 3436
+#line 3441
     }
-#line 3436
+#line 3441
    /* update xpp and tp */
-#line 3436
+#line 3441
     if (realign) xp = (float *) *xpp;
-#line 3436
+#line 3441
     xp += ni;
-#line 3436
+#line 3441
     tp += ni;
-#line 3436
+#line 3441
     *xpp = (void*)xp;
-#line 3436
+#line 3441
   }
-#line 3436
+#line 3441
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3436
+#line 3441
 
-#line 3436
+#line 3441
 #else   /* not SX */
-#line 3436
+#line 3441
 	const char *xp = (const char *) *xpp;
-#line 3436
+#line 3441
 	int status = NC_NOERR;
-#line 3436
+#line 3441
 
-#line 3436
+#line 3441
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3436
+#line 3441
 	{
-#line 3436
+#line 3441
 		const int lstatus = ncx_get_float_long(xp, tp);
-#line 3436
+#line 3441
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3436
+#line 3441
 			status = lstatus;
-#line 3436
+#line 3441
 	}
-#line 3436
+#line 3441
 
-#line 3436
+#line 3441
 	*xpp = (const void *)xp;
-#line 3436
+#line 3441
 	return status;
-#line 3436
+#line 3441
 #endif
-#line 3436
+#line 3441
 }
-#line 3436
+#line 3441
 
 int
-#line 3437
+#line 3442
 ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
-#line 3437
+#line 3442
 {
-#line 3437
+#line 3442
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3437
+#line 3442
 
-#line 3437
+#line 3442
  /* basic algorithm is:
-#line 3437
+#line 3442
   *   - ensure sane alignment of input data
-#line 3437
+#line 3442
   *   - copy (conversion happens automatically) input data
-#line 3437
+#line 3442
   *     to output
-#line 3437
+#line 3442
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3437
+#line 3442
   *     at next location for converted output
-#line 3437
+#line 3442
   */
-#line 3437
+#line 3442
   long i, j, ni;
-#line 3437
+#line 3442
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3437
+#line 3442
   float *xp;
-#line 3437
+#line 3442
   int nrange = 0;         /* number of range errors */
-#line 3437
+#line 3442
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3437
+#line 3442
   long cxp = (long) *((char**)xpp);
-#line 3437
+#line 3442
 
-#line 3437
+#line 3442
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3437
+#line 3442
   /* sjl: manually stripmine so we can limit amount of
-#line 3437
+#line 3442
    * vector work space reserved to LOOPCNT elements. Also
-#line 3437
+#line 3442
    * makes vectorisation easy */
-#line 3437
+#line 3442
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3437
+#line 3442
     ni=Min(nelems-j,LOOPCNT);
-#line 3437
+#line 3442
     if (realign) {
-#line 3437
+#line 3442
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3437
+#line 3442
       xp = tmp;
-#line 3437
+#line 3442
     } else {
-#line 3437
+#line 3442
       xp = (float *) *xpp;
-#line 3437
+#line 3442
     }
-#line 3437
+#line 3442
    /* copy the next block */
-#line 3437
+#line 3442
 #pragma cdir loopcnt=LOOPCNT
-#line 3437
+#line 3442
 #pragma cdir shortloop
-#line 3437
+#line 3442
     for (i=0; i<ni; i++) {
-#line 3437
+#line 3442
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3437
+#line 3442
      /* test for range errors (not always needed but do it anyway) */
-#line 3437
+#line 3442
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3437
+#line 3442
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3437
+#line 3442
       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
-#line 3437
+#line 3442
     }
-#line 3437
+#line 3442
    /* update xpp and tp */
-#line 3437
+#line 3442
     if (realign) xp = (float *) *xpp;
-#line 3437
+#line 3442
     xp += ni;
-#line 3437
+#line 3442
     tp += ni;
-#line 3437
+#line 3442
     *xpp = (void*)xp;
-#line 3437
+#line 3442
   }
-#line 3437
+#line 3442
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3437
+#line 3442
 
-#line 3437
+#line 3442
 #else   /* not SX */
-#line 3437
+#line 3442
 	const char *xp = (const char *) *xpp;
-#line 3437
+#line 3442
 	int status = NC_NOERR;
-#line 3437
+#line 3442
 
-#line 3437
+#line 3442
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3437
+#line 3442
 	{
-#line 3437
+#line 3442
 		const int lstatus = ncx_get_float_double(xp, tp);
-#line 3437
+#line 3442
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3437
+#line 3442
 			status = lstatus;
-#line 3437
+#line 3442
 	}
-#line 3437
+#line 3442
 
-#line 3437
+#line 3442
 	*xpp = (const void *)xp;
-#line 3437
+#line 3442
 	return status;
-#line 3437
+#line 3442
 #endif
-#line 3437
+#line 3442
 }
-#line 3437
+#line 3442
 
 int
-#line 3438
+#line 3443
 ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3438
+#line 3443
 {
-#line 3438
+#line 3443
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3438
+#line 3443
 
-#line 3438
+#line 3443
  /* basic algorithm is:
-#line 3438
+#line 3443
   *   - ensure sane alignment of input data
-#line 3438
+#line 3443
   *   - copy (conversion happens automatically) input data
-#line 3438
+#line 3443
   *     to output
-#line 3438
+#line 3443
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3438
+#line 3443
   *     at next location for converted output
-#line 3438
+#line 3443
   */
-#line 3438
+#line 3443
   long i, j, ni;
-#line 3438
+#line 3443
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3438
+#line 3443
   float *xp;
-#line 3438
+#line 3443
   int nrange = 0;         /* number of range errors */
-#line 3438
+#line 3443
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3438
+#line 3443
   long cxp = (long) *((char**)xpp);
-#line 3438
+#line 3443
 
-#line 3438
+#line 3443
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3438
+#line 3443
   /* sjl: manually stripmine so we can limit amount of
-#line 3438
+#line 3443
    * vector work space reserved to LOOPCNT elements. Also
-#line 3438
+#line 3443
    * makes vectorisation easy */
-#line 3438
+#line 3443
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3438
+#line 3443
     ni=Min(nelems-j,LOOPCNT);
-#line 3438
+#line 3443
     if (realign) {
-#line 3438
+#line 3443
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3438
+#line 3443
       xp = tmp;
-#line 3438
+#line 3443
     } else {
-#line 3438
+#line 3443
       xp = (float *) *xpp;
-#line 3438
+#line 3443
     }
-#line 3438
+#line 3443
    /* copy the next block */
-#line 3438
+#line 3443
 #pragma cdir loopcnt=LOOPCNT
-#line 3438
+#line 3443
 #pragma cdir shortloop
-#line 3438
+#line 3443
     for (i=0; i<ni; i++) {
-#line 3438
+#line 3443
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3438
+#line 3443
      /* test for range errors (not always needed but do it anyway) */
-#line 3438
+#line 3443
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3438
+#line 3443
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3438
+#line 3443
       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
-#line 3438
+#line 3443
     }
-#line 3438
+#line 3443
    /* update xpp and tp */
-#line 3438
+#line 3443
     if (realign) xp = (float *) *xpp;
-#line 3438
+#line 3443
     xp += ni;
-#line 3438
+#line 3443
     tp += ni;
-#line 3438
+#line 3443
     *xpp = (void*)xp;
-#line 3438
+#line 3443
   }
-#line 3438
+#line 3443
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3438
+#line 3443
 
-#line 3438
+#line 3443
 #else   /* not SX */
-#line 3438
+#line 3443
 	const char *xp = (const char *) *xpp;
-#line 3438
+#line 3443
 	int status = NC_NOERR;
-#line 3438
+#line 3443
 
-#line 3438
+#line 3443
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3438
+#line 3443
 	{
-#line 3438
+#line 3443
 		const int lstatus = ncx_get_float_longlong(xp, tp);
-#line 3438
+#line 3443
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3438
+#line 3443
 			status = lstatus;
-#line 3438
+#line 3443
 	}
-#line 3438
+#line 3443
 
-#line 3438
+#line 3443
 	*xpp = (const void *)xp;
-#line 3438
+#line 3443
 	return status;
-#line 3438
+#line 3443
 #endif
-#line 3438
+#line 3443
 }
-#line 3438
+#line 3443
 
 int
-#line 3439
+#line 3444
 ncx_getn_float_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3439
+#line 3444
 {
-#line 3439
+#line 3444
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3439
+#line 3444
 
-#line 3439
+#line 3444
  /* basic algorithm is:
-#line 3439
+#line 3444
   *   - ensure sane alignment of input data
-#line 3439
+#line 3444
   *   - copy (conversion happens automatically) input data
-#line 3439
+#line 3444
   *     to output
-#line 3439
+#line 3444
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3439
+#line 3444
   *     at next location for converted output
-#line 3439
+#line 3444
   */
-#line 3439
+#line 3444
   long i, j, ni;
-#line 3439
+#line 3444
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3439
+#line 3444
   float *xp;
-#line 3439
+#line 3444
   int nrange = 0;         /* number of range errors */
-#line 3439
+#line 3444
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3439
+#line 3444
   long cxp = (long) *((char**)xpp);
-#line 3439
+#line 3444
 
-#line 3439
+#line 3444
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3439
+#line 3444
   /* sjl: manually stripmine so we can limit amount of
-#line 3439
+#line 3444
    * vector work space reserved to LOOPCNT elements. Also
-#line 3439
+#line 3444
    * makes vectorisation easy */
-#line 3439
+#line 3444
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3439
+#line 3444
     ni=Min(nelems-j,LOOPCNT);
-#line 3439
+#line 3444
     if (realign) {
-#line 3439
+#line 3444
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3439
+#line 3444
       xp = tmp;
-#line 3439
+#line 3444
     } else {
-#line 3439
+#line 3444
       xp = (float *) *xpp;
-#line 3439
+#line 3444
     }
-#line 3439
+#line 3444
    /* copy the next block */
-#line 3439
+#line 3444
 #pragma cdir loopcnt=LOOPCNT
-#line 3439
+#line 3444
 #pragma cdir shortloop
-#line 3439
+#line 3444
     for (i=0; i<ni; i++) {
-#line 3439
+#line 3444
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3439
+#line 3444
      /* test for range errors (not always needed but do it anyway) */
-#line 3439
+#line 3444
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3439
+#line 3444
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3439
+#line 3444
       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
-#line 3439
+#line 3444
     }
-#line 3439
+#line 3444
    /* update xpp and tp */
-#line 3439
+#line 3444
     if (realign) xp = (float *) *xpp;
-#line 3439
+#line 3444
     xp += ni;
-#line 3439
+#line 3444
     tp += ni;
-#line 3439
+#line 3444
     *xpp = (void*)xp;
-#line 3439
+#line 3444
   }
-#line 3439
+#line 3444
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3439
+#line 3444
 
-#line 3439
+#line 3444
 #else   /* not SX */
-#line 3439
+#line 3444
 	const char *xp = (const char *) *xpp;
-#line 3439
+#line 3444
 	int status = NC_NOERR;
-#line 3439
+#line 3444
 
-#line 3439
+#line 3444
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3439
+#line 3444
 	{
-#line 3439
+#line 3444
 		const int lstatus = ncx_get_float_ushort(xp, tp);
-#line 3439
+#line 3444
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3439
+#line 3444
 			status = lstatus;
-#line 3439
+#line 3444
 	}
-#line 3439
+#line 3444
 
-#line 3439
+#line 3444
 	*xpp = (const void *)xp;
-#line 3439
+#line 3444
 	return status;
-#line 3439
+#line 3444
 #endif
-#line 3439
+#line 3444
 }
-#line 3439
+#line 3444
 
 int
-#line 3440
+#line 3445
 ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3440
+#line 3445
 {
-#line 3440
+#line 3445
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3440
+#line 3445
 
-#line 3440
+#line 3445
  /* basic algorithm is:
-#line 3440
+#line 3445
   *   - ensure sane alignment of input data
-#line 3440
+#line 3445
   *   - copy (conversion happens automatically) input data
-#line 3440
+#line 3445
   *     to output
-#line 3440
+#line 3445
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3440
+#line 3445
   *     at next location for converted output
-#line 3440
+#line 3445
   */
-#line 3440
+#line 3445
   long i, j, ni;
-#line 3440
+#line 3445
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3440
+#line 3445
   float *xp;
-#line 3440
+#line 3445
   int nrange = 0;         /* number of range errors */
-#line 3440
+#line 3445
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3440
+#line 3445
   long cxp = (long) *((char**)xpp);
-#line 3440
+#line 3445
 
-#line 3440
+#line 3445
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3440
+#line 3445
   /* sjl: manually stripmine so we can limit amount of
-#line 3440
+#line 3445
    * vector work space reserved to LOOPCNT elements. Also
-#line 3440
+#line 3445
    * makes vectorisation easy */
-#line 3440
+#line 3445
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3440
+#line 3445
     ni=Min(nelems-j,LOOPCNT);
-#line 3440
+#line 3445
     if (realign) {
-#line 3440
+#line 3445
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3440
+#line 3445
       xp = tmp;
-#line 3440
+#line 3445
     } else {
-#line 3440
+#line 3445
       xp = (float *) *xpp;
-#line 3440
+#line 3445
     }
-#line 3440
+#line 3445
    /* copy the next block */
-#line 3440
+#line 3445
 #pragma cdir loopcnt=LOOPCNT
-#line 3440
+#line 3445
 #pragma cdir shortloop
-#line 3440
+#line 3445
     for (i=0; i<ni; i++) {
-#line 3440
+#line 3445
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3440
+#line 3445
      /* test for range errors (not always needed but do it anyway) */
-#line 3440
+#line 3445
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3440
+#line 3445
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3440
+#line 3445
       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
-#line 3440
+#line 3445
     }
-#line 3440
+#line 3445
    /* update xpp and tp */
-#line 3440
+#line 3445
     if (realign) xp = (float *) *xpp;
-#line 3440
+#line 3445
     xp += ni;
-#line 3440
+#line 3445
     tp += ni;
-#line 3440
+#line 3445
     *xpp = (void*)xp;
-#line 3440
+#line 3445
   }
-#line 3440
+#line 3445
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3440
+#line 3445
 
-#line 3440
+#line 3445
 #else   /* not SX */
-#line 3440
+#line 3445
 	const char *xp = (const char *) *xpp;
-#line 3440
+#line 3445
 	int status = NC_NOERR;
-#line 3440
+#line 3445
 
-#line 3440
+#line 3445
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3440
+#line 3445
 	{
-#line 3440
+#line 3445
 		const int lstatus = ncx_get_float_uchar(xp, tp);
-#line 3440
+#line 3445
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3440
+#line 3445
 			status = lstatus;
-#line 3440
+#line 3445
 	}
-#line 3440
+#line 3445
 
-#line 3440
+#line 3445
 	*xpp = (const void *)xp;
-#line 3440
+#line 3445
 	return status;
-#line 3440
+#line 3445
 #endif
-#line 3440
+#line 3445
 }
-#line 3440
+#line 3445
 
 int
-#line 3441
+#line 3446
 ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3441
+#line 3446
 {
-#line 3441
+#line 3446
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3441
+#line 3446
 
-#line 3441
+#line 3446
  /* basic algorithm is:
-#line 3441
+#line 3446
   *   - ensure sane alignment of input data
-#line 3441
+#line 3446
   *   - copy (conversion happens automatically) input data
-#line 3441
+#line 3446
   *     to output
-#line 3441
+#line 3446
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3441
+#line 3446
   *     at next location for converted output
-#line 3441
+#line 3446
   */
-#line 3441
+#line 3446
   long i, j, ni;
-#line 3441
+#line 3446
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3441
+#line 3446
   float *xp;
-#line 3441
+#line 3446
   int nrange = 0;         /* number of range errors */
-#line 3441
+#line 3446
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3441
+#line 3446
   long cxp = (long) *((char**)xpp);
-#line 3441
+#line 3446
 
-#line 3441
+#line 3446
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3441
+#line 3446
   /* sjl: manually stripmine so we can limit amount of
-#line 3441
+#line 3446
    * vector work space reserved to LOOPCNT elements. Also
-#line 3441
+#line 3446
    * makes vectorisation easy */
-#line 3441
+#line 3446
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3441
+#line 3446
     ni=Min(nelems-j,LOOPCNT);
-#line 3441
+#line 3446
     if (realign) {
-#line 3441
+#line 3446
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3441
+#line 3446
       xp = tmp;
-#line 3441
+#line 3446
     } else {
-#line 3441
+#line 3446
       xp = (float *) *xpp;
-#line 3441
+#line 3446
     }
-#line 3441
+#line 3446
    /* copy the next block */
-#line 3441
+#line 3446
 #pragma cdir loopcnt=LOOPCNT
-#line 3441
+#line 3446
 #pragma cdir shortloop
-#line 3441
+#line 3446
     for (i=0; i<ni; i++) {
-#line 3441
+#line 3446
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3441
+#line 3446
      /* test for range errors (not always needed but do it anyway) */
-#line 3441
+#line 3446
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3441
+#line 3446
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3441
+#line 3446
       nrange += xp[i] > UINT_MAX || xp[i] < 0;
-#line 3441
+#line 3446
     }
-#line 3441
+#line 3446
    /* update xpp and tp */
-#line 3441
+#line 3446
     if (realign) xp = (float *) *xpp;
-#line 3441
+#line 3446
     xp += ni;
-#line 3441
+#line 3446
     tp += ni;
-#line 3441
+#line 3446
     *xpp = (void*)xp;
-#line 3441
+#line 3446
   }
-#line 3441
+#line 3446
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3441
+#line 3446
 
-#line 3441
+#line 3446
 #else   /* not SX */
-#line 3441
+#line 3446
 	const char *xp = (const char *) *xpp;
-#line 3441
+#line 3446
 	int status = NC_NOERR;
-#line 3441
+#line 3446
 
-#line 3441
+#line 3446
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3441
+#line 3446
 	{
-#line 3441
+#line 3446
 		const int lstatus = ncx_get_float_uint(xp, tp);
-#line 3441
+#line 3446
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3441
+#line 3446
 			status = lstatus;
-#line 3441
+#line 3446
 	}
-#line 3441
+#line 3446
 
-#line 3441
+#line 3446
 	*xpp = (const void *)xp;
-#line 3441
+#line 3446
 	return status;
-#line 3441
+#line 3446
 #endif
-#line 3441
+#line 3446
 }
-#line 3441
+#line 3446
 
 int
-#line 3442
+#line 3447
 ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3442
+#line 3447
 {
-#line 3442
+#line 3447
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3442
+#line 3447
 
-#line 3442
+#line 3447
  /* basic algorithm is:
-#line 3442
+#line 3447
   *   - ensure sane alignment of input data
-#line 3442
+#line 3447
   *   - copy (conversion happens automatically) input data
-#line 3442
+#line 3447
   *     to output
-#line 3442
+#line 3447
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3442
+#line 3447
   *     at next location for converted output
-#line 3442
+#line 3447
   */
-#line 3442
+#line 3447
   long i, j, ni;
-#line 3442
+#line 3447
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3442
+#line 3447
   float *xp;
-#line 3442
+#line 3447
   int nrange = 0;         /* number of range errors */
-#line 3442
+#line 3447
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3442
+#line 3447
   long cxp = (long) *((char**)xpp);
-#line 3442
+#line 3447
 
-#line 3442
+#line 3447
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3442
+#line 3447
   /* sjl: manually stripmine so we can limit amount of
-#line 3442
+#line 3447
    * vector work space reserved to LOOPCNT elements. Also
-#line 3442
+#line 3447
    * makes vectorisation easy */
-#line 3442
+#line 3447
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3442
+#line 3447
     ni=Min(nelems-j,LOOPCNT);
-#line 3442
+#line 3447
     if (realign) {
-#line 3442
+#line 3447
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
-#line 3442
+#line 3447
       xp = tmp;
-#line 3442
+#line 3447
     } else {
-#line 3442
+#line 3447
       xp = (float *) *xpp;
-#line 3442
+#line 3447
     }
-#line 3442
+#line 3447
    /* copy the next block */
-#line 3442
+#line 3447
 #pragma cdir loopcnt=LOOPCNT
-#line 3442
+#line 3447
 #pragma cdir shortloop
-#line 3442
+#line 3447
     for (i=0; i<ni; i++) {
-#line 3442
+#line 3447
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3442
+#line 3447
      /* test for range errors (not always needed but do it anyway) */
-#line 3442
+#line 3447
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3442
+#line 3447
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3442
+#line 3447
       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
-#line 3442
+#line 3447
     }
-#line 3442
+#line 3447
    /* update xpp and tp */
-#line 3442
+#line 3447
     if (realign) xp = (float *) *xpp;
-#line 3442
+#line 3447
     xp += ni;
-#line 3442
+#line 3447
     tp += ni;
-#line 3442
+#line 3447
     *xpp = (void*)xp;
-#line 3442
+#line 3447
   }
-#line 3442
+#line 3447
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3442
+#line 3447
 
-#line 3442
+#line 3447
 #else   /* not SX */
-#line 3442
+#line 3447
 	const char *xp = (const char *) *xpp;
-#line 3442
+#line 3447
 	int status = NC_NOERR;
-#line 3442
+#line 3447
 
-#line 3442
+#line 3447
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3442
+#line 3447
 	{
-#line 3442
+#line 3447
 		const int lstatus = ncx_get_float_ulonglong(xp, tp);
-#line 3442
+#line 3447
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3442
+#line 3447
 			status = lstatus;
-#line 3442
+#line 3447
 	}
-#line 3442
+#line 3447
 
-#line 3442
+#line 3447
 	*xpp = (const void *)xp;
-#line 3442
+#line 3447
 	return status;
-#line 3442
+#line 3447
 #endif
-#line 3442
+#line 3447
 }
-#line 3442
+#line 3447
 
 
 int
@@ -28900,93 +28905,93 @@ ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
 
 	while (tp < end) {
 				const struct vax_single *const vsp =
-#line 3462
+#line 3467
 			 (const struct vax_single *)ip;
-#line 3462
+#line 3467
 		struct ieee_single *const isp = (struct ieee_single *) (*xpp);
-#line 3462
+#line 3467
 
-#line 3462
+#line 3467
 		switch(vsp->exp){
-#line 3462
+#line 3467
 		case 0 :
-#line 3462
+#line 3467
 			/* all vax float with zero exponent map to zero */
-#line 3462
+#line 3467
 			*isp = min.ieee;
-#line 3462
+#line 3467
 			break;
-#line 3462
+#line 3467
 		case 2 :
-#line 3462
+#line 3467
 		case 1 :
-#line 3462
+#line 3467
 		{
-#line 3462
+#line 3467
 			/* These will map to subnormals */
-#line 3462
+#line 3467
 			unsigned mantissa = (vsp->mantissa1 << 16)
-#line 3462
+#line 3467
 					 | vsp->mantissa2;
-#line 3462
+#line 3467
 			mantissa >>= 3 - vsp->exp;
-#line 3462
+#line 3467
 			mantissa += (1 << (20 + vsp->exp));
-#line 3462
+#line 3467
 			isp->mant_lo_lo = mantissa;
-#line 3462
+#line 3467
 			isp->mant_lo_hi = mantissa >> 8;
-#line 3462
+#line 3467
 			isp->mant_hi = mantissa >> 16;
-#line 3462
+#line 3467
 			isp->exp_lo = 0;
-#line 3462
+#line 3467
 			isp->exp_hi = 0;
-#line 3462
+#line 3467
 		}
-#line 3462
+#line 3467
 			break;
-#line 3462
+#line 3467
 		case 0xff : /* max.s.exp */
-#line 3462
+#line 3467
 			if (vsp->mantissa2 == max.s.mantissa2 &&
-#line 3462
+#line 3467
 			    vsp->mantissa1 == max.s.mantissa1)
-#line 3462
+#line 3467
 			{
-#line 3462
+#line 3467
 				/* map largest vax float to ieee infinity */
-#line 3462
+#line 3467
 				*isp = max.ieee;
-#line 3462
+#line 3467
 				break;
-#line 3462
+#line 3467
 			} /* else, fall thru */
-#line 3462
+#line 3467
 		default :
-#line 3462
+#line 3467
 		{
-#line 3462
+#line 3467
 			unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
-#line 3462
+#line 3467
 			isp->exp_hi = exp >> 1;
-#line 3462
+#line 3467
 			isp->exp_lo = exp;
-#line 3462
+#line 3467
 			isp->mant_lo_lo = vsp->mantissa2;
-#line 3462
+#line 3467
 			isp->mant_lo_hi = vsp->mantissa2 >> 8;
-#line 3462
+#line 3467
 			isp->mant_hi = vsp->mantissa1;
-#line 3462
+#line 3467
 		}
-#line 3462
+#line 3467
 		}
-#line 3462
+#line 3467
 
-#line 3462
+#line 3467
 		isp->sign = vsp->sign;
-#line 3462
+#line 3467
 
 		tp++;
 		*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
@@ -29009,1394 +29014,1394 @@ ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
 }
 #endif
 int
-#line 3483
+#line 3488
 ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3483
+#line 3488
 {
-#line 3483
+#line 3488
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3483
+#line 3488
 
-#line 3483
+#line 3488
  /* basic algorithm is:
-#line 3483
+#line 3488
   *   - ensure sane alignment of output data
-#line 3483
+#line 3488
   *   - copy (conversion happens automatically) input data
-#line 3483
+#line 3488
   *     to output
-#line 3483
+#line 3488
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3483
+#line 3488
   *     at next location for converted output
-#line 3483
+#line 3488
   */
-#line 3483
+#line 3488
   long i, j, ni;
-#line 3483
+#line 3488
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3483
+#line 3488
   float *xp;
-#line 3483
+#line 3488
   int nrange = 0;         /* number of range errors */
-#line 3483
+#line 3488
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3483
+#line 3488
   long cxp = (long) *((char**)xpp);
-#line 3483
+#line 3488
 
-#line 3483
+#line 3488
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3483
+#line 3488
   /* sjl: manually stripmine so we can limit amount of
-#line 3483
+#line 3488
    * vector work space reserved to LOOPCNT elements. Also
-#line 3483
+#line 3488
    * makes vectorisation easy */
-#line 3483
+#line 3488
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3483
+#line 3488
     ni=Min(nelems-j,LOOPCNT);
-#line 3483
+#line 3488
     if (realign) {
-#line 3483
+#line 3488
       xp = tmp;
-#line 3483
+#line 3488
     } else {
-#line 3483
+#line 3488
       xp = (float *) *xpp;
-#line 3483
+#line 3488
     }
-#line 3483
+#line 3488
    /* copy the next block */
-#line 3483
+#line 3488
 #pragma cdir loopcnt=LOOPCNT
-#line 3483
+#line 3488
 #pragma cdir shortloop
-#line 3483
+#line 3488
     for (i=0; i<ni; i++) {
-#line 3483
+#line 3488
       /* the normal case: */
-#line 3483
+#line 3488
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3483
+#line 3488
      /* test for range errors (not always needed but do it anyway) */
-#line 3483
+#line 3488
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3483
+#line 3488
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3483
+#line 3488
       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
-#line 3483
+#line 3488
     }
-#line 3483
+#line 3488
    /* copy workspace back if necessary */
-#line 3483
+#line 3488
     if (realign) {
-#line 3483
+#line 3488
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3483
+#line 3488
       xp = (float *) *xpp;
-#line 3483
+#line 3488
     }
-#line 3483
+#line 3488
    /* update xpp and tp */
-#line 3483
+#line 3488
     xp += ni;
-#line 3483
+#line 3488
     tp += ni;
-#line 3483
+#line 3488
     *xpp = (void*)xp;
-#line 3483
+#line 3488
   }
-#line 3483
+#line 3488
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3483
+#line 3488
 
-#line 3483
+#line 3488
 #else   /* not SX */
-#line 3483
+#line 3488
 
-#line 3483
+#line 3488
 	char *xp = (char *) *xpp;
-#line 3483
+#line 3488
 	int status = NC_NOERR;
-#line 3483
+#line 3488
 
-#line 3483
+#line 3488
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3483
+#line 3488
 	{
-#line 3483
+#line 3488
 		int lstatus = ncx_put_float_schar(xp, tp, fillp);
-#line 3483
+#line 3488
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3483
+#line 3488
 			status = lstatus;
-#line 3483
+#line 3488
 	}
-#line 3483
+#line 3488
 
-#line 3483
+#line 3488
 	*xpp = (void *)xp;
-#line 3483
+#line 3488
 	return status;
-#line 3483
+#line 3488
 #endif
-#line 3483
+#line 3488
 }
-#line 3483
+#line 3488
 
 int
-#line 3484
+#line 3489
 ncx_putn_float_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3484
+#line 3489
 {
-#line 3484
+#line 3489
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3484
+#line 3489
 
-#line 3484
+#line 3489
  /* basic algorithm is:
-#line 3484
+#line 3489
   *   - ensure sane alignment of output data
-#line 3484
+#line 3489
   *   - copy (conversion happens automatically) input data
-#line 3484
+#line 3489
   *     to output
-#line 3484
+#line 3489
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3484
+#line 3489
   *     at next location for converted output
-#line 3484
+#line 3489
   */
-#line 3484
+#line 3489
   long i, j, ni;
-#line 3484
+#line 3489
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3484
+#line 3489
   float *xp;
-#line 3484
+#line 3489
   int nrange = 0;         /* number of range errors */
-#line 3484
+#line 3489
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3484
+#line 3489
   long cxp = (long) *((char**)xpp);
-#line 3484
+#line 3489
 
-#line 3484
+#line 3489
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3484
+#line 3489
   /* sjl: manually stripmine so we can limit amount of
-#line 3484
+#line 3489
    * vector work space reserved to LOOPCNT elements. Also
-#line 3484
+#line 3489
    * makes vectorisation easy */
-#line 3484
+#line 3489
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3484
+#line 3489
     ni=Min(nelems-j,LOOPCNT);
-#line 3484
+#line 3489
     if (realign) {
-#line 3484
+#line 3489
       xp = tmp;
-#line 3484
+#line 3489
     } else {
-#line 3484
+#line 3489
       xp = (float *) *xpp;
-#line 3484
+#line 3489
     }
-#line 3484
+#line 3489
    /* copy the next block */
-#line 3484
+#line 3489
 #pragma cdir loopcnt=LOOPCNT
-#line 3484
+#line 3489
 #pragma cdir shortloop
-#line 3484
+#line 3489
     for (i=0; i<ni; i++) {
-#line 3484
+#line 3489
       /* the normal case: */
-#line 3484
+#line 3489
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3484
+#line 3489
      /* test for range errors (not always needed but do it anyway) */
-#line 3484
+#line 3489
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3484
+#line 3489
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3484
+#line 3489
       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
-#line 3484
+#line 3489
     }
-#line 3484
+#line 3489
    /* copy workspace back if necessary */
-#line 3484
+#line 3489
     if (realign) {
-#line 3484
+#line 3489
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3484
+#line 3489
       xp = (float *) *xpp;
-#line 3484
+#line 3489
     }
-#line 3484
+#line 3489
    /* update xpp and tp */
-#line 3484
+#line 3489
     xp += ni;
-#line 3484
+#line 3489
     tp += ni;
-#line 3484
+#line 3489
     *xpp = (void*)xp;
-#line 3484
+#line 3489
   }
-#line 3484
+#line 3489
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3484
+#line 3489
 
-#line 3484
+#line 3489
 #else   /* not SX */
-#line 3484
+#line 3489
 
-#line 3484
+#line 3489
 	char *xp = (char *) *xpp;
-#line 3484
+#line 3489
 	int status = NC_NOERR;
-#line 3484
+#line 3489
 
-#line 3484
+#line 3489
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3484
+#line 3489
 	{
-#line 3484
+#line 3489
 		int lstatus = ncx_put_float_short(xp, tp, fillp);
-#line 3484
+#line 3489
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3484
+#line 3489
 			status = lstatus;
-#line 3484
+#line 3489
 	}
-#line 3484
+#line 3489
 
-#line 3484
+#line 3489
 	*xpp = (void *)xp;
-#line 3484
+#line 3489
 	return status;
-#line 3484
+#line 3489
 #endif
-#line 3484
+#line 3489
 }
-#line 3484
+#line 3489
 
 int
-#line 3485
+#line 3490
 ncx_putn_float_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3485
+#line 3490
 {
-#line 3485
+#line 3490
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3485
+#line 3490
 
-#line 3485
+#line 3490
  /* basic algorithm is:
-#line 3485
+#line 3490
   *   - ensure sane alignment of output data
-#line 3485
+#line 3490
   *   - copy (conversion happens automatically) input data
-#line 3485
+#line 3490
   *     to output
-#line 3485
+#line 3490
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3485
+#line 3490
   *     at next location for converted output
-#line 3485
+#line 3490
   */
-#line 3485
+#line 3490
   long i, j, ni;
-#line 3485
+#line 3490
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3485
+#line 3490
   float *xp;
-#line 3485
+#line 3490
   int nrange = 0;         /* number of range errors */
-#line 3485
+#line 3490
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3485
+#line 3490
   long cxp = (long) *((char**)xpp);
-#line 3485
+#line 3490
 
-#line 3485
+#line 3490
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3485
+#line 3490
   /* sjl: manually stripmine so we can limit amount of
-#line 3485
+#line 3490
    * vector work space reserved to LOOPCNT elements. Also
-#line 3485
+#line 3490
    * makes vectorisation easy */
-#line 3485
+#line 3490
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3485
+#line 3490
     ni=Min(nelems-j,LOOPCNT);
-#line 3485
+#line 3490
     if (realign) {
-#line 3485
+#line 3490
       xp = tmp;
-#line 3485
+#line 3490
     } else {
-#line 3485
+#line 3490
       xp = (float *) *xpp;
-#line 3485
+#line 3490
     }
-#line 3485
+#line 3490
    /* copy the next block */
-#line 3485
+#line 3490
 #pragma cdir loopcnt=LOOPCNT
-#line 3485
+#line 3490
 #pragma cdir shortloop
-#line 3485
+#line 3490
     for (i=0; i<ni; i++) {
-#line 3485
+#line 3490
       /* the normal case: */
-#line 3485
+#line 3490
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3485
+#line 3490
      /* test for range errors (not always needed but do it anyway) */
-#line 3485
+#line 3490
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3485
+#line 3490
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3485
+#line 3490
       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
-#line 3485
+#line 3490
     }
-#line 3485
+#line 3490
    /* copy workspace back if necessary */
-#line 3485
+#line 3490
     if (realign) {
-#line 3485
+#line 3490
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3485
+#line 3490
       xp = (float *) *xpp;
-#line 3485
+#line 3490
     }
-#line 3485
+#line 3490
    /* update xpp and tp */
-#line 3485
+#line 3490
     xp += ni;
-#line 3485
+#line 3490
     tp += ni;
-#line 3485
+#line 3490
     *xpp = (void*)xp;
-#line 3485
+#line 3490
   }
-#line 3485
+#line 3490
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3485
+#line 3490
 
-#line 3485
+#line 3490
 #else   /* not SX */
-#line 3485
+#line 3490
 
-#line 3485
+#line 3490
 	char *xp = (char *) *xpp;
-#line 3485
+#line 3490
 	int status = NC_NOERR;
-#line 3485
+#line 3490
 
-#line 3485
+#line 3490
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3485
+#line 3490
 	{
-#line 3485
+#line 3490
 		int lstatus = ncx_put_float_int(xp, tp, fillp);
-#line 3485
+#line 3490
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3485
+#line 3490
 			status = lstatus;
-#line 3485
+#line 3490
 	}
-#line 3485
+#line 3490
 
-#line 3485
+#line 3490
 	*xpp = (void *)xp;
-#line 3485
+#line 3490
 	return status;
-#line 3485
+#line 3490
 #endif
-#line 3485
+#line 3490
 }
-#line 3485
+#line 3490
 
 int
-#line 3486
+#line 3491
 ncx_putn_float_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3486
+#line 3491
 {
-#line 3486
+#line 3491
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3486
+#line 3491
 
-#line 3486
+#line 3491
  /* basic algorithm is:
-#line 3486
+#line 3491
   *   - ensure sane alignment of output data
-#line 3486
+#line 3491
   *   - copy (conversion happens automatically) input data
-#line 3486
+#line 3491
   *     to output
-#line 3486
+#line 3491
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3486
+#line 3491
   *     at next location for converted output
-#line 3486
+#line 3491
   */
-#line 3486
+#line 3491
   long i, j, ni;
-#line 3486
+#line 3491
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3486
+#line 3491
   float *xp;
-#line 3486
+#line 3491
   int nrange = 0;         /* number of range errors */
-#line 3486
+#line 3491
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3486
+#line 3491
   long cxp = (long) *((char**)xpp);
-#line 3486
+#line 3491
 
-#line 3486
+#line 3491
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3486
+#line 3491
   /* sjl: manually stripmine so we can limit amount of
-#line 3486
+#line 3491
    * vector work space reserved to LOOPCNT elements. Also
-#line 3486
+#line 3491
    * makes vectorisation easy */
-#line 3486
+#line 3491
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3486
+#line 3491
     ni=Min(nelems-j,LOOPCNT);
-#line 3486
+#line 3491
     if (realign) {
-#line 3486
+#line 3491
       xp = tmp;
-#line 3486
+#line 3491
     } else {
-#line 3486
+#line 3491
       xp = (float *) *xpp;
-#line 3486
+#line 3491
     }
-#line 3486
+#line 3491
    /* copy the next block */
-#line 3486
+#line 3491
 #pragma cdir loopcnt=LOOPCNT
-#line 3486
+#line 3491
 #pragma cdir shortloop
-#line 3486
+#line 3491
     for (i=0; i<ni; i++) {
-#line 3486
+#line 3491
       /* the normal case: */
-#line 3486
+#line 3491
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3486
+#line 3491
      /* test for range errors (not always needed but do it anyway) */
-#line 3486
+#line 3491
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3486
+#line 3491
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3486
+#line 3491
       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
-#line 3486
+#line 3491
     }
-#line 3486
+#line 3491
    /* copy workspace back if necessary */
-#line 3486
+#line 3491
     if (realign) {
-#line 3486
+#line 3491
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3486
+#line 3491
       xp = (float *) *xpp;
-#line 3486
+#line 3491
     }
-#line 3486
+#line 3491
    /* update xpp and tp */
-#line 3486
+#line 3491
     xp += ni;
-#line 3486
+#line 3491
     tp += ni;
-#line 3486
+#line 3491
     *xpp = (void*)xp;
-#line 3486
+#line 3491
   }
-#line 3486
+#line 3491
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3486
+#line 3491
 
-#line 3486
+#line 3491
 #else   /* not SX */
-#line 3486
+#line 3491
 
-#line 3486
+#line 3491
 	char *xp = (char *) *xpp;
-#line 3486
+#line 3491
 	int status = NC_NOERR;
-#line 3486
+#line 3491
 
-#line 3486
+#line 3491
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3486
+#line 3491
 	{
-#line 3486
+#line 3491
 		int lstatus = ncx_put_float_long(xp, tp, fillp);
-#line 3486
+#line 3491
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3486
+#line 3491
 			status = lstatus;
-#line 3486
+#line 3491
 	}
-#line 3486
+#line 3491
 
-#line 3486
+#line 3491
 	*xpp = (void *)xp;
-#line 3486
+#line 3491
 	return status;
-#line 3486
+#line 3491
 #endif
-#line 3486
+#line 3491
 }
-#line 3486
+#line 3491
 
 int
-#line 3487
+#line 3492
 ncx_putn_float_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3487
+#line 3492
 {
-#line 3487
+#line 3492
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3487
+#line 3492
 
-#line 3487
+#line 3492
  /* basic algorithm is:
-#line 3487
+#line 3492
   *   - ensure sane alignment of output data
-#line 3487
+#line 3492
   *   - copy (conversion happens automatically) input data
-#line 3487
+#line 3492
   *     to output
-#line 3487
+#line 3492
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3487
+#line 3492
   *     at next location for converted output
-#line 3487
+#line 3492
   */
-#line 3487
+#line 3492
   long i, j, ni;
-#line 3487
+#line 3492
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3487
+#line 3492
   float *xp;
-#line 3487
+#line 3492
   int nrange = 0;         /* number of range errors */
-#line 3487
+#line 3492
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3487
+#line 3492
   long cxp = (long) *((char**)xpp);
-#line 3487
+#line 3492
 
-#line 3487
+#line 3492
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3487
+#line 3492
   /* sjl: manually stripmine so we can limit amount of
-#line 3487
+#line 3492
    * vector work space reserved to LOOPCNT elements. Also
-#line 3487
+#line 3492
    * makes vectorisation easy */
-#line 3487
+#line 3492
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3487
+#line 3492
     ni=Min(nelems-j,LOOPCNT);
-#line 3487
+#line 3492
     if (realign) {
-#line 3487
+#line 3492
       xp = tmp;
-#line 3487
+#line 3492
     } else {
-#line 3487
+#line 3492
       xp = (float *) *xpp;
-#line 3487
+#line 3492
     }
-#line 3487
+#line 3492
    /* copy the next block */
-#line 3487
+#line 3492
 #pragma cdir loopcnt=LOOPCNT
-#line 3487
+#line 3492
 #pragma cdir shortloop
-#line 3487
+#line 3492
     for (i=0; i<ni; i++) {
-#line 3487
+#line 3492
       /* the normal case: */
-#line 3487
+#line 3492
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3487
+#line 3492
      /* test for range errors (not always needed but do it anyway) */
-#line 3487
+#line 3492
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3487
+#line 3492
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3487
+#line 3492
       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
-#line 3487
+#line 3492
     }
-#line 3487
+#line 3492
    /* copy workspace back if necessary */
-#line 3487
+#line 3492
     if (realign) {
-#line 3487
+#line 3492
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3487
+#line 3492
       xp = (float *) *xpp;
-#line 3487
+#line 3492
     }
-#line 3487
+#line 3492
    /* update xpp and tp */
-#line 3487
+#line 3492
     xp += ni;
-#line 3487
+#line 3492
     tp += ni;
-#line 3487
+#line 3492
     *xpp = (void*)xp;
-#line 3487
+#line 3492
   }
-#line 3487
+#line 3492
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3487
+#line 3492
 
-#line 3487
+#line 3492
 #else   /* not SX */
-#line 3487
+#line 3492
 
-#line 3487
+#line 3492
 	char *xp = (char *) *xpp;
-#line 3487
+#line 3492
 	int status = NC_NOERR;
-#line 3487
+#line 3492
 
-#line 3487
+#line 3492
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3487
+#line 3492
 	{
-#line 3487
+#line 3492
 		int lstatus = ncx_put_float_double(xp, tp, fillp);
-#line 3487
+#line 3492
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3487
+#line 3492
 			status = lstatus;
-#line 3487
+#line 3492
 	}
-#line 3487
+#line 3492
 
-#line 3487
+#line 3492
 	*xpp = (void *)xp;
-#line 3487
+#line 3492
 	return status;
-#line 3487
+#line 3492
 #endif
-#line 3487
+#line 3492
 }
-#line 3487
+#line 3492
 
 int
-#line 3488
+#line 3493
 ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3488
+#line 3493
 {
-#line 3488
+#line 3493
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3488
+#line 3493
 
-#line 3488
+#line 3493
  /* basic algorithm is:
-#line 3488
+#line 3493
   *   - ensure sane alignment of output data
-#line 3488
+#line 3493
   *   - copy (conversion happens automatically) input data
-#line 3488
+#line 3493
   *     to output
-#line 3488
+#line 3493
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3488
+#line 3493
   *     at next location for converted output
-#line 3488
+#line 3493
   */
-#line 3488
+#line 3493
   long i, j, ni;
-#line 3488
+#line 3493
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3488
+#line 3493
   float *xp;
-#line 3488
+#line 3493
   int nrange = 0;         /* number of range errors */
-#line 3488
+#line 3493
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3488
+#line 3493
   long cxp = (long) *((char**)xpp);
-#line 3488
+#line 3493
 
-#line 3488
+#line 3493
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3488
+#line 3493
   /* sjl: manually stripmine so we can limit amount of
-#line 3488
+#line 3493
    * vector work space reserved to LOOPCNT elements. Also
-#line 3488
+#line 3493
    * makes vectorisation easy */
-#line 3488
+#line 3493
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3488
+#line 3493
     ni=Min(nelems-j,LOOPCNT);
-#line 3488
+#line 3493
     if (realign) {
-#line 3488
+#line 3493
       xp = tmp;
-#line 3488
+#line 3493
     } else {
-#line 3488
+#line 3493
       xp = (float *) *xpp;
-#line 3488
+#line 3493
     }
-#line 3488
+#line 3493
    /* copy the next block */
-#line 3488
+#line 3493
 #pragma cdir loopcnt=LOOPCNT
-#line 3488
+#line 3493
 #pragma cdir shortloop
-#line 3488
+#line 3493
     for (i=0; i<ni; i++) {
-#line 3488
+#line 3493
       /* the normal case: */
-#line 3488
+#line 3493
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3488
+#line 3493
      /* test for range errors (not always needed but do it anyway) */
-#line 3488
+#line 3493
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3488
+#line 3493
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3488
+#line 3493
       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
-#line 3488
+#line 3493
     }
-#line 3488
+#line 3493
    /* copy workspace back if necessary */
-#line 3488
+#line 3493
     if (realign) {
-#line 3488
+#line 3493
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3488
+#line 3493
       xp = (float *) *xpp;
-#line 3488
+#line 3493
     }
-#line 3488
+#line 3493
    /* update xpp and tp */
-#line 3488
+#line 3493
     xp += ni;
-#line 3488
+#line 3493
     tp += ni;
-#line 3488
+#line 3493
     *xpp = (void*)xp;
-#line 3488
+#line 3493
   }
-#line 3488
+#line 3493
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3488
+#line 3493
 
-#line 3488
+#line 3493
 #else   /* not SX */
-#line 3488
+#line 3493
 
-#line 3488
+#line 3493
 	char *xp = (char *) *xpp;
-#line 3488
+#line 3493
 	int status = NC_NOERR;
-#line 3488
+#line 3493
 
-#line 3488
+#line 3493
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3488
+#line 3493
 	{
-#line 3488
+#line 3493
 		int lstatus = ncx_put_float_longlong(xp, tp, fillp);
-#line 3488
+#line 3493
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3488
+#line 3493
 			status = lstatus;
-#line 3488
+#line 3493
 	}
-#line 3488
+#line 3493
 
-#line 3488
+#line 3493
 	*xpp = (void *)xp;
-#line 3488
+#line 3493
 	return status;
-#line 3488
+#line 3493
 #endif
-#line 3488
+#line 3493
 }
-#line 3488
+#line 3493
 
 int
-#line 3489
+#line 3494
 ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3489
+#line 3494
 {
-#line 3489
+#line 3494
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3489
+#line 3494
 
-#line 3489
+#line 3494
  /* basic algorithm is:
-#line 3489
+#line 3494
   *   - ensure sane alignment of output data
-#line 3489
+#line 3494
   *   - copy (conversion happens automatically) input data
-#line 3489
+#line 3494
   *     to output
-#line 3489
+#line 3494
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3489
+#line 3494
   *     at next location for converted output
-#line 3489
+#line 3494
   */
-#line 3489
+#line 3494
   long i, j, ni;
-#line 3489
+#line 3494
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3489
+#line 3494
   float *xp;
-#line 3489
+#line 3494
   int nrange = 0;         /* number of range errors */
-#line 3489
+#line 3494
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3489
+#line 3494
   long cxp = (long) *((char**)xpp);
-#line 3489
+#line 3494
 
-#line 3489
+#line 3494
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3489
+#line 3494
   /* sjl: manually stripmine so we can limit amount of
-#line 3489
+#line 3494
    * vector work space reserved to LOOPCNT elements. Also
-#line 3489
+#line 3494
    * makes vectorisation easy */
-#line 3489
+#line 3494
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3489
+#line 3494
     ni=Min(nelems-j,LOOPCNT);
-#line 3489
+#line 3494
     if (realign) {
-#line 3489
+#line 3494
       xp = tmp;
-#line 3489
+#line 3494
     } else {
-#line 3489
+#line 3494
       xp = (float *) *xpp;
-#line 3489
+#line 3494
     }
-#line 3489
+#line 3494
    /* copy the next block */
-#line 3489
+#line 3494
 #pragma cdir loopcnt=LOOPCNT
-#line 3489
+#line 3494
 #pragma cdir shortloop
-#line 3489
+#line 3494
     for (i=0; i<ni; i++) {
-#line 3489
+#line 3494
       /* the normal case: */
-#line 3489
+#line 3494
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3489
+#line 3494
      /* test for range errors (not always needed but do it anyway) */
-#line 3489
+#line 3494
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3489
+#line 3494
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3489
+#line 3494
       nrange += tp[i] > X_FLOAT_MAX ;
-#line 3489
+#line 3494
     }
-#line 3489
+#line 3494
    /* copy workspace back if necessary */
-#line 3489
+#line 3494
     if (realign) {
-#line 3489
+#line 3494
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3489
+#line 3494
       xp = (float *) *xpp;
-#line 3489
+#line 3494
     }
-#line 3489
+#line 3494
    /* update xpp and tp */
-#line 3489
+#line 3494
     xp += ni;
-#line 3489
+#line 3494
     tp += ni;
-#line 3489
+#line 3494
     *xpp = (void*)xp;
-#line 3489
+#line 3494
   }
-#line 3489
+#line 3494
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3489
+#line 3494
 
-#line 3489
+#line 3494
 #else   /* not SX */
-#line 3489
+#line 3494
 
-#line 3489
+#line 3494
 	char *xp = (char *) *xpp;
-#line 3489
+#line 3494
 	int status = NC_NOERR;
-#line 3489
+#line 3494
 
-#line 3489
+#line 3494
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3489
+#line 3494
 	{
-#line 3489
+#line 3494
 		int lstatus = ncx_put_float_uchar(xp, tp, fillp);
-#line 3489
+#line 3494
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3489
+#line 3494
 			status = lstatus;
-#line 3489
+#line 3494
 	}
-#line 3489
+#line 3494
 
-#line 3489
+#line 3494
 	*xpp = (void *)xp;
-#line 3489
+#line 3494
 	return status;
-#line 3489
+#line 3494
 #endif
-#line 3489
+#line 3494
 }
-#line 3489
+#line 3494
 
 int
-#line 3490
+#line 3495
 ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3490
+#line 3495
 {
-#line 3490
+#line 3495
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3490
+#line 3495
 
-#line 3490
+#line 3495
  /* basic algorithm is:
-#line 3490
+#line 3495
   *   - ensure sane alignment of output data
-#line 3490
+#line 3495
   *   - copy (conversion happens automatically) input data
-#line 3490
+#line 3495
   *     to output
-#line 3490
+#line 3495
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3490
+#line 3495
   *     at next location for converted output
-#line 3490
+#line 3495
   */
-#line 3490
+#line 3495
   long i, j, ni;
-#line 3490
+#line 3495
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3490
+#line 3495
   float *xp;
-#line 3490
+#line 3495
   int nrange = 0;         /* number of range errors */
-#line 3490
+#line 3495
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3490
+#line 3495
   long cxp = (long) *((char**)xpp);
-#line 3490
+#line 3495
 
-#line 3490
+#line 3495
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3490
+#line 3495
   /* sjl: manually stripmine so we can limit amount of
-#line 3490
+#line 3495
    * vector work space reserved to LOOPCNT elements. Also
-#line 3490
+#line 3495
    * makes vectorisation easy */
-#line 3490
+#line 3495
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3490
+#line 3495
     ni=Min(nelems-j,LOOPCNT);
-#line 3490
+#line 3495
     if (realign) {
-#line 3490
+#line 3495
       xp = tmp;
-#line 3490
+#line 3495
     } else {
-#line 3490
+#line 3495
       xp = (float *) *xpp;
-#line 3490
+#line 3495
     }
-#line 3490
+#line 3495
    /* copy the next block */
-#line 3490
+#line 3495
 #pragma cdir loopcnt=LOOPCNT
-#line 3490
+#line 3495
 #pragma cdir shortloop
-#line 3490
+#line 3495
     for (i=0; i<ni; i++) {
-#line 3490
+#line 3495
       /* the normal case: */
-#line 3490
+#line 3495
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3490
+#line 3495
      /* test for range errors (not always needed but do it anyway) */
-#line 3490
+#line 3495
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3490
+#line 3495
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3490
+#line 3495
       nrange += tp[i] > X_FLOAT_MAX ;
-#line 3490
+#line 3495
     }
-#line 3490
+#line 3495
    /* copy workspace back if necessary */
-#line 3490
+#line 3495
     if (realign) {
-#line 3490
+#line 3495
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3490
+#line 3495
       xp = (float *) *xpp;
-#line 3490
+#line 3495
     }
-#line 3490
+#line 3495
    /* update xpp and tp */
-#line 3490
+#line 3495
     xp += ni;
-#line 3490
+#line 3495
     tp += ni;
-#line 3490
+#line 3495
     *xpp = (void*)xp;
-#line 3490
+#line 3495
   }
-#line 3490
+#line 3495
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3490
+#line 3495
 
-#line 3490
+#line 3495
 #else   /* not SX */
-#line 3490
+#line 3495
 
-#line 3490
+#line 3495
 	char *xp = (char *) *xpp;
-#line 3490
+#line 3495
 	int status = NC_NOERR;
-#line 3490
+#line 3495
 
-#line 3490
+#line 3495
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3490
+#line 3495
 	{
-#line 3490
+#line 3495
 		int lstatus = ncx_put_float_ushort(xp, tp, fillp);
-#line 3490
+#line 3495
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3490
+#line 3495
 			status = lstatus;
-#line 3490
+#line 3495
 	}
-#line 3490
+#line 3495
 
-#line 3490
+#line 3495
 	*xpp = (void *)xp;
-#line 3490
+#line 3495
 	return status;
-#line 3490
+#line 3495
 #endif
-#line 3490
+#line 3495
 }
-#line 3490
+#line 3495
 
 int
-#line 3491
+#line 3496
 ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3491
+#line 3496
 {
-#line 3491
+#line 3496
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3491
+#line 3496
 
-#line 3491
+#line 3496
  /* basic algorithm is:
-#line 3491
+#line 3496
   *   - ensure sane alignment of output data
-#line 3491
+#line 3496
   *   - copy (conversion happens automatically) input data
-#line 3491
+#line 3496
   *     to output
-#line 3491
+#line 3496
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3491
+#line 3496
   *     at next location for converted output
-#line 3491
+#line 3496
   */
-#line 3491
+#line 3496
   long i, j, ni;
-#line 3491
+#line 3496
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3491
+#line 3496
   float *xp;
-#line 3491
+#line 3496
   int nrange = 0;         /* number of range errors */
-#line 3491
+#line 3496
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3491
+#line 3496
   long cxp = (long) *((char**)xpp);
-#line 3491
+#line 3496
 
-#line 3491
+#line 3496
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3491
+#line 3496
   /* sjl: manually stripmine so we can limit amount of
-#line 3491
+#line 3496
    * vector work space reserved to LOOPCNT elements. Also
-#line 3491
+#line 3496
    * makes vectorisation easy */
-#line 3491
+#line 3496
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3491
+#line 3496
     ni=Min(nelems-j,LOOPCNT);
-#line 3491
+#line 3496
     if (realign) {
-#line 3491
+#line 3496
       xp = tmp;
-#line 3491
+#line 3496
     } else {
-#line 3491
+#line 3496
       xp = (float *) *xpp;
-#line 3491
+#line 3496
     }
-#line 3491
+#line 3496
    /* copy the next block */
-#line 3491
+#line 3496
 #pragma cdir loopcnt=LOOPCNT
-#line 3491
+#line 3496
 #pragma cdir shortloop
-#line 3491
+#line 3496
     for (i=0; i<ni; i++) {
-#line 3491
+#line 3496
       /* the normal case: */
-#line 3491
+#line 3496
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3491
+#line 3496
      /* test for range errors (not always needed but do it anyway) */
-#line 3491
+#line 3496
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3491
+#line 3496
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3491
+#line 3496
       nrange += tp[i] > X_FLOAT_MAX ;
-#line 3491
+#line 3496
     }
-#line 3491
+#line 3496
    /* copy workspace back if necessary */
-#line 3491
+#line 3496
     if (realign) {
-#line 3491
+#line 3496
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3491
+#line 3496
       xp = (float *) *xpp;
-#line 3491
+#line 3496
     }
-#line 3491
+#line 3496
    /* update xpp and tp */
-#line 3491
+#line 3496
     xp += ni;
-#line 3491
+#line 3496
     tp += ni;
-#line 3491
+#line 3496
     *xpp = (void*)xp;
-#line 3491
+#line 3496
   }
-#line 3491
+#line 3496
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3491
+#line 3496
 
-#line 3491
+#line 3496
 #else   /* not SX */
-#line 3491
+#line 3496
 
-#line 3491
+#line 3496
 	char *xp = (char *) *xpp;
-#line 3491
+#line 3496
 	int status = NC_NOERR;
-#line 3491
+#line 3496
 
-#line 3491
+#line 3496
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3491
+#line 3496
 	{
-#line 3491
+#line 3496
 		int lstatus = ncx_put_float_uint(xp, tp, fillp);
-#line 3491
+#line 3496
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3491
+#line 3496
 			status = lstatus;
-#line 3491
+#line 3496
 	}
-#line 3491
+#line 3496
 
-#line 3491
+#line 3496
 	*xpp = (void *)xp;
-#line 3491
+#line 3496
 	return status;
-#line 3491
+#line 3496
 #endif
-#line 3491
+#line 3496
 }
-#line 3491
+#line 3496
 
 int
-#line 3492
+#line 3497
 ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3492
+#line 3497
 {
-#line 3492
+#line 3497
 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
-#line 3492
+#line 3497
 
-#line 3492
+#line 3497
  /* basic algorithm is:
-#line 3492
+#line 3497
   *   - ensure sane alignment of output data
-#line 3492
+#line 3497
   *   - copy (conversion happens automatically) input data
-#line 3492
+#line 3497
   *     to output
-#line 3492
+#line 3497
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3492
+#line 3497
   *     at next location for converted output
-#line 3492
+#line 3497
   */
-#line 3492
+#line 3497
   long i, j, ni;
-#line 3492
+#line 3497
   float tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3492
+#line 3497
   float *xp;
-#line 3492
+#line 3497
   int nrange = 0;         /* number of range errors */
-#line 3492
+#line 3497
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3492
+#line 3497
   long cxp = (long) *((char**)xpp);
-#line 3492
+#line 3497
 
-#line 3492
+#line 3497
   realign = (cxp & 7) % SIZEOF_FLOAT;
-#line 3492
+#line 3497
   /* sjl: manually stripmine so we can limit amount of
-#line 3492
+#line 3497
    * vector work space reserved to LOOPCNT elements. Also
-#line 3492
+#line 3497
    * makes vectorisation easy */
-#line 3492
+#line 3497
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3492
+#line 3497
     ni=Min(nelems-j,LOOPCNT);
-#line 3492
+#line 3497
     if (realign) {
-#line 3492
+#line 3497
       xp = tmp;
-#line 3492
+#line 3497
     } else {
-#line 3492
+#line 3497
       xp = (float *) *xpp;
-#line 3492
+#line 3497
     }
-#line 3492
+#line 3497
    /* copy the next block */
-#line 3492
+#line 3497
 #pragma cdir loopcnt=LOOPCNT
-#line 3492
+#line 3497
 #pragma cdir shortloop
-#line 3492
+#line 3497
     for (i=0; i<ni; i++) {
-#line 3492
+#line 3497
       /* the normal case: */
-#line 3492
+#line 3497
       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
-#line 3492
+#line 3497
      /* test for range errors (not always needed but do it anyway) */
-#line 3492
+#line 3497
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3492
+#line 3497
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3492
+#line 3497
       nrange += tp[i] > X_FLOAT_MAX ;
-#line 3492
+#line 3497
     }
-#line 3492
+#line 3497
    /* copy workspace back if necessary */
-#line 3492
+#line 3497
     if (realign) {
-#line 3492
+#line 3497
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
-#line 3492
+#line 3497
       xp = (float *) *xpp;
-#line 3492
+#line 3497
     }
-#line 3492
+#line 3497
    /* update xpp and tp */
-#line 3492
+#line 3497
     xp += ni;
-#line 3492
+#line 3497
     tp += ni;
-#line 3492
+#line 3497
     *xpp = (void*)xp;
-#line 3492
+#line 3497
   }
-#line 3492
+#line 3497
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3492
+#line 3497
 
-#line 3492
+#line 3497
 #else   /* not SX */
-#line 3492
+#line 3497
 
-#line 3492
+#line 3497
 	char *xp = (char *) *xpp;
-#line 3492
+#line 3497
 	int status = NC_NOERR;
-#line 3492
+#line 3497
 
-#line 3492
+#line 3497
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
-#line 3492
+#line 3497
 	{
-#line 3492
+#line 3497
 		int lstatus = ncx_put_float_ulonglong(xp, tp, fillp);
-#line 3492
+#line 3497
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3492
+#line 3497
 			status = lstatus;
-#line 3492
+#line 3497
 	}
-#line 3492
+#line 3497
 
-#line 3492
+#line 3497
 	*xpp = (void *)xp;
-#line 3492
+#line 3497
 	return status;
-#line 3492
+#line 3497
 #endif
-#line 3492
+#line 3497
 }
-#line 3492
+#line 3497
 
 
 /* double --------------------------------------------------------------------*/
@@ -30423,87 +30428,87 @@ ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
 	while (ip < end)
 	{
 	struct vax_double *const vdp =
-#line 3517
+#line 3522
 			 (struct vax_double *)ip;
-#line 3517
+#line 3522
 	const struct ieee_double *const idp =
-#line 3517
+#line 3522
 			 (const struct ieee_double *) (*xpp);
-#line 3517
+#line 3522
 	{
-#line 3517
+#line 3522
 		const struct dbl_limits *lim;
-#line 3517
+#line 3522
 		int ii;
-#line 3517
+#line 3522
 		for (ii = 0, lim = dbl_limits;
-#line 3517
+#line 3522
 			ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
-#line 3517
+#line 3522
 			ii++, lim++)
-#line 3517
+#line 3522
 		{
-#line 3517
+#line 3522
 			if ((idp->mant_lo == lim->ieee.mant_lo)
-#line 3517
+#line 3522
 				&& (idp->mant_4 == lim->ieee.mant_4)
-#line 3517
+#line 3522
 				&& (idp->mant_5 == lim->ieee.mant_5)
-#line 3517
+#line 3522
 				&& (idp->mant_6 == lim->ieee.mant_6)
-#line 3517
+#line 3522
 				&& (idp->exp_lo == lim->ieee.exp_lo)
-#line 3517
+#line 3522
 				&& (idp->exp_hi == lim->ieee.exp_hi)
-#line 3517
+#line 3522
 				)
-#line 3517
+#line 3522
 			{
-#line 3517
+#line 3522
 				*vdp = lim->d;
-#line 3517
+#line 3522
 				goto doneit;
-#line 3517
+#line 3522
 			}
-#line 3517
+#line 3522
 		}
-#line 3517
+#line 3522
 	}
-#line 3517
+#line 3522
 	{
-#line 3517
+#line 3522
 		unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
-#line 3517
+#line 3522
 		vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
-#line 3517
+#line 3522
 	}
-#line 3517
+#line 3522
 	{
-#line 3517
+#line 3522
 		unsigned mant_hi = ((idp->mant_6 << 16)
-#line 3517
+#line 3522
 				 | (idp->mant_5 << 8)
-#line 3517
+#line 3522
 				 | idp->mant_4);
-#line 3517
+#line 3522
 		unsigned mant_lo = SWAP4(idp->mant_lo);
-#line 3517
+#line 3522
 		vdp->mantissa1 = (mant_hi >> 13);
-#line 3517
+#line 3522
 		vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
-#line 3517
+#line 3522
 				| (mant_lo >> 29);
-#line 3517
+#line 3522
 		vdp->mantissa3 = (mant_lo >> 13);
-#line 3517
+#line 3522
 		vdp->mantissa4 = (mant_lo << 3);
-#line 3517
+#line 3522
 	}
-#line 3517
+#line 3522
 	doneit:
-#line 3517
+#line 3522
 		vdp->sign = idp->sign;
-#line 3517
+#line 3522
 
 		ip++;
 		*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
@@ -30530,1294 +30535,1294 @@ ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
 }
 #endif
 int
-#line 3542
+#line 3547
 ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3542
+#line 3547
 {
-#line 3542
+#line 3547
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3542
+#line 3547
 
-#line 3542
+#line 3547
  /* basic algorithm is:
-#line 3542
+#line 3547
   *   - ensure sane alignment of input data
-#line 3542
+#line 3547
   *   - copy (conversion happens automatically) input data
-#line 3542
+#line 3547
   *     to output
-#line 3542
+#line 3547
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3542
+#line 3547
   *     at next location for converted output
-#line 3542
+#line 3547
   */
-#line 3542
+#line 3547
   long i, j, ni;
-#line 3542
+#line 3547
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3542
+#line 3547
   double *xp;
-#line 3542
+#line 3547
   int nrange = 0;         /* number of range errors */
-#line 3542
+#line 3547
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3542
+#line 3547
   long cxp = (long) *((char**)xpp);
-#line 3542
+#line 3547
 
-#line 3542
+#line 3547
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3542
+#line 3547
   /* sjl: manually stripmine so we can limit amount of
-#line 3542
+#line 3547
    * vector work space reserved to LOOPCNT elements. Also
-#line 3542
+#line 3547
    * makes vectorisation easy */
-#line 3542
+#line 3547
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3542
+#line 3547
     ni=Min(nelems-j,LOOPCNT);
-#line 3542
+#line 3547
     if (realign) {
-#line 3542
+#line 3547
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3542
+#line 3547
       xp = tmp;
-#line 3542
+#line 3547
     } else {
-#line 3542
+#line 3547
       xp = (double *) *xpp;
-#line 3542
+#line 3547
     }
-#line 3542
+#line 3547
    /* copy the next block */
-#line 3542
+#line 3547
 #pragma cdir loopcnt=LOOPCNT
-#line 3542
+#line 3547
 #pragma cdir shortloop
-#line 3542
+#line 3547
     for (i=0; i<ni; i++) {
-#line 3542
+#line 3547
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3542
+#line 3547
      /* test for range errors (not always needed but do it anyway) */
-#line 3542
+#line 3547
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3542
+#line 3547
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3542
+#line 3547
       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
-#line 3542
+#line 3547
     }
-#line 3542
+#line 3547
    /* update xpp and tp */
-#line 3542
+#line 3547
     if (realign) xp = (double *) *xpp;
-#line 3542
+#line 3547
     xp += ni;
-#line 3542
+#line 3547
     tp += ni;
-#line 3542
+#line 3547
     *xpp = (void*)xp;
-#line 3542
+#line 3547
   }
-#line 3542
+#line 3547
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3542
+#line 3547
 
-#line 3542
+#line 3547
 #else   /* not SX */
-#line 3542
+#line 3547
 	const char *xp = (const char *) *xpp;
-#line 3542
+#line 3547
 	int status = NC_NOERR;
-#line 3542
+#line 3547
 
-#line 3542
+#line 3547
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3542
+#line 3547
 	{
-#line 3542
+#line 3547
 		const int lstatus = ncx_get_double_schar(xp, tp);
-#line 3542
+#line 3547
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3542
+#line 3547
 			status = lstatus;
-#line 3542
+#line 3547
 	}
-#line 3542
+#line 3547
 
-#line 3542
+#line 3547
 	*xpp = (const void *)xp;
-#line 3542
+#line 3547
 	return status;
-#line 3542
+#line 3547
 #endif
-#line 3542
+#line 3547
 }
-#line 3542
+#line 3547
 
 int
-#line 3543
+#line 3548
 ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
-#line 3543
+#line 3548
 {
-#line 3543
+#line 3548
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3543
+#line 3548
 
-#line 3543
+#line 3548
  /* basic algorithm is:
-#line 3543
+#line 3548
   *   - ensure sane alignment of input data
-#line 3543
+#line 3548
   *   - copy (conversion happens automatically) input data
-#line 3543
+#line 3548
   *     to output
-#line 3543
+#line 3548
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3543
+#line 3548
   *     at next location for converted output
-#line 3543
+#line 3548
   */
-#line 3543
+#line 3548
   long i, j, ni;
-#line 3543
+#line 3548
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3543
+#line 3548
   double *xp;
-#line 3543
+#line 3548
   int nrange = 0;         /* number of range errors */
-#line 3543
+#line 3548
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3543
+#line 3548
   long cxp = (long) *((char**)xpp);
-#line 3543
+#line 3548
 
-#line 3543
+#line 3548
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3543
+#line 3548
   /* sjl: manually stripmine so we can limit amount of
-#line 3543
+#line 3548
    * vector work space reserved to LOOPCNT elements. Also
-#line 3543
+#line 3548
    * makes vectorisation easy */
-#line 3543
+#line 3548
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3543
+#line 3548
     ni=Min(nelems-j,LOOPCNT);
-#line 3543
+#line 3548
     if (realign) {
-#line 3543
+#line 3548
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3543
+#line 3548
       xp = tmp;
-#line 3543
+#line 3548
     } else {
-#line 3543
+#line 3548
       xp = (double *) *xpp;
-#line 3543
+#line 3548
     }
-#line 3543
+#line 3548
    /* copy the next block */
-#line 3543
+#line 3548
 #pragma cdir loopcnt=LOOPCNT
-#line 3543
+#line 3548
 #pragma cdir shortloop
-#line 3543
+#line 3548
     for (i=0; i<ni; i++) {
-#line 3543
+#line 3548
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3543
+#line 3548
      /* test for range errors (not always needed but do it anyway) */
-#line 3543
+#line 3548
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3543
+#line 3548
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3543
+#line 3548
       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
-#line 3543
+#line 3548
     }
-#line 3543
+#line 3548
    /* update xpp and tp */
-#line 3543
+#line 3548
     if (realign) xp = (double *) *xpp;
-#line 3543
+#line 3548
     xp += ni;
-#line 3543
+#line 3548
     tp += ni;
-#line 3543
+#line 3548
     *xpp = (void*)xp;
-#line 3543
+#line 3548
   }
-#line 3543
+#line 3548
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3543
+#line 3548
 
-#line 3543
+#line 3548
 #else   /* not SX */
-#line 3543
+#line 3548
 	const char *xp = (const char *) *xpp;
-#line 3543
+#line 3548
 	int status = NC_NOERR;
-#line 3543
+#line 3548
 
-#line 3543
+#line 3548
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3543
+#line 3548
 	{
-#line 3543
+#line 3548
 		const int lstatus = ncx_get_double_short(xp, tp);
-#line 3543
+#line 3548
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3543
+#line 3548
 			status = lstatus;
-#line 3543
+#line 3548
 	}
-#line 3543
+#line 3548
 
-#line 3543
+#line 3548
 	*xpp = (const void *)xp;
-#line 3543
+#line 3548
 	return status;
-#line 3543
+#line 3548
 #endif
-#line 3543
+#line 3548
 }
-#line 3543
+#line 3548
 
 int
-#line 3544
+#line 3549
 ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
-#line 3544
+#line 3549
 {
-#line 3544
+#line 3549
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3544
+#line 3549
 
-#line 3544
+#line 3549
  /* basic algorithm is:
-#line 3544
+#line 3549
   *   - ensure sane alignment of input data
-#line 3544
+#line 3549
   *   - copy (conversion happens automatically) input data
-#line 3544
+#line 3549
   *     to output
-#line 3544
+#line 3549
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3544
+#line 3549
   *     at next location for converted output
-#line 3544
+#line 3549
   */
-#line 3544
+#line 3549
   long i, j, ni;
-#line 3544
+#line 3549
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3544
+#line 3549
   double *xp;
-#line 3544
+#line 3549
   int nrange = 0;         /* number of range errors */
-#line 3544
+#line 3549
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3544
+#line 3549
   long cxp = (long) *((char**)xpp);
-#line 3544
+#line 3549
 
-#line 3544
+#line 3549
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3544
+#line 3549
   /* sjl: manually stripmine so we can limit amount of
-#line 3544
+#line 3549
    * vector work space reserved to LOOPCNT elements. Also
-#line 3544
+#line 3549
    * makes vectorisation easy */
-#line 3544
+#line 3549
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3544
+#line 3549
     ni=Min(nelems-j,LOOPCNT);
-#line 3544
+#line 3549
     if (realign) {
-#line 3544
+#line 3549
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3544
+#line 3549
       xp = tmp;
-#line 3544
+#line 3549
     } else {
-#line 3544
+#line 3549
       xp = (double *) *xpp;
-#line 3544
+#line 3549
     }
-#line 3544
+#line 3549
    /* copy the next block */
-#line 3544
+#line 3549
 #pragma cdir loopcnt=LOOPCNT
-#line 3544
+#line 3549
 #pragma cdir shortloop
-#line 3544
+#line 3549
     for (i=0; i<ni; i++) {
-#line 3544
+#line 3549
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3544
+#line 3549
      /* test for range errors (not always needed but do it anyway) */
-#line 3544
+#line 3549
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3544
+#line 3549
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3544
+#line 3549
       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
-#line 3544
+#line 3549
     }
-#line 3544
+#line 3549
    /* update xpp and tp */
-#line 3544
+#line 3549
     if (realign) xp = (double *) *xpp;
-#line 3544
+#line 3549
     xp += ni;
-#line 3544
+#line 3549
     tp += ni;
-#line 3544
+#line 3549
     *xpp = (void*)xp;
-#line 3544
+#line 3549
   }
-#line 3544
+#line 3549
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3544
+#line 3549
 
-#line 3544
+#line 3549
 #else   /* not SX */
-#line 3544
+#line 3549
 	const char *xp = (const char *) *xpp;
-#line 3544
+#line 3549
 	int status = NC_NOERR;
-#line 3544
+#line 3549
 
-#line 3544
+#line 3549
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3544
+#line 3549
 	{
-#line 3544
+#line 3549
 		const int lstatus = ncx_get_double_int(xp, tp);
-#line 3544
+#line 3549
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3544
+#line 3549
 			status = lstatus;
-#line 3544
+#line 3549
 	}
-#line 3544
+#line 3549
 
-#line 3544
+#line 3549
 	*xpp = (const void *)xp;
-#line 3544
+#line 3549
 	return status;
-#line 3544
+#line 3549
 #endif
-#line 3544
+#line 3549
 }
-#line 3544
+#line 3549
 
 int
-#line 3545
+#line 3550
 ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
-#line 3545
+#line 3550
 {
-#line 3545
+#line 3550
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3545
+#line 3550
 
-#line 3545
+#line 3550
  /* basic algorithm is:
-#line 3545
+#line 3550
   *   - ensure sane alignment of input data
-#line 3545
+#line 3550
   *   - copy (conversion happens automatically) input data
-#line 3545
+#line 3550
   *     to output
-#line 3545
+#line 3550
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3545
+#line 3550
   *     at next location for converted output
-#line 3545
+#line 3550
   */
-#line 3545
+#line 3550
   long i, j, ni;
-#line 3545
+#line 3550
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3545
+#line 3550
   double *xp;
-#line 3545
+#line 3550
   int nrange = 0;         /* number of range errors */
-#line 3545
+#line 3550
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3545
+#line 3550
   long cxp = (long) *((char**)xpp);
-#line 3545
+#line 3550
 
-#line 3545
+#line 3550
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3545
+#line 3550
   /* sjl: manually stripmine so we can limit amount of
-#line 3545
+#line 3550
    * vector work space reserved to LOOPCNT elements. Also
-#line 3545
+#line 3550
    * makes vectorisation easy */
-#line 3545
+#line 3550
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3545
+#line 3550
     ni=Min(nelems-j,LOOPCNT);
-#line 3545
+#line 3550
     if (realign) {
-#line 3545
+#line 3550
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3545
+#line 3550
       xp = tmp;
-#line 3545
+#line 3550
     } else {
-#line 3545
+#line 3550
       xp = (double *) *xpp;
-#line 3545
+#line 3550
     }
-#line 3545
+#line 3550
    /* copy the next block */
-#line 3545
+#line 3550
 #pragma cdir loopcnt=LOOPCNT
-#line 3545
+#line 3550
 #pragma cdir shortloop
-#line 3545
+#line 3550
     for (i=0; i<ni; i++) {
-#line 3545
+#line 3550
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3545
+#line 3550
      /* test for range errors (not always needed but do it anyway) */
-#line 3545
+#line 3550
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3545
+#line 3550
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3545
+#line 3550
       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
-#line 3545
+#line 3550
     }
-#line 3545
+#line 3550
    /* update xpp and tp */
-#line 3545
+#line 3550
     if (realign) xp = (double *) *xpp;
-#line 3545
+#line 3550
     xp += ni;
-#line 3545
+#line 3550
     tp += ni;
-#line 3545
+#line 3550
     *xpp = (void*)xp;
-#line 3545
+#line 3550
   }
-#line 3545
+#line 3550
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3545
+#line 3550
 
-#line 3545
+#line 3550
 #else   /* not SX */
-#line 3545
+#line 3550
 	const char *xp = (const char *) *xpp;
-#line 3545
+#line 3550
 	int status = NC_NOERR;
-#line 3545
+#line 3550
 
-#line 3545
+#line 3550
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3545
+#line 3550
 	{
-#line 3545
+#line 3550
 		const int lstatus = ncx_get_double_long(xp, tp);
-#line 3545
+#line 3550
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3545
+#line 3550
 			status = lstatus;
-#line 3545
+#line 3550
 	}
-#line 3545
+#line 3550
 
-#line 3545
+#line 3550
 	*xpp = (const void *)xp;
-#line 3545
+#line 3550
 	return status;
-#line 3545
+#line 3550
 #endif
-#line 3545
+#line 3550
 }
-#line 3545
+#line 3550
 
 int
-#line 3546
+#line 3551
 ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
-#line 3546
+#line 3551
 {
-#line 3546
+#line 3551
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3546
+#line 3551
 
-#line 3546
+#line 3551
  /* basic algorithm is:
-#line 3546
+#line 3551
   *   - ensure sane alignment of input data
-#line 3546
+#line 3551
   *   - copy (conversion happens automatically) input data
-#line 3546
+#line 3551
   *     to output
-#line 3546
+#line 3551
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3546
+#line 3551
   *     at next location for converted output
-#line 3546
+#line 3551
   */
-#line 3546
+#line 3551
   long i, j, ni;
-#line 3546
+#line 3551
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3546
+#line 3551
   double *xp;
-#line 3546
+#line 3551
   int nrange = 0;         /* number of range errors */
-#line 3546
+#line 3551
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3546
+#line 3551
   long cxp = (long) *((char**)xpp);
-#line 3546
+#line 3551
 
-#line 3546
+#line 3551
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3546
+#line 3551
   /* sjl: manually stripmine so we can limit amount of
-#line 3546
+#line 3551
    * vector work space reserved to LOOPCNT elements. Also
-#line 3546
+#line 3551
    * makes vectorisation easy */
-#line 3546
+#line 3551
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3546
+#line 3551
     ni=Min(nelems-j,LOOPCNT);
-#line 3546
+#line 3551
     if (realign) {
-#line 3546
+#line 3551
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3546
+#line 3551
       xp = tmp;
-#line 3546
+#line 3551
     } else {
-#line 3546
+#line 3551
       xp = (double *) *xpp;
-#line 3546
+#line 3551
     }
-#line 3546
+#line 3551
    /* copy the next block */
-#line 3546
+#line 3551
 #pragma cdir loopcnt=LOOPCNT
-#line 3546
+#line 3551
 #pragma cdir shortloop
-#line 3546
+#line 3551
     for (i=0; i<ni; i++) {
-#line 3546
+#line 3551
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3546
+#line 3551
      /* test for range errors (not always needed but do it anyway) */
-#line 3546
+#line 3551
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3546
+#line 3551
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3546
+#line 3551
       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
-#line 3546
+#line 3551
     }
-#line 3546
+#line 3551
    /* update xpp and tp */
-#line 3546
+#line 3551
     if (realign) xp = (double *) *xpp;
-#line 3546
+#line 3551
     xp += ni;
-#line 3546
+#line 3551
     tp += ni;
-#line 3546
+#line 3551
     *xpp = (void*)xp;
-#line 3546
+#line 3551
   }
-#line 3546
+#line 3551
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3546
+#line 3551
 
-#line 3546
+#line 3551
 #else   /* not SX */
-#line 3546
+#line 3551
 	const char *xp = (const char *) *xpp;
-#line 3546
+#line 3551
 	int status = NC_NOERR;
-#line 3546
+#line 3551
 
-#line 3546
+#line 3551
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3546
+#line 3551
 	{
-#line 3546
+#line 3551
 		const int lstatus = ncx_get_double_float(xp, tp);
-#line 3546
+#line 3551
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3546
+#line 3551
 			status = lstatus;
-#line 3546
+#line 3551
 	}
-#line 3546
+#line 3551
 
-#line 3546
+#line 3551
 	*xpp = (const void *)xp;
-#line 3546
+#line 3551
 	return status;
-#line 3546
+#line 3551
 #endif
-#line 3546
+#line 3551
 }
-#line 3546
+#line 3551
 
 int
-#line 3547
+#line 3552
 ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3547
+#line 3552
 {
-#line 3547
+#line 3552
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3547
+#line 3552
 
-#line 3547
+#line 3552
  /* basic algorithm is:
-#line 3547
+#line 3552
   *   - ensure sane alignment of input data
-#line 3547
+#line 3552
   *   - copy (conversion happens automatically) input data
-#line 3547
+#line 3552
   *     to output
-#line 3547
+#line 3552
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3547
+#line 3552
   *     at next location for converted output
-#line 3547
+#line 3552
   */
-#line 3547
+#line 3552
   long i, j, ni;
-#line 3547
+#line 3552
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3547
+#line 3552
   double *xp;
-#line 3547
+#line 3552
   int nrange = 0;         /* number of range errors */
-#line 3547
+#line 3552
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3547
+#line 3552
   long cxp = (long) *((char**)xpp);
-#line 3547
+#line 3552
 
-#line 3547
+#line 3552
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3547
+#line 3552
   /* sjl: manually stripmine so we can limit amount of
-#line 3547
+#line 3552
    * vector work space reserved to LOOPCNT elements. Also
-#line 3547
+#line 3552
    * makes vectorisation easy */
-#line 3547
+#line 3552
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3547
+#line 3552
     ni=Min(nelems-j,LOOPCNT);
-#line 3547
+#line 3552
     if (realign) {
-#line 3547
+#line 3552
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3547
+#line 3552
       xp = tmp;
-#line 3547
+#line 3552
     } else {
-#line 3547
+#line 3552
       xp = (double *) *xpp;
-#line 3547
+#line 3552
     }
-#line 3547
+#line 3552
    /* copy the next block */
-#line 3547
+#line 3552
 #pragma cdir loopcnt=LOOPCNT
-#line 3547
+#line 3552
 #pragma cdir shortloop
-#line 3547
+#line 3552
     for (i=0; i<ni; i++) {
-#line 3547
+#line 3552
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3547
+#line 3552
      /* test for range errors (not always needed but do it anyway) */
-#line 3547
+#line 3552
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3547
+#line 3552
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3547
+#line 3552
       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
-#line 3547
+#line 3552
     }
-#line 3547
+#line 3552
    /* update xpp and tp */
-#line 3547
+#line 3552
     if (realign) xp = (double *) *xpp;
-#line 3547
+#line 3552
     xp += ni;
-#line 3547
+#line 3552
     tp += ni;
-#line 3547
+#line 3552
     *xpp = (void*)xp;
-#line 3547
+#line 3552
   }
-#line 3547
+#line 3552
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3547
+#line 3552
 
-#line 3547
+#line 3552
 #else   /* not SX */
-#line 3547
+#line 3552
 	const char *xp = (const char *) *xpp;
-#line 3547
+#line 3552
 	int status = NC_NOERR;
-#line 3547
+#line 3552
 
-#line 3547
+#line 3552
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3547
+#line 3552
 	{
-#line 3547
+#line 3552
 		const int lstatus = ncx_get_double_longlong(xp, tp);
-#line 3547
+#line 3552
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3547
+#line 3552
 			status = lstatus;
-#line 3547
+#line 3552
 	}
-#line 3547
+#line 3552
 
-#line 3547
+#line 3552
 	*xpp = (const void *)xp;
-#line 3547
+#line 3552
 	return status;
-#line 3547
+#line 3552
 #endif
-#line 3547
+#line 3552
 }
-#line 3547
+#line 3552
 
 int
-#line 3548
+#line 3553
 ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3548
+#line 3553
 {
-#line 3548
+#line 3553
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3548
+#line 3553
 
-#line 3548
+#line 3553
  /* basic algorithm is:
-#line 3548
+#line 3553
   *   - ensure sane alignment of input data
-#line 3548
+#line 3553
   *   - copy (conversion happens automatically) input data
-#line 3548
+#line 3553
   *     to output
-#line 3548
+#line 3553
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3548
+#line 3553
   *     at next location for converted output
-#line 3548
+#line 3553
   */
-#line 3548
+#line 3553
   long i, j, ni;
-#line 3548
+#line 3553
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3548
+#line 3553
   double *xp;
-#line 3548
+#line 3553
   int nrange = 0;         /* number of range errors */
-#line 3548
+#line 3553
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3548
+#line 3553
   long cxp = (long) *((char**)xpp);
-#line 3548
+#line 3553
 
-#line 3548
+#line 3553
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3548
+#line 3553
   /* sjl: manually stripmine so we can limit amount of
-#line 3548
+#line 3553
    * vector work space reserved to LOOPCNT elements. Also
-#line 3548
+#line 3553
    * makes vectorisation easy */
-#line 3548
+#line 3553
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3548
+#line 3553
     ni=Min(nelems-j,LOOPCNT);
-#line 3548
+#line 3553
     if (realign) {
-#line 3548
+#line 3553
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3548
+#line 3553
       xp = tmp;
-#line 3548
+#line 3553
     } else {
-#line 3548
+#line 3553
       xp = (double *) *xpp;
-#line 3548
+#line 3553
     }
-#line 3548
+#line 3553
    /* copy the next block */
-#line 3548
+#line 3553
 #pragma cdir loopcnt=LOOPCNT
-#line 3548
+#line 3553
 #pragma cdir shortloop
-#line 3548
+#line 3553
     for (i=0; i<ni; i++) {
-#line 3548
+#line 3553
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3548
+#line 3553
      /* test for range errors (not always needed but do it anyway) */
-#line 3548
+#line 3553
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3548
+#line 3553
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3548
+#line 3553
       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
-#line 3548
+#line 3553
     }
-#line 3548
+#line 3553
    /* update xpp and tp */
-#line 3548
+#line 3553
     if (realign) xp = (double *) *xpp;
-#line 3548
+#line 3553
     xp += ni;
-#line 3548
+#line 3553
     tp += ni;
-#line 3548
+#line 3553
     *xpp = (void*)xp;
-#line 3548
+#line 3553
   }
-#line 3548
+#line 3553
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3548
+#line 3553
 
-#line 3548
+#line 3553
 #else   /* not SX */
-#line 3548
+#line 3553
 	const char *xp = (const char *) *xpp;
-#line 3548
+#line 3553
 	int status = NC_NOERR;
-#line 3548
+#line 3553
 
-#line 3548
+#line 3553
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3548
+#line 3553
 	{
-#line 3548
+#line 3553
 		const int lstatus = ncx_get_double_uchar(xp, tp);
-#line 3548
+#line 3553
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3548
+#line 3553
 			status = lstatus;
-#line 3548
+#line 3553
 	}
-#line 3548
+#line 3553
 
-#line 3548
+#line 3553
 	*xpp = (const void *)xp;
-#line 3548
+#line 3553
 	return status;
-#line 3548
+#line 3553
 #endif
-#line 3548
+#line 3553
 }
-#line 3548
+#line 3553
 
 int
-#line 3549
+#line 3554
 ncx_getn_double_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3549
+#line 3554
 {
-#line 3549
+#line 3554
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3549
+#line 3554
 
-#line 3549
+#line 3554
  /* basic algorithm is:
-#line 3549
+#line 3554
   *   - ensure sane alignment of input data
-#line 3549
+#line 3554
   *   - copy (conversion happens automatically) input data
-#line 3549
+#line 3554
   *     to output
-#line 3549
+#line 3554
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3549
+#line 3554
   *     at next location for converted output
-#line 3549
+#line 3554
   */
-#line 3549
+#line 3554
   long i, j, ni;
-#line 3549
+#line 3554
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3549
+#line 3554
   double *xp;
-#line 3549
+#line 3554
   int nrange = 0;         /* number of range errors */
-#line 3549
+#line 3554
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3549
+#line 3554
   long cxp = (long) *((char**)xpp);
-#line 3549
+#line 3554
 
-#line 3549
+#line 3554
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3549
+#line 3554
   /* sjl: manually stripmine so we can limit amount of
-#line 3549
+#line 3554
    * vector work space reserved to LOOPCNT elements. Also
-#line 3549
+#line 3554
    * makes vectorisation easy */
-#line 3549
+#line 3554
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3549
+#line 3554
     ni=Min(nelems-j,LOOPCNT);
-#line 3549
+#line 3554
     if (realign) {
-#line 3549
+#line 3554
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3549
+#line 3554
       xp = tmp;
-#line 3549
+#line 3554
     } else {
-#line 3549
+#line 3554
       xp = (double *) *xpp;
-#line 3549
+#line 3554
     }
-#line 3549
+#line 3554
    /* copy the next block */
-#line 3549
+#line 3554
 #pragma cdir loopcnt=LOOPCNT
-#line 3549
+#line 3554
 #pragma cdir shortloop
-#line 3549
+#line 3554
     for (i=0; i<ni; i++) {
-#line 3549
+#line 3554
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3549
+#line 3554
      /* test for range errors (not always needed but do it anyway) */
-#line 3549
+#line 3554
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3549
+#line 3554
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3549
+#line 3554
       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
-#line 3549
+#line 3554
     }
-#line 3549
+#line 3554
    /* update xpp and tp */
-#line 3549
+#line 3554
     if (realign) xp = (double *) *xpp;
-#line 3549
+#line 3554
     xp += ni;
-#line 3549
+#line 3554
     tp += ni;
-#line 3549
+#line 3554
     *xpp = (void*)xp;
-#line 3549
+#line 3554
   }
-#line 3549
+#line 3554
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3549
+#line 3554
 
-#line 3549
+#line 3554
 #else   /* not SX */
-#line 3549
+#line 3554
 	const char *xp = (const char *) *xpp;
-#line 3549
+#line 3554
 	int status = NC_NOERR;
-#line 3549
+#line 3554
 
-#line 3549
+#line 3554
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3549
+#line 3554
 	{
-#line 3549
+#line 3554
 		const int lstatus = ncx_get_double_ushort(xp, tp);
-#line 3549
+#line 3554
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3549
+#line 3554
 			status = lstatus;
-#line 3549
+#line 3554
 	}
-#line 3549
+#line 3554
 
-#line 3549
+#line 3554
 	*xpp = (const void *)xp;
-#line 3549
+#line 3554
 	return status;
-#line 3549
+#line 3554
 #endif
-#line 3549
+#line 3554
 }
-#line 3549
+#line 3554
 
 int
-#line 3550
+#line 3555
 ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3550
+#line 3555
 {
-#line 3550
+#line 3555
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3550
+#line 3555
 
-#line 3550
+#line 3555
  /* basic algorithm is:
-#line 3550
+#line 3555
   *   - ensure sane alignment of input data
-#line 3550
+#line 3555
   *   - copy (conversion happens automatically) input data
-#line 3550
+#line 3555
   *     to output
-#line 3550
+#line 3555
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3550
+#line 3555
   *     at next location for converted output
-#line 3550
+#line 3555
   */
-#line 3550
+#line 3555
   long i, j, ni;
-#line 3550
+#line 3555
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3550
+#line 3555
   double *xp;
-#line 3550
+#line 3555
   int nrange = 0;         /* number of range errors */
-#line 3550
+#line 3555
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3550
+#line 3555
   long cxp = (long) *((char**)xpp);
-#line 3550
+#line 3555
 
-#line 3550
+#line 3555
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3550
+#line 3555
   /* sjl: manually stripmine so we can limit amount of
-#line 3550
+#line 3555
    * vector work space reserved to LOOPCNT elements. Also
-#line 3550
+#line 3555
    * makes vectorisation easy */
-#line 3550
+#line 3555
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3550
+#line 3555
     ni=Min(nelems-j,LOOPCNT);
-#line 3550
+#line 3555
     if (realign) {
-#line 3550
+#line 3555
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3550
+#line 3555
       xp = tmp;
-#line 3550
+#line 3555
     } else {
-#line 3550
+#line 3555
       xp = (double *) *xpp;
-#line 3550
+#line 3555
     }
-#line 3550
+#line 3555
    /* copy the next block */
-#line 3550
+#line 3555
 #pragma cdir loopcnt=LOOPCNT
-#line 3550
+#line 3555
 #pragma cdir shortloop
-#line 3550
+#line 3555
     for (i=0; i<ni; i++) {
-#line 3550
+#line 3555
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3550
+#line 3555
      /* test for range errors (not always needed but do it anyway) */
-#line 3550
+#line 3555
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3550
+#line 3555
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3550
+#line 3555
       nrange += xp[i] > UINT_MAX || xp[i] < 0;
-#line 3550
+#line 3555
     }
-#line 3550
+#line 3555
    /* update xpp and tp */
-#line 3550
+#line 3555
     if (realign) xp = (double *) *xpp;
-#line 3550
+#line 3555
     xp += ni;
-#line 3550
+#line 3555
     tp += ni;
-#line 3550
+#line 3555
     *xpp = (void*)xp;
-#line 3550
+#line 3555
   }
-#line 3550
+#line 3555
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3550
+#line 3555
 
-#line 3550
+#line 3555
 #else   /* not SX */
-#line 3550
+#line 3555
 	const char *xp = (const char *) *xpp;
-#line 3550
+#line 3555
 	int status = NC_NOERR;
-#line 3550
+#line 3555
 
-#line 3550
+#line 3555
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3550
+#line 3555
 	{
-#line 3550
+#line 3555
 		const int lstatus = ncx_get_double_uint(xp, tp);
-#line 3550
+#line 3555
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3550
+#line 3555
 			status = lstatus;
-#line 3550
+#line 3555
 	}
-#line 3550
+#line 3555
 
-#line 3550
+#line 3555
 	*xpp = (const void *)xp;
-#line 3550
+#line 3555
 	return status;
-#line 3550
+#line 3555
 #endif
-#line 3550
+#line 3555
 }
-#line 3550
+#line 3555
 
 int
-#line 3551
+#line 3556
 ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3551
+#line 3556
 {
-#line 3551
+#line 3556
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3551
+#line 3556
 
-#line 3551
+#line 3556
  /* basic algorithm is:
-#line 3551
+#line 3556
   *   - ensure sane alignment of input data
-#line 3551
+#line 3556
   *   - copy (conversion happens automatically) input data
-#line 3551
+#line 3556
   *     to output
-#line 3551
+#line 3556
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3551
+#line 3556
   *     at next location for converted output
-#line 3551
+#line 3556
   */
-#line 3551
+#line 3556
   long i, j, ni;
-#line 3551
+#line 3556
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3551
+#line 3556
   double *xp;
-#line 3551
+#line 3556
   int nrange = 0;         /* number of range errors */
-#line 3551
+#line 3556
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3551
+#line 3556
   long cxp = (long) *((char**)xpp);
-#line 3551
+#line 3556
 
-#line 3551
+#line 3556
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3551
+#line 3556
   /* sjl: manually stripmine so we can limit amount of
-#line 3551
+#line 3556
    * vector work space reserved to LOOPCNT elements. Also
-#line 3551
+#line 3556
    * makes vectorisation easy */
-#line 3551
+#line 3556
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3551
+#line 3556
     ni=Min(nelems-j,LOOPCNT);
-#line 3551
+#line 3556
     if (realign) {
-#line 3551
+#line 3556
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
-#line 3551
+#line 3556
       xp = tmp;
-#line 3551
+#line 3556
     } else {
-#line 3551
+#line 3556
       xp = (double *) *xpp;
-#line 3551
+#line 3556
     }
-#line 3551
+#line 3556
    /* copy the next block */
-#line 3551
+#line 3556
 #pragma cdir loopcnt=LOOPCNT
-#line 3551
+#line 3556
 #pragma cdir shortloop
-#line 3551
+#line 3556
     for (i=0; i<ni; i++) {
-#line 3551
+#line 3556
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3551
+#line 3556
      /* test for range errors (not always needed but do it anyway) */
-#line 3551
+#line 3556
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3551
+#line 3556
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3551
+#line 3556
       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
-#line 3551
+#line 3556
     }
-#line 3551
+#line 3556
    /* update xpp and tp */
-#line 3551
+#line 3556
     if (realign) xp = (double *) *xpp;
-#line 3551
+#line 3556
     xp += ni;
-#line 3551
+#line 3556
     tp += ni;
-#line 3551
+#line 3556
     *xpp = (void*)xp;
-#line 3551
+#line 3556
   }
-#line 3551
+#line 3556
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3551
+#line 3556
 
-#line 3551
+#line 3556
 #else   /* not SX */
-#line 3551
+#line 3556
 	const char *xp = (const char *) *xpp;
-#line 3551
+#line 3556
 	int status = NC_NOERR;
-#line 3551
+#line 3556
 
-#line 3551
+#line 3556
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3551
+#line 3556
 	{
-#line 3551
+#line 3556
 		const int lstatus = ncx_get_double_ulonglong(xp, tp);
-#line 3551
+#line 3556
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3551
+#line 3556
 			status = lstatus;
-#line 3551
+#line 3556
 	}
-#line 3551
+#line 3556
 
-#line 3551
+#line 3556
 	*xpp = (const void *)xp;
-#line 3551
+#line 3556
 	return status;
-#line 3551
+#line 3556
 #endif
-#line 3551
+#line 3556
 }
-#line 3551
+#line 3556
 
 
 #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
@@ -31842,123 +31847,123 @@ ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip, void *fill
 	while (ip < end)
 	{
 	const struct vax_double *const vdp =
-#line 3574
+#line 3579
 			(const struct vax_double *)ip;
-#line 3574
+#line 3579
 	struct ieee_double *const idp =
-#line 3574
+#line 3579
 			 (struct ieee_double *) (*xpp);
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 	if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
-#line 3574
+#line 3579
 		(vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
-#line 3574
+#line 3579
 		(vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
-#line 3574
+#line 3579
 		(vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
-#line 3574
+#line 3579
 		(vdp->exp == dbl_limits[0].d.exp))
-#line 3574
+#line 3579
 	{
-#line 3574
+#line 3579
 		*idp = dbl_limits[0].ieee;
-#line 3574
+#line 3579
 		goto shipit;
-#line 3574
+#line 3579
 	}
-#line 3574
+#line 3579
 	if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
-#line 3574
+#line 3579
 		(vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
-#line 3574
+#line 3579
 		(vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
-#line 3574
+#line 3579
 		(vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
-#line 3574
+#line 3579
 		(vdp->exp == dbl_limits[1].d.exp))
-#line 3574
+#line 3579
 	{
-#line 3574
+#line 3579
 		*idp = dbl_limits[1].ieee;
-#line 3574
+#line 3579
 		goto shipit;
-#line 3574
+#line 3579
 	}
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 	{
-#line 3574
+#line 3579
 		unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 		unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
-#line 3574
+#line 3579
 			(vdp->mantissa3 << 13) |
-#line 3574
+#line 3579
 			((vdp->mantissa4 >> 3) & MASK(13));
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 		unsigned mant_hi = (vdp->mantissa1 << 13)
-#line 3574
+#line 3579
 				 | (vdp->mantissa2 >> 3);
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 		if ((vdp->mantissa4 & 7) > 4)
-#line 3574
+#line 3579
 		{
-#line 3574
+#line 3579
 			/* round up */
-#line 3574
+#line 3579
 			mant_lo++;
-#line 3574
+#line 3579
 			if (mant_lo == 0)
-#line 3574
+#line 3579
 			{
-#line 3574
+#line 3579
 				mant_hi++;
-#line 3574
+#line 3579
 				if (mant_hi > 0xffffff)
-#line 3574
+#line 3579
 				{
-#line 3574
+#line 3579
 					mant_hi = 0;
-#line 3574
+#line 3579
 					exp++;
-#line 3574
+#line 3579
 				}
-#line 3574
+#line 3579
 			}
-#line 3574
+#line 3579
 		}
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 		idp->mant_lo = SWAP4(mant_lo);
-#line 3574
+#line 3579
 		idp->mant_6 = mant_hi >> 16;
-#line 3574
+#line 3579
 		idp->mant_5 = (mant_hi & 0xff00) >> 8;
-#line 3574
+#line 3579
 		idp->mant_4 = mant_hi;
-#line 3574
+#line 3579
 		idp->exp_hi = exp >> 4;
-#line 3574
+#line 3579
 		idp->exp_lo = exp;
-#line 3574
+#line 3579
 	}
-#line 3574
+#line 3579
 
-#line 3574
+#line 3579
 	shipit:
-#line 3574
+#line 3579
 		idp->sign = vdp->sign;
-#line 3574
+#line 3579
 
 		ip++;
 		*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
@@ -31985,1394 +31990,1394 @@ ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
 }
 #endif
 int
-#line 3599
+#line 3604
 ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3599
+#line 3604
 {
-#line 3599
+#line 3604
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3599
+#line 3604
 
-#line 3599
+#line 3604
  /* basic algorithm is:
-#line 3599
+#line 3604
   *   - ensure sane alignment of output data
-#line 3599
+#line 3604
   *   - copy (conversion happens automatically) input data
-#line 3599
+#line 3604
   *     to output
-#line 3599
+#line 3604
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3599
+#line 3604
   *     at next location for converted output
-#line 3599
+#line 3604
   */
-#line 3599
+#line 3604
   long i, j, ni;
-#line 3599
+#line 3604
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3599
+#line 3604
   double *xp;
-#line 3599
+#line 3604
   int nrange = 0;         /* number of range errors */
-#line 3599
+#line 3604
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3599
+#line 3604
   long cxp = (long) *((char**)xpp);
-#line 3599
+#line 3604
 
-#line 3599
+#line 3604
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3599
+#line 3604
   /* sjl: manually stripmine so we can limit amount of
-#line 3599
+#line 3604
    * vector work space reserved to LOOPCNT elements. Also
-#line 3599
+#line 3604
    * makes vectorisation easy */
-#line 3599
+#line 3604
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3599
+#line 3604
     ni=Min(nelems-j,LOOPCNT);
-#line 3599
+#line 3604
     if (realign) {
-#line 3599
+#line 3604
       xp = tmp;
-#line 3599
+#line 3604
     } else {
-#line 3599
+#line 3604
       xp = (double *) *xpp;
-#line 3599
+#line 3604
     }
-#line 3599
+#line 3604
    /* copy the next block */
-#line 3599
+#line 3604
 #pragma cdir loopcnt=LOOPCNT
-#line 3599
+#line 3604
 #pragma cdir shortloop
-#line 3599
+#line 3604
     for (i=0; i<ni; i++) {
-#line 3599
+#line 3604
       /* the normal case: */
-#line 3599
+#line 3604
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3599
+#line 3604
      /* test for range errors (not always needed but do it anyway) */
-#line 3599
+#line 3604
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3599
+#line 3604
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3599
+#line 3604
       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
-#line 3599
+#line 3604
     }
-#line 3599
+#line 3604
    /* copy workspace back if necessary */
-#line 3599
+#line 3604
     if (realign) {
-#line 3599
+#line 3604
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3599
+#line 3604
       xp = (double *) *xpp;
-#line 3599
+#line 3604
     }
-#line 3599
+#line 3604
    /* update xpp and tp */
-#line 3599
+#line 3604
     xp += ni;
-#line 3599
+#line 3604
     tp += ni;
-#line 3599
+#line 3604
     *xpp = (void*)xp;
-#line 3599
+#line 3604
   }
-#line 3599
+#line 3604
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3599
+#line 3604
 
-#line 3599
+#line 3604
 #else   /* not SX */
-#line 3599
+#line 3604
 
-#line 3599
+#line 3604
 	char *xp = (char *) *xpp;
-#line 3599
+#line 3604
 	int status = NC_NOERR;
-#line 3599
+#line 3604
 
-#line 3599
+#line 3604
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3599
+#line 3604
 	{
-#line 3599
+#line 3604
 		int lstatus = ncx_put_double_schar(xp, tp, fillp);
-#line 3599
+#line 3604
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3599
+#line 3604
 			status = lstatus;
-#line 3599
+#line 3604
 	}
-#line 3599
+#line 3604
 
-#line 3599
+#line 3604
 	*xpp = (void *)xp;
-#line 3599
+#line 3604
 	return status;
-#line 3599
+#line 3604
 #endif
-#line 3599
+#line 3604
 }
-#line 3599
+#line 3604
 
 int
-#line 3600
+#line 3605
 ncx_putn_double_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3600
+#line 3605
 {
-#line 3600
+#line 3605
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3600
+#line 3605
 
-#line 3600
+#line 3605
  /* basic algorithm is:
-#line 3600
+#line 3605
   *   - ensure sane alignment of output data
-#line 3600
+#line 3605
   *   - copy (conversion happens automatically) input data
-#line 3600
+#line 3605
   *     to output
-#line 3600
+#line 3605
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3600
+#line 3605
   *     at next location for converted output
-#line 3600
+#line 3605
   */
-#line 3600
+#line 3605
   long i, j, ni;
-#line 3600
+#line 3605
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3600
+#line 3605
   double *xp;
-#line 3600
+#line 3605
   int nrange = 0;         /* number of range errors */
-#line 3600
+#line 3605
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3600
+#line 3605
   long cxp = (long) *((char**)xpp);
-#line 3600
+#line 3605
 
-#line 3600
+#line 3605
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3600
+#line 3605
   /* sjl: manually stripmine so we can limit amount of
-#line 3600
+#line 3605
    * vector work space reserved to LOOPCNT elements. Also
-#line 3600
+#line 3605
    * makes vectorisation easy */
-#line 3600
+#line 3605
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3600
+#line 3605
     ni=Min(nelems-j,LOOPCNT);
-#line 3600
+#line 3605
     if (realign) {
-#line 3600
+#line 3605
       xp = tmp;
-#line 3600
+#line 3605
     } else {
-#line 3600
+#line 3605
       xp = (double *) *xpp;
-#line 3600
+#line 3605
     }
-#line 3600
+#line 3605
    /* copy the next block */
-#line 3600
+#line 3605
 #pragma cdir loopcnt=LOOPCNT
-#line 3600
+#line 3605
 #pragma cdir shortloop
-#line 3600
+#line 3605
     for (i=0; i<ni; i++) {
-#line 3600
+#line 3605
       /* the normal case: */
-#line 3600
+#line 3605
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3600
+#line 3605
      /* test for range errors (not always needed but do it anyway) */
-#line 3600
+#line 3605
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3600
+#line 3605
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3600
+#line 3605
       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
-#line 3600
+#line 3605
     }
-#line 3600
+#line 3605
    /* copy workspace back if necessary */
-#line 3600
+#line 3605
     if (realign) {
-#line 3600
+#line 3605
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3600
+#line 3605
       xp = (double *) *xpp;
-#line 3600
+#line 3605
     }
-#line 3600
+#line 3605
    /* update xpp and tp */
-#line 3600
+#line 3605
     xp += ni;
-#line 3600
+#line 3605
     tp += ni;
-#line 3600
+#line 3605
     *xpp = (void*)xp;
-#line 3600
+#line 3605
   }
-#line 3600
+#line 3605
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3600
+#line 3605
 
-#line 3600
+#line 3605
 #else   /* not SX */
-#line 3600
+#line 3605
 
-#line 3600
+#line 3605
 	char *xp = (char *) *xpp;
-#line 3600
+#line 3605
 	int status = NC_NOERR;
-#line 3600
+#line 3605
 
-#line 3600
+#line 3605
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3600
+#line 3605
 	{
-#line 3600
+#line 3605
 		int lstatus = ncx_put_double_short(xp, tp, fillp);
-#line 3600
+#line 3605
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3600
+#line 3605
 			status = lstatus;
-#line 3600
+#line 3605
 	}
-#line 3600
+#line 3605
 
-#line 3600
+#line 3605
 	*xpp = (void *)xp;
-#line 3600
+#line 3605
 	return status;
-#line 3600
+#line 3605
 #endif
-#line 3600
+#line 3605
 }
-#line 3600
+#line 3605
 
 int
-#line 3601
+#line 3606
 ncx_putn_double_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3601
+#line 3606
 {
-#line 3601
+#line 3606
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3601
+#line 3606
 
-#line 3601
+#line 3606
  /* basic algorithm is:
-#line 3601
+#line 3606
   *   - ensure sane alignment of output data
-#line 3601
+#line 3606
   *   - copy (conversion happens automatically) input data
-#line 3601
+#line 3606
   *     to output
-#line 3601
+#line 3606
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3601
+#line 3606
   *     at next location for converted output
-#line 3601
+#line 3606
   */
-#line 3601
+#line 3606
   long i, j, ni;
-#line 3601
+#line 3606
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3601
+#line 3606
   double *xp;
-#line 3601
+#line 3606
   int nrange = 0;         /* number of range errors */
-#line 3601
+#line 3606
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3601
+#line 3606
   long cxp = (long) *((char**)xpp);
-#line 3601
+#line 3606
 
-#line 3601
+#line 3606
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3601
+#line 3606
   /* sjl: manually stripmine so we can limit amount of
-#line 3601
+#line 3606
    * vector work space reserved to LOOPCNT elements. Also
-#line 3601
+#line 3606
    * makes vectorisation easy */
-#line 3601
+#line 3606
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3601
+#line 3606
     ni=Min(nelems-j,LOOPCNT);
-#line 3601
+#line 3606
     if (realign) {
-#line 3601
+#line 3606
       xp = tmp;
-#line 3601
+#line 3606
     } else {
-#line 3601
+#line 3606
       xp = (double *) *xpp;
-#line 3601
+#line 3606
     }
-#line 3601
+#line 3606
    /* copy the next block */
-#line 3601
+#line 3606
 #pragma cdir loopcnt=LOOPCNT
-#line 3601
+#line 3606
 #pragma cdir shortloop
-#line 3601
+#line 3606
     for (i=0; i<ni; i++) {
-#line 3601
+#line 3606
       /* the normal case: */
-#line 3601
+#line 3606
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3601
+#line 3606
      /* test for range errors (not always needed but do it anyway) */
-#line 3601
+#line 3606
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3601
+#line 3606
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3601
+#line 3606
       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
-#line 3601
+#line 3606
     }
-#line 3601
+#line 3606
    /* copy workspace back if necessary */
-#line 3601
+#line 3606
     if (realign) {
-#line 3601
+#line 3606
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3601
+#line 3606
       xp = (double *) *xpp;
-#line 3601
+#line 3606
     }
-#line 3601
+#line 3606
    /* update xpp and tp */
-#line 3601
+#line 3606
     xp += ni;
-#line 3601
+#line 3606
     tp += ni;
-#line 3601
+#line 3606
     *xpp = (void*)xp;
-#line 3601
+#line 3606
   }
-#line 3601
+#line 3606
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3601
+#line 3606
 
-#line 3601
+#line 3606
 #else   /* not SX */
-#line 3601
+#line 3606
 
-#line 3601
+#line 3606
 	char *xp = (char *) *xpp;
-#line 3601
+#line 3606
 	int status = NC_NOERR;
-#line 3601
+#line 3606
 
-#line 3601
+#line 3606
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3601
+#line 3606
 	{
-#line 3601
+#line 3606
 		int lstatus = ncx_put_double_int(xp, tp, fillp);
-#line 3601
+#line 3606
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3601
+#line 3606
 			status = lstatus;
-#line 3601
+#line 3606
 	}
-#line 3601
+#line 3606
 
-#line 3601
+#line 3606
 	*xpp = (void *)xp;
-#line 3601
+#line 3606
 	return status;
-#line 3601
+#line 3606
 #endif
-#line 3601
+#line 3606
 }
-#line 3601
+#line 3606
 
 int
-#line 3602
+#line 3607
 ncx_putn_double_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3602
+#line 3607
 {
-#line 3602
+#line 3607
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3602
+#line 3607
 
-#line 3602
+#line 3607
  /* basic algorithm is:
-#line 3602
+#line 3607
   *   - ensure sane alignment of output data
-#line 3602
+#line 3607
   *   - copy (conversion happens automatically) input data
-#line 3602
+#line 3607
   *     to output
-#line 3602
+#line 3607
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3602
+#line 3607
   *     at next location for converted output
-#line 3602
+#line 3607
   */
-#line 3602
+#line 3607
   long i, j, ni;
-#line 3602
+#line 3607
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3602
+#line 3607
   double *xp;
-#line 3602
+#line 3607
   int nrange = 0;         /* number of range errors */
-#line 3602
+#line 3607
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3602
+#line 3607
   long cxp = (long) *((char**)xpp);
-#line 3602
+#line 3607
 
-#line 3602
+#line 3607
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3602
+#line 3607
   /* sjl: manually stripmine so we can limit amount of
-#line 3602
+#line 3607
    * vector work space reserved to LOOPCNT elements. Also
-#line 3602
+#line 3607
    * makes vectorisation easy */
-#line 3602
+#line 3607
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3602
+#line 3607
     ni=Min(nelems-j,LOOPCNT);
-#line 3602
+#line 3607
     if (realign) {
-#line 3602
+#line 3607
       xp = tmp;
-#line 3602
+#line 3607
     } else {
-#line 3602
+#line 3607
       xp = (double *) *xpp;
-#line 3602
+#line 3607
     }
-#line 3602
+#line 3607
    /* copy the next block */
-#line 3602
+#line 3607
 #pragma cdir loopcnt=LOOPCNT
-#line 3602
+#line 3607
 #pragma cdir shortloop
-#line 3602
+#line 3607
     for (i=0; i<ni; i++) {
-#line 3602
+#line 3607
       /* the normal case: */
-#line 3602
+#line 3607
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3602
+#line 3607
      /* test for range errors (not always needed but do it anyway) */
-#line 3602
+#line 3607
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3602
+#line 3607
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3602
+#line 3607
       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
-#line 3602
+#line 3607
     }
-#line 3602
+#line 3607
    /* copy workspace back if necessary */
-#line 3602
+#line 3607
     if (realign) {
-#line 3602
+#line 3607
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3602
+#line 3607
       xp = (double *) *xpp;
-#line 3602
+#line 3607
     }
-#line 3602
+#line 3607
    /* update xpp and tp */
-#line 3602
+#line 3607
     xp += ni;
-#line 3602
+#line 3607
     tp += ni;
-#line 3602
+#line 3607
     *xpp = (void*)xp;
-#line 3602
+#line 3607
   }
-#line 3602
+#line 3607
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3602
+#line 3607
 
-#line 3602
+#line 3607
 #else   /* not SX */
-#line 3602
+#line 3607
 
-#line 3602
+#line 3607
 	char *xp = (char *) *xpp;
-#line 3602
+#line 3607
 	int status = NC_NOERR;
-#line 3602
+#line 3607
 
-#line 3602
+#line 3607
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3602
+#line 3607
 	{
-#line 3602
+#line 3607
 		int lstatus = ncx_put_double_long(xp, tp, fillp);
-#line 3602
+#line 3607
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3602
+#line 3607
 			status = lstatus;
-#line 3602
+#line 3607
 	}
-#line 3602
+#line 3607
 
-#line 3602
+#line 3607
 	*xpp = (void *)xp;
-#line 3602
+#line 3607
 	return status;
-#line 3602
+#line 3607
 #endif
-#line 3602
+#line 3607
 }
-#line 3602
+#line 3607
 
 int
-#line 3603
+#line 3608
 ncx_putn_double_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3603
+#line 3608
 {
-#line 3603
+#line 3608
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3603
+#line 3608
 
-#line 3603
+#line 3608
  /* basic algorithm is:
-#line 3603
+#line 3608
   *   - ensure sane alignment of output data
-#line 3603
+#line 3608
   *   - copy (conversion happens automatically) input data
-#line 3603
+#line 3608
   *     to output
-#line 3603
+#line 3608
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3603
+#line 3608
   *     at next location for converted output
-#line 3603
+#line 3608
   */
-#line 3603
+#line 3608
   long i, j, ni;
-#line 3603
+#line 3608
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3603
+#line 3608
   double *xp;
-#line 3603
+#line 3608
   int nrange = 0;         /* number of range errors */
-#line 3603
+#line 3608
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3603
+#line 3608
   long cxp = (long) *((char**)xpp);
-#line 3603
+#line 3608
 
-#line 3603
+#line 3608
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3603
+#line 3608
   /* sjl: manually stripmine so we can limit amount of
-#line 3603
+#line 3608
    * vector work space reserved to LOOPCNT elements. Also
-#line 3603
+#line 3608
    * makes vectorisation easy */
-#line 3603
+#line 3608
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3603
+#line 3608
     ni=Min(nelems-j,LOOPCNT);
-#line 3603
+#line 3608
     if (realign) {
-#line 3603
+#line 3608
       xp = tmp;
-#line 3603
+#line 3608
     } else {
-#line 3603
+#line 3608
       xp = (double *) *xpp;
-#line 3603
+#line 3608
     }
-#line 3603
+#line 3608
    /* copy the next block */
-#line 3603
+#line 3608
 #pragma cdir loopcnt=LOOPCNT
-#line 3603
+#line 3608
 #pragma cdir shortloop
-#line 3603
+#line 3608
     for (i=0; i<ni; i++) {
-#line 3603
+#line 3608
       /* the normal case: */
-#line 3603
+#line 3608
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3603
+#line 3608
      /* test for range errors (not always needed but do it anyway) */
-#line 3603
+#line 3608
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3603
+#line 3608
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3603
+#line 3608
       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
-#line 3603
+#line 3608
     }
-#line 3603
+#line 3608
    /* copy workspace back if necessary */
-#line 3603
+#line 3608
     if (realign) {
-#line 3603
+#line 3608
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3603
+#line 3608
       xp = (double *) *xpp;
-#line 3603
+#line 3608
     }
-#line 3603
+#line 3608
    /* update xpp and tp */
-#line 3603
+#line 3608
     xp += ni;
-#line 3603
+#line 3608
     tp += ni;
-#line 3603
+#line 3608
     *xpp = (void*)xp;
-#line 3603
+#line 3608
   }
-#line 3603
+#line 3608
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3603
+#line 3608
 
-#line 3603
+#line 3608
 #else   /* not SX */
-#line 3603
+#line 3608
 
-#line 3603
+#line 3608
 	char *xp = (char *) *xpp;
-#line 3603
+#line 3608
 	int status = NC_NOERR;
-#line 3603
+#line 3608
 
-#line 3603
+#line 3608
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3603
+#line 3608
 	{
-#line 3603
+#line 3608
 		int lstatus = ncx_put_double_float(xp, tp, fillp);
-#line 3603
+#line 3608
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3603
+#line 3608
 			status = lstatus;
-#line 3603
+#line 3608
 	}
-#line 3603
+#line 3608
 
-#line 3603
+#line 3608
 	*xpp = (void *)xp;
-#line 3603
+#line 3608
 	return status;
-#line 3603
+#line 3608
 #endif
-#line 3603
+#line 3608
 }
-#line 3603
+#line 3608
 
 int
-#line 3604
+#line 3609
 ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3604
+#line 3609
 {
-#line 3604
+#line 3609
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3604
+#line 3609
 
-#line 3604
+#line 3609
  /* basic algorithm is:
-#line 3604
+#line 3609
   *   - ensure sane alignment of output data
-#line 3604
+#line 3609
   *   - copy (conversion happens automatically) input data
-#line 3604
+#line 3609
   *     to output
-#line 3604
+#line 3609
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3604
+#line 3609
   *     at next location for converted output
-#line 3604
+#line 3609
   */
-#line 3604
+#line 3609
   long i, j, ni;
-#line 3604
+#line 3609
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3604
+#line 3609
   double *xp;
-#line 3604
+#line 3609
   int nrange = 0;         /* number of range errors */
-#line 3604
+#line 3609
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3604
+#line 3609
   long cxp = (long) *((char**)xpp);
-#line 3604
+#line 3609
 
-#line 3604
+#line 3609
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3604
+#line 3609
   /* sjl: manually stripmine so we can limit amount of
-#line 3604
+#line 3609
    * vector work space reserved to LOOPCNT elements. Also
-#line 3604
+#line 3609
    * makes vectorisation easy */
-#line 3604
+#line 3609
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3604
+#line 3609
     ni=Min(nelems-j,LOOPCNT);
-#line 3604
+#line 3609
     if (realign) {
-#line 3604
+#line 3609
       xp = tmp;
-#line 3604
+#line 3609
     } else {
-#line 3604
+#line 3609
       xp = (double *) *xpp;
-#line 3604
+#line 3609
     }
-#line 3604
+#line 3609
    /* copy the next block */
-#line 3604
+#line 3609
 #pragma cdir loopcnt=LOOPCNT
-#line 3604
+#line 3609
 #pragma cdir shortloop
-#line 3604
+#line 3609
     for (i=0; i<ni; i++) {
-#line 3604
+#line 3609
       /* the normal case: */
-#line 3604
+#line 3609
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3604
+#line 3609
      /* test for range errors (not always needed but do it anyway) */
-#line 3604
+#line 3609
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3604
+#line 3609
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3604
+#line 3609
       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
-#line 3604
+#line 3609
     }
-#line 3604
+#line 3609
    /* copy workspace back if necessary */
-#line 3604
+#line 3609
     if (realign) {
-#line 3604
+#line 3609
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3604
+#line 3609
       xp = (double *) *xpp;
-#line 3604
+#line 3609
     }
-#line 3604
+#line 3609
    /* update xpp and tp */
-#line 3604
+#line 3609
     xp += ni;
-#line 3604
+#line 3609
     tp += ni;
-#line 3604
+#line 3609
     *xpp = (void*)xp;
-#line 3604
+#line 3609
   }
-#line 3604
+#line 3609
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3604
+#line 3609
 
-#line 3604
+#line 3609
 #else   /* not SX */
-#line 3604
+#line 3609
 
-#line 3604
+#line 3609
 	char *xp = (char *) *xpp;
-#line 3604
+#line 3609
 	int status = NC_NOERR;
-#line 3604
+#line 3609
 
-#line 3604
+#line 3609
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3604
+#line 3609
 	{
-#line 3604
+#line 3609
 		int lstatus = ncx_put_double_longlong(xp, tp, fillp);
-#line 3604
+#line 3609
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3604
+#line 3609
 			status = lstatus;
-#line 3604
+#line 3609
 	}
-#line 3604
+#line 3609
 
-#line 3604
+#line 3609
 	*xpp = (void *)xp;
-#line 3604
+#line 3609
 	return status;
-#line 3604
+#line 3609
 #endif
-#line 3604
+#line 3609
 }
-#line 3604
+#line 3609
 
 int
-#line 3605
+#line 3610
 ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3605
+#line 3610
 {
-#line 3605
+#line 3610
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3605
+#line 3610
 
-#line 3605
+#line 3610
  /* basic algorithm is:
-#line 3605
+#line 3610
   *   - ensure sane alignment of output data
-#line 3605
+#line 3610
   *   - copy (conversion happens automatically) input data
-#line 3605
+#line 3610
   *     to output
-#line 3605
+#line 3610
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3605
+#line 3610
   *     at next location for converted output
-#line 3605
+#line 3610
   */
-#line 3605
+#line 3610
   long i, j, ni;
-#line 3605
+#line 3610
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3605
+#line 3610
   double *xp;
-#line 3605
+#line 3610
   int nrange = 0;         /* number of range errors */
-#line 3605
+#line 3610
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3605
+#line 3610
   long cxp = (long) *((char**)xpp);
-#line 3605
+#line 3610
 
-#line 3605
+#line 3610
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3605
+#line 3610
   /* sjl: manually stripmine so we can limit amount of
-#line 3605
+#line 3610
    * vector work space reserved to LOOPCNT elements. Also
-#line 3605
+#line 3610
    * makes vectorisation easy */
-#line 3605
+#line 3610
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3605
+#line 3610
     ni=Min(nelems-j,LOOPCNT);
-#line 3605
+#line 3610
     if (realign) {
-#line 3605
+#line 3610
       xp = tmp;
-#line 3605
+#line 3610
     } else {
-#line 3605
+#line 3610
       xp = (double *) *xpp;
-#line 3605
+#line 3610
     }
-#line 3605
+#line 3610
    /* copy the next block */
-#line 3605
+#line 3610
 #pragma cdir loopcnt=LOOPCNT
-#line 3605
+#line 3610
 #pragma cdir shortloop
-#line 3605
+#line 3610
     for (i=0; i<ni; i++) {
-#line 3605
+#line 3610
       /* the normal case: */
-#line 3605
+#line 3610
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3605
+#line 3610
      /* test for range errors (not always needed but do it anyway) */
-#line 3605
+#line 3610
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3605
+#line 3610
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3605
+#line 3610
       nrange += tp[i] > X_DOUBLE_MAX ;
-#line 3605
+#line 3610
     }
-#line 3605
+#line 3610
    /* copy workspace back if necessary */
-#line 3605
+#line 3610
     if (realign) {
-#line 3605
+#line 3610
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3605
+#line 3610
       xp = (double *) *xpp;
-#line 3605
+#line 3610
     }
-#line 3605
+#line 3610
    /* update xpp and tp */
-#line 3605
+#line 3610
     xp += ni;
-#line 3605
+#line 3610
     tp += ni;
-#line 3605
+#line 3610
     *xpp = (void*)xp;
-#line 3605
+#line 3610
   }
-#line 3605
+#line 3610
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3605
+#line 3610
 
-#line 3605
+#line 3610
 #else   /* not SX */
-#line 3605
+#line 3610
 
-#line 3605
+#line 3610
 	char *xp = (char *) *xpp;
-#line 3605
+#line 3610
 	int status = NC_NOERR;
-#line 3605
+#line 3610
 
-#line 3605
+#line 3610
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3605
+#line 3610
 	{
-#line 3605
+#line 3610
 		int lstatus = ncx_put_double_uchar(xp, tp, fillp);
-#line 3605
+#line 3610
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3605
+#line 3610
 			status = lstatus;
-#line 3605
+#line 3610
 	}
-#line 3605
+#line 3610
 
-#line 3605
+#line 3610
 	*xpp = (void *)xp;
-#line 3605
+#line 3610
 	return status;
-#line 3605
+#line 3610
 #endif
-#line 3605
+#line 3610
 }
-#line 3605
+#line 3610
 
 int
-#line 3606
+#line 3611
 ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3606
+#line 3611
 {
-#line 3606
+#line 3611
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3606
+#line 3611
 
-#line 3606
+#line 3611
  /* basic algorithm is:
-#line 3606
+#line 3611
   *   - ensure sane alignment of output data
-#line 3606
+#line 3611
   *   - copy (conversion happens automatically) input data
-#line 3606
+#line 3611
   *     to output
-#line 3606
+#line 3611
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3606
+#line 3611
   *     at next location for converted output
-#line 3606
+#line 3611
   */
-#line 3606
+#line 3611
   long i, j, ni;
-#line 3606
+#line 3611
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3606
+#line 3611
   double *xp;
-#line 3606
+#line 3611
   int nrange = 0;         /* number of range errors */
-#line 3606
+#line 3611
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3606
+#line 3611
   long cxp = (long) *((char**)xpp);
-#line 3606
+#line 3611
 
-#line 3606
+#line 3611
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3606
+#line 3611
   /* sjl: manually stripmine so we can limit amount of
-#line 3606
+#line 3611
    * vector work space reserved to LOOPCNT elements. Also
-#line 3606
+#line 3611
    * makes vectorisation easy */
-#line 3606
+#line 3611
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3606
+#line 3611
     ni=Min(nelems-j,LOOPCNT);
-#line 3606
+#line 3611
     if (realign) {
-#line 3606
+#line 3611
       xp = tmp;
-#line 3606
+#line 3611
     } else {
-#line 3606
+#line 3611
       xp = (double *) *xpp;
-#line 3606
+#line 3611
     }
-#line 3606
+#line 3611
    /* copy the next block */
-#line 3606
+#line 3611
 #pragma cdir loopcnt=LOOPCNT
-#line 3606
+#line 3611
 #pragma cdir shortloop
-#line 3606
+#line 3611
     for (i=0; i<ni; i++) {
-#line 3606
+#line 3611
       /* the normal case: */
-#line 3606
+#line 3611
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3606
+#line 3611
      /* test for range errors (not always needed but do it anyway) */
-#line 3606
+#line 3611
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3606
+#line 3611
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3606
+#line 3611
       nrange += tp[i] > X_DOUBLE_MAX ;
-#line 3606
+#line 3611
     }
-#line 3606
+#line 3611
    /* copy workspace back if necessary */
-#line 3606
+#line 3611
     if (realign) {
-#line 3606
+#line 3611
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3606
+#line 3611
       xp = (double *) *xpp;
-#line 3606
+#line 3611
     }
-#line 3606
+#line 3611
    /* update xpp and tp */
-#line 3606
+#line 3611
     xp += ni;
-#line 3606
+#line 3611
     tp += ni;
-#line 3606
+#line 3611
     *xpp = (void*)xp;
-#line 3606
+#line 3611
   }
-#line 3606
+#line 3611
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3606
+#line 3611
 
-#line 3606
+#line 3611
 #else   /* not SX */
-#line 3606
+#line 3611
 
-#line 3606
+#line 3611
 	char *xp = (char *) *xpp;
-#line 3606
+#line 3611
 	int status = NC_NOERR;
-#line 3606
+#line 3611
 
-#line 3606
+#line 3611
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3606
+#line 3611
 	{
-#line 3606
+#line 3611
 		int lstatus = ncx_put_double_ushort(xp, tp, fillp);
-#line 3606
+#line 3611
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3606
+#line 3611
 			status = lstatus;
-#line 3606
+#line 3611
 	}
-#line 3606
+#line 3611
 
-#line 3606
+#line 3611
 	*xpp = (void *)xp;
-#line 3606
+#line 3611
 	return status;
-#line 3606
+#line 3611
 #endif
-#line 3606
+#line 3611
 }
-#line 3606
+#line 3611
 
 int
-#line 3607
+#line 3612
 ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3607
+#line 3612
 {
-#line 3607
+#line 3612
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3607
+#line 3612
 
-#line 3607
+#line 3612
  /* basic algorithm is:
-#line 3607
+#line 3612
   *   - ensure sane alignment of output data
-#line 3607
+#line 3612
   *   - copy (conversion happens automatically) input data
-#line 3607
+#line 3612
   *     to output
-#line 3607
+#line 3612
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3607
+#line 3612
   *     at next location for converted output
-#line 3607
+#line 3612
   */
-#line 3607
+#line 3612
   long i, j, ni;
-#line 3607
+#line 3612
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3607
+#line 3612
   double *xp;
-#line 3607
+#line 3612
   int nrange = 0;         /* number of range errors */
-#line 3607
+#line 3612
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3607
+#line 3612
   long cxp = (long) *((char**)xpp);
-#line 3607
+#line 3612
 
-#line 3607
+#line 3612
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3607
+#line 3612
   /* sjl: manually stripmine so we can limit amount of
-#line 3607
+#line 3612
    * vector work space reserved to LOOPCNT elements. Also
-#line 3607
+#line 3612
    * makes vectorisation easy */
-#line 3607
+#line 3612
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3607
+#line 3612
     ni=Min(nelems-j,LOOPCNT);
-#line 3607
+#line 3612
     if (realign) {
-#line 3607
+#line 3612
       xp = tmp;
-#line 3607
+#line 3612
     } else {
-#line 3607
+#line 3612
       xp = (double *) *xpp;
-#line 3607
+#line 3612
     }
-#line 3607
+#line 3612
    /* copy the next block */
-#line 3607
+#line 3612
 #pragma cdir loopcnt=LOOPCNT
-#line 3607
+#line 3612
 #pragma cdir shortloop
-#line 3607
+#line 3612
     for (i=0; i<ni; i++) {
-#line 3607
+#line 3612
       /* the normal case: */
-#line 3607
+#line 3612
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3607
+#line 3612
      /* test for range errors (not always needed but do it anyway) */
-#line 3607
+#line 3612
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3607
+#line 3612
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3607
+#line 3612
       nrange += tp[i] > X_DOUBLE_MAX ;
-#line 3607
+#line 3612
     }
-#line 3607
+#line 3612
    /* copy workspace back if necessary */
-#line 3607
+#line 3612
     if (realign) {
-#line 3607
+#line 3612
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3607
+#line 3612
       xp = (double *) *xpp;
-#line 3607
+#line 3612
     }
-#line 3607
+#line 3612
    /* update xpp and tp */
-#line 3607
+#line 3612
     xp += ni;
-#line 3607
+#line 3612
     tp += ni;
-#line 3607
+#line 3612
     *xpp = (void*)xp;
-#line 3607
+#line 3612
   }
-#line 3607
+#line 3612
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3607
+#line 3612
 
-#line 3607
+#line 3612
 #else   /* not SX */
-#line 3607
+#line 3612
 
-#line 3607
+#line 3612
 	char *xp = (char *) *xpp;
-#line 3607
+#line 3612
 	int status = NC_NOERR;
-#line 3607
+#line 3612
 
-#line 3607
+#line 3612
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3607
+#line 3612
 	{
-#line 3607
+#line 3612
 		int lstatus = ncx_put_double_uint(xp, tp, fillp);
-#line 3607
+#line 3612
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3607
+#line 3612
 			status = lstatus;
-#line 3607
+#line 3612
 	}
-#line 3607
+#line 3612
 
-#line 3607
+#line 3612
 	*xpp = (void *)xp;
-#line 3607
+#line 3612
 	return status;
-#line 3607
+#line 3612
 #endif
-#line 3607
+#line 3612
 }
-#line 3607
+#line 3612
 
 int
-#line 3608
+#line 3613
 ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3608
+#line 3613
 {
-#line 3608
+#line 3613
 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
-#line 3608
+#line 3613
 
-#line 3608
+#line 3613
  /* basic algorithm is:
-#line 3608
+#line 3613
   *   - ensure sane alignment of output data
-#line 3608
+#line 3613
   *   - copy (conversion happens automatically) input data
-#line 3608
+#line 3613
   *     to output
-#line 3608
+#line 3613
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3608
+#line 3613
   *     at next location for converted output
-#line 3608
+#line 3613
   */
-#line 3608
+#line 3613
   long i, j, ni;
-#line 3608
+#line 3613
   double tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3608
+#line 3613
   double *xp;
-#line 3608
+#line 3613
   int nrange = 0;         /* number of range errors */
-#line 3608
+#line 3613
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3608
+#line 3613
   long cxp = (long) *((char**)xpp);
-#line 3608
+#line 3613
 
-#line 3608
+#line 3613
   realign = (cxp & 7) % SIZEOF_DOUBLE;
-#line 3608
+#line 3613
   /* sjl: manually stripmine so we can limit amount of
-#line 3608
+#line 3613
    * vector work space reserved to LOOPCNT elements. Also
-#line 3608
+#line 3613
    * makes vectorisation easy */
-#line 3608
+#line 3613
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3608
+#line 3613
     ni=Min(nelems-j,LOOPCNT);
-#line 3608
+#line 3613
     if (realign) {
-#line 3608
+#line 3613
       xp = tmp;
-#line 3608
+#line 3613
     } else {
-#line 3608
+#line 3613
       xp = (double *) *xpp;
-#line 3608
+#line 3613
     }
-#line 3608
+#line 3613
    /* copy the next block */
-#line 3608
+#line 3613
 #pragma cdir loopcnt=LOOPCNT
-#line 3608
+#line 3613
 #pragma cdir shortloop
-#line 3608
+#line 3613
     for (i=0; i<ni; i++) {
-#line 3608
+#line 3613
       /* the normal case: */
-#line 3608
+#line 3613
       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
-#line 3608
+#line 3613
      /* test for range errors (not always needed but do it anyway) */
-#line 3608
+#line 3613
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3608
+#line 3613
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3608
+#line 3613
       nrange += tp[i] > X_DOUBLE_MAX ;
-#line 3608
+#line 3613
     }
-#line 3608
+#line 3613
    /* copy workspace back if necessary */
-#line 3608
+#line 3613
     if (realign) {
-#line 3608
+#line 3613
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
-#line 3608
+#line 3613
       xp = (double *) *xpp;
-#line 3608
+#line 3613
     }
-#line 3608
+#line 3613
    /* update xpp and tp */
-#line 3608
+#line 3613
     xp += ni;
-#line 3608
+#line 3613
     tp += ni;
-#line 3608
+#line 3613
     *xpp = (void*)xp;
-#line 3608
+#line 3613
   }
-#line 3608
+#line 3613
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3608
+#line 3613
 
-#line 3608
+#line 3613
 #else   /* not SX */
-#line 3608
+#line 3613
 
-#line 3608
+#line 3613
 	char *xp = (char *) *xpp;
-#line 3608
+#line 3613
 	int status = NC_NOERR;
-#line 3608
+#line 3613
 
-#line 3608
+#line 3613
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
-#line 3608
+#line 3613
 	{
-#line 3608
+#line 3613
 		int lstatus = ncx_put_double_ulonglong(xp, tp, fillp);
-#line 3608
+#line 3613
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3608
+#line 3613
 			status = lstatus;
-#line 3608
+#line 3613
 	}
-#line 3608
+#line 3613
 
-#line 3608
+#line 3613
 	*xpp = (void *)xp;
-#line 3608
+#line 3613
 	return status;
-#line 3608
+#line 3613
 #endif
-#line 3608
+#line 3613
 }
-#line 3608
+#line 3613
 
 
 
@@ -33393,1424 +33398,1424 @@ ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
 }
 #else
 int
-#line 3627
+#line 3632
 ncx_getn_longlong_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3627
+#line 3632
 {
-#line 3627
+#line 3632
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3627
+#line 3632
 
-#line 3627
+#line 3632
  /* basic algorithm is:
-#line 3627
+#line 3632
   *   - ensure sane alignment of input data
-#line 3627
+#line 3632
   *   - copy (conversion happens automatically) input data
-#line 3627
+#line 3632
   *     to output
-#line 3627
+#line 3632
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3627
+#line 3632
   *     at next location for converted output
-#line 3627
+#line 3632
   */
-#line 3627
+#line 3632
   long i, j, ni;
-#line 3627
+#line 3632
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3627
+#line 3632
   int64 *xp;
-#line 3627
+#line 3632
   int nrange = 0;         /* number of range errors */
-#line 3627
+#line 3632
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3627
+#line 3632
   long cxp = (long) *((char**)xpp);
-#line 3627
+#line 3632
 
-#line 3627
+#line 3632
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3627
+#line 3632
   /* sjl: manually stripmine so we can limit amount of
-#line 3627
+#line 3632
    * vector work space reserved to LOOPCNT elements. Also
-#line 3627
+#line 3632
    * makes vectorisation easy */
-#line 3627
+#line 3632
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3627
+#line 3632
     ni=Min(nelems-j,LOOPCNT);
-#line 3627
+#line 3632
     if (realign) {
-#line 3627
+#line 3632
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3627
+#line 3632
       xp = tmp;
-#line 3627
+#line 3632
     } else {
-#line 3627
+#line 3632
       xp = (int64 *) *xpp;
-#line 3627
+#line 3632
     }
-#line 3627
+#line 3632
    /* copy the next block */
-#line 3627
+#line 3632
 #pragma cdir loopcnt=LOOPCNT
-#line 3627
+#line 3632
 #pragma cdir shortloop
-#line 3627
+#line 3632
     for (i=0; i<ni; i++) {
-#line 3627
+#line 3632
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3627
+#line 3632
      /* test for range errors (not always needed but do it anyway) */
-#line 3627
+#line 3632
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3627
+#line 3632
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3627
+#line 3632
       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
-#line 3627
+#line 3632
     }
-#line 3627
+#line 3632
    /* update xpp and tp */
-#line 3627
+#line 3632
     if (realign) xp = (int64 *) *xpp;
-#line 3627
+#line 3632
     xp += ni;
-#line 3627
+#line 3632
     tp += ni;
-#line 3627
+#line 3632
     *xpp = (void*)xp;
-#line 3627
+#line 3632
   }
-#line 3627
+#line 3632
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3627
+#line 3632
 
-#line 3627
+#line 3632
 #else   /* not SX */
-#line 3627
+#line 3632
 	const char *xp = (const char *) *xpp;
-#line 3627
+#line 3632
 	int status = NC_NOERR;
-#line 3627
+#line 3632
 
-#line 3627
+#line 3632
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3627
+#line 3632
 	{
-#line 3627
+#line 3632
 		const int lstatus = ncx_get_longlong_longlong(xp, tp);
-#line 3627
+#line 3632
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3627
+#line 3632
 			status = lstatus;
-#line 3627
+#line 3632
 	}
-#line 3627
+#line 3632
 
-#line 3627
+#line 3632
 	*xpp = (const void *)xp;
-#line 3627
+#line 3632
 	return status;
-#line 3627
+#line 3632
 #endif
-#line 3627
+#line 3632
 }
-#line 3627
+#line 3632
 
 #endif
 int
-#line 3629
+#line 3634
 ncx_getn_longlong_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3629
+#line 3634
 {
-#line 3629
+#line 3634
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3629
+#line 3634
 
-#line 3629
+#line 3634
  /* basic algorithm is:
-#line 3629
+#line 3634
   *   - ensure sane alignment of input data
-#line 3629
+#line 3634
   *   - copy (conversion happens automatically) input data
-#line 3629
+#line 3634
   *     to output
-#line 3629
+#line 3634
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3629
+#line 3634
   *     at next location for converted output
-#line 3629
+#line 3634
   */
-#line 3629
+#line 3634
   long i, j, ni;
-#line 3629
+#line 3634
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3629
+#line 3634
   int64 *xp;
-#line 3629
+#line 3634
   int nrange = 0;         /* number of range errors */
-#line 3629
+#line 3634
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3629
+#line 3634
   long cxp = (long) *((char**)xpp);
-#line 3629
+#line 3634
 
-#line 3629
+#line 3634
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3629
+#line 3634
   /* sjl: manually stripmine so we can limit amount of
-#line 3629
+#line 3634
    * vector work space reserved to LOOPCNT elements. Also
-#line 3629
+#line 3634
    * makes vectorisation easy */
-#line 3629
+#line 3634
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3629
+#line 3634
     ni=Min(nelems-j,LOOPCNT);
-#line 3629
+#line 3634
     if (realign) {
-#line 3629
+#line 3634
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3629
+#line 3634
       xp = tmp;
-#line 3629
+#line 3634
     } else {
-#line 3629
+#line 3634
       xp = (int64 *) *xpp;
-#line 3629
+#line 3634
     }
-#line 3629
+#line 3634
    /* copy the next block */
-#line 3629
+#line 3634
 #pragma cdir loopcnt=LOOPCNT
-#line 3629
+#line 3634
 #pragma cdir shortloop
-#line 3629
+#line 3634
     for (i=0; i<ni; i++) {
-#line 3629
+#line 3634
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3629
+#line 3634
      /* test for range errors (not always needed but do it anyway) */
-#line 3629
+#line 3634
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3629
+#line 3634
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3629
+#line 3634
       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
-#line 3629
+#line 3634
     }
-#line 3629
+#line 3634
    /* update xpp and tp */
-#line 3629
+#line 3634
     if (realign) xp = (int64 *) *xpp;
-#line 3629
+#line 3634
     xp += ni;
-#line 3629
+#line 3634
     tp += ni;
-#line 3629
+#line 3634
     *xpp = (void*)xp;
-#line 3629
+#line 3634
   }
-#line 3629
+#line 3634
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3629
+#line 3634
 
-#line 3629
+#line 3634
 #else   /* not SX */
-#line 3629
+#line 3634
 	const char *xp = (const char *) *xpp;
-#line 3629
+#line 3634
 	int status = NC_NOERR;
-#line 3629
+#line 3634
 
-#line 3629
+#line 3634
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3629
+#line 3634
 	{
-#line 3629
+#line 3634
 		const int lstatus = ncx_get_longlong_schar(xp, tp);
-#line 3629
+#line 3634
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3629
+#line 3634
 			status = lstatus;
-#line 3629
+#line 3634
 	}
-#line 3629
+#line 3634
 
-#line 3629
+#line 3634
 	*xpp = (const void *)xp;
-#line 3629
+#line 3634
 	return status;
-#line 3629
+#line 3634
 #endif
-#line 3629
+#line 3634
 }
-#line 3629
+#line 3634
 
 int
-#line 3630
+#line 3635
 ncx_getn_longlong_short(const void **xpp, size_t nelems, short *tp)
-#line 3630
+#line 3635
 {
-#line 3630
+#line 3635
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3630
+#line 3635
 
-#line 3630
+#line 3635
  /* basic algorithm is:
-#line 3630
+#line 3635
   *   - ensure sane alignment of input data
-#line 3630
+#line 3635
   *   - copy (conversion happens automatically) input data
-#line 3630
+#line 3635
   *     to output
-#line 3630
+#line 3635
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3630
+#line 3635
   *     at next location for converted output
-#line 3630
+#line 3635
   */
-#line 3630
+#line 3635
   long i, j, ni;
-#line 3630
+#line 3635
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3630
+#line 3635
   int64 *xp;
-#line 3630
+#line 3635
   int nrange = 0;         /* number of range errors */
-#line 3630
+#line 3635
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3630
+#line 3635
   long cxp = (long) *((char**)xpp);
-#line 3630
+#line 3635
 
-#line 3630
+#line 3635
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3630
+#line 3635
   /* sjl: manually stripmine so we can limit amount of
-#line 3630
+#line 3635
    * vector work space reserved to LOOPCNT elements. Also
-#line 3630
+#line 3635
    * makes vectorisation easy */
-#line 3630
+#line 3635
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3630
+#line 3635
     ni=Min(nelems-j,LOOPCNT);
-#line 3630
+#line 3635
     if (realign) {
-#line 3630
+#line 3635
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3630
+#line 3635
       xp = tmp;
-#line 3630
+#line 3635
     } else {
-#line 3630
+#line 3635
       xp = (int64 *) *xpp;
-#line 3630
+#line 3635
     }
-#line 3630
+#line 3635
    /* copy the next block */
-#line 3630
+#line 3635
 #pragma cdir loopcnt=LOOPCNT
-#line 3630
+#line 3635
 #pragma cdir shortloop
-#line 3630
+#line 3635
     for (i=0; i<ni; i++) {
-#line 3630
+#line 3635
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3630
+#line 3635
      /* test for range errors (not always needed but do it anyway) */
-#line 3630
+#line 3635
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3630
+#line 3635
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3630
+#line 3635
       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
-#line 3630
+#line 3635
     }
-#line 3630
+#line 3635
    /* update xpp and tp */
-#line 3630
+#line 3635
     if (realign) xp = (int64 *) *xpp;
-#line 3630
+#line 3635
     xp += ni;
-#line 3630
+#line 3635
     tp += ni;
-#line 3630
+#line 3635
     *xpp = (void*)xp;
-#line 3630
+#line 3635
   }
-#line 3630
+#line 3635
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3630
+#line 3635
 
-#line 3630
+#line 3635
 #else   /* not SX */
-#line 3630
+#line 3635
 	const char *xp = (const char *) *xpp;
-#line 3630
+#line 3635
 	int status = NC_NOERR;
-#line 3630
+#line 3635
 
-#line 3630
+#line 3635
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3630
+#line 3635
 	{
-#line 3630
+#line 3635
 		const int lstatus = ncx_get_longlong_short(xp, tp);
-#line 3630
+#line 3635
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3630
+#line 3635
 			status = lstatus;
-#line 3630
+#line 3635
 	}
-#line 3630
+#line 3635
 
-#line 3630
+#line 3635
 	*xpp = (const void *)xp;
-#line 3630
+#line 3635
 	return status;
-#line 3630
+#line 3635
 #endif
-#line 3630
+#line 3635
 }
-#line 3630
+#line 3635
 
 int
-#line 3631
+#line 3636
 ncx_getn_longlong_int(const void **xpp, size_t nelems, int *tp)
-#line 3631
+#line 3636
 {
-#line 3631
+#line 3636
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3631
+#line 3636
 
-#line 3631
+#line 3636
  /* basic algorithm is:
-#line 3631
+#line 3636
   *   - ensure sane alignment of input data
-#line 3631
+#line 3636
   *   - copy (conversion happens automatically) input data
-#line 3631
+#line 3636
   *     to output
-#line 3631
+#line 3636
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3631
+#line 3636
   *     at next location for converted output
-#line 3631
+#line 3636
   */
-#line 3631
+#line 3636
   long i, j, ni;
-#line 3631
+#line 3636
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3631
+#line 3636
   int64 *xp;
-#line 3631
+#line 3636
   int nrange = 0;         /* number of range errors */
-#line 3631
+#line 3636
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3631
+#line 3636
   long cxp = (long) *((char**)xpp);
-#line 3631
+#line 3636
 
-#line 3631
+#line 3636
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3631
+#line 3636
   /* sjl: manually stripmine so we can limit amount of
-#line 3631
+#line 3636
    * vector work space reserved to LOOPCNT elements. Also
-#line 3631
+#line 3636
    * makes vectorisation easy */
-#line 3631
+#line 3636
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3631
+#line 3636
     ni=Min(nelems-j,LOOPCNT);
-#line 3631
+#line 3636
     if (realign) {
-#line 3631
+#line 3636
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3631
+#line 3636
       xp = tmp;
-#line 3631
+#line 3636
     } else {
-#line 3631
+#line 3636
       xp = (int64 *) *xpp;
-#line 3631
+#line 3636
     }
-#line 3631
+#line 3636
    /* copy the next block */
-#line 3631
+#line 3636
 #pragma cdir loopcnt=LOOPCNT
-#line 3631
+#line 3636
 #pragma cdir shortloop
-#line 3631
+#line 3636
     for (i=0; i<ni; i++) {
-#line 3631
+#line 3636
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3631
+#line 3636
      /* test for range errors (not always needed but do it anyway) */
-#line 3631
+#line 3636
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3631
+#line 3636
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3631
+#line 3636
       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
-#line 3631
+#line 3636
     }
-#line 3631
+#line 3636
    /* update xpp and tp */
-#line 3631
+#line 3636
     if (realign) xp = (int64 *) *xpp;
-#line 3631
+#line 3636
     xp += ni;
-#line 3631
+#line 3636
     tp += ni;
-#line 3631
+#line 3636
     *xpp = (void*)xp;
-#line 3631
+#line 3636
   }
-#line 3631
+#line 3636
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3631
+#line 3636
 
-#line 3631
+#line 3636
 #else   /* not SX */
-#line 3631
+#line 3636
 	const char *xp = (const char *) *xpp;
-#line 3631
+#line 3636
 	int status = NC_NOERR;
-#line 3631
+#line 3636
 
-#line 3631
+#line 3636
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3631
+#line 3636
 	{
-#line 3631
+#line 3636
 		const int lstatus = ncx_get_longlong_int(xp, tp);
-#line 3631
+#line 3636
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3631
+#line 3636
 			status = lstatus;
-#line 3631
+#line 3636
 	}
-#line 3631
+#line 3636
 
-#line 3631
+#line 3636
 	*xpp = (const void *)xp;
-#line 3631
+#line 3636
 	return status;
-#line 3631
+#line 3636
 #endif
-#line 3631
+#line 3636
 }
-#line 3631
+#line 3636
 
 int
-#line 3632
+#line 3637
 ncx_getn_longlong_long(const void **xpp, size_t nelems, long *tp)
-#line 3632
+#line 3637
 {
-#line 3632
+#line 3637
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3632
+#line 3637
 
-#line 3632
+#line 3637
  /* basic algorithm is:
-#line 3632
+#line 3637
   *   - ensure sane alignment of input data
-#line 3632
+#line 3637
   *   - copy (conversion happens automatically) input data
-#line 3632
+#line 3637
   *     to output
-#line 3632
+#line 3637
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3632
+#line 3637
   *     at next location for converted output
-#line 3632
+#line 3637
   */
-#line 3632
+#line 3637
   long i, j, ni;
-#line 3632
+#line 3637
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3632
+#line 3637
   int64 *xp;
-#line 3632
+#line 3637
   int nrange = 0;         /* number of range errors */
-#line 3632
+#line 3637
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3632
+#line 3637
   long cxp = (long) *((char**)xpp);
-#line 3632
+#line 3637
 
-#line 3632
+#line 3637
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3632
+#line 3637
   /* sjl: manually stripmine so we can limit amount of
-#line 3632
+#line 3637
    * vector work space reserved to LOOPCNT elements. Also
-#line 3632
+#line 3637
    * makes vectorisation easy */
-#line 3632
+#line 3637
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3632
+#line 3637
     ni=Min(nelems-j,LOOPCNT);
-#line 3632
+#line 3637
     if (realign) {
-#line 3632
+#line 3637
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3632
+#line 3637
       xp = tmp;
-#line 3632
+#line 3637
     } else {
-#line 3632
+#line 3637
       xp = (int64 *) *xpp;
-#line 3632
+#line 3637
     }
-#line 3632
+#line 3637
    /* copy the next block */
-#line 3632
+#line 3637
 #pragma cdir loopcnt=LOOPCNT
-#line 3632
+#line 3637
 #pragma cdir shortloop
-#line 3632
+#line 3637
     for (i=0; i<ni; i++) {
-#line 3632
+#line 3637
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3632
+#line 3637
      /* test for range errors (not always needed but do it anyway) */
-#line 3632
+#line 3637
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3632
+#line 3637
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3632
+#line 3637
       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
-#line 3632
+#line 3637
     }
-#line 3632
+#line 3637
    /* update xpp and tp */
-#line 3632
+#line 3637
     if (realign) xp = (int64 *) *xpp;
-#line 3632
+#line 3637
     xp += ni;
-#line 3632
+#line 3637
     tp += ni;
-#line 3632
+#line 3637
     *xpp = (void*)xp;
-#line 3632
+#line 3637
   }
-#line 3632
+#line 3637
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3632
+#line 3637
 
-#line 3632
+#line 3637
 #else   /* not SX */
-#line 3632
+#line 3637
 	const char *xp = (const char *) *xpp;
-#line 3632
+#line 3637
 	int status = NC_NOERR;
-#line 3632
+#line 3637
 
-#line 3632
+#line 3637
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3632
+#line 3637
 	{
-#line 3632
+#line 3637
 		const int lstatus = ncx_get_longlong_long(xp, tp);
-#line 3632
+#line 3637
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3632
+#line 3637
 			status = lstatus;
-#line 3632
+#line 3637
 	}
-#line 3632
+#line 3637
 
-#line 3632
+#line 3637
 	*xpp = (const void *)xp;
-#line 3632
+#line 3637
 	return status;
-#line 3632
+#line 3637
 #endif
-#line 3632
+#line 3637
 }
-#line 3632
+#line 3637
 
 int
-#line 3633
+#line 3638
 ncx_getn_longlong_float(const void **xpp, size_t nelems, float *tp)
-#line 3633
+#line 3638
 {
-#line 3633
+#line 3638
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3633
+#line 3638
 
-#line 3633
+#line 3638
  /* basic algorithm is:
-#line 3633
+#line 3638
   *   - ensure sane alignment of input data
-#line 3633
+#line 3638
   *   - copy (conversion happens automatically) input data
-#line 3633
+#line 3638
   *     to output
-#line 3633
+#line 3638
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3633
+#line 3638
   *     at next location for converted output
-#line 3633
+#line 3638
   */
-#line 3633
+#line 3638
   long i, j, ni;
-#line 3633
+#line 3638
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3633
+#line 3638
   int64 *xp;
-#line 3633
+#line 3638
   int nrange = 0;         /* number of range errors */
-#line 3633
+#line 3638
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3633
+#line 3638
   long cxp = (long) *((char**)xpp);
-#line 3633
+#line 3638
 
-#line 3633
+#line 3638
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3633
+#line 3638
   /* sjl: manually stripmine so we can limit amount of
-#line 3633
+#line 3638
    * vector work space reserved to LOOPCNT elements. Also
-#line 3633
+#line 3638
    * makes vectorisation easy */
-#line 3633
+#line 3638
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3633
+#line 3638
     ni=Min(nelems-j,LOOPCNT);
-#line 3633
+#line 3638
     if (realign) {
-#line 3633
+#line 3638
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3633
+#line 3638
       xp = tmp;
-#line 3633
+#line 3638
     } else {
-#line 3633
+#line 3638
       xp = (int64 *) *xpp;
-#line 3633
+#line 3638
     }
-#line 3633
+#line 3638
    /* copy the next block */
-#line 3633
+#line 3638
 #pragma cdir loopcnt=LOOPCNT
-#line 3633
+#line 3638
 #pragma cdir shortloop
-#line 3633
+#line 3638
     for (i=0; i<ni; i++) {
-#line 3633
+#line 3638
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3633
+#line 3638
      /* test for range errors (not always needed but do it anyway) */
-#line 3633
+#line 3638
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3633
+#line 3638
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3633
+#line 3638
       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
-#line 3633
+#line 3638
     }
-#line 3633
+#line 3638
    /* update xpp and tp */
-#line 3633
+#line 3638
     if (realign) xp = (int64 *) *xpp;
-#line 3633
+#line 3638
     xp += ni;
-#line 3633
+#line 3638
     tp += ni;
-#line 3633
+#line 3638
     *xpp = (void*)xp;
-#line 3633
+#line 3638
   }
-#line 3633
+#line 3638
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3633
+#line 3638
 
-#line 3633
+#line 3638
 #else   /* not SX */
-#line 3633
+#line 3638
 	const char *xp = (const char *) *xpp;
-#line 3633
+#line 3638
 	int status = NC_NOERR;
-#line 3633
+#line 3638
 
-#line 3633
+#line 3638
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3633
+#line 3638
 	{
-#line 3633
+#line 3638
 		const int lstatus = ncx_get_longlong_float(xp, tp);
-#line 3633
+#line 3638
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3633
+#line 3638
 			status = lstatus;
-#line 3633
+#line 3638
 	}
-#line 3633
+#line 3638
 
-#line 3633
+#line 3638
 	*xpp = (const void *)xp;
-#line 3633
+#line 3638
 	return status;
-#line 3633
+#line 3638
 #endif
-#line 3633
+#line 3638
 }
-#line 3633
+#line 3638
 
 int
-#line 3634
+#line 3639
 ncx_getn_longlong_double(const void **xpp, size_t nelems, double *tp)
-#line 3634
+#line 3639
 {
-#line 3634
+#line 3639
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3634
+#line 3639
 
-#line 3634
+#line 3639
  /* basic algorithm is:
-#line 3634
+#line 3639
   *   - ensure sane alignment of input data
-#line 3634
+#line 3639
   *   - copy (conversion happens automatically) input data
-#line 3634
+#line 3639
   *     to output
-#line 3634
+#line 3639
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3634
+#line 3639
   *     at next location for converted output
-#line 3634
+#line 3639
   */
-#line 3634
+#line 3639
   long i, j, ni;
-#line 3634
+#line 3639
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3634
+#line 3639
   int64 *xp;
-#line 3634
+#line 3639
   int nrange = 0;         /* number of range errors */
-#line 3634
+#line 3639
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3634
+#line 3639
   long cxp = (long) *((char**)xpp);
-#line 3634
+#line 3639
 
-#line 3634
+#line 3639
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3634
+#line 3639
   /* sjl: manually stripmine so we can limit amount of
-#line 3634
+#line 3639
    * vector work space reserved to LOOPCNT elements. Also
-#line 3634
+#line 3639
    * makes vectorisation easy */
-#line 3634
+#line 3639
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3634
+#line 3639
     ni=Min(nelems-j,LOOPCNT);
-#line 3634
+#line 3639
     if (realign) {
-#line 3634
+#line 3639
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3634
+#line 3639
       xp = tmp;
-#line 3634
+#line 3639
     } else {
-#line 3634
+#line 3639
       xp = (int64 *) *xpp;
-#line 3634
+#line 3639
     }
-#line 3634
+#line 3639
    /* copy the next block */
-#line 3634
+#line 3639
 #pragma cdir loopcnt=LOOPCNT
-#line 3634
+#line 3639
 #pragma cdir shortloop
-#line 3634
+#line 3639
     for (i=0; i<ni; i++) {
-#line 3634
+#line 3639
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3634
+#line 3639
      /* test for range errors (not always needed but do it anyway) */
-#line 3634
+#line 3639
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3634
+#line 3639
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3634
+#line 3639
       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
-#line 3634
+#line 3639
     }
-#line 3634
+#line 3639
    /* update xpp and tp */
-#line 3634
+#line 3639
     if (realign) xp = (int64 *) *xpp;
-#line 3634
+#line 3639
     xp += ni;
-#line 3634
+#line 3639
     tp += ni;
-#line 3634
+#line 3639
     *xpp = (void*)xp;
-#line 3634
+#line 3639
   }
-#line 3634
+#line 3639
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3634
+#line 3639
 
-#line 3634
+#line 3639
 #else   /* not SX */
-#line 3634
+#line 3639
 	const char *xp = (const char *) *xpp;
-#line 3634
+#line 3639
 	int status = NC_NOERR;
-#line 3634
+#line 3639
 
-#line 3634
+#line 3639
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3634
+#line 3639
 	{
-#line 3634
+#line 3639
 		const int lstatus = ncx_get_longlong_double(xp, tp);
-#line 3634
+#line 3639
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3634
+#line 3639
 			status = lstatus;
-#line 3634
+#line 3639
 	}
-#line 3634
+#line 3639
 
-#line 3634
+#line 3639
 	*xpp = (const void *)xp;
-#line 3634
+#line 3639
 	return status;
-#line 3634
+#line 3639
 #endif
-#line 3634
+#line 3639
 }
-#line 3634
+#line 3639
 
 int
-#line 3635
+#line 3640
 ncx_getn_longlong_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3635
+#line 3640
 {
-#line 3635
+#line 3640
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3635
+#line 3640
 
-#line 3635
+#line 3640
  /* basic algorithm is:
-#line 3635
+#line 3640
   *   - ensure sane alignment of input data
-#line 3635
+#line 3640
   *   - copy (conversion happens automatically) input data
-#line 3635
+#line 3640
   *     to output
-#line 3635
+#line 3640
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3635
+#line 3640
   *     at next location for converted output
-#line 3635
+#line 3640
   */
-#line 3635
+#line 3640
   long i, j, ni;
-#line 3635
+#line 3640
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3635
+#line 3640
   int64 *xp;
-#line 3635
+#line 3640
   int nrange = 0;         /* number of range errors */
-#line 3635
+#line 3640
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3635
+#line 3640
   long cxp = (long) *((char**)xpp);
-#line 3635
+#line 3640
 
-#line 3635
+#line 3640
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3635
+#line 3640
   /* sjl: manually stripmine so we can limit amount of
-#line 3635
+#line 3640
    * vector work space reserved to LOOPCNT elements. Also
-#line 3635
+#line 3640
    * makes vectorisation easy */
-#line 3635
+#line 3640
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3635
+#line 3640
     ni=Min(nelems-j,LOOPCNT);
-#line 3635
+#line 3640
     if (realign) {
-#line 3635
+#line 3640
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3635
+#line 3640
       xp = tmp;
-#line 3635
+#line 3640
     } else {
-#line 3635
+#line 3640
       xp = (int64 *) *xpp;
-#line 3635
+#line 3640
     }
-#line 3635
+#line 3640
    /* copy the next block */
-#line 3635
+#line 3640
 #pragma cdir loopcnt=LOOPCNT
-#line 3635
+#line 3640
 #pragma cdir shortloop
-#line 3635
+#line 3640
     for (i=0; i<ni; i++) {
-#line 3635
+#line 3640
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3635
+#line 3640
      /* test for range errors (not always needed but do it anyway) */
-#line 3635
+#line 3640
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3635
+#line 3640
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3635
+#line 3640
       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
-#line 3635
+#line 3640
     }
-#line 3635
+#line 3640
    /* update xpp and tp */
-#line 3635
+#line 3640
     if (realign) xp = (int64 *) *xpp;
-#line 3635
+#line 3640
     xp += ni;
-#line 3635
+#line 3640
     tp += ni;
-#line 3635
+#line 3640
     *xpp = (void*)xp;
-#line 3635
+#line 3640
   }
-#line 3635
+#line 3640
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3635
+#line 3640
 
-#line 3635
+#line 3640
 #else   /* not SX */
-#line 3635
+#line 3640
 	const char *xp = (const char *) *xpp;
-#line 3635
+#line 3640
 	int status = NC_NOERR;
-#line 3635
+#line 3640
 
-#line 3635
+#line 3640
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3635
+#line 3640
 	{
-#line 3635
+#line 3640
 		const int lstatus = ncx_get_longlong_uchar(xp, tp);
-#line 3635
+#line 3640
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3635
+#line 3640
 			status = lstatus;
-#line 3635
+#line 3640
 	}
-#line 3635
+#line 3640
 
-#line 3635
+#line 3640
 	*xpp = (const void *)xp;
-#line 3635
+#line 3640
 	return status;
-#line 3635
+#line 3640
 #endif
-#line 3635
+#line 3640
 }
-#line 3635
+#line 3640
 
 int
-#line 3636
+#line 3641
 ncx_getn_longlong_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3636
+#line 3641
 {
-#line 3636
+#line 3641
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3636
+#line 3641
 
-#line 3636
+#line 3641
  /* basic algorithm is:
-#line 3636
+#line 3641
   *   - ensure sane alignment of input data
-#line 3636
+#line 3641
   *   - copy (conversion happens automatically) input data
-#line 3636
+#line 3641
   *     to output
-#line 3636
+#line 3641
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3636
+#line 3641
   *     at next location for converted output
-#line 3636
+#line 3641
   */
-#line 3636
+#line 3641
   long i, j, ni;
-#line 3636
+#line 3641
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3636
+#line 3641
   int64 *xp;
-#line 3636
+#line 3641
   int nrange = 0;         /* number of range errors */
-#line 3636
+#line 3641
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3636
+#line 3641
   long cxp = (long) *((char**)xpp);
-#line 3636
+#line 3641
 
-#line 3636
+#line 3641
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3636
+#line 3641
   /* sjl: manually stripmine so we can limit amount of
-#line 3636
+#line 3641
    * vector work space reserved to LOOPCNT elements. Also
-#line 3636
+#line 3641
    * makes vectorisation easy */
-#line 3636
+#line 3641
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3636
+#line 3641
     ni=Min(nelems-j,LOOPCNT);
-#line 3636
+#line 3641
     if (realign) {
-#line 3636
+#line 3641
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3636
+#line 3641
       xp = tmp;
-#line 3636
+#line 3641
     } else {
-#line 3636
+#line 3641
       xp = (int64 *) *xpp;
-#line 3636
+#line 3641
     }
-#line 3636
+#line 3641
    /* copy the next block */
-#line 3636
+#line 3641
 #pragma cdir loopcnt=LOOPCNT
-#line 3636
+#line 3641
 #pragma cdir shortloop
-#line 3636
+#line 3641
     for (i=0; i<ni; i++) {
-#line 3636
+#line 3641
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3636
+#line 3641
      /* test for range errors (not always needed but do it anyway) */
-#line 3636
+#line 3641
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3636
+#line 3641
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3636
+#line 3641
       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
-#line 3636
+#line 3641
     }
-#line 3636
+#line 3641
    /* update xpp and tp */
-#line 3636
+#line 3641
     if (realign) xp = (int64 *) *xpp;
-#line 3636
+#line 3641
     xp += ni;
-#line 3636
+#line 3641
     tp += ni;
-#line 3636
+#line 3641
     *xpp = (void*)xp;
-#line 3636
+#line 3641
   }
-#line 3636
+#line 3641
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3636
+#line 3641
 
-#line 3636
+#line 3641
 #else   /* not SX */
-#line 3636
+#line 3641
 	const char *xp = (const char *) *xpp;
-#line 3636
+#line 3641
 	int status = NC_NOERR;
-#line 3636
+#line 3641
 
-#line 3636
+#line 3641
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3636
+#line 3641
 	{
-#line 3636
+#line 3641
 		const int lstatus = ncx_get_longlong_ushort(xp, tp);
-#line 3636
+#line 3641
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3636
+#line 3641
 			status = lstatus;
-#line 3636
+#line 3641
 	}
-#line 3636
+#line 3641
 
-#line 3636
+#line 3641
 	*xpp = (const void *)xp;
-#line 3636
+#line 3641
 	return status;
-#line 3636
+#line 3641
 #endif
-#line 3636
+#line 3641
 }
-#line 3636
+#line 3641
 
 int
-#line 3637
+#line 3642
 ncx_getn_longlong_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3637
+#line 3642
 {
-#line 3637
+#line 3642
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3637
+#line 3642
 
-#line 3637
+#line 3642
  /* basic algorithm is:
-#line 3637
+#line 3642
   *   - ensure sane alignment of input data
-#line 3637
+#line 3642
   *   - copy (conversion happens automatically) input data
-#line 3637
+#line 3642
   *     to output
-#line 3637
+#line 3642
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3637
+#line 3642
   *     at next location for converted output
-#line 3637
+#line 3642
   */
-#line 3637
+#line 3642
   long i, j, ni;
-#line 3637
+#line 3642
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3637
+#line 3642
   int64 *xp;
-#line 3637
+#line 3642
   int nrange = 0;         /* number of range errors */
-#line 3637
+#line 3642
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3637
+#line 3642
   long cxp = (long) *((char**)xpp);
-#line 3637
+#line 3642
 
-#line 3637
+#line 3642
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3637
+#line 3642
   /* sjl: manually stripmine so we can limit amount of
-#line 3637
+#line 3642
    * vector work space reserved to LOOPCNT elements. Also
-#line 3637
+#line 3642
    * makes vectorisation easy */
-#line 3637
+#line 3642
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3637
+#line 3642
     ni=Min(nelems-j,LOOPCNT);
-#line 3637
+#line 3642
     if (realign) {
-#line 3637
+#line 3642
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3637
+#line 3642
       xp = tmp;
-#line 3637
+#line 3642
     } else {
-#line 3637
+#line 3642
       xp = (int64 *) *xpp;
-#line 3637
+#line 3642
     }
-#line 3637
+#line 3642
    /* copy the next block */
-#line 3637
+#line 3642
 #pragma cdir loopcnt=LOOPCNT
-#line 3637
+#line 3642
 #pragma cdir shortloop
-#line 3637
+#line 3642
     for (i=0; i<ni; i++) {
-#line 3637
+#line 3642
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3637
+#line 3642
      /* test for range errors (not always needed but do it anyway) */
-#line 3637
+#line 3642
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3637
+#line 3642
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3637
+#line 3642
       nrange += xp[i] > UINT_MAX || xp[i] < 0;
-#line 3637
+#line 3642
     }
-#line 3637
+#line 3642
    /* update xpp and tp */
-#line 3637
+#line 3642
     if (realign) xp = (int64 *) *xpp;
-#line 3637
+#line 3642
     xp += ni;
-#line 3637
+#line 3642
     tp += ni;
-#line 3637
+#line 3642
     *xpp = (void*)xp;
-#line 3637
+#line 3642
   }
-#line 3637
+#line 3642
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3637
+#line 3642
 
-#line 3637
+#line 3642
 #else   /* not SX */
-#line 3637
+#line 3642
 	const char *xp = (const char *) *xpp;
-#line 3637
+#line 3642
 	int status = NC_NOERR;
-#line 3637
+#line 3642
 
-#line 3637
+#line 3642
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3637
+#line 3642
 	{
-#line 3637
+#line 3642
 		const int lstatus = ncx_get_longlong_uint(xp, tp);
-#line 3637
+#line 3642
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3637
+#line 3642
 			status = lstatus;
-#line 3637
+#line 3642
 	}
-#line 3637
+#line 3642
 
-#line 3637
+#line 3642
 	*xpp = (const void *)xp;
-#line 3637
+#line 3642
 	return status;
-#line 3637
+#line 3642
 #endif
-#line 3637
+#line 3642
 }
-#line 3637
+#line 3642
 
 int
-#line 3638
+#line 3643
 ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3638
+#line 3643
 {
-#line 3638
+#line 3643
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3638
+#line 3643
 
-#line 3638
+#line 3643
  /* basic algorithm is:
-#line 3638
+#line 3643
   *   - ensure sane alignment of input data
-#line 3638
+#line 3643
   *   - copy (conversion happens automatically) input data
-#line 3638
+#line 3643
   *     to output
-#line 3638
+#line 3643
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3638
+#line 3643
   *     at next location for converted output
-#line 3638
+#line 3643
   */
-#line 3638
+#line 3643
   long i, j, ni;
-#line 3638
+#line 3643
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3638
+#line 3643
   int64 *xp;
-#line 3638
+#line 3643
   int nrange = 0;         /* number of range errors */
-#line 3638
+#line 3643
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3638
+#line 3643
   long cxp = (long) *((char**)xpp);
-#line 3638
+#line 3643
 
-#line 3638
+#line 3643
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3638
+#line 3643
   /* sjl: manually stripmine so we can limit amount of
-#line 3638
+#line 3643
    * vector work space reserved to LOOPCNT elements. Also
-#line 3638
+#line 3643
    * makes vectorisation easy */
-#line 3638
+#line 3643
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3638
+#line 3643
     ni=Min(nelems-j,LOOPCNT);
-#line 3638
+#line 3643
     if (realign) {
-#line 3638
+#line 3643
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
-#line 3638
+#line 3643
       xp = tmp;
-#line 3638
+#line 3643
     } else {
-#line 3638
+#line 3643
       xp = (int64 *) *xpp;
-#line 3638
+#line 3643
     }
-#line 3638
+#line 3643
    /* copy the next block */
-#line 3638
+#line 3643
 #pragma cdir loopcnt=LOOPCNT
-#line 3638
+#line 3643
 #pragma cdir shortloop
-#line 3638
+#line 3643
     for (i=0; i<ni; i++) {
-#line 3638
+#line 3643
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3638
+#line 3643
      /* test for range errors (not always needed but do it anyway) */
-#line 3638
+#line 3643
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3638
+#line 3643
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3638
+#line 3643
       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
-#line 3638
+#line 3643
     }
-#line 3638
+#line 3643
    /* update xpp and tp */
-#line 3638
+#line 3643
     if (realign) xp = (int64 *) *xpp;
-#line 3638
+#line 3643
     xp += ni;
-#line 3638
+#line 3643
     tp += ni;
-#line 3638
+#line 3643
     *xpp = (void*)xp;
-#line 3638
+#line 3643
   }
-#line 3638
+#line 3643
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3638
+#line 3643
 
-#line 3638
+#line 3643
 #else   /* not SX */
-#line 3638
+#line 3643
 	const char *xp = (const char *) *xpp;
-#line 3638
+#line 3643
 	int status = NC_NOERR;
-#line 3638
+#line 3643
 
-#line 3638
+#line 3643
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3638
+#line 3643
 	{
-#line 3638
+#line 3643
 		const int lstatus = ncx_get_longlong_ulonglong(xp, tp);
-#line 3638
+#line 3643
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3638
+#line 3643
 			status = lstatus;
-#line 3638
+#line 3643
 	}
-#line 3638
+#line 3643
 
-#line 3638
+#line 3643
 	*xpp = (const void *)xp;
-#line 3638
+#line 3643
 	return status;
-#line 3638
+#line 3643
 #endif
-#line 3638
+#line 3643
 }
-#line 3638
+#line 3643
 
 
 #if X_SIZEOF_INT64 == SIZEOF_LONGLONG
@@ -34828,1534 +34833,1534 @@ ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp, void
 }
 #else
 int
-#line 3654
+#line 3659
 ncx_putn_longlong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3654
+#line 3659
 {
-#line 3654
+#line 3659
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3654
+#line 3659
 
-#line 3654
+#line 3659
  /* basic algorithm is:
-#line 3654
+#line 3659
   *   - ensure sane alignment of output data
-#line 3654
+#line 3659
   *   - copy (conversion happens automatically) input data
-#line 3654
+#line 3659
   *     to output
-#line 3654
+#line 3659
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3654
+#line 3659
   *     at next location for converted output
-#line 3654
+#line 3659
   */
-#line 3654
+#line 3659
   long i, j, ni;
-#line 3654
+#line 3659
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3654
+#line 3659
   int64 *xp;
-#line 3654
+#line 3659
   int nrange = 0;         /* number of range errors */
-#line 3654
+#line 3659
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3654
+#line 3659
   long cxp = (long) *((char**)xpp);
-#line 3654
+#line 3659
 
-#line 3654
+#line 3659
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3654
+#line 3659
   /* sjl: manually stripmine so we can limit amount of
-#line 3654
+#line 3659
    * vector work space reserved to LOOPCNT elements. Also
-#line 3654
+#line 3659
    * makes vectorisation easy */
-#line 3654
+#line 3659
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3654
+#line 3659
     ni=Min(nelems-j,LOOPCNT);
-#line 3654
+#line 3659
     if (realign) {
-#line 3654
+#line 3659
       xp = tmp;
-#line 3654
+#line 3659
     } else {
-#line 3654
+#line 3659
       xp = (int64 *) *xpp;
-#line 3654
+#line 3659
     }
-#line 3654
+#line 3659
    /* copy the next block */
-#line 3654
+#line 3659
 #pragma cdir loopcnt=LOOPCNT
-#line 3654
+#line 3659
 #pragma cdir shortloop
-#line 3654
+#line 3659
     for (i=0; i<ni; i++) {
-#line 3654
+#line 3659
       /* the normal case: */
-#line 3654
+#line 3659
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3654
+#line 3659
      /* test for range errors (not always needed but do it anyway) */
-#line 3654
+#line 3659
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3654
+#line 3659
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3654
+#line 3659
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3654
+#line 3659
     }
-#line 3654
+#line 3659
    /* copy workspace back if necessary */
-#line 3654
+#line 3659
     if (realign) {
-#line 3654
+#line 3659
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3654
+#line 3659
       xp = (int64 *) *xpp;
-#line 3654
+#line 3659
     }
-#line 3654
+#line 3659
    /* update xpp and tp */
-#line 3654
+#line 3659
     xp += ni;
-#line 3654
+#line 3659
     tp += ni;
-#line 3654
+#line 3659
     *xpp = (void*)xp;
-#line 3654
+#line 3659
   }
-#line 3654
+#line 3659
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3654
+#line 3659
 
-#line 3654
+#line 3659
 #else   /* not SX */
-#line 3654
+#line 3659
 
-#line 3654
+#line 3659
 	char *xp = (char *) *xpp;
-#line 3654
+#line 3659
 	int status = NC_NOERR;
-#line 3654
+#line 3659
 
-#line 3654
+#line 3659
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3654
+#line 3659
 	{
-#line 3654
+#line 3659
 		int lstatus = ncx_put_longlong_longlong(xp, tp, fillp);
-#line 3654
+#line 3659
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3654
+#line 3659
 			status = lstatus;
-#line 3654
+#line 3659
 	}
-#line 3654
+#line 3659
 
-#line 3654
+#line 3659
 	*xpp = (void *)xp;
-#line 3654
+#line 3659
 	return status;
-#line 3654
+#line 3659
 #endif
-#line 3654
+#line 3659
 }
-#line 3654
+#line 3659
 
 #endif
 int
-#line 3656
+#line 3661
 ncx_putn_longlong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3656
+#line 3661
 {
-#line 3656
+#line 3661
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3656
+#line 3661
 
-#line 3656
+#line 3661
  /* basic algorithm is:
-#line 3656
+#line 3661
   *   - ensure sane alignment of output data
-#line 3656
+#line 3661
   *   - copy (conversion happens automatically) input data
-#line 3656
+#line 3661
   *     to output
-#line 3656
+#line 3661
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3656
+#line 3661
   *     at next location for converted output
-#line 3656
+#line 3661
   */
-#line 3656
+#line 3661
   long i, j, ni;
-#line 3656
+#line 3661
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3656
+#line 3661
   int64 *xp;
-#line 3656
+#line 3661
   int nrange = 0;         /* number of range errors */
-#line 3656
+#line 3661
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3656
+#line 3661
   long cxp = (long) *((char**)xpp);
-#line 3656
+#line 3661
 
-#line 3656
+#line 3661
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3656
+#line 3661
   /* sjl: manually stripmine so we can limit amount of
-#line 3656
+#line 3661
    * vector work space reserved to LOOPCNT elements. Also
-#line 3656
+#line 3661
    * makes vectorisation easy */
-#line 3656
+#line 3661
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3656
+#line 3661
     ni=Min(nelems-j,LOOPCNT);
-#line 3656
+#line 3661
     if (realign) {
-#line 3656
+#line 3661
       xp = tmp;
-#line 3656
+#line 3661
     } else {
-#line 3656
+#line 3661
       xp = (int64 *) *xpp;
-#line 3656
+#line 3661
     }
-#line 3656
+#line 3661
    /* copy the next block */
-#line 3656
+#line 3661
 #pragma cdir loopcnt=LOOPCNT
-#line 3656
+#line 3661
 #pragma cdir shortloop
-#line 3656
+#line 3661
     for (i=0; i<ni; i++) {
-#line 3656
+#line 3661
       /* the normal case: */
-#line 3656
+#line 3661
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3656
+#line 3661
      /* test for range errors (not always needed but do it anyway) */
-#line 3656
+#line 3661
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3656
+#line 3661
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3656
+#line 3661
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3656
+#line 3661
     }
-#line 3656
+#line 3661
    /* copy workspace back if necessary */
-#line 3656
+#line 3661
     if (realign) {
-#line 3656
+#line 3661
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3656
+#line 3661
       xp = (int64 *) *xpp;
-#line 3656
+#line 3661
     }
-#line 3656
+#line 3661
    /* update xpp and tp */
-#line 3656
+#line 3661
     xp += ni;
-#line 3656
+#line 3661
     tp += ni;
-#line 3656
+#line 3661
     *xpp = (void*)xp;
-#line 3656
+#line 3661
   }
-#line 3656
+#line 3661
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3656
+#line 3661
 
-#line 3656
+#line 3661
 #else   /* not SX */
-#line 3656
+#line 3661
 
-#line 3656
+#line 3661
 	char *xp = (char *) *xpp;
-#line 3656
+#line 3661
 	int status = NC_NOERR;
-#line 3656
+#line 3661
 
-#line 3656
+#line 3661
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3656
+#line 3661
 	{
-#line 3656
+#line 3661
 		int lstatus = ncx_put_longlong_schar(xp, tp, fillp);
-#line 3656
+#line 3661
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3656
+#line 3661
 			status = lstatus;
-#line 3656
+#line 3661
 	}
-#line 3656
+#line 3661
 
-#line 3656
+#line 3661
 	*xpp = (void *)xp;
-#line 3656
+#line 3661
 	return status;
-#line 3656
+#line 3661
 #endif
-#line 3656
+#line 3661
 }
-#line 3656
+#line 3661
 
 int
-#line 3657
+#line 3662
 ncx_putn_longlong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3657
+#line 3662
 {
-#line 3657
+#line 3662
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3657
+#line 3662
 
-#line 3657
+#line 3662
  /* basic algorithm is:
-#line 3657
+#line 3662
   *   - ensure sane alignment of output data
-#line 3657
+#line 3662
   *   - copy (conversion happens automatically) input data
-#line 3657
+#line 3662
   *     to output
-#line 3657
+#line 3662
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3657
+#line 3662
   *     at next location for converted output
-#line 3657
+#line 3662
   */
-#line 3657
+#line 3662
   long i, j, ni;
-#line 3657
+#line 3662
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3657
+#line 3662
   int64 *xp;
-#line 3657
+#line 3662
   int nrange = 0;         /* number of range errors */
-#line 3657
+#line 3662
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3657
+#line 3662
   long cxp = (long) *((char**)xpp);
-#line 3657
+#line 3662
 
-#line 3657
+#line 3662
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3657
+#line 3662
   /* sjl: manually stripmine so we can limit amount of
-#line 3657
+#line 3662
    * vector work space reserved to LOOPCNT elements. Also
-#line 3657
+#line 3662
    * makes vectorisation easy */
-#line 3657
+#line 3662
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3657
+#line 3662
     ni=Min(nelems-j,LOOPCNT);
-#line 3657
+#line 3662
     if (realign) {
-#line 3657
+#line 3662
       xp = tmp;
-#line 3657
+#line 3662
     } else {
-#line 3657
+#line 3662
       xp = (int64 *) *xpp;
-#line 3657
+#line 3662
     }
-#line 3657
+#line 3662
    /* copy the next block */
-#line 3657
+#line 3662
 #pragma cdir loopcnt=LOOPCNT
-#line 3657
+#line 3662
 #pragma cdir shortloop
-#line 3657
+#line 3662
     for (i=0; i<ni; i++) {
-#line 3657
+#line 3662
       /* the normal case: */
-#line 3657
+#line 3662
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3657
+#line 3662
      /* test for range errors (not always needed but do it anyway) */
-#line 3657
+#line 3662
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3657
+#line 3662
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3657
+#line 3662
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3657
+#line 3662
     }
-#line 3657
+#line 3662
    /* copy workspace back if necessary */
-#line 3657
+#line 3662
     if (realign) {
-#line 3657
+#line 3662
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3657
+#line 3662
       xp = (int64 *) *xpp;
-#line 3657
+#line 3662
     }
-#line 3657
+#line 3662
    /* update xpp and tp */
-#line 3657
+#line 3662
     xp += ni;
-#line 3657
+#line 3662
     tp += ni;
-#line 3657
+#line 3662
     *xpp = (void*)xp;
-#line 3657
+#line 3662
   }
-#line 3657
+#line 3662
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3657
+#line 3662
 
-#line 3657
+#line 3662
 #else   /* not SX */
-#line 3657
+#line 3662
 
-#line 3657
+#line 3662
 	char *xp = (char *) *xpp;
-#line 3657
+#line 3662
 	int status = NC_NOERR;
-#line 3657
+#line 3662
 
-#line 3657
+#line 3662
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3657
+#line 3662
 	{
-#line 3657
+#line 3662
 		int lstatus = ncx_put_longlong_short(xp, tp, fillp);
-#line 3657
+#line 3662
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3657
+#line 3662
 			status = lstatus;
-#line 3657
+#line 3662
 	}
-#line 3657
+#line 3662
 
-#line 3657
+#line 3662
 	*xpp = (void *)xp;
-#line 3657
+#line 3662
 	return status;
-#line 3657
+#line 3662
 #endif
-#line 3657
+#line 3662
 }
-#line 3657
+#line 3662
 
 int
-#line 3658
+#line 3663
 ncx_putn_longlong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3658
+#line 3663
 {
-#line 3658
+#line 3663
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3658
+#line 3663
 
-#line 3658
+#line 3663
  /* basic algorithm is:
-#line 3658
+#line 3663
   *   - ensure sane alignment of output data
-#line 3658
+#line 3663
   *   - copy (conversion happens automatically) input data
-#line 3658
+#line 3663
   *     to output
-#line 3658
+#line 3663
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3658
+#line 3663
   *     at next location for converted output
-#line 3658
+#line 3663
   */
-#line 3658
+#line 3663
   long i, j, ni;
-#line 3658
+#line 3663
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3658
+#line 3663
   int64 *xp;
-#line 3658
+#line 3663
   int nrange = 0;         /* number of range errors */
-#line 3658
+#line 3663
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3658
+#line 3663
   long cxp = (long) *((char**)xpp);
-#line 3658
+#line 3663
 
-#line 3658
+#line 3663
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3658
+#line 3663
   /* sjl: manually stripmine so we can limit amount of
-#line 3658
+#line 3663
    * vector work space reserved to LOOPCNT elements. Also
-#line 3658
+#line 3663
    * makes vectorisation easy */
-#line 3658
+#line 3663
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3658
+#line 3663
     ni=Min(nelems-j,LOOPCNT);
-#line 3658
+#line 3663
     if (realign) {
-#line 3658
+#line 3663
       xp = tmp;
-#line 3658
+#line 3663
     } else {
-#line 3658
+#line 3663
       xp = (int64 *) *xpp;
-#line 3658
+#line 3663
     }
-#line 3658
+#line 3663
    /* copy the next block */
-#line 3658
+#line 3663
 #pragma cdir loopcnt=LOOPCNT
-#line 3658
+#line 3663
 #pragma cdir shortloop
-#line 3658
+#line 3663
     for (i=0; i<ni; i++) {
-#line 3658
+#line 3663
       /* the normal case: */
-#line 3658
+#line 3663
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3658
+#line 3663
      /* test for range errors (not always needed but do it anyway) */
-#line 3658
+#line 3663
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3658
+#line 3663
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3658
+#line 3663
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3658
+#line 3663
     }
-#line 3658
+#line 3663
    /* copy workspace back if necessary */
-#line 3658
+#line 3663
     if (realign) {
-#line 3658
+#line 3663
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3658
+#line 3663
       xp = (int64 *) *xpp;
-#line 3658
+#line 3663
     }
-#line 3658
+#line 3663
    /* update xpp and tp */
-#line 3658
+#line 3663
     xp += ni;
-#line 3658
+#line 3663
     tp += ni;
-#line 3658
+#line 3663
     *xpp = (void*)xp;
-#line 3658
+#line 3663
   }
-#line 3658
+#line 3663
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3658
+#line 3663
 
-#line 3658
+#line 3663
 #else   /* not SX */
-#line 3658
+#line 3663
 
-#line 3658
+#line 3663
 	char *xp = (char *) *xpp;
-#line 3658
+#line 3663
 	int status = NC_NOERR;
-#line 3658
+#line 3663
 
-#line 3658
+#line 3663
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3658
+#line 3663
 	{
-#line 3658
+#line 3663
 		int lstatus = ncx_put_longlong_int(xp, tp, fillp);
-#line 3658
+#line 3663
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3658
+#line 3663
 			status = lstatus;
-#line 3658
+#line 3663
 	}
-#line 3658
+#line 3663
 
-#line 3658
+#line 3663
 	*xpp = (void *)xp;
-#line 3658
+#line 3663
 	return status;
-#line 3658
+#line 3663
 #endif
-#line 3658
+#line 3663
 }
-#line 3658
+#line 3663
 
 int
-#line 3659
+#line 3664
 ncx_putn_longlong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3659
+#line 3664
 {
-#line 3659
+#line 3664
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3659
+#line 3664
 
-#line 3659
+#line 3664
  /* basic algorithm is:
-#line 3659
+#line 3664
   *   - ensure sane alignment of output data
-#line 3659
+#line 3664
   *   - copy (conversion happens automatically) input data
-#line 3659
+#line 3664
   *     to output
-#line 3659
+#line 3664
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3659
+#line 3664
   *     at next location for converted output
-#line 3659
+#line 3664
   */
-#line 3659
+#line 3664
   long i, j, ni;
-#line 3659
+#line 3664
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3659
+#line 3664
   int64 *xp;
-#line 3659
+#line 3664
   int nrange = 0;         /* number of range errors */
-#line 3659
+#line 3664
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3659
+#line 3664
   long cxp = (long) *((char**)xpp);
-#line 3659
+#line 3664
 
-#line 3659
+#line 3664
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3659
+#line 3664
   /* sjl: manually stripmine so we can limit amount of
-#line 3659
+#line 3664
    * vector work space reserved to LOOPCNT elements. Also
-#line 3659
+#line 3664
    * makes vectorisation easy */
-#line 3659
+#line 3664
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3659
+#line 3664
     ni=Min(nelems-j,LOOPCNT);
-#line 3659
+#line 3664
     if (realign) {
-#line 3659
+#line 3664
       xp = tmp;
-#line 3659
+#line 3664
     } else {
-#line 3659
+#line 3664
       xp = (int64 *) *xpp;
-#line 3659
+#line 3664
     }
-#line 3659
+#line 3664
    /* copy the next block */
-#line 3659
+#line 3664
 #pragma cdir loopcnt=LOOPCNT
-#line 3659
+#line 3664
 #pragma cdir shortloop
-#line 3659
+#line 3664
     for (i=0; i<ni; i++) {
-#line 3659
+#line 3664
       /* the normal case: */
-#line 3659
+#line 3664
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3659
+#line 3664
      /* test for range errors (not always needed but do it anyway) */
-#line 3659
+#line 3664
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3659
+#line 3664
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3659
+#line 3664
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3659
+#line 3664
     }
-#line 3659
+#line 3664
    /* copy workspace back if necessary */
-#line 3659
+#line 3664
     if (realign) {
-#line 3659
+#line 3664
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3659
+#line 3664
       xp = (int64 *) *xpp;
-#line 3659
+#line 3664
     }
-#line 3659
+#line 3664
    /* update xpp and tp */
-#line 3659
+#line 3664
     xp += ni;
-#line 3659
+#line 3664
     tp += ni;
-#line 3659
+#line 3664
     *xpp = (void*)xp;
-#line 3659
+#line 3664
   }
-#line 3659
+#line 3664
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3659
+#line 3664
 
-#line 3659
+#line 3664
 #else   /* not SX */
-#line 3659
+#line 3664
 
-#line 3659
+#line 3664
 	char *xp = (char *) *xpp;
-#line 3659
+#line 3664
 	int status = NC_NOERR;
-#line 3659
+#line 3664
 
-#line 3659
+#line 3664
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3659
+#line 3664
 	{
-#line 3659
+#line 3664
 		int lstatus = ncx_put_longlong_long(xp, tp, fillp);
-#line 3659
+#line 3664
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3659
+#line 3664
 			status = lstatus;
-#line 3659
+#line 3664
 	}
-#line 3659
+#line 3664
 
-#line 3659
+#line 3664
 	*xpp = (void *)xp;
-#line 3659
+#line 3664
 	return status;
-#line 3659
+#line 3664
 #endif
-#line 3659
+#line 3664
 }
-#line 3659
+#line 3664
 
 int
-#line 3660
+#line 3665
 ncx_putn_longlong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3660
+#line 3665
 {
-#line 3660
+#line 3665
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3660
+#line 3665
 
-#line 3660
+#line 3665
  /* basic algorithm is:
-#line 3660
+#line 3665
   *   - ensure sane alignment of output data
-#line 3660
+#line 3665
   *   - copy (conversion happens automatically) input data
-#line 3660
+#line 3665
   *     to output
-#line 3660
+#line 3665
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3660
+#line 3665
   *     at next location for converted output
-#line 3660
+#line 3665
   */
-#line 3660
+#line 3665
   long i, j, ni;
-#line 3660
+#line 3665
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3660
+#line 3665
   int64 *xp;
-#line 3660
+#line 3665
   int nrange = 0;         /* number of range errors */
-#line 3660
+#line 3665
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3660
+#line 3665
   long cxp = (long) *((char**)xpp);
-#line 3660
+#line 3665
 
-#line 3660
+#line 3665
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3660
+#line 3665
   /* sjl: manually stripmine so we can limit amount of
-#line 3660
+#line 3665
    * vector work space reserved to LOOPCNT elements. Also
-#line 3660
+#line 3665
    * makes vectorisation easy */
-#line 3660
+#line 3665
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3660
+#line 3665
     ni=Min(nelems-j,LOOPCNT);
-#line 3660
+#line 3665
     if (realign) {
-#line 3660
+#line 3665
       xp = tmp;
-#line 3660
+#line 3665
     } else {
-#line 3660
+#line 3665
       xp = (int64 *) *xpp;
-#line 3660
+#line 3665
     }
-#line 3660
+#line 3665
    /* copy the next block */
-#line 3660
+#line 3665
 #pragma cdir loopcnt=LOOPCNT
-#line 3660
+#line 3665
 #pragma cdir shortloop
-#line 3660
+#line 3665
     for (i=0; i<ni; i++) {
-#line 3660
+#line 3665
       /* the normal case: */
-#line 3660
+#line 3665
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3660
+#line 3665
      /* test for range errors (not always needed but do it anyway) */
-#line 3660
+#line 3665
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3660
+#line 3665
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3660
+#line 3665
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3660
+#line 3665
     }
-#line 3660
+#line 3665
    /* copy workspace back if necessary */
-#line 3660
+#line 3665
     if (realign) {
-#line 3660
+#line 3665
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3660
+#line 3665
       xp = (int64 *) *xpp;
-#line 3660
+#line 3665
     }
-#line 3660
+#line 3665
    /* update xpp and tp */
-#line 3660
+#line 3665
     xp += ni;
-#line 3660
+#line 3665
     tp += ni;
-#line 3660
+#line 3665
     *xpp = (void*)xp;
-#line 3660
+#line 3665
   }
-#line 3660
+#line 3665
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3660
+#line 3665
 
-#line 3660
+#line 3665
 #else   /* not SX */
-#line 3660
+#line 3665
 
-#line 3660
+#line 3665
 	char *xp = (char *) *xpp;
-#line 3660
+#line 3665
 	int status = NC_NOERR;
-#line 3660
+#line 3665
 
-#line 3660
+#line 3665
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3660
+#line 3665
 	{
-#line 3660
+#line 3665
 		int lstatus = ncx_put_longlong_float(xp, tp, fillp);
-#line 3660
+#line 3665
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3660
+#line 3665
 			status = lstatus;
-#line 3660
+#line 3665
 	}
-#line 3660
+#line 3665
 
-#line 3660
+#line 3665
 	*xpp = (void *)xp;
-#line 3660
+#line 3665
 	return status;
-#line 3660
+#line 3665
 #endif
-#line 3660
+#line 3665
 }
-#line 3660
+#line 3665
 
 int
-#line 3661
+#line 3666
 ncx_putn_longlong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3661
+#line 3666
 {
-#line 3661
+#line 3666
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3661
+#line 3666
 
-#line 3661
+#line 3666
  /* basic algorithm is:
-#line 3661
+#line 3666
   *   - ensure sane alignment of output data
-#line 3661
+#line 3666
   *   - copy (conversion happens automatically) input data
-#line 3661
+#line 3666
   *     to output
-#line 3661
+#line 3666
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3661
+#line 3666
   *     at next location for converted output
-#line 3661
+#line 3666
   */
-#line 3661
+#line 3666
   long i, j, ni;
-#line 3661
+#line 3666
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3661
+#line 3666
   int64 *xp;
-#line 3661
+#line 3666
   int nrange = 0;         /* number of range errors */
-#line 3661
+#line 3666
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3661
+#line 3666
   long cxp = (long) *((char**)xpp);
-#line 3661
+#line 3666
 
-#line 3661
+#line 3666
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3661
+#line 3666
   /* sjl: manually stripmine so we can limit amount of
-#line 3661
+#line 3666
    * vector work space reserved to LOOPCNT elements. Also
-#line 3661
+#line 3666
    * makes vectorisation easy */
-#line 3661
+#line 3666
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3661
+#line 3666
     ni=Min(nelems-j,LOOPCNT);
-#line 3661
+#line 3666
     if (realign) {
-#line 3661
+#line 3666
       xp = tmp;
-#line 3661
+#line 3666
     } else {
-#line 3661
+#line 3666
       xp = (int64 *) *xpp;
-#line 3661
+#line 3666
     }
-#line 3661
+#line 3666
    /* copy the next block */
-#line 3661
+#line 3666
 #pragma cdir loopcnt=LOOPCNT
-#line 3661
+#line 3666
 #pragma cdir shortloop
-#line 3661
+#line 3666
     for (i=0; i<ni; i++) {
-#line 3661
+#line 3666
       /* the normal case: */
-#line 3661
+#line 3666
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3661
+#line 3666
      /* test for range errors (not always needed but do it anyway) */
-#line 3661
+#line 3666
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3661
+#line 3666
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3661
+#line 3666
       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
-#line 3661
+#line 3666
     }
-#line 3661
+#line 3666
    /* copy workspace back if necessary */
-#line 3661
+#line 3666
     if (realign) {
-#line 3661
+#line 3666
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3661
+#line 3666
       xp = (int64 *) *xpp;
-#line 3661
+#line 3666
     }
-#line 3661
+#line 3666
    /* update xpp and tp */
-#line 3661
+#line 3666
     xp += ni;
-#line 3661
+#line 3666
     tp += ni;
-#line 3661
+#line 3666
     *xpp = (void*)xp;
-#line 3661
+#line 3666
   }
-#line 3661
+#line 3666
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3661
+#line 3666
 
-#line 3661
+#line 3666
 #else   /* not SX */
-#line 3661
+#line 3666
 
-#line 3661
+#line 3666
 	char *xp = (char *) *xpp;
-#line 3661
+#line 3666
 	int status = NC_NOERR;
-#line 3661
+#line 3666
 
-#line 3661
+#line 3666
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3661
+#line 3666
 	{
-#line 3661
+#line 3666
 		int lstatus = ncx_put_longlong_double(xp, tp, fillp);
-#line 3661
+#line 3666
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3661
+#line 3666
 			status = lstatus;
-#line 3661
+#line 3666
 	}
-#line 3661
+#line 3666
 
-#line 3661
+#line 3666
 	*xpp = (void *)xp;
-#line 3661
+#line 3666
 	return status;
-#line 3661
+#line 3666
 #endif
-#line 3661
+#line 3666
 }
-#line 3661
+#line 3666
 
 int
-#line 3662
+#line 3667
 ncx_putn_longlong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3662
+#line 3667
 {
-#line 3662
+#line 3667
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3662
+#line 3667
 
-#line 3662
+#line 3667
  /* basic algorithm is:
-#line 3662
+#line 3667
   *   - ensure sane alignment of output data
-#line 3662
+#line 3667
   *   - copy (conversion happens automatically) input data
-#line 3662
+#line 3667
   *     to output
-#line 3662
+#line 3667
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3662
+#line 3667
   *     at next location for converted output
-#line 3662
+#line 3667
   */
-#line 3662
+#line 3667
   long i, j, ni;
-#line 3662
+#line 3667
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3662
+#line 3667
   int64 *xp;
-#line 3662
+#line 3667
   int nrange = 0;         /* number of range errors */
-#line 3662
+#line 3667
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3662
+#line 3667
   long cxp = (long) *((char**)xpp);
-#line 3662
+#line 3667
 
-#line 3662
+#line 3667
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3662
+#line 3667
   /* sjl: manually stripmine so we can limit amount of
-#line 3662
+#line 3667
    * vector work space reserved to LOOPCNT elements. Also
-#line 3662
+#line 3667
    * makes vectorisation easy */
-#line 3662
+#line 3667
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3662
+#line 3667
     ni=Min(nelems-j,LOOPCNT);
-#line 3662
+#line 3667
     if (realign) {
-#line 3662
+#line 3667
       xp = tmp;
-#line 3662
+#line 3667
     } else {
-#line 3662
+#line 3667
       xp = (int64 *) *xpp;
-#line 3662
+#line 3667
     }
-#line 3662
+#line 3667
    /* copy the next block */
-#line 3662
+#line 3667
 #pragma cdir loopcnt=LOOPCNT
-#line 3662
+#line 3667
 #pragma cdir shortloop
-#line 3662
+#line 3667
     for (i=0; i<ni; i++) {
-#line 3662
+#line 3667
       /* the normal case: */
-#line 3662
+#line 3667
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3662
+#line 3667
      /* test for range errors (not always needed but do it anyway) */
-#line 3662
+#line 3667
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3662
+#line 3667
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3662
+#line 3667
       nrange += tp[i] > X_INT64_MAX ;
-#line 3662
+#line 3667
     }
-#line 3662
+#line 3667
    /* copy workspace back if necessary */
-#line 3662
+#line 3667
     if (realign) {
-#line 3662
+#line 3667
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3662
+#line 3667
       xp = (int64 *) *xpp;
-#line 3662
+#line 3667
     }
-#line 3662
+#line 3667
    /* update xpp and tp */
-#line 3662
+#line 3667
     xp += ni;
-#line 3662
+#line 3667
     tp += ni;
-#line 3662
+#line 3667
     *xpp = (void*)xp;
-#line 3662
+#line 3667
   }
-#line 3662
+#line 3667
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3662
+#line 3667
 
-#line 3662
+#line 3667
 #else   /* not SX */
-#line 3662
+#line 3667
 
-#line 3662
+#line 3667
 	char *xp = (char *) *xpp;
-#line 3662
+#line 3667
 	int status = NC_NOERR;
-#line 3662
+#line 3667
 
-#line 3662
+#line 3667
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3662
+#line 3667
 	{
-#line 3662
+#line 3667
 		int lstatus = ncx_put_longlong_uchar(xp, tp, fillp);
-#line 3662
+#line 3667
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3662
+#line 3667
 			status = lstatus;
-#line 3662
+#line 3667
 	}
-#line 3662
+#line 3667
 
-#line 3662
+#line 3667
 	*xpp = (void *)xp;
-#line 3662
+#line 3667
 	return status;
-#line 3662
+#line 3667
 #endif
-#line 3662
+#line 3667
 }
-#line 3662
+#line 3667
 
 int
-#line 3663
+#line 3668
 ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3663
+#line 3668
 {
-#line 3663
+#line 3668
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3663
+#line 3668
 
-#line 3663
+#line 3668
  /* basic algorithm is:
-#line 3663
+#line 3668
   *   - ensure sane alignment of output data
-#line 3663
+#line 3668
   *   - copy (conversion happens automatically) input data
-#line 3663
+#line 3668
   *     to output
-#line 3663
+#line 3668
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3663
+#line 3668
   *     at next location for converted output
-#line 3663
+#line 3668
   */
-#line 3663
+#line 3668
   long i, j, ni;
-#line 3663
+#line 3668
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3663
+#line 3668
   int64 *xp;
-#line 3663
+#line 3668
   int nrange = 0;         /* number of range errors */
-#line 3663
+#line 3668
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3663
+#line 3668
   long cxp = (long) *((char**)xpp);
-#line 3663
+#line 3668
 
-#line 3663
+#line 3668
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3663
+#line 3668
   /* sjl: manually stripmine so we can limit amount of
-#line 3663
+#line 3668
    * vector work space reserved to LOOPCNT elements. Also
-#line 3663
+#line 3668
    * makes vectorisation easy */
-#line 3663
+#line 3668
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3663
+#line 3668
     ni=Min(nelems-j,LOOPCNT);
-#line 3663
+#line 3668
     if (realign) {
-#line 3663
+#line 3668
       xp = tmp;
-#line 3663
+#line 3668
     } else {
-#line 3663
+#line 3668
       xp = (int64 *) *xpp;
-#line 3663
+#line 3668
     }
-#line 3663
+#line 3668
    /* copy the next block */
-#line 3663
+#line 3668
 #pragma cdir loopcnt=LOOPCNT
-#line 3663
+#line 3668
 #pragma cdir shortloop
-#line 3663
+#line 3668
     for (i=0; i<ni; i++) {
-#line 3663
+#line 3668
       /* the normal case: */
-#line 3663
+#line 3668
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3663
+#line 3668
      /* test for range errors (not always needed but do it anyway) */
-#line 3663
+#line 3668
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3663
+#line 3668
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3663
+#line 3668
       nrange += tp[i] > X_INT64_MAX ;
-#line 3663
+#line 3668
     }
-#line 3663
+#line 3668
    /* copy workspace back if necessary */
-#line 3663
+#line 3668
     if (realign) {
-#line 3663
+#line 3668
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3663
+#line 3668
       xp = (int64 *) *xpp;
-#line 3663
+#line 3668
     }
-#line 3663
+#line 3668
    /* update xpp and tp */
-#line 3663
+#line 3668
     xp += ni;
-#line 3663
+#line 3668
     tp += ni;
-#line 3663
+#line 3668
     *xpp = (void*)xp;
-#line 3663
+#line 3668
   }
-#line 3663
+#line 3668
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3663
+#line 3668
 
-#line 3663
+#line 3668
 #else   /* not SX */
-#line 3663
+#line 3668
 
-#line 3663
+#line 3668
 	char *xp = (char *) *xpp;
-#line 3663
+#line 3668
 	int status = NC_NOERR;
-#line 3663
+#line 3668
 
-#line 3663
+#line 3668
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3663
+#line 3668
 	{
-#line 3663
+#line 3668
 		int lstatus = ncx_put_longlong_ushort(xp, tp, fillp);
-#line 3663
+#line 3668
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3663
+#line 3668
 			status = lstatus;
-#line 3663
+#line 3668
 	}
-#line 3663
+#line 3668
 
-#line 3663
+#line 3668
 	*xpp = (void *)xp;
-#line 3663
+#line 3668
 	return status;
-#line 3663
+#line 3668
 #endif
-#line 3663
+#line 3668
 }
-#line 3663
+#line 3668
 
 int
-#line 3664
+#line 3669
 ncx_putn_longlong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3664
+#line 3669
 {
-#line 3664
+#line 3669
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3664
+#line 3669
 
-#line 3664
+#line 3669
  /* basic algorithm is:
-#line 3664
+#line 3669
   *   - ensure sane alignment of output data
-#line 3664
+#line 3669
   *   - copy (conversion happens automatically) input data
-#line 3664
+#line 3669
   *     to output
-#line 3664
+#line 3669
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3664
+#line 3669
   *     at next location for converted output
-#line 3664
+#line 3669
   */
-#line 3664
+#line 3669
   long i, j, ni;
-#line 3664
+#line 3669
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3664
+#line 3669
   int64 *xp;
-#line 3664
+#line 3669
   int nrange = 0;         /* number of range errors */
-#line 3664
+#line 3669
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3664
+#line 3669
   long cxp = (long) *((char**)xpp);
-#line 3664
+#line 3669
 
-#line 3664
+#line 3669
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3664
+#line 3669
   /* sjl: manually stripmine so we can limit amount of
-#line 3664
+#line 3669
    * vector work space reserved to LOOPCNT elements. Also
-#line 3664
+#line 3669
    * makes vectorisation easy */
-#line 3664
+#line 3669
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3664
+#line 3669
     ni=Min(nelems-j,LOOPCNT);
-#line 3664
+#line 3669
     if (realign) {
-#line 3664
+#line 3669
       xp = tmp;
-#line 3664
+#line 3669
     } else {
-#line 3664
+#line 3669
       xp = (int64 *) *xpp;
-#line 3664
+#line 3669
     }
-#line 3664
+#line 3669
    /* copy the next block */
-#line 3664
+#line 3669
 #pragma cdir loopcnt=LOOPCNT
-#line 3664
+#line 3669
 #pragma cdir shortloop
-#line 3664
+#line 3669
     for (i=0; i<ni; i++) {
-#line 3664
+#line 3669
       /* the normal case: */
-#line 3664
+#line 3669
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3664
+#line 3669
      /* test for range errors (not always needed but do it anyway) */
-#line 3664
+#line 3669
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3664
+#line 3669
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3664
+#line 3669
       nrange += tp[i] > X_INT64_MAX ;
-#line 3664
+#line 3669
     }
-#line 3664
+#line 3669
    /* copy workspace back if necessary */
-#line 3664
+#line 3669
     if (realign) {
-#line 3664
+#line 3669
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3664
+#line 3669
       xp = (int64 *) *xpp;
-#line 3664
+#line 3669
     }
-#line 3664
+#line 3669
    /* update xpp and tp */
-#line 3664
+#line 3669
     xp += ni;
-#line 3664
+#line 3669
     tp += ni;
-#line 3664
+#line 3669
     *xpp = (void*)xp;
-#line 3664
+#line 3669
   }
-#line 3664
+#line 3669
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3664
+#line 3669
 
-#line 3664
+#line 3669
 #else   /* not SX */
-#line 3664
+#line 3669
 
-#line 3664
+#line 3669
 	char *xp = (char *) *xpp;
-#line 3664
+#line 3669
 	int status = NC_NOERR;
-#line 3664
+#line 3669
 
-#line 3664
+#line 3669
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3664
+#line 3669
 	{
-#line 3664
+#line 3669
 		int lstatus = ncx_put_longlong_uint(xp, tp, fillp);
-#line 3664
+#line 3669
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3664
+#line 3669
 			status = lstatus;
-#line 3664
+#line 3669
 	}
-#line 3664
+#line 3669
 
-#line 3664
+#line 3669
 	*xpp = (void *)xp;
-#line 3664
+#line 3669
 	return status;
-#line 3664
+#line 3669
 #endif
-#line 3664
+#line 3669
 }
-#line 3664
+#line 3669
 
 int
-#line 3665
+#line 3670
 ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3665
+#line 3670
 {
-#line 3665
+#line 3670
 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
-#line 3665
+#line 3670
 
-#line 3665
+#line 3670
  /* basic algorithm is:
-#line 3665
+#line 3670
   *   - ensure sane alignment of output data
-#line 3665
+#line 3670
   *   - copy (conversion happens automatically) input data
-#line 3665
+#line 3670
   *     to output
-#line 3665
+#line 3670
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3665
+#line 3670
   *     at next location for converted output
-#line 3665
+#line 3670
   */
-#line 3665
+#line 3670
   long i, j, ni;
-#line 3665
+#line 3670
   int64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3665
+#line 3670
   int64 *xp;
-#line 3665
+#line 3670
   int nrange = 0;         /* number of range errors */
-#line 3665
+#line 3670
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3665
+#line 3670
   long cxp = (long) *((char**)xpp);
-#line 3665
+#line 3670
 
-#line 3665
+#line 3670
   realign = (cxp & 7) % SIZEOF_INT64;
-#line 3665
+#line 3670
   /* sjl: manually stripmine so we can limit amount of
-#line 3665
+#line 3670
    * vector work space reserved to LOOPCNT elements. Also
-#line 3665
+#line 3670
    * makes vectorisation easy */
-#line 3665
+#line 3670
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3665
+#line 3670
     ni=Min(nelems-j,LOOPCNT);
-#line 3665
+#line 3670
     if (realign) {
-#line 3665
+#line 3670
       xp = tmp;
-#line 3665
+#line 3670
     } else {
-#line 3665
+#line 3670
       xp = (int64 *) *xpp;
-#line 3665
+#line 3670
     }
-#line 3665
+#line 3670
    /* copy the next block */
-#line 3665
+#line 3670
 #pragma cdir loopcnt=LOOPCNT
-#line 3665
+#line 3670
 #pragma cdir shortloop
-#line 3665
+#line 3670
     for (i=0; i<ni; i++) {
-#line 3665
+#line 3670
       /* the normal case: */
-#line 3665
+#line 3670
       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
-#line 3665
+#line 3670
      /* test for range errors (not always needed but do it anyway) */
-#line 3665
+#line 3670
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3665
+#line 3670
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3665
+#line 3670
       nrange += tp[i] > X_INT64_MAX ;
-#line 3665
+#line 3670
     }
-#line 3665
+#line 3670
    /* copy workspace back if necessary */
-#line 3665
+#line 3670
     if (realign) {
-#line 3665
+#line 3670
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
-#line 3665
+#line 3670
       xp = (int64 *) *xpp;
-#line 3665
+#line 3670
     }
-#line 3665
+#line 3670
    /* update xpp and tp */
-#line 3665
+#line 3670
     xp += ni;
-#line 3665
+#line 3670
     tp += ni;
-#line 3665
+#line 3670
     *xpp = (void*)xp;
-#line 3665
+#line 3670
   }
-#line 3665
+#line 3670
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3665
+#line 3670
 
-#line 3665
+#line 3670
 #else   /* not SX */
-#line 3665
+#line 3670
 
-#line 3665
+#line 3670
 	char *xp = (char *) *xpp;
-#line 3665
+#line 3670
 	int status = NC_NOERR;
-#line 3665
+#line 3670
 
-#line 3665
+#line 3670
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
-#line 3665
+#line 3670
 	{
-#line 3665
+#line 3670
 		int lstatus = ncx_put_longlong_ulonglong(xp, tp, fillp);
-#line 3665
+#line 3670
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3665
+#line 3670
 			status = lstatus;
-#line 3665
+#line 3670
 	}
-#line 3665
+#line 3670
 
-#line 3665
+#line 3670
 	*xpp = (void *)xp;
-#line 3665
+#line 3670
 	return status;
-#line 3665
+#line 3670
 #endif
-#line 3665
+#line 3670
 }
-#line 3665
+#line 3670
 
 
 /* uint64 --------------------------------------------------------------------*/
@@ -36375,1424 +36380,1424 @@ ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long
 }
 #else
 int
-#line 3683
+#line 3688
 ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
-#line 3683
+#line 3688
 {
-#line 3683
+#line 3688
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3683
+#line 3688
 
-#line 3683
+#line 3688
  /* basic algorithm is:
-#line 3683
+#line 3688
   *   - ensure sane alignment of input data
-#line 3683
+#line 3688
   *   - copy (conversion happens automatically) input data
-#line 3683
+#line 3688
   *     to output
-#line 3683
+#line 3688
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3683
+#line 3688
   *     at next location for converted output
-#line 3683
+#line 3688
   */
-#line 3683
+#line 3688
   long i, j, ni;
-#line 3683
+#line 3688
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3683
+#line 3688
   uint64 *xp;
-#line 3683
+#line 3688
   int nrange = 0;         /* number of range errors */
-#line 3683
+#line 3688
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3683
+#line 3688
   long cxp = (long) *((char**)xpp);
-#line 3683
+#line 3688
 
-#line 3683
+#line 3688
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3683
+#line 3688
   /* sjl: manually stripmine so we can limit amount of
-#line 3683
+#line 3688
    * vector work space reserved to LOOPCNT elements. Also
-#line 3683
+#line 3688
    * makes vectorisation easy */
-#line 3683
+#line 3688
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3683
+#line 3688
     ni=Min(nelems-j,LOOPCNT);
-#line 3683
+#line 3688
     if (realign) {
-#line 3683
+#line 3688
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3683
+#line 3688
       xp = tmp;
-#line 3683
+#line 3688
     } else {
-#line 3683
+#line 3688
       xp = (uint64 *) *xpp;
-#line 3683
+#line 3688
     }
-#line 3683
+#line 3688
    /* copy the next block */
-#line 3683
+#line 3688
 #pragma cdir loopcnt=LOOPCNT
-#line 3683
+#line 3688
 #pragma cdir shortloop
-#line 3683
+#line 3688
     for (i=0; i<ni; i++) {
-#line 3683
+#line 3688
       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
-#line 3683
+#line 3688
      /* test for range errors (not always needed but do it anyway) */
-#line 3683
+#line 3688
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3683
+#line 3688
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3683
+#line 3688
       nrange += xp[i] > ULONGLONG_MAX ;
-#line 3683
+#line 3688
     }
-#line 3683
+#line 3688
    /* update xpp and tp */
-#line 3683
+#line 3688
     if (realign) xp = (uint64 *) *xpp;
-#line 3683
+#line 3688
     xp += ni;
-#line 3683
+#line 3688
     tp += ni;
-#line 3683
+#line 3688
     *xpp = (void*)xp;
-#line 3683
+#line 3688
   }
-#line 3683
+#line 3688
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3683
+#line 3688
 
-#line 3683
+#line 3688
 #else   /* not SX */
-#line 3683
+#line 3688
 	const char *xp = (const char *) *xpp;
-#line 3683
+#line 3688
 	int status = NC_NOERR;
-#line 3683
+#line 3688
 
-#line 3683
+#line 3688
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3683
+#line 3688
 	{
-#line 3683
+#line 3688
 		const int lstatus = ncx_get_ulonglong_ulonglong(xp, tp);
-#line 3683
+#line 3688
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3683
+#line 3688
 			status = lstatus;
-#line 3683
+#line 3688
 	}
-#line 3683
+#line 3688
 
-#line 3683
+#line 3688
 	*xpp = (const void *)xp;
-#line 3683
+#line 3688
 	return status;
-#line 3683
+#line 3688
 #endif
-#line 3683
+#line 3688
 }
-#line 3683
+#line 3688
 
 #endif
 int
-#line 3685
+#line 3690
 ncx_getn_ulonglong_schar(const void **xpp, size_t nelems, schar *tp)
-#line 3685
+#line 3690
 {
-#line 3685
+#line 3690
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3685
+#line 3690
 
-#line 3685
+#line 3690
  /* basic algorithm is:
-#line 3685
+#line 3690
   *   - ensure sane alignment of input data
-#line 3685
+#line 3690
   *   - copy (conversion happens automatically) input data
-#line 3685
+#line 3690
   *     to output
-#line 3685
+#line 3690
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3685
+#line 3690
   *     at next location for converted output
-#line 3685
+#line 3690
   */
-#line 3685
+#line 3690
   long i, j, ni;
-#line 3685
+#line 3690
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3685
+#line 3690
   uint64 *xp;
-#line 3685
+#line 3690
   int nrange = 0;         /* number of range errors */
-#line 3685
+#line 3690
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3685
+#line 3690
   long cxp = (long) *((char**)xpp);
-#line 3685
+#line 3690
 
-#line 3685
+#line 3690
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3685
+#line 3690
   /* sjl: manually stripmine so we can limit amount of
-#line 3685
+#line 3690
    * vector work space reserved to LOOPCNT elements. Also
-#line 3685
+#line 3690
    * makes vectorisation easy */
-#line 3685
+#line 3690
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3685
+#line 3690
     ni=Min(nelems-j,LOOPCNT);
-#line 3685
+#line 3690
     if (realign) {
-#line 3685
+#line 3690
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3685
+#line 3690
       xp = tmp;
-#line 3685
+#line 3690
     } else {
-#line 3685
+#line 3690
       xp = (uint64 *) *xpp;
-#line 3685
+#line 3690
     }
-#line 3685
+#line 3690
    /* copy the next block */
-#line 3685
+#line 3690
 #pragma cdir loopcnt=LOOPCNT
-#line 3685
+#line 3690
 #pragma cdir shortloop
-#line 3685
+#line 3690
     for (i=0; i<ni; i++) {
-#line 3685
+#line 3690
       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
-#line 3685
+#line 3690
      /* test for range errors (not always needed but do it anyway) */
-#line 3685
+#line 3690
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3685
+#line 3690
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3685
+#line 3690
       nrange += xp[i] > SCHAR_MAX ;
-#line 3685
+#line 3690
     }
-#line 3685
+#line 3690
    /* update xpp and tp */
-#line 3685
+#line 3690
     if (realign) xp = (uint64 *) *xpp;
-#line 3685
+#line 3690
     xp += ni;
-#line 3685
+#line 3690
     tp += ni;
-#line 3685
+#line 3690
     *xpp = (void*)xp;
-#line 3685
+#line 3690
   }
-#line 3685
+#line 3690
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3685
+#line 3690
 
-#line 3685
+#line 3690
 #else   /* not SX */
-#line 3685
+#line 3690
 	const char *xp = (const char *) *xpp;
-#line 3685
+#line 3690
 	int status = NC_NOERR;
-#line 3685
+#line 3690
 
-#line 3685
+#line 3690
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3685
+#line 3690
 	{
-#line 3685
+#line 3690
 		const int lstatus = ncx_get_ulonglong_schar(xp, tp);
-#line 3685
+#line 3690
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3685
+#line 3690
 			status = lstatus;
-#line 3685
+#line 3690
 	}
-#line 3685
+#line 3690
 
-#line 3685
+#line 3690
 	*xpp = (const void *)xp;
-#line 3685
+#line 3690
 	return status;
-#line 3685
+#line 3690
 #endif
-#line 3685
+#line 3690
 }
-#line 3685
+#line 3690
 
 int
-#line 3686
+#line 3691
 ncx_getn_ulonglong_short(const void **xpp, size_t nelems, short *tp)
-#line 3686
+#line 3691
 {
-#line 3686
+#line 3691
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3686
+#line 3691
 
-#line 3686
+#line 3691
  /* basic algorithm is:
-#line 3686
+#line 3691
   *   - ensure sane alignment of input data
-#line 3686
+#line 3691
   *   - copy (conversion happens automatically) input data
-#line 3686
+#line 3691
   *     to output
-#line 3686
+#line 3691
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3686
+#line 3691
   *     at next location for converted output
-#line 3686
+#line 3691
   */
-#line 3686
+#line 3691
   long i, j, ni;
-#line 3686
+#line 3691
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3686
+#line 3691
   uint64 *xp;
-#line 3686
+#line 3691
   int nrange = 0;         /* number of range errors */
-#line 3686
+#line 3691
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3686
+#line 3691
   long cxp = (long) *((char**)xpp);
-#line 3686
+#line 3691
 
-#line 3686
+#line 3691
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3686
+#line 3691
   /* sjl: manually stripmine so we can limit amount of
-#line 3686
+#line 3691
    * vector work space reserved to LOOPCNT elements. Also
-#line 3686
+#line 3691
    * makes vectorisation easy */
-#line 3686
+#line 3691
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3686
+#line 3691
     ni=Min(nelems-j,LOOPCNT);
-#line 3686
+#line 3691
     if (realign) {
-#line 3686
+#line 3691
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3686
+#line 3691
       xp = tmp;
-#line 3686
+#line 3691
     } else {
-#line 3686
+#line 3691
       xp = (uint64 *) *xpp;
-#line 3686
+#line 3691
     }
-#line 3686
+#line 3691
    /* copy the next block */
-#line 3686
+#line 3691
 #pragma cdir loopcnt=LOOPCNT
-#line 3686
+#line 3691
 #pragma cdir shortloop
-#line 3686
+#line 3691
     for (i=0; i<ni; i++) {
-#line 3686
+#line 3691
       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
-#line 3686
+#line 3691
      /* test for range errors (not always needed but do it anyway) */
-#line 3686
+#line 3691
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3686
+#line 3691
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3686
+#line 3691
       nrange += xp[i] > SHORT_MAX ;
-#line 3686
+#line 3691
     }
-#line 3686
+#line 3691
    /* update xpp and tp */
-#line 3686
+#line 3691
     if (realign) xp = (uint64 *) *xpp;
-#line 3686
+#line 3691
     xp += ni;
-#line 3686
+#line 3691
     tp += ni;
-#line 3686
+#line 3691
     *xpp = (void*)xp;
-#line 3686
+#line 3691
   }
-#line 3686
+#line 3691
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3686
+#line 3691
 
-#line 3686
+#line 3691
 #else   /* not SX */
-#line 3686
+#line 3691
 	const char *xp = (const char *) *xpp;
-#line 3686
+#line 3691
 	int status = NC_NOERR;
-#line 3686
+#line 3691
 
-#line 3686
+#line 3691
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3686
+#line 3691
 	{
-#line 3686
+#line 3691
 		const int lstatus = ncx_get_ulonglong_short(xp, tp);
-#line 3686
+#line 3691
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3686
+#line 3691
 			status = lstatus;
-#line 3686
+#line 3691
 	}
-#line 3686
+#line 3691
 
-#line 3686
+#line 3691
 	*xpp = (const void *)xp;
-#line 3686
+#line 3691
 	return status;
-#line 3686
+#line 3691
 #endif
-#line 3686
+#line 3691
 }
-#line 3686
+#line 3691
 
 int
-#line 3687
+#line 3692
 ncx_getn_ulonglong_int(const void **xpp, size_t nelems, int *tp)
-#line 3687
+#line 3692
 {
-#line 3687
+#line 3692
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3687
+#line 3692
 
-#line 3687
+#line 3692
  /* basic algorithm is:
-#line 3687
+#line 3692
   *   - ensure sane alignment of input data
-#line 3687
+#line 3692
   *   - copy (conversion happens automatically) input data
-#line 3687
+#line 3692
   *     to output
-#line 3687
+#line 3692
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3687
+#line 3692
   *     at next location for converted output
-#line 3687
+#line 3692
   */
-#line 3687
+#line 3692
   long i, j, ni;
-#line 3687
+#line 3692
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3687
+#line 3692
   uint64 *xp;
-#line 3687
+#line 3692
   int nrange = 0;         /* number of range errors */
-#line 3687
+#line 3692
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3687
+#line 3692
   long cxp = (long) *((char**)xpp);
-#line 3687
+#line 3692
 
-#line 3687
+#line 3692
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3687
+#line 3692
   /* sjl: manually stripmine so we can limit amount of
-#line 3687
+#line 3692
    * vector work space reserved to LOOPCNT elements. Also
-#line 3687
+#line 3692
    * makes vectorisation easy */
-#line 3687
+#line 3692
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3687
+#line 3692
     ni=Min(nelems-j,LOOPCNT);
-#line 3687
+#line 3692
     if (realign) {
-#line 3687
+#line 3692
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3687
+#line 3692
       xp = tmp;
-#line 3687
+#line 3692
     } else {
-#line 3687
+#line 3692
       xp = (uint64 *) *xpp;
-#line 3687
+#line 3692
     }
-#line 3687
+#line 3692
    /* copy the next block */
-#line 3687
+#line 3692
 #pragma cdir loopcnt=LOOPCNT
-#line 3687
+#line 3692
 #pragma cdir shortloop
-#line 3687
+#line 3692
     for (i=0; i<ni; i++) {
-#line 3687
+#line 3692
       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
-#line 3687
+#line 3692
      /* test for range errors (not always needed but do it anyway) */
-#line 3687
+#line 3692
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3687
+#line 3692
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3687
+#line 3692
       nrange += xp[i] > INT_MAX ;
-#line 3687
+#line 3692
     }
-#line 3687
+#line 3692
    /* update xpp and tp */
-#line 3687
+#line 3692
     if (realign) xp = (uint64 *) *xpp;
-#line 3687
+#line 3692
     xp += ni;
-#line 3687
+#line 3692
     tp += ni;
-#line 3687
+#line 3692
     *xpp = (void*)xp;
-#line 3687
+#line 3692
   }
-#line 3687
+#line 3692
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3687
+#line 3692
 
-#line 3687
+#line 3692
 #else   /* not SX */
-#line 3687
+#line 3692
 	const char *xp = (const char *) *xpp;
-#line 3687
+#line 3692
 	int status = NC_NOERR;
-#line 3687
+#line 3692
 
-#line 3687
+#line 3692
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3687
+#line 3692
 	{
-#line 3687
+#line 3692
 		const int lstatus = ncx_get_ulonglong_int(xp, tp);
-#line 3687
+#line 3692
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3687
+#line 3692
 			status = lstatus;
-#line 3687
+#line 3692
 	}
-#line 3687
+#line 3692
 
-#line 3687
+#line 3692
 	*xpp = (const void *)xp;
-#line 3687
+#line 3692
 	return status;
-#line 3687
+#line 3692
 #endif
-#line 3687
+#line 3692
 }
-#line 3687
+#line 3692
 
 int
-#line 3688
+#line 3693
 ncx_getn_ulonglong_long(const void **xpp, size_t nelems, long *tp)
-#line 3688
+#line 3693
 {
-#line 3688
+#line 3693
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3688
+#line 3693
 
-#line 3688
+#line 3693
  /* basic algorithm is:
-#line 3688
+#line 3693
   *   - ensure sane alignment of input data
-#line 3688
+#line 3693
   *   - copy (conversion happens automatically) input data
-#line 3688
+#line 3693
   *     to output
-#line 3688
+#line 3693
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3688
+#line 3693
   *     at next location for converted output
-#line 3688
+#line 3693
   */
-#line 3688
+#line 3693
   long i, j, ni;
-#line 3688
+#line 3693
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3688
+#line 3693
   uint64 *xp;
-#line 3688
+#line 3693
   int nrange = 0;         /* number of range errors */
-#line 3688
+#line 3693
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3688
+#line 3693
   long cxp = (long) *((char**)xpp);
-#line 3688
+#line 3693
 
-#line 3688
+#line 3693
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3688
+#line 3693
   /* sjl: manually stripmine so we can limit amount of
-#line 3688
+#line 3693
    * vector work space reserved to LOOPCNT elements. Also
-#line 3688
+#line 3693
    * makes vectorisation easy */
-#line 3688
+#line 3693
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3688
+#line 3693
     ni=Min(nelems-j,LOOPCNT);
-#line 3688
+#line 3693
     if (realign) {
-#line 3688
+#line 3693
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3688
+#line 3693
       xp = tmp;
-#line 3688
+#line 3693
     } else {
-#line 3688
+#line 3693
       xp = (uint64 *) *xpp;
-#line 3688
+#line 3693
     }
-#line 3688
+#line 3693
    /* copy the next block */
-#line 3688
+#line 3693
 #pragma cdir loopcnt=LOOPCNT
-#line 3688
+#line 3693
 #pragma cdir shortloop
-#line 3688
+#line 3693
     for (i=0; i<ni; i++) {
-#line 3688
+#line 3693
       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
-#line 3688
+#line 3693
      /* test for range errors (not always needed but do it anyway) */
-#line 3688
+#line 3693
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3688
+#line 3693
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3688
+#line 3693
       nrange += xp[i] > LONG_MAX ;
-#line 3688
+#line 3693
     }
-#line 3688
+#line 3693
    /* update xpp and tp */
-#line 3688
+#line 3693
     if (realign) xp = (uint64 *) *xpp;
-#line 3688
+#line 3693
     xp += ni;
-#line 3688
+#line 3693
     tp += ni;
-#line 3688
+#line 3693
     *xpp = (void*)xp;
-#line 3688
+#line 3693
   }
-#line 3688
+#line 3693
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3688
+#line 3693
 
-#line 3688
+#line 3693
 #else   /* not SX */
-#line 3688
+#line 3693
 	const char *xp = (const char *) *xpp;
-#line 3688
+#line 3693
 	int status = NC_NOERR;
-#line 3688
+#line 3693
 
-#line 3688
+#line 3693
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3688
+#line 3693
 	{
-#line 3688
+#line 3693
 		const int lstatus = ncx_get_ulonglong_long(xp, tp);
-#line 3688
+#line 3693
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3688
+#line 3693
 			status = lstatus;
-#line 3688
+#line 3693
 	}
-#line 3688
+#line 3693
 
-#line 3688
+#line 3693
 	*xpp = (const void *)xp;
-#line 3688
+#line 3693
 	return status;
-#line 3688
+#line 3693
 #endif
-#line 3688
+#line 3693
 }
-#line 3688
+#line 3693
 
 int
-#line 3689
+#line 3694
 ncx_getn_ulonglong_float(const void **xpp, size_t nelems, float *tp)
-#line 3689
+#line 3694
 {
-#line 3689
+#line 3694
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3689
+#line 3694
 
-#line 3689
+#line 3694
  /* basic algorithm is:
-#line 3689
+#line 3694
   *   - ensure sane alignment of input data
-#line 3689
+#line 3694
   *   - copy (conversion happens automatically) input data
-#line 3689
+#line 3694
   *     to output
-#line 3689
+#line 3694
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3689
+#line 3694
   *     at next location for converted output
-#line 3689
+#line 3694
   */
-#line 3689
+#line 3694
   long i, j, ni;
-#line 3689
+#line 3694
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3689
+#line 3694
   uint64 *xp;
-#line 3689
+#line 3694
   int nrange = 0;         /* number of range errors */
-#line 3689
+#line 3694
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3689
+#line 3694
   long cxp = (long) *((char**)xpp);
-#line 3689
+#line 3694
 
-#line 3689
+#line 3694
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3689
+#line 3694
   /* sjl: manually stripmine so we can limit amount of
-#line 3689
+#line 3694
    * vector work space reserved to LOOPCNT elements. Also
-#line 3689
+#line 3694
    * makes vectorisation easy */
-#line 3689
+#line 3694
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3689
+#line 3694
     ni=Min(nelems-j,LOOPCNT);
-#line 3689
+#line 3694
     if (realign) {
-#line 3689
+#line 3694
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3689
+#line 3694
       xp = tmp;
-#line 3689
+#line 3694
     } else {
-#line 3689
+#line 3694
       xp = (uint64 *) *xpp;
-#line 3689
+#line 3694
     }
-#line 3689
+#line 3694
    /* copy the next block */
-#line 3689
+#line 3694
 #pragma cdir loopcnt=LOOPCNT
-#line 3689
+#line 3694
 #pragma cdir shortloop
-#line 3689
+#line 3694
     for (i=0; i<ni; i++) {
-#line 3689
+#line 3694
       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
-#line 3689
+#line 3694
      /* test for range errors (not always needed but do it anyway) */
-#line 3689
+#line 3694
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3689
+#line 3694
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3689
+#line 3694
       nrange += xp[i] > FLOAT_MAX ;
-#line 3689
+#line 3694
     }
-#line 3689
+#line 3694
    /* update xpp and tp */
-#line 3689
+#line 3694
     if (realign) xp = (uint64 *) *xpp;
-#line 3689
+#line 3694
     xp += ni;
-#line 3689
+#line 3694
     tp += ni;
-#line 3689
+#line 3694
     *xpp = (void*)xp;
-#line 3689
+#line 3694
   }
-#line 3689
+#line 3694
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3689
+#line 3694
 
-#line 3689
+#line 3694
 #else   /* not SX */
-#line 3689
+#line 3694
 	const char *xp = (const char *) *xpp;
-#line 3689
+#line 3694
 	int status = NC_NOERR;
-#line 3689
+#line 3694
 
-#line 3689
+#line 3694
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3689
+#line 3694
 	{
-#line 3689
+#line 3694
 		const int lstatus = ncx_get_ulonglong_float(xp, tp);
-#line 3689
+#line 3694
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3689
+#line 3694
 			status = lstatus;
-#line 3689
+#line 3694
 	}
-#line 3689
+#line 3694
 
-#line 3689
+#line 3694
 	*xpp = (const void *)xp;
-#line 3689
+#line 3694
 	return status;
-#line 3689
+#line 3694
 #endif
-#line 3689
+#line 3694
 }
-#line 3689
+#line 3694
 
 int
-#line 3690
+#line 3695
 ncx_getn_ulonglong_double(const void **xpp, size_t nelems, double *tp)
-#line 3690
+#line 3695
 {
-#line 3690
+#line 3695
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3690
+#line 3695
 
-#line 3690
+#line 3695
  /* basic algorithm is:
-#line 3690
+#line 3695
   *   - ensure sane alignment of input data
-#line 3690
+#line 3695
   *   - copy (conversion happens automatically) input data
-#line 3690
+#line 3695
   *     to output
-#line 3690
+#line 3695
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3690
+#line 3695
   *     at next location for converted output
-#line 3690
+#line 3695
   */
-#line 3690
+#line 3695
   long i, j, ni;
-#line 3690
+#line 3695
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3690
+#line 3695
   uint64 *xp;
-#line 3690
+#line 3695
   int nrange = 0;         /* number of range errors */
-#line 3690
+#line 3695
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3690
+#line 3695
   long cxp = (long) *((char**)xpp);
-#line 3690
+#line 3695
 
-#line 3690
+#line 3695
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3690
+#line 3695
   /* sjl: manually stripmine so we can limit amount of
-#line 3690
+#line 3695
    * vector work space reserved to LOOPCNT elements. Also
-#line 3690
+#line 3695
    * makes vectorisation easy */
-#line 3690
+#line 3695
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3690
+#line 3695
     ni=Min(nelems-j,LOOPCNT);
-#line 3690
+#line 3695
     if (realign) {
-#line 3690
+#line 3695
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3690
+#line 3695
       xp = tmp;
-#line 3690
+#line 3695
     } else {
-#line 3690
+#line 3695
       xp = (uint64 *) *xpp;
-#line 3690
+#line 3695
     }
-#line 3690
+#line 3695
    /* copy the next block */
-#line 3690
+#line 3695
 #pragma cdir loopcnt=LOOPCNT
-#line 3690
+#line 3695
 #pragma cdir shortloop
-#line 3690
+#line 3695
     for (i=0; i<ni; i++) {
-#line 3690
+#line 3695
       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
-#line 3690
+#line 3695
      /* test for range errors (not always needed but do it anyway) */
-#line 3690
+#line 3695
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3690
+#line 3695
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3690
+#line 3695
       nrange += xp[i] > DOUBLE_MAX ;
-#line 3690
+#line 3695
     }
-#line 3690
+#line 3695
    /* update xpp and tp */
-#line 3690
+#line 3695
     if (realign) xp = (uint64 *) *xpp;
-#line 3690
+#line 3695
     xp += ni;
-#line 3690
+#line 3695
     tp += ni;
-#line 3690
+#line 3695
     *xpp = (void*)xp;
-#line 3690
+#line 3695
   }
-#line 3690
+#line 3695
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3690
+#line 3695
 
-#line 3690
+#line 3695
 #else   /* not SX */
-#line 3690
+#line 3695
 	const char *xp = (const char *) *xpp;
-#line 3690
+#line 3695
 	int status = NC_NOERR;
-#line 3690
+#line 3695
 
-#line 3690
+#line 3695
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3690
+#line 3695
 	{
-#line 3690
+#line 3695
 		const int lstatus = ncx_get_ulonglong_double(xp, tp);
-#line 3690
+#line 3695
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3690
+#line 3695
 			status = lstatus;
-#line 3690
+#line 3695
 	}
-#line 3690
+#line 3695
 
-#line 3690
+#line 3695
 	*xpp = (const void *)xp;
-#line 3690
+#line 3695
 	return status;
-#line 3690
+#line 3695
 #endif
-#line 3690
+#line 3695
 }
-#line 3690
+#line 3695
 
 int
-#line 3691
+#line 3696
 ncx_getn_ulonglong_longlong(const void **xpp, size_t nelems, longlong *tp)
-#line 3691
+#line 3696
 {
-#line 3691
+#line 3696
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3691
+#line 3696
 
-#line 3691
+#line 3696
  /* basic algorithm is:
-#line 3691
+#line 3696
   *   - ensure sane alignment of input data
-#line 3691
+#line 3696
   *   - copy (conversion happens automatically) input data
-#line 3691
+#line 3696
   *     to output
-#line 3691
+#line 3696
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3691
+#line 3696
   *     at next location for converted output
-#line 3691
+#line 3696
   */
-#line 3691
+#line 3696
   long i, j, ni;
-#line 3691
+#line 3696
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3691
+#line 3696
   uint64 *xp;
-#line 3691
+#line 3696
   int nrange = 0;         /* number of range errors */
-#line 3691
+#line 3696
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3691
+#line 3696
   long cxp = (long) *((char**)xpp);
-#line 3691
+#line 3696
 
-#line 3691
+#line 3696
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3691
+#line 3696
   /* sjl: manually stripmine so we can limit amount of
-#line 3691
+#line 3696
    * vector work space reserved to LOOPCNT elements. Also
-#line 3691
+#line 3696
    * makes vectorisation easy */
-#line 3691
+#line 3696
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3691
+#line 3696
     ni=Min(nelems-j,LOOPCNT);
-#line 3691
+#line 3696
     if (realign) {
-#line 3691
+#line 3696
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3691
+#line 3696
       xp = tmp;
-#line 3691
+#line 3696
     } else {
-#line 3691
+#line 3696
       xp = (uint64 *) *xpp;
-#line 3691
+#line 3696
     }
-#line 3691
+#line 3696
    /* copy the next block */
-#line 3691
+#line 3696
 #pragma cdir loopcnt=LOOPCNT
-#line 3691
+#line 3696
 #pragma cdir shortloop
-#line 3691
+#line 3696
     for (i=0; i<ni; i++) {
-#line 3691
+#line 3696
       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
-#line 3691
+#line 3696
      /* test for range errors (not always needed but do it anyway) */
-#line 3691
+#line 3696
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3691
+#line 3696
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3691
+#line 3696
       nrange += xp[i] > LONGLONG_MAX ;
-#line 3691
+#line 3696
     }
-#line 3691
+#line 3696
    /* update xpp and tp */
-#line 3691
+#line 3696
     if (realign) xp = (uint64 *) *xpp;
-#line 3691
+#line 3696
     xp += ni;
-#line 3691
+#line 3696
     tp += ni;
-#line 3691
+#line 3696
     *xpp = (void*)xp;
-#line 3691
+#line 3696
   }
-#line 3691
+#line 3696
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3691
+#line 3696
 
-#line 3691
+#line 3696
 #else   /* not SX */
-#line 3691
+#line 3696
 	const char *xp = (const char *) *xpp;
-#line 3691
+#line 3696
 	int status = NC_NOERR;
-#line 3691
+#line 3696
 
-#line 3691
+#line 3696
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3691
+#line 3696
 	{
-#line 3691
+#line 3696
 		const int lstatus = ncx_get_ulonglong_longlong(xp, tp);
-#line 3691
+#line 3696
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3691
+#line 3696
 			status = lstatus;
-#line 3691
+#line 3696
 	}
-#line 3691
+#line 3696
 
-#line 3691
+#line 3696
 	*xpp = (const void *)xp;
-#line 3691
+#line 3696
 	return status;
-#line 3691
+#line 3696
 #endif
-#line 3691
+#line 3696
 }
-#line 3691
+#line 3696
 
 int
-#line 3692
+#line 3697
 ncx_getn_ulonglong_uchar(const void **xpp, size_t nelems, uchar *tp)
-#line 3692
+#line 3697
 {
-#line 3692
+#line 3697
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3692
+#line 3697
 
-#line 3692
+#line 3697
  /* basic algorithm is:
-#line 3692
+#line 3697
   *   - ensure sane alignment of input data
-#line 3692
+#line 3697
   *   - copy (conversion happens automatically) input data
-#line 3692
+#line 3697
   *     to output
-#line 3692
+#line 3697
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3692
+#line 3697
   *     at next location for converted output
-#line 3692
+#line 3697
   */
-#line 3692
+#line 3697
   long i, j, ni;
-#line 3692
+#line 3697
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3692
+#line 3697
   uint64 *xp;
-#line 3692
+#line 3697
   int nrange = 0;         /* number of range errors */
-#line 3692
+#line 3697
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3692
+#line 3697
   long cxp = (long) *((char**)xpp);
-#line 3692
+#line 3697
 
-#line 3692
+#line 3697
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3692
+#line 3697
   /* sjl: manually stripmine so we can limit amount of
-#line 3692
+#line 3697
    * vector work space reserved to LOOPCNT elements. Also
-#line 3692
+#line 3697
    * makes vectorisation easy */
-#line 3692
+#line 3697
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3692
+#line 3697
     ni=Min(nelems-j,LOOPCNT);
-#line 3692
+#line 3697
     if (realign) {
-#line 3692
+#line 3697
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3692
+#line 3697
       xp = tmp;
-#line 3692
+#line 3697
     } else {
-#line 3692
+#line 3697
       xp = (uint64 *) *xpp;
-#line 3692
+#line 3697
     }
-#line 3692
+#line 3697
    /* copy the next block */
-#line 3692
+#line 3697
 #pragma cdir loopcnt=LOOPCNT
-#line 3692
+#line 3697
 #pragma cdir shortloop
-#line 3692
+#line 3697
     for (i=0; i<ni; i++) {
-#line 3692
+#line 3697
       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
-#line 3692
+#line 3697
      /* test for range errors (not always needed but do it anyway) */
-#line 3692
+#line 3697
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3692
+#line 3697
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3692
+#line 3697
       nrange += xp[i] > UCHAR_MAX ;
-#line 3692
+#line 3697
     }
-#line 3692
+#line 3697
    /* update xpp and tp */
-#line 3692
+#line 3697
     if (realign) xp = (uint64 *) *xpp;
-#line 3692
+#line 3697
     xp += ni;
-#line 3692
+#line 3697
     tp += ni;
-#line 3692
+#line 3697
     *xpp = (void*)xp;
-#line 3692
+#line 3697
   }
-#line 3692
+#line 3697
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3692
+#line 3697
 
-#line 3692
+#line 3697
 #else   /* not SX */
-#line 3692
+#line 3697
 	const char *xp = (const char *) *xpp;
-#line 3692
+#line 3697
 	int status = NC_NOERR;
-#line 3692
+#line 3697
 
-#line 3692
+#line 3697
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3692
+#line 3697
 	{
-#line 3692
+#line 3697
 		const int lstatus = ncx_get_ulonglong_uchar(xp, tp);
-#line 3692
+#line 3697
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3692
+#line 3697
 			status = lstatus;
-#line 3692
+#line 3697
 	}
-#line 3692
+#line 3697
 
-#line 3692
+#line 3697
 	*xpp = (const void *)xp;
-#line 3692
+#line 3697
 	return status;
-#line 3692
+#line 3697
 #endif
-#line 3692
+#line 3697
 }
-#line 3692
+#line 3697
 
 int
-#line 3693
+#line 3698
 ncx_getn_ulonglong_ushort(const void **xpp, size_t nelems, ushort *tp)
-#line 3693
+#line 3698
 {
-#line 3693
+#line 3698
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3693
+#line 3698
 
-#line 3693
+#line 3698
  /* basic algorithm is:
-#line 3693
+#line 3698
   *   - ensure sane alignment of input data
-#line 3693
+#line 3698
   *   - copy (conversion happens automatically) input data
-#line 3693
+#line 3698
   *     to output
-#line 3693
+#line 3698
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3693
+#line 3698
   *     at next location for converted output
-#line 3693
+#line 3698
   */
-#line 3693
+#line 3698
   long i, j, ni;
-#line 3693
+#line 3698
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3693
+#line 3698
   uint64 *xp;
-#line 3693
+#line 3698
   int nrange = 0;         /* number of range errors */
-#line 3693
+#line 3698
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3693
+#line 3698
   long cxp = (long) *((char**)xpp);
-#line 3693
+#line 3698
 
-#line 3693
+#line 3698
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3693
+#line 3698
   /* sjl: manually stripmine so we can limit amount of
-#line 3693
+#line 3698
    * vector work space reserved to LOOPCNT elements. Also
-#line 3693
+#line 3698
    * makes vectorisation easy */
-#line 3693
+#line 3698
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3693
+#line 3698
     ni=Min(nelems-j,LOOPCNT);
-#line 3693
+#line 3698
     if (realign) {
-#line 3693
+#line 3698
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3693
+#line 3698
       xp = tmp;
-#line 3693
+#line 3698
     } else {
-#line 3693
+#line 3698
       xp = (uint64 *) *xpp;
-#line 3693
+#line 3698
     }
-#line 3693
+#line 3698
    /* copy the next block */
-#line 3693
+#line 3698
 #pragma cdir loopcnt=LOOPCNT
-#line 3693
+#line 3698
 #pragma cdir shortloop
-#line 3693
+#line 3698
     for (i=0; i<ni; i++) {
-#line 3693
+#line 3698
       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
-#line 3693
+#line 3698
      /* test for range errors (not always needed but do it anyway) */
-#line 3693
+#line 3698
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3693
+#line 3698
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3693
+#line 3698
       nrange += xp[i] > USHORT_MAX ;
-#line 3693
+#line 3698
     }
-#line 3693
+#line 3698
    /* update xpp and tp */
-#line 3693
+#line 3698
     if (realign) xp = (uint64 *) *xpp;
-#line 3693
+#line 3698
     xp += ni;
-#line 3693
+#line 3698
     tp += ni;
-#line 3693
+#line 3698
     *xpp = (void*)xp;
-#line 3693
+#line 3698
   }
-#line 3693
+#line 3698
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3693
+#line 3698
 
-#line 3693
+#line 3698
 #else   /* not SX */
-#line 3693
+#line 3698
 	const char *xp = (const char *) *xpp;
-#line 3693
+#line 3698
 	int status = NC_NOERR;
-#line 3693
+#line 3698
 
-#line 3693
+#line 3698
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3693
+#line 3698
 	{
-#line 3693
+#line 3698
 		const int lstatus = ncx_get_ulonglong_ushort(xp, tp);
-#line 3693
+#line 3698
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3693
+#line 3698
 			status = lstatus;
-#line 3693
+#line 3698
 	}
-#line 3693
+#line 3698
 
-#line 3693
+#line 3698
 	*xpp = (const void *)xp;
-#line 3693
+#line 3698
 	return status;
-#line 3693
+#line 3698
 #endif
-#line 3693
+#line 3698
 }
-#line 3693
+#line 3698
 
 int
-#line 3694
+#line 3699
 ncx_getn_ulonglong_uint(const void **xpp, size_t nelems, uint *tp)
-#line 3694
+#line 3699
 {
-#line 3694
+#line 3699
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3694
+#line 3699
 
-#line 3694
+#line 3699
  /* basic algorithm is:
-#line 3694
+#line 3699
   *   - ensure sane alignment of input data
-#line 3694
+#line 3699
   *   - copy (conversion happens automatically) input data
-#line 3694
+#line 3699
   *     to output
-#line 3694
+#line 3699
   *   - update xpp to point at next unconverted input, and tp to point
-#line 3694
+#line 3699
   *     at next location for converted output
-#line 3694
+#line 3699
   */
-#line 3694
+#line 3699
   long i, j, ni;
-#line 3694
+#line 3699
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3694
+#line 3699
   uint64 *xp;
-#line 3694
+#line 3699
   int nrange = 0;         /* number of range errors */
-#line 3694
+#line 3699
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3694
+#line 3699
   long cxp = (long) *((char**)xpp);
-#line 3694
+#line 3699
 
-#line 3694
+#line 3699
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3694
+#line 3699
   /* sjl: manually stripmine so we can limit amount of
-#line 3694
+#line 3699
    * vector work space reserved to LOOPCNT elements. Also
-#line 3694
+#line 3699
    * makes vectorisation easy */
-#line 3694
+#line 3699
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3694
+#line 3699
     ni=Min(nelems-j,LOOPCNT);
-#line 3694
+#line 3699
     if (realign) {
-#line 3694
+#line 3699
       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
-#line 3694
+#line 3699
       xp = tmp;
-#line 3694
+#line 3699
     } else {
-#line 3694
+#line 3699
       xp = (uint64 *) *xpp;
-#line 3694
+#line 3699
     }
-#line 3694
+#line 3699
    /* copy the next block */
-#line 3694
+#line 3699
 #pragma cdir loopcnt=LOOPCNT
-#line 3694
+#line 3699
 #pragma cdir shortloop
-#line 3694
+#line 3699
     for (i=0; i<ni; i++) {
-#line 3694
+#line 3699
       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
-#line 3694
+#line 3699
      /* test for range errors (not always needed but do it anyway) */
-#line 3694
+#line 3699
      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
-#line 3694
+#line 3699
      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
-#line 3694
+#line 3699
       nrange += xp[i] > UINT_MAX ;
-#line 3694
+#line 3699
     }
-#line 3694
+#line 3699
    /* update xpp and tp */
-#line 3694
+#line 3699
     if (realign) xp = (uint64 *) *xpp;
-#line 3694
+#line 3699
     xp += ni;
-#line 3694
+#line 3699
     tp += ni;
-#line 3694
+#line 3699
     *xpp = (void*)xp;
-#line 3694
+#line 3699
   }
-#line 3694
+#line 3699
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3694
+#line 3699
 
-#line 3694
+#line 3699
 #else   /* not SX */
-#line 3694
+#line 3699
 	const char *xp = (const char *) *xpp;
-#line 3694
+#line 3699
 	int status = NC_NOERR;
-#line 3694
+#line 3699
 
-#line 3694
+#line 3699
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3694
+#line 3699
 	{
-#line 3694
+#line 3699
 		const int lstatus = ncx_get_ulonglong_uint(xp, tp);
-#line 3694
+#line 3699
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3694
+#line 3699
 			status = lstatus;
-#line 3694
+#line 3699
 	}
-#line 3694
+#line 3699
 
-#line 3694
+#line 3699
 	*xpp = (const void *)xp;
-#line 3694
+#line 3699
 	return status;
-#line 3694
+#line 3699
 #endif
-#line 3694
+#line 3699
 }
-#line 3694
+#line 3699
 
 
 #if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
@@ -37810,1534 +37815,1534 @@ ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long
 }
 #else
 int
-#line 3710
+#line 3715
 ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
-#line 3710
+#line 3715
 {
-#line 3710
+#line 3715
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3710
+#line 3715
 
-#line 3710
+#line 3715
  /* basic algorithm is:
-#line 3710
+#line 3715
   *   - ensure sane alignment of output data
-#line 3710
+#line 3715
   *   - copy (conversion happens automatically) input data
-#line 3710
+#line 3715
   *     to output
-#line 3710
+#line 3715
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3710
+#line 3715
   *     at next location for converted output
-#line 3710
+#line 3715
   */
-#line 3710
+#line 3715
   long i, j, ni;
-#line 3710
+#line 3715
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3710
+#line 3715
   uint64 *xp;
-#line 3710
+#line 3715
   int nrange = 0;         /* number of range errors */
-#line 3710
+#line 3715
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3710
+#line 3715
   long cxp = (long) *((char**)xpp);
-#line 3710
+#line 3715
 
-#line 3710
+#line 3715
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3710
+#line 3715
   /* sjl: manually stripmine so we can limit amount of
-#line 3710
+#line 3715
    * vector work space reserved to LOOPCNT elements. Also
-#line 3710
+#line 3715
    * makes vectorisation easy */
-#line 3710
+#line 3715
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3710
+#line 3715
     ni=Min(nelems-j,LOOPCNT);
-#line 3710
+#line 3715
     if (realign) {
-#line 3710
+#line 3715
       xp = tmp;
-#line 3710
+#line 3715
     } else {
-#line 3710
+#line 3715
       xp = (uint64 *) *xpp;
-#line 3710
+#line 3715
     }
-#line 3710
+#line 3715
    /* copy the next block */
-#line 3710
+#line 3715
 #pragma cdir loopcnt=LOOPCNT
-#line 3710
+#line 3715
 #pragma cdir shortloop
-#line 3710
+#line 3715
     for (i=0; i<ni; i++) {
-#line 3710
+#line 3715
       /* the normal case: */
-#line 3710
+#line 3715
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3710
+#line 3715
      /* test for range errors (not always needed but do it anyway) */
-#line 3710
+#line 3715
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3710
+#line 3715
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3710
+#line 3715
       nrange += tp[i] > X_UINT64_MAX ;
-#line 3710
+#line 3715
     }
-#line 3710
+#line 3715
    /* copy workspace back if necessary */
-#line 3710
+#line 3715
     if (realign) {
-#line 3710
+#line 3715
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3710
+#line 3715
       xp = (uint64 *) *xpp;
-#line 3710
+#line 3715
     }
-#line 3710
+#line 3715
    /* update xpp and tp */
-#line 3710
+#line 3715
     xp += ni;
-#line 3710
+#line 3715
     tp += ni;
-#line 3710
+#line 3715
     *xpp = (void*)xp;
-#line 3710
+#line 3715
   }
-#line 3710
+#line 3715
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3710
+#line 3715
 
-#line 3710
+#line 3715
 #else   /* not SX */
-#line 3710
+#line 3715
 
-#line 3710
+#line 3715
 	char *xp = (char *) *xpp;
-#line 3710
+#line 3715
 	int status = NC_NOERR;
-#line 3710
+#line 3715
 
-#line 3710
+#line 3715
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3710
+#line 3715
 	{
-#line 3710
+#line 3715
 		int lstatus = ncx_put_ulonglong_ulonglong(xp, tp, fillp);
-#line 3710
+#line 3715
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3710
+#line 3715
 			status = lstatus;
-#line 3710
+#line 3715
 	}
-#line 3710
+#line 3715
 
-#line 3710
+#line 3715
 	*xpp = (void *)xp;
-#line 3710
+#line 3715
 	return status;
-#line 3710
+#line 3715
 #endif
-#line 3710
+#line 3715
 }
-#line 3710
+#line 3715
 
 #endif
 int
-#line 3712
+#line 3717
 ncx_putn_ulonglong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
-#line 3712
+#line 3717
 {
-#line 3712
+#line 3717
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3712
+#line 3717
 
-#line 3712
+#line 3717
  /* basic algorithm is:
-#line 3712
+#line 3717
   *   - ensure sane alignment of output data
-#line 3712
+#line 3717
   *   - copy (conversion happens automatically) input data
-#line 3712
+#line 3717
   *     to output
-#line 3712
+#line 3717
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3712
+#line 3717
   *     at next location for converted output
-#line 3712
+#line 3717
   */
-#line 3712
+#line 3717
   long i, j, ni;
-#line 3712
+#line 3717
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3712
+#line 3717
   uint64 *xp;
-#line 3712
+#line 3717
   int nrange = 0;         /* number of range errors */
-#line 3712
+#line 3717
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3712
+#line 3717
   long cxp = (long) *((char**)xpp);
-#line 3712
+#line 3717
 
-#line 3712
+#line 3717
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3712
+#line 3717
   /* sjl: manually stripmine so we can limit amount of
-#line 3712
+#line 3717
    * vector work space reserved to LOOPCNT elements. Also
-#line 3712
+#line 3717
    * makes vectorisation easy */
-#line 3712
+#line 3717
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3712
+#line 3717
     ni=Min(nelems-j,LOOPCNT);
-#line 3712
+#line 3717
     if (realign) {
-#line 3712
+#line 3717
       xp = tmp;
-#line 3712
+#line 3717
     } else {
-#line 3712
+#line 3717
       xp = (uint64 *) *xpp;
-#line 3712
+#line 3717
     }
-#line 3712
+#line 3717
    /* copy the next block */
-#line 3712
+#line 3717
 #pragma cdir loopcnt=LOOPCNT
-#line 3712
+#line 3717
 #pragma cdir shortloop
-#line 3712
+#line 3717
     for (i=0; i<ni; i++) {
-#line 3712
+#line 3717
       /* the normal case: */
-#line 3712
+#line 3717
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3712
+#line 3717
      /* test for range errors (not always needed but do it anyway) */
-#line 3712
+#line 3717
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3712
+#line 3717
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3712
+#line 3717
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3712
+#line 3717
     }
-#line 3712
+#line 3717
    /* copy workspace back if necessary */
-#line 3712
+#line 3717
     if (realign) {
-#line 3712
+#line 3717
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3712
+#line 3717
       xp = (uint64 *) *xpp;
-#line 3712
+#line 3717
     }
-#line 3712
+#line 3717
    /* update xpp and tp */
-#line 3712
+#line 3717
     xp += ni;
-#line 3712
+#line 3717
     tp += ni;
-#line 3712
+#line 3717
     *xpp = (void*)xp;
-#line 3712
+#line 3717
   }
-#line 3712
+#line 3717
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3712
+#line 3717
 
-#line 3712
+#line 3717
 #else   /* not SX */
-#line 3712
+#line 3717
 
-#line 3712
+#line 3717
 	char *xp = (char *) *xpp;
-#line 3712
+#line 3717
 	int status = NC_NOERR;
-#line 3712
+#line 3717
 
-#line 3712
+#line 3717
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3712
+#line 3717
 	{
-#line 3712
+#line 3717
 		int lstatus = ncx_put_ulonglong_schar(xp, tp, fillp);
-#line 3712
+#line 3717
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3712
+#line 3717
 			status = lstatus;
-#line 3712
+#line 3717
 	}
-#line 3712
+#line 3717
 
-#line 3712
+#line 3717
 	*xpp = (void *)xp;
-#line 3712
+#line 3717
 	return status;
-#line 3712
+#line 3717
 #endif
-#line 3712
+#line 3717
 }
-#line 3712
+#line 3717
 
 int
-#line 3713
+#line 3718
 ncx_putn_ulonglong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
-#line 3713
+#line 3718
 {
-#line 3713
+#line 3718
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3713
+#line 3718
 
-#line 3713
+#line 3718
  /* basic algorithm is:
-#line 3713
+#line 3718
   *   - ensure sane alignment of output data
-#line 3713
+#line 3718
   *   - copy (conversion happens automatically) input data
-#line 3713
+#line 3718
   *     to output
-#line 3713
+#line 3718
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3713
+#line 3718
   *     at next location for converted output
-#line 3713
+#line 3718
   */
-#line 3713
+#line 3718
   long i, j, ni;
-#line 3713
+#line 3718
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3713
+#line 3718
   uint64 *xp;
-#line 3713
+#line 3718
   int nrange = 0;         /* number of range errors */
-#line 3713
+#line 3718
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3713
+#line 3718
   long cxp = (long) *((char**)xpp);
-#line 3713
+#line 3718
 
-#line 3713
+#line 3718
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3713
+#line 3718
   /* sjl: manually stripmine so we can limit amount of
-#line 3713
+#line 3718
    * vector work space reserved to LOOPCNT elements. Also
-#line 3713
+#line 3718
    * makes vectorisation easy */
-#line 3713
+#line 3718
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3713
+#line 3718
     ni=Min(nelems-j,LOOPCNT);
-#line 3713
+#line 3718
     if (realign) {
-#line 3713
+#line 3718
       xp = tmp;
-#line 3713
+#line 3718
     } else {
-#line 3713
+#line 3718
       xp = (uint64 *) *xpp;
-#line 3713
+#line 3718
     }
-#line 3713
+#line 3718
    /* copy the next block */
-#line 3713
+#line 3718
 #pragma cdir loopcnt=LOOPCNT
-#line 3713
+#line 3718
 #pragma cdir shortloop
-#line 3713
+#line 3718
     for (i=0; i<ni; i++) {
-#line 3713
+#line 3718
       /* the normal case: */
-#line 3713
+#line 3718
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3713
+#line 3718
      /* test for range errors (not always needed but do it anyway) */
-#line 3713
+#line 3718
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3713
+#line 3718
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3713
+#line 3718
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3713
+#line 3718
     }
-#line 3713
+#line 3718
    /* copy workspace back if necessary */
-#line 3713
+#line 3718
     if (realign) {
-#line 3713
+#line 3718
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3713
+#line 3718
       xp = (uint64 *) *xpp;
-#line 3713
+#line 3718
     }
-#line 3713
+#line 3718
    /* update xpp and tp */
-#line 3713
+#line 3718
     xp += ni;
-#line 3713
+#line 3718
     tp += ni;
-#line 3713
+#line 3718
     *xpp = (void*)xp;
-#line 3713
+#line 3718
   }
-#line 3713
+#line 3718
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3713
+#line 3718
 
-#line 3713
+#line 3718
 #else   /* not SX */
-#line 3713
+#line 3718
 
-#line 3713
+#line 3718
 	char *xp = (char *) *xpp;
-#line 3713
+#line 3718
 	int status = NC_NOERR;
-#line 3713
+#line 3718
 
-#line 3713
+#line 3718
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3713
+#line 3718
 	{
-#line 3713
+#line 3718
 		int lstatus = ncx_put_ulonglong_short(xp, tp, fillp);
-#line 3713
+#line 3718
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3713
+#line 3718
 			status = lstatus;
-#line 3713
+#line 3718
 	}
-#line 3713
+#line 3718
 
-#line 3713
+#line 3718
 	*xpp = (void *)xp;
-#line 3713
+#line 3718
 	return status;
-#line 3713
+#line 3718
 #endif
-#line 3713
+#line 3718
 }
-#line 3713
+#line 3718
 
 int
-#line 3714
+#line 3719
 ncx_putn_ulonglong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
-#line 3714
+#line 3719
 {
-#line 3714
+#line 3719
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3714
+#line 3719
 
-#line 3714
+#line 3719
  /* basic algorithm is:
-#line 3714
+#line 3719
   *   - ensure sane alignment of output data
-#line 3714
+#line 3719
   *   - copy (conversion happens automatically) input data
-#line 3714
+#line 3719
   *     to output
-#line 3714
+#line 3719
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3714
+#line 3719
   *     at next location for converted output
-#line 3714
+#line 3719
   */
-#line 3714
+#line 3719
   long i, j, ni;
-#line 3714
+#line 3719
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3714
+#line 3719
   uint64 *xp;
-#line 3714
+#line 3719
   int nrange = 0;         /* number of range errors */
-#line 3714
+#line 3719
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3714
+#line 3719
   long cxp = (long) *((char**)xpp);
-#line 3714
+#line 3719
 
-#line 3714
+#line 3719
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3714
+#line 3719
   /* sjl: manually stripmine so we can limit amount of
-#line 3714
+#line 3719
    * vector work space reserved to LOOPCNT elements. Also
-#line 3714
+#line 3719
    * makes vectorisation easy */
-#line 3714
+#line 3719
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3714
+#line 3719
     ni=Min(nelems-j,LOOPCNT);
-#line 3714
+#line 3719
     if (realign) {
-#line 3714
+#line 3719
       xp = tmp;
-#line 3714
+#line 3719
     } else {
-#line 3714
+#line 3719
       xp = (uint64 *) *xpp;
-#line 3714
+#line 3719
     }
-#line 3714
+#line 3719
    /* copy the next block */
-#line 3714
+#line 3719
 #pragma cdir loopcnt=LOOPCNT
-#line 3714
+#line 3719
 #pragma cdir shortloop
-#line 3714
+#line 3719
     for (i=0; i<ni; i++) {
-#line 3714
+#line 3719
       /* the normal case: */
-#line 3714
+#line 3719
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3714
+#line 3719
      /* test for range errors (not always needed but do it anyway) */
-#line 3714
+#line 3719
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3714
+#line 3719
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3714
+#line 3719
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3714
+#line 3719
     }
-#line 3714
+#line 3719
    /* copy workspace back if necessary */
-#line 3714
+#line 3719
     if (realign) {
-#line 3714
+#line 3719
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3714
+#line 3719
       xp = (uint64 *) *xpp;
-#line 3714
+#line 3719
     }
-#line 3714
+#line 3719
    /* update xpp and tp */
-#line 3714
+#line 3719
     xp += ni;
-#line 3714
+#line 3719
     tp += ni;
-#line 3714
+#line 3719
     *xpp = (void*)xp;
-#line 3714
+#line 3719
   }
-#line 3714
+#line 3719
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3714
+#line 3719
 
-#line 3714
+#line 3719
 #else   /* not SX */
-#line 3714
+#line 3719
 
-#line 3714
+#line 3719
 	char *xp = (char *) *xpp;
-#line 3714
+#line 3719
 	int status = NC_NOERR;
-#line 3714
+#line 3719
 
-#line 3714
+#line 3719
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3714
+#line 3719
 	{
-#line 3714
+#line 3719
 		int lstatus = ncx_put_ulonglong_int(xp, tp, fillp);
-#line 3714
+#line 3719
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3714
+#line 3719
 			status = lstatus;
-#line 3714
+#line 3719
 	}
-#line 3714
+#line 3719
 
-#line 3714
+#line 3719
 	*xpp = (void *)xp;
-#line 3714
+#line 3719
 	return status;
-#line 3714
+#line 3719
 #endif
-#line 3714
+#line 3719
 }
-#line 3714
+#line 3719
 
 int
-#line 3715
+#line 3720
 ncx_putn_ulonglong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
-#line 3715
+#line 3720
 {
-#line 3715
+#line 3720
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3715
+#line 3720
 
-#line 3715
+#line 3720
  /* basic algorithm is:
-#line 3715
+#line 3720
   *   - ensure sane alignment of output data
-#line 3715
+#line 3720
   *   - copy (conversion happens automatically) input data
-#line 3715
+#line 3720
   *     to output
-#line 3715
+#line 3720
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3715
+#line 3720
   *     at next location for converted output
-#line 3715
+#line 3720
   */
-#line 3715
+#line 3720
   long i, j, ni;
-#line 3715
+#line 3720
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3715
+#line 3720
   uint64 *xp;
-#line 3715
+#line 3720
   int nrange = 0;         /* number of range errors */
-#line 3715
+#line 3720
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3715
+#line 3720
   long cxp = (long) *((char**)xpp);
-#line 3715
+#line 3720
 
-#line 3715
+#line 3720
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3715
+#line 3720
   /* sjl: manually stripmine so we can limit amount of
-#line 3715
+#line 3720
    * vector work space reserved to LOOPCNT elements. Also
-#line 3715
+#line 3720
    * makes vectorisation easy */
-#line 3715
+#line 3720
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3715
+#line 3720
     ni=Min(nelems-j,LOOPCNT);
-#line 3715
+#line 3720
     if (realign) {
-#line 3715
+#line 3720
       xp = tmp;
-#line 3715
+#line 3720
     } else {
-#line 3715
+#line 3720
       xp = (uint64 *) *xpp;
-#line 3715
+#line 3720
     }
-#line 3715
+#line 3720
    /* copy the next block */
-#line 3715
+#line 3720
 #pragma cdir loopcnt=LOOPCNT
-#line 3715
+#line 3720
 #pragma cdir shortloop
-#line 3715
+#line 3720
     for (i=0; i<ni; i++) {
-#line 3715
+#line 3720
       /* the normal case: */
-#line 3715
+#line 3720
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3715
+#line 3720
      /* test for range errors (not always needed but do it anyway) */
-#line 3715
+#line 3720
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3715
+#line 3720
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3715
+#line 3720
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3715
+#line 3720
     }
-#line 3715
+#line 3720
    /* copy workspace back if necessary */
-#line 3715
+#line 3720
     if (realign) {
-#line 3715
+#line 3720
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3715
+#line 3720
       xp = (uint64 *) *xpp;
-#line 3715
+#line 3720
     }
-#line 3715
+#line 3720
    /* update xpp and tp */
-#line 3715
+#line 3720
     xp += ni;
-#line 3715
+#line 3720
     tp += ni;
-#line 3715
+#line 3720
     *xpp = (void*)xp;
-#line 3715
+#line 3720
   }
-#line 3715
+#line 3720
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3715
+#line 3720
 
-#line 3715
+#line 3720
 #else   /* not SX */
-#line 3715
+#line 3720
 
-#line 3715
+#line 3720
 	char *xp = (char *) *xpp;
-#line 3715
+#line 3720
 	int status = NC_NOERR;
-#line 3715
+#line 3720
 
-#line 3715
+#line 3720
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3715
+#line 3720
 	{
-#line 3715
+#line 3720
 		int lstatus = ncx_put_ulonglong_long(xp, tp, fillp);
-#line 3715
+#line 3720
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3715
+#line 3720
 			status = lstatus;
-#line 3715
+#line 3720
 	}
-#line 3715
+#line 3720
 
-#line 3715
+#line 3720
 	*xpp = (void *)xp;
-#line 3715
+#line 3720
 	return status;
-#line 3715
+#line 3720
 #endif
-#line 3715
+#line 3720
 }
-#line 3715
+#line 3720
 
 int
-#line 3716
+#line 3721
 ncx_putn_ulonglong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
-#line 3716
+#line 3721
 {
-#line 3716
+#line 3721
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3716
+#line 3721
 
-#line 3716
+#line 3721
  /* basic algorithm is:
-#line 3716
+#line 3721
   *   - ensure sane alignment of output data
-#line 3716
+#line 3721
   *   - copy (conversion happens automatically) input data
-#line 3716
+#line 3721
   *     to output
-#line 3716
+#line 3721
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3716
+#line 3721
   *     at next location for converted output
-#line 3716
+#line 3721
   */
-#line 3716
+#line 3721
   long i, j, ni;
-#line 3716
+#line 3721
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3716
+#line 3721
   uint64 *xp;
-#line 3716
+#line 3721
   int nrange = 0;         /* number of range errors */
-#line 3716
+#line 3721
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3716
+#line 3721
   long cxp = (long) *((char**)xpp);
-#line 3716
+#line 3721
 
-#line 3716
+#line 3721
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3716
+#line 3721
   /* sjl: manually stripmine so we can limit amount of
-#line 3716
+#line 3721
    * vector work space reserved to LOOPCNT elements. Also
-#line 3716
+#line 3721
    * makes vectorisation easy */
-#line 3716
+#line 3721
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3716
+#line 3721
     ni=Min(nelems-j,LOOPCNT);
-#line 3716
+#line 3721
     if (realign) {
-#line 3716
+#line 3721
       xp = tmp;
-#line 3716
+#line 3721
     } else {
-#line 3716
+#line 3721
       xp = (uint64 *) *xpp;
-#line 3716
+#line 3721
     }
-#line 3716
+#line 3721
    /* copy the next block */
-#line 3716
+#line 3721
 #pragma cdir loopcnt=LOOPCNT
-#line 3716
+#line 3721
 #pragma cdir shortloop
-#line 3716
+#line 3721
     for (i=0; i<ni; i++) {
-#line 3716
+#line 3721
       /* the normal case: */
-#line 3716
+#line 3721
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3716
+#line 3721
      /* test for range errors (not always needed but do it anyway) */
-#line 3716
+#line 3721
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3716
+#line 3721
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3716
+#line 3721
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3716
+#line 3721
     }
-#line 3716
+#line 3721
    /* copy workspace back if necessary */
-#line 3716
+#line 3721
     if (realign) {
-#line 3716
+#line 3721
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3716
+#line 3721
       xp = (uint64 *) *xpp;
-#line 3716
+#line 3721
     }
-#line 3716
+#line 3721
    /* update xpp and tp */
-#line 3716
+#line 3721
     xp += ni;
-#line 3716
+#line 3721
     tp += ni;
-#line 3716
+#line 3721
     *xpp = (void*)xp;
-#line 3716
+#line 3721
   }
-#line 3716
+#line 3721
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3716
+#line 3721
 
-#line 3716
+#line 3721
 #else   /* not SX */
-#line 3716
+#line 3721
 
-#line 3716
+#line 3721
 	char *xp = (char *) *xpp;
-#line 3716
+#line 3721
 	int status = NC_NOERR;
-#line 3716
+#line 3721
 
-#line 3716
+#line 3721
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3716
+#line 3721
 	{
-#line 3716
+#line 3721
 		int lstatus = ncx_put_ulonglong_float(xp, tp, fillp);
-#line 3716
+#line 3721
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3716
+#line 3721
 			status = lstatus;
-#line 3716
+#line 3721
 	}
-#line 3716
+#line 3721
 
-#line 3716
+#line 3721
 	*xpp = (void *)xp;
-#line 3716
+#line 3721
 	return status;
-#line 3716
+#line 3721
 #endif
-#line 3716
+#line 3721
 }
-#line 3716
+#line 3721
 
 int
-#line 3717
+#line 3722
 ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
-#line 3717
+#line 3722
 {
-#line 3717
+#line 3722
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3717
+#line 3722
 
-#line 3717
+#line 3722
  /* basic algorithm is:
-#line 3717
+#line 3722
   *   - ensure sane alignment of output data
-#line 3717
+#line 3722
   *   - copy (conversion happens automatically) input data
-#line 3717
+#line 3722
   *     to output
-#line 3717
+#line 3722
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3717
+#line 3722
   *     at next location for converted output
-#line 3717
+#line 3722
   */
-#line 3717
+#line 3722
   long i, j, ni;
-#line 3717
+#line 3722
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3717
+#line 3722
   uint64 *xp;
-#line 3717
+#line 3722
   int nrange = 0;         /* number of range errors */
-#line 3717
+#line 3722
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3717
+#line 3722
   long cxp = (long) *((char**)xpp);
-#line 3717
+#line 3722
 
-#line 3717
+#line 3722
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3717
+#line 3722
   /* sjl: manually stripmine so we can limit amount of
-#line 3717
+#line 3722
    * vector work space reserved to LOOPCNT elements. Also
-#line 3717
+#line 3722
    * makes vectorisation easy */
-#line 3717
+#line 3722
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3717
+#line 3722
     ni=Min(nelems-j,LOOPCNT);
-#line 3717
+#line 3722
     if (realign) {
-#line 3717
+#line 3722
       xp = tmp;
-#line 3717
+#line 3722
     } else {
-#line 3717
+#line 3722
       xp = (uint64 *) *xpp;
-#line 3717
+#line 3722
     }
-#line 3717
+#line 3722
    /* copy the next block */
-#line 3717
+#line 3722
 #pragma cdir loopcnt=LOOPCNT
-#line 3717
+#line 3722
 #pragma cdir shortloop
-#line 3717
+#line 3722
     for (i=0; i<ni; i++) {
-#line 3717
+#line 3722
       /* the normal case: */
-#line 3717
+#line 3722
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3717
+#line 3722
      /* test for range errors (not always needed but do it anyway) */
-#line 3717
+#line 3722
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3717
+#line 3722
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3717
+#line 3722
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3717
+#line 3722
     }
-#line 3717
+#line 3722
    /* copy workspace back if necessary */
-#line 3717
+#line 3722
     if (realign) {
-#line 3717
+#line 3722
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3717
+#line 3722
       xp = (uint64 *) *xpp;
-#line 3717
+#line 3722
     }
-#line 3717
+#line 3722
    /* update xpp and tp */
-#line 3717
+#line 3722
     xp += ni;
-#line 3717
+#line 3722
     tp += ni;
-#line 3717
+#line 3722
     *xpp = (void*)xp;
-#line 3717
+#line 3722
   }
-#line 3717
+#line 3722
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3717
+#line 3722
 
-#line 3717
+#line 3722
 #else   /* not SX */
-#line 3717
+#line 3722
 
-#line 3717
+#line 3722
 	char *xp = (char *) *xpp;
-#line 3717
+#line 3722
 	int status = NC_NOERR;
-#line 3717
+#line 3722
 
-#line 3717
+#line 3722
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3717
+#line 3722
 	{
-#line 3717
+#line 3722
 		int lstatus = ncx_put_ulonglong_double(xp, tp, fillp);
-#line 3717
+#line 3722
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3717
+#line 3722
 			status = lstatus;
-#line 3717
+#line 3722
 	}
-#line 3717
+#line 3722
 
-#line 3717
+#line 3722
 	*xpp = (void *)xp;
-#line 3717
+#line 3722
 	return status;
-#line 3717
+#line 3722
 #endif
-#line 3717
+#line 3722
 }
-#line 3717
+#line 3722
 
 int
-#line 3718
+#line 3723
 ncx_putn_ulonglong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
-#line 3718
+#line 3723
 {
-#line 3718
+#line 3723
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3718
+#line 3723
 
-#line 3718
+#line 3723
  /* basic algorithm is:
-#line 3718
+#line 3723
   *   - ensure sane alignment of output data
-#line 3718
+#line 3723
   *   - copy (conversion happens automatically) input data
-#line 3718
+#line 3723
   *     to output
-#line 3718
+#line 3723
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3718
+#line 3723
   *     at next location for converted output
-#line 3718
+#line 3723
   */
-#line 3718
+#line 3723
   long i, j, ni;
-#line 3718
+#line 3723
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3718
+#line 3723
   uint64 *xp;
-#line 3718
+#line 3723
   int nrange = 0;         /* number of range errors */
-#line 3718
+#line 3723
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3718
+#line 3723
   long cxp = (long) *((char**)xpp);
-#line 3718
+#line 3723
 
-#line 3718
+#line 3723
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3718
+#line 3723
   /* sjl: manually stripmine so we can limit amount of
-#line 3718
+#line 3723
    * vector work space reserved to LOOPCNT elements. Also
-#line 3718
+#line 3723
    * makes vectorisation easy */
-#line 3718
+#line 3723
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3718
+#line 3723
     ni=Min(nelems-j,LOOPCNT);
-#line 3718
+#line 3723
     if (realign) {
-#line 3718
+#line 3723
       xp = tmp;
-#line 3718
+#line 3723
     } else {
-#line 3718
+#line 3723
       xp = (uint64 *) *xpp;
-#line 3718
+#line 3723
     }
-#line 3718
+#line 3723
    /* copy the next block */
-#line 3718
+#line 3723
 #pragma cdir loopcnt=LOOPCNT
-#line 3718
+#line 3723
 #pragma cdir shortloop
-#line 3718
+#line 3723
     for (i=0; i<ni; i++) {
-#line 3718
+#line 3723
       /* the normal case: */
-#line 3718
+#line 3723
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3718
+#line 3723
      /* test for range errors (not always needed but do it anyway) */
-#line 3718
+#line 3723
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3718
+#line 3723
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3718
+#line 3723
       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
-#line 3718
+#line 3723
     }
-#line 3718
+#line 3723
    /* copy workspace back if necessary */
-#line 3718
+#line 3723
     if (realign) {
-#line 3718
+#line 3723
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3718
+#line 3723
       xp = (uint64 *) *xpp;
-#line 3718
+#line 3723
     }
-#line 3718
+#line 3723
    /* update xpp and tp */
-#line 3718
+#line 3723
     xp += ni;
-#line 3718
+#line 3723
     tp += ni;
-#line 3718
+#line 3723
     *xpp = (void*)xp;
-#line 3718
+#line 3723
   }
-#line 3718
+#line 3723
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3718
+#line 3723
 
-#line 3718
+#line 3723
 #else   /* not SX */
-#line 3718
+#line 3723
 
-#line 3718
+#line 3723
 	char *xp = (char *) *xpp;
-#line 3718
+#line 3723
 	int status = NC_NOERR;
-#line 3718
+#line 3723
 
-#line 3718
+#line 3723
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3718
+#line 3723
 	{
-#line 3718
+#line 3723
 		int lstatus = ncx_put_ulonglong_longlong(xp, tp, fillp);
-#line 3718
+#line 3723
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3718
+#line 3723
 			status = lstatus;
-#line 3718
+#line 3723
 	}
-#line 3718
+#line 3723
 
-#line 3718
+#line 3723
 	*xpp = (void *)xp;
-#line 3718
+#line 3723
 	return status;
-#line 3718
+#line 3723
 #endif
-#line 3718
+#line 3723
 }
-#line 3718
+#line 3723
 
 int
-#line 3719
+#line 3724
 ncx_putn_ulonglong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
-#line 3719
+#line 3724
 {
-#line 3719
+#line 3724
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3719
+#line 3724
 
-#line 3719
+#line 3724
  /* basic algorithm is:
-#line 3719
+#line 3724
   *   - ensure sane alignment of output data
-#line 3719
+#line 3724
   *   - copy (conversion happens automatically) input data
-#line 3719
+#line 3724
   *     to output
-#line 3719
+#line 3724
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3719
+#line 3724
   *     at next location for converted output
-#line 3719
+#line 3724
   */
-#line 3719
+#line 3724
   long i, j, ni;
-#line 3719
+#line 3724
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3719
+#line 3724
   uint64 *xp;
-#line 3719
+#line 3724
   int nrange = 0;         /* number of range errors */
-#line 3719
+#line 3724
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3719
+#line 3724
   long cxp = (long) *((char**)xpp);
-#line 3719
+#line 3724
 
-#line 3719
+#line 3724
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3719
+#line 3724
   /* sjl: manually stripmine so we can limit amount of
-#line 3719
+#line 3724
    * vector work space reserved to LOOPCNT elements. Also
-#line 3719
+#line 3724
    * makes vectorisation easy */
-#line 3719
+#line 3724
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3719
+#line 3724
     ni=Min(nelems-j,LOOPCNT);
-#line 3719
+#line 3724
     if (realign) {
-#line 3719
+#line 3724
       xp = tmp;
-#line 3719
+#line 3724
     } else {
-#line 3719
+#line 3724
       xp = (uint64 *) *xpp;
-#line 3719
+#line 3724
     }
-#line 3719
+#line 3724
    /* copy the next block */
-#line 3719
+#line 3724
 #pragma cdir loopcnt=LOOPCNT
-#line 3719
+#line 3724
 #pragma cdir shortloop
-#line 3719
+#line 3724
     for (i=0; i<ni; i++) {
-#line 3719
+#line 3724
       /* the normal case: */
-#line 3719
+#line 3724
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3719
+#line 3724
      /* test for range errors (not always needed but do it anyway) */
-#line 3719
+#line 3724
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3719
+#line 3724
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3719
+#line 3724
       nrange += tp[i] > X_UINT64_MAX ;
-#line 3719
+#line 3724
     }
-#line 3719
+#line 3724
    /* copy workspace back if necessary */
-#line 3719
+#line 3724
     if (realign) {
-#line 3719
+#line 3724
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3719
+#line 3724
       xp = (uint64 *) *xpp;
-#line 3719
+#line 3724
     }
-#line 3719
+#line 3724
    /* update xpp and tp */
-#line 3719
+#line 3724
     xp += ni;
-#line 3719
+#line 3724
     tp += ni;
-#line 3719
+#line 3724
     *xpp = (void*)xp;
-#line 3719
+#line 3724
   }
-#line 3719
+#line 3724
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3719
+#line 3724
 
-#line 3719
+#line 3724
 #else   /* not SX */
-#line 3719
+#line 3724
 
-#line 3719
+#line 3724
 	char *xp = (char *) *xpp;
-#line 3719
+#line 3724
 	int status = NC_NOERR;
-#line 3719
+#line 3724
 
-#line 3719
+#line 3724
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3719
+#line 3724
 	{
-#line 3719
+#line 3724
 		int lstatus = ncx_put_ulonglong_uchar(xp, tp, fillp);
-#line 3719
+#line 3724
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3719
+#line 3724
 			status = lstatus;
-#line 3719
+#line 3724
 	}
-#line 3719
+#line 3724
 
-#line 3719
+#line 3724
 	*xpp = (void *)xp;
-#line 3719
+#line 3724
 	return status;
-#line 3719
+#line 3724
 #endif
-#line 3719
+#line 3724
 }
-#line 3719
+#line 3724
 
 int
-#line 3720
+#line 3725
 ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
-#line 3720
+#line 3725
 {
-#line 3720
+#line 3725
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3720
+#line 3725
 
-#line 3720
+#line 3725
  /* basic algorithm is:
-#line 3720
+#line 3725
   *   - ensure sane alignment of output data
-#line 3720
+#line 3725
   *   - copy (conversion happens automatically) input data
-#line 3720
+#line 3725
   *     to output
-#line 3720
+#line 3725
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3720
+#line 3725
   *     at next location for converted output
-#line 3720
+#line 3725
   */
-#line 3720
+#line 3725
   long i, j, ni;
-#line 3720
+#line 3725
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3720
+#line 3725
   uint64 *xp;
-#line 3720
+#line 3725
   int nrange = 0;         /* number of range errors */
-#line 3720
+#line 3725
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3720
+#line 3725
   long cxp = (long) *((char**)xpp);
-#line 3720
+#line 3725
 
-#line 3720
+#line 3725
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3720
+#line 3725
   /* sjl: manually stripmine so we can limit amount of
-#line 3720
+#line 3725
    * vector work space reserved to LOOPCNT elements. Also
-#line 3720
+#line 3725
    * makes vectorisation easy */
-#line 3720
+#line 3725
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3720
+#line 3725
     ni=Min(nelems-j,LOOPCNT);
-#line 3720
+#line 3725
     if (realign) {
-#line 3720
+#line 3725
       xp = tmp;
-#line 3720
+#line 3725
     } else {
-#line 3720
+#line 3725
       xp = (uint64 *) *xpp;
-#line 3720
+#line 3725
     }
-#line 3720
+#line 3725
    /* copy the next block */
-#line 3720
+#line 3725
 #pragma cdir loopcnt=LOOPCNT
-#line 3720
+#line 3725
 #pragma cdir shortloop
-#line 3720
+#line 3725
     for (i=0; i<ni; i++) {
-#line 3720
+#line 3725
       /* the normal case: */
-#line 3720
+#line 3725
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3720
+#line 3725
      /* test for range errors (not always needed but do it anyway) */
-#line 3720
+#line 3725
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3720
+#line 3725
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3720
+#line 3725
       nrange += tp[i] > X_UINT64_MAX ;
-#line 3720
+#line 3725
     }
-#line 3720
+#line 3725
    /* copy workspace back if necessary */
-#line 3720
+#line 3725
     if (realign) {
-#line 3720
+#line 3725
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3720
+#line 3725
       xp = (uint64 *) *xpp;
-#line 3720
+#line 3725
     }
-#line 3720
+#line 3725
    /* update xpp and tp */
-#line 3720
+#line 3725
     xp += ni;
-#line 3720
+#line 3725
     tp += ni;
-#line 3720
+#line 3725
     *xpp = (void*)xp;
-#line 3720
+#line 3725
   }
-#line 3720
+#line 3725
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3720
+#line 3725
 
-#line 3720
+#line 3725
 #else   /* not SX */
-#line 3720
+#line 3725
 
-#line 3720
+#line 3725
 	char *xp = (char *) *xpp;
-#line 3720
+#line 3725
 	int status = NC_NOERR;
-#line 3720
+#line 3725
 
-#line 3720
+#line 3725
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3720
+#line 3725
 	{
-#line 3720
+#line 3725
 		int lstatus = ncx_put_ulonglong_ushort(xp, tp, fillp);
-#line 3720
+#line 3725
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3720
+#line 3725
 			status = lstatus;
-#line 3720
+#line 3725
 	}
-#line 3720
+#line 3725
 
-#line 3720
+#line 3725
 	*xpp = (void *)xp;
-#line 3720
+#line 3725
 	return status;
-#line 3720
+#line 3725
 #endif
-#line 3720
+#line 3725
 }
-#line 3720
+#line 3725
 
 int
-#line 3721
+#line 3726
 ncx_putn_ulonglong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
-#line 3721
+#line 3726
 {
-#line 3721
+#line 3726
 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
-#line 3721
+#line 3726
 
-#line 3721
+#line 3726
  /* basic algorithm is:
-#line 3721
+#line 3726
   *   - ensure sane alignment of output data
-#line 3721
+#line 3726
   *   - copy (conversion happens automatically) input data
-#line 3721
+#line 3726
   *     to output
-#line 3721
+#line 3726
   *   - update tp to point at next unconverted input, and xpp to point
-#line 3721
+#line 3726
   *     at next location for converted output
-#line 3721
+#line 3726
   */
-#line 3721
+#line 3726
   long i, j, ni;
-#line 3721
+#line 3726
   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
-#line 3721
+#line 3726
   uint64 *xp;
-#line 3721
+#line 3726
   int nrange = 0;         /* number of range errors */
-#line 3721
+#line 3726
   int realign = 0;        /* "do we need to fix input data alignment?" */
-#line 3721
+#line 3726
   long cxp = (long) *((char**)xpp);
-#line 3721
+#line 3726
 
-#line 3721
+#line 3726
   realign = (cxp & 7) % SIZEOF_UINT64;
-#line 3721
+#line 3726
   /* sjl: manually stripmine so we can limit amount of
-#line 3721
+#line 3726
    * vector work space reserved to LOOPCNT elements. Also
-#line 3721
+#line 3726
    * makes vectorisation easy */
-#line 3721
+#line 3726
   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
-#line 3721
+#line 3726
     ni=Min(nelems-j,LOOPCNT);
-#line 3721
+#line 3726
     if (realign) {
-#line 3721
+#line 3726
       xp = tmp;
-#line 3721
+#line 3726
     } else {
-#line 3721
+#line 3726
       xp = (uint64 *) *xpp;
-#line 3721
+#line 3726
     }
-#line 3721
+#line 3726
    /* copy the next block */
-#line 3721
+#line 3726
 #pragma cdir loopcnt=LOOPCNT
-#line 3721
+#line 3726
 #pragma cdir shortloop
-#line 3721
+#line 3726
     for (i=0; i<ni; i++) {
-#line 3721
+#line 3726
       /* the normal case: */
-#line 3721
+#line 3726
       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
-#line 3721
+#line 3726
      /* test for range errors (not always needed but do it anyway) */
-#line 3721
+#line 3726
      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
-#line 3721
+#line 3726
      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
-#line 3721
+#line 3726
       nrange += tp[i] > X_UINT64_MAX ;
-#line 3721
+#line 3726
     }
-#line 3721
+#line 3726
    /* copy workspace back if necessary */
-#line 3721
+#line 3726
     if (realign) {
-#line 3721
+#line 3726
       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
-#line 3721
+#line 3726
       xp = (uint64 *) *xpp;
-#line 3721
+#line 3726
     }
-#line 3721
+#line 3726
    /* update xpp and tp */
-#line 3721
+#line 3726
     xp += ni;
-#line 3721
+#line 3726
     tp += ni;
-#line 3721
+#line 3726
     *xpp = (void*)xp;
-#line 3721
+#line 3726
   }
-#line 3721
+#line 3726
   return nrange == 0 ? NC_NOERR : NC_ERANGE;
-#line 3721
+#line 3726
 
-#line 3721
+#line 3726
 #else   /* not SX */
-#line 3721
+#line 3726
 
-#line 3721
+#line 3726
 	char *xp = (char *) *xpp;
-#line 3721
+#line 3726
 	int status = NC_NOERR;
-#line 3721
+#line 3726
 
-#line 3721
+#line 3726
 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
-#line 3721
+#line 3726
 	{
-#line 3721
+#line 3726
 		int lstatus = ncx_put_ulonglong_uint(xp, tp, fillp);
-#line 3721
+#line 3726
 		if (status == NC_NOERR) /* report the first encountered error */
-#line 3721
+#line 3726
 			status = lstatus;
-#line 3721
+#line 3726
 	}
-#line 3721
+#line 3726
 
-#line 3721
+#line 3726
 	*xpp = (void *)xp;
-#line 3721
+#line 3726
 	return status;
-#line 3721
+#line 3726
 #endif
-#line 3721
+#line 3726
 }
-#line 3721
+#line 3726
 
 
 
@@ -39351,11 +39356,11 @@ int
 ncx_getn_text(const void **xpp, size_t nelems, char *tp)
 {
 	(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 3733
+#line 3738
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3733
+#line 3738
 	return NC_NOERR;
-#line 3733
+#line 3738
 
 }
 
@@ -39363,23 +39368,23 @@ int
 ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
 {
 	size_t rndup = nelems % X_ALIGN;
-#line 3739
+#line 3744
 
-#line 3739
+#line 3744
 	if (rndup)
-#line 3739
+#line 3744
 		rndup = X_ALIGN - rndup;
-#line 3739
+#line 3744
 
-#line 3739
+#line 3744
 	(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 3739
+#line 3744
 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
-#line 3739
+#line 3744
 
-#line 3739
+#line 3744
 	return NC_NOERR;
-#line 3739
+#line 3744
 
 }
 
@@ -39387,13 +39392,13 @@ int
 ncx_putn_text(void **xpp, size_t nelems, const char *tp)
 {
 	(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 3745
+#line 3750
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3745
+#line 3750
 
-#line 3745
+#line 3750
 	return NC_NOERR;
-#line 3745
+#line 3750
 
 }
 
@@ -39401,35 +39406,35 @@ int
 ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
 {
 	size_t rndup = nelems % X_ALIGN;
-#line 3751
+#line 3756
 
-#line 3751
+#line 3756
 	if (rndup)
-#line 3751
+#line 3756
 		rndup = X_ALIGN - rndup;
-#line 3751
+#line 3756
 
-#line 3751
+#line 3756
 	(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 3751
+#line 3756
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3751
+#line 3756
 
-#line 3751
+#line 3756
 	if (rndup)
-#line 3751
+#line 3756
 	{
-#line 3751
+#line 3756
 		(void) memcpy(*xpp, nada, (size_t)rndup);
-#line 3751
+#line 3756
 		*xpp = (void *)((char *)(*xpp) + rndup);
-#line 3751
+#line 3756
 	}
-#line 3751
+#line 3756
 
-#line 3751
+#line 3756
 	return NC_NOERR;
-#line 3751
+#line 3756
 
 }
 
@@ -39440,11 +39445,11 @@ int
 ncx_getn_void(const void **xpp, size_t nelems, void *tp)
 {
 	(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 3760
+#line 3765
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3760
+#line 3765
 	return NC_NOERR;
-#line 3760
+#line 3765
 
 }
 
@@ -39452,23 +39457,23 @@ int
 ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
 {
 	size_t rndup = nelems % X_ALIGN;
-#line 3766
+#line 3771
 
-#line 3766
+#line 3771
 	if (rndup)
-#line 3766
+#line 3771
 		rndup = X_ALIGN - rndup;
-#line 3766
+#line 3771
 
-#line 3766
+#line 3771
 	(void) memcpy(tp, *xpp, (size_t)nelems);
-#line 3766
+#line 3771
 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
-#line 3766
+#line 3771
 
-#line 3766
+#line 3771
 	return NC_NOERR;
-#line 3766
+#line 3771
 
 }
 
@@ -39476,13 +39481,13 @@ int
 ncx_putn_void(void **xpp, size_t nelems, const void *tp)
 {
 	(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 3772
+#line 3777
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3772
+#line 3777
 
-#line 3772
+#line 3777
 	return NC_NOERR;
-#line 3772
+#line 3777
 
 }
 
@@ -39490,34 +39495,34 @@ int
 ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
 {
 	size_t rndup = nelems % X_ALIGN;
-#line 3778
+#line 3783
 
-#line 3778
+#line 3783
 	if (rndup)
-#line 3778
+#line 3783
 		rndup = X_ALIGN - rndup;
-#line 3778
+#line 3783
 
-#line 3778
+#line 3783
 	(void) memcpy(*xpp, tp, (size_t)nelems);
-#line 3778
+#line 3783
 	*xpp = (void *)((char *)(*xpp) + nelems);
-#line 3778
+#line 3783
 
-#line 3778
+#line 3783
 	if (rndup)
-#line 3778
+#line 3783
 	{
-#line 3778
+#line 3783
 		(void) memcpy(*xpp, nada, (size_t)rndup);
-#line 3778
+#line 3783
 		*xpp = (void *)((char *)(*xpp) + rndup);
-#line 3778
+#line 3783
 	}
-#line 3778
+#line 3783
 
-#line 3778
+#line 3783
 	return NC_NOERR;
-#line 3778
+#line 3783
 
 }
diff --git a/libsrc/ncx.h b/libsrc/ncx.h
index 6b2313c..a9ffcdc 100644
--- a/libsrc/ncx.h
+++ b/libsrc/ncx.h
@@ -45,6 +45,17 @@
 #define CRAYFLOAT 1 /* CRAY Floating point */
 #endif
 
+#ifndef __cplusplus
+  #if __STDC_VERSION__ == 199901L /* C99 */
+  /* "inline" is a keyword */
+  #elif _MSC_VER >= 1500 /* MSVC 9 or newer */
+    #define inline __inline
+  #elif __GNUC__ >= 3 /* GCC 3 or newer */
+    #define inline __inline
+  #else /* Unknown or ancient */
+    #define inline
+  #endif
+#endif
 
 /*
  * External sizes of the primitive elements.
@@ -156,15 +167,9 @@
 
 /* End ncx_len */
 
-#ifdef __CHAR_UNSIGNED__
-	/* 'char' is unsigned, declare ncbyte as 'signed char' */
+#ifndef HAVE_SCHAR
 typedef signed char schar;
-
-#else
-	/* 'char' is signed */
-typedef char schar;
-
-#endif	/* __CHAR_UNSIGNED__ */
+#endif
 
 /*
  * Primitive numeric conversion functions.
diff --git a/libsrc/ncx.m4 b/libsrc/ncx.m4
index f28aa9a..9dc0edf 100644
--- a/libsrc/ncx.m4
+++ b/libsrc/ncx.m4
@@ -461,10 +461,15 @@ swap8b(void *dst, const void *src)
     op = (uint32_t*)((char*)dst+4);
     *op = SWAP4(*op);
 #else
+    uint64_t tmp = *(uint64_t*)src;
+    tmp = SWAP8(tmp);
+    memcpy(dst, &tmp, 8);
+
+    /* Codes below will cause "break strict-aliasing rules" in gcc
     uint64_t *op = (uint64_t*)dst;
-    /* copy over, make the below swap in-place */
     *op = *(uint64_t*)src;
     *op = SWAP8(*op);
+    */
 #endif
 
 #if 0
@@ -2262,6 +2267,9 @@ APIPrefix`x_get_size_t'(const void **xpp,  size_t *ulp)
 int
 APIPrefix`x_put_off_t'(void **xpp, const off_t *lp, size_t sizeof_off_t)
 {
+	/* similar to put_ix_int() */
+	uchar *cp = (uchar *) *xpp;
+
 	/* No negative offsets stored in netcdf */
 	if (*lp < 0) {
 	  /* Assume this is an overflow of a 32-bit int... */
@@ -2270,9 +2278,6 @@ APIPrefix`x_put_off_t'(void **xpp, const off_t *lp, size_t sizeof_off_t)
 
 	assert(sizeof_off_t == 4 || sizeof_off_t == 8);
 
-	/* similar to put_ix_int() */
-	uchar *cp = (uchar *) *xpp;
-
 	if (sizeof_off_t == 4) {
 		*cp++ = (uchar) ((*lp)               >> 24);
 		*cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
diff --git a/libsrc/posixio.c b/libsrc/posixio.c
index 5a7fc67..335d261 100644
--- a/libsrc/posixio.c
+++ b/libsrc/posixio.c
@@ -338,9 +338,6 @@ px_pgin(ncio *const nciop,
 {
 	int status;
 	ssize_t nread;
-    size_t read_count = 0;
-    ssize_t bytes_xfered = 0;
-    void *p = vp;
 #ifdef X_ALIGN
 	assert(offset % X_ALIGN == 0);
 	assert(extent % X_ALIGN == 0);
diff --git a/libsrc/v1hpg.c b/libsrc/v1hpg.c
index 07c322c..a691503 100644
--- a/libsrc/v1hpg.c
+++ b/libsrc/v1hpg.c
@@ -303,9 +303,12 @@ v1h_put_NC_string(v1hs *psp, const NC_string *ncstrp)
 static int
 v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp)
 {
-	int status;
-	size_t padding, nchars = 0;
-	NC_string *ncstrp;
+	int status = 0;
+	size_t nchars = 0;
+	NC_string *ncstrp = NULL;
+#if USE_STRICT_NULL_BYTE_HEADER_PADDING
+        size_t padding = 0;        
+#endif /* USE_STRICT_NULL_BYTE_HEADER_PADDING */
 
 	status = v1h_get_size_t(gsp, &nchars);
 	if(status != NC_NOERR)
@@ -333,17 +336,20 @@ v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp)
 	if(status != NC_NOERR)
 		goto unwind_alloc;
 
+#if USE_STRICT_NULL_BYTE_HEADER_PADDING
 	padding = _RNDUP(X_SIZEOF_CHAR * ncstrp->nchars, X_ALIGN)
 		- X_SIZEOF_CHAR * ncstrp->nchars;
+
 	if (padding > 0) {
 		/* CDF specification: Header padding uses null (\x00) bytes. */
 		char pad[X_ALIGN-1];
 		memset(pad, 0, X_ALIGN-1);
 		if (memcmp((char*)gsp->pos-padding, pad, padding) != 0) {
 			free_NC_string(ncstrp);
-			return NC_EINVAL;
+			return NC_ENULLPAD;
 		}
 	}
+#endif
 
 	*ncstrpp = ncstrp;
 
@@ -618,11 +624,11 @@ ncmpix_len_nctype(nc_type type) {
 static int
 v1h_put_NC_attrV(v1hs *psp, const NC_attr *attrp)
 {
-	int status;
+	int status = 0;
 	const size_t perchunk =  psp->extent;
 	size_t remaining = attrp->xsz;
 	void *value = attrp->xvalue;
-	size_t nbytes, padding;
+	size_t nbytes = 0, padding = 0;
 
 	assert(psp->extent % X_ALIGN == 0);
 
@@ -641,6 +647,7 @@ v1h_put_NC_attrV(v1hs *psp, const NC_attr *attrp)
 
 	} while(remaining != 0);
 
+
 	padding = attrp->xsz - ncmpix_len_nctype(attrp->type) * attrp->nelems;
 	if (padding > 0) {
 		/* CDF specification: Header padding uses null (\x00) bytes. */
@@ -688,7 +695,10 @@ 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, padding;
+	size_t nget;
+#if USE_STRICT_NULL_BYTE_HEADER_PADDING
+	size_t padding;
+#endif /* USE_STRICT_NULL_BYTE_HEADER_PADDING */
 
 	do {
 		nget = MIN(perchunk, remaining);
@@ -706,14 +716,16 @@ v1h_get_NC_attrV(v1hs *gsp, NC_attr *attrp)
 
 	} while(remaining != 0);
 
+#if USE_STRICT_NULL_BYTE_HEADER_PADDING
 	padding = attrp->xsz - ncmpix_len_nctype(attrp->type) * attrp->nelems;
 	if (padding > 0) {
 		/* CDF specification: Header padding uses null (\x00) bytes. */
 		char pad[X_ALIGN-1];
 		memset(pad, 0, X_ALIGN-1);
 		if (memcmp((char*)gsp->pos-padding, pad, (size_t)padding) != 0)
-			return NC_EINVAL;
+			return NC_ENULLPAD;
 	}
+#endif
 
 	return NC_NOERR;
 }
diff --git a/libsrc/var.c b/libsrc/var.c
index b6b0bb2..ca5b469 100644
--- a/libsrc/var.c
+++ b/libsrc/var.c
@@ -603,17 +603,14 @@ NC3_def_var( int ncid, const char *name, nc_type type,
 	if(status != NC_NOERR)
 		return status;
 
+        if (ndims > NC_MAX_VAR_DIMS) return NC_EMAXDIMS;
+
 		/* cast needed for braindead systems with signed size_t */
 	if((unsigned long) ndims > X_INT_MAX) /* Backward compat */
 	{
 		return NC_EINVAL;
 	}
 
-	if(ncp->vars.nelems >= NC_MAX_VARS)
-	{
-		return NC_EMAXVARS;
-	}
-
 	varid = NC_findvar(&ncp->vars, name, &varp);
 	if(varid != -1)
 	{
diff --git a/libsrc4/Makefile.am b/libsrc4/Makefile.am
index b064eb2..80bdd87 100644
--- a/libsrc4/Makefile.am
+++ b/libsrc4/Makefile.am
@@ -2,23 +2,19 @@
 # the COPYRIGHT file for more information.
 
 # This automake file generates the Makefile to build netCDF-4.
+# Ed Hartnett
 
 include $(top_srcdir)/lib_flags.am
 
 libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS}
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
-if BUILD_DLL
-libnetcdf4_la_CPPFLAGS += -DDLL_EXPORT
-endif
-
 # This is our output. The netCDF-4 convenience library.
 noinst_LTLIBRARIES = libnetcdf4.la
-libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c	\
-nc4file.c nc4grp.c nc4hdf.c nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c \
+libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c nc4file.c	\
+nc4grp.c nc4hdf.c nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c	\
 nc4info.c nc4printer.c
 
-EXTRA_DIST=CMakeLists.txt
+EXTRA_DIST = CMakeLists.txt
 
 
 
diff --git a/libsrc4/Makefile.in b/libsrc4/Makefile.in
index e34375b..d74940e 100644
--- a/libsrc4/Makefile.in
+++ b/libsrc4/Makefile.in
@@ -18,6 +18,7 @@
 # the COPYRIGHT file for more information.
 
 # This automake file generates the Makefile to build netCDF-4.
+# Ed Hartnett
 
 # This is part of the netCDF package.
 # Copyright 2005 University Corporation for Atmospheric Research/Unidata
@@ -103,12 +104,6 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_3 = -DDLL_EXPORT
 subdir = libsrc4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -203,11 +198,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -230,12 +224,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -261,6 +257,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -275,6 +272,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -378,13 +376,13 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
-libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_3)
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
+libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS}
 
 # This is our output. The netCDF-4 convenience library.
 noinst_LTLIBRARIES = libnetcdf4.la
-libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c	\
-nc4file.c nc4grp.c nc4hdf.c nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c \
+libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c nc4file.c	\
+nc4grp.c nc4hdf.c nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c	\
 nc4info.c nc4printer.c
 
 EXTRA_DIST = CMakeLists.txt
diff --git a/libsrc4/nc3stub.c b/libsrc4/nc3stub.c
deleted file mode 100644
index 15fd4cd..0000000
--- a/libsrc4/nc3stub.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * Copyright 1993-2011 University Corporation for Atmospheric
- * Research/Unidata
- * 
- */
-
-#include "config.h"
-#include <stdlib.h>
-#include "nc.h"
-
-#ifndef MPI_INCLUDED
-typedef int MPI_Comm;
-typedef int MPI_Info;
-#endif
-
-int
-nc3_create(const char *path, int cmode, size_t initialsz, int basepe,
-	   size_t *chunksizehintp,
-	   MPI_Comm comm, MPI_Info info,
-	   NC** ncp) {abort();}
-
-int
-nc3_open(const char *path, int mode, int basepe, size_t *chunksizehintp, 
-	 int use_parallel, MPI_Comm comm, MPI_Info info,
-	 NC** ncp) {abort();}
-
-int
-nc3_redef(int ncid) {abort();}
-
-int
-nc3__enddef(int ncid, size_t h_minfree, size_t v_align,
-	size_t v_minfree, size_t r_align) {abort();}
-
-int
-nc3_sync(int ncid) {abort();}
-
-int
-nc3_abort(int ncid) {abort();}
-
-int
-nc3_close(int ncid) {abort();}
-
-int
-nc3_set_fill(int ncid, int fillmode, int *old_modep) {abort();}
-
-int
-nc3_set_base_pe(int ncid, int pe) {abort();}
-
-int
-nc3_inq_base_pe(int ncid, int *pe) {abort();}
-
-int
-nc3_inq_format(int ncid, int *formatp) {abort();}
-
-int
-nc3_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp) {abort();}
-
-int
-nc3_inq_type(int ncid, nc_type xtype,char* name,size_t* sizep) {abort();}
-
-/* Begin _dim */
-
-int
-nc3_def_dim(int ncid, const char *name, size_t len, int *idp) {abort();}
-
-int
-nc3_inq_dimid(int ncid, const char *name, int *idp) {abort();}
-
-int
-nc3_inq_dim(int ncid, int dimid, char *name, size_t *lenp) {abort();}
-
-int
-nc3_rename_dim(int ncid, int dimid, const char *name) {abort();}
-
-/* End _dim */
-/* Begin _att */
-
-int
-nc3_inq_att(int ncid, int varid, const char *name,
-	 nc_type *xtypep, size_t *lenp) {abort();}
-
-int 
-nc3_inq_attid(int ncid, int varid, const char *name, int *idp) {abort();}
-
-int
-nc3_inq_attname(int ncid, int varid, int attnum, char *name) {abort();}
-
-int
-nc3_rename_att(int ncid, int varid, const char *name, const char *newname) {abort();}
-
-int
-nc3_del_att(int ncid, int varid, const char* name) {abort();}
-
-/* End _att */
-/* Begin {put,get}_att */
-
-int
-nc3_get_att(int ncid, int varid, const char *name, void *value, nc_type xtype) {abort();}
-
-int
-nc3_put_att(int ncid, int varid, const char *name, nc_type datatype,
-	   size_t len, const void *value, nc_type xtype) {abort();}
-
-/* End {put,get}_att */
-/* Begin _var */
-
-int
-nc3_def_var(int ncid, const char *name,
-	 nc_type xtype, int ndims, const int *dimidsp, int *varidp) {abort();}
-
-int
-nc3_inq_var(int ncid, int varid, char *name,
-	 nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp) {abort();}
-
-int
-nc3_inq_varid(int ncid, const char *name, int *varidp) {abort();}
-
-int
-nc3_rename_var(int ncid, int varid, const char *name) {abort();}
-
-int
-nc3_put_vara(int ncid, int varid,
-   	     const size_t *start, const size_t *count,
-             const void *value, nc_type xtype) {abort();}
-
-int
-nc3_get_vara(int ncid, int varid,
-	     const size_t *start, const size_t *count,
-             void *value, nc_type xtype) {abort();}
-
-int
-nc3_put_var(int ncid, int varid,  const void *op) {abort();}
-
-int
-nc3_get_var(int ncid, int varid,  void *ip) {abort();}
-
-int
-nc3_put_var1(int ncid, int varid,  const size_t *indexp,
-	    const void *op) {abort();}
-
-int
-nc3_get_var1(int ncid, int varid,  const size_t *indexp, void *ip) {abort();}
-
-int
-nc3_put_vars(int ncid, int varid,  const size_t *startp, 
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    const void *op) {abort();}
-
-int
-nc3_get_vars(int ncid, int varid,  const size_t *startp, 
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    void *ip) {abort();}
-
-int
-nc3_put_varm(int ncid, int varid,  const size_t *startp, 
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    const ptrdiff_t *imapp, const void *op) {abort();}
-
-int
-nc3_get_varm(int ncid, int varid,  const size_t *startp, 
-	    const size_t *countp, const ptrdiff_t *stridep,
-	    const ptrdiff_t *imapp, void *ip) {abort();}
-
-/* End _var */
-
-/* netCDF4 API only */
-int
-nc3_var_par_access(int ncid,int varid,int pint) {abort();}
-
-int
-nc3_inq_ncid(int ncid,const char* pnm,int* pintp) {abort();}
-
-int
-nc3_inq_grps(int ncid,int* pintp,int* pintp2) {abort();}
-
-int
-nc3_inq_grpname(int ncid,char* pcharp) {abort();}
-
-int
-nc3_inq_grpname_full(int ncid,size_t* psize_tp,char* pcharp) {abort();}
-
-int
-nc3_inq_grp_parent(int ncid,int* pintp) {abort();}
-
-int
-nc3_inq_grp_full_ncid(int ncid,const char* pnm,int* pintp) {abort();}
-
-int
-nc3_inq_varids(int ncid,int* nvars,int* pintp) {abort();}
-
-int
-nc3_inq_dimids(int ncid,int* ndims,int* pintp,int pint) {abort();}
-
-int
-nc3_inq_typeids(int ncid,int* ntypes,int* pintp) {abort();}
-
-int
-nc3_inq_type_equal(int ncid,nc_type pnc_type,int pint,nc_type pnc_type2,int* pintp) {abort();}
-
-int
-nc3_def_grp(int ncid,const char* pnm,int* pintp) {abort();}
-
-int
-nc3_inq_user_type(int ncid,nc_type pnc_type,char* pnm,size_t* psize_tp,nc_type* pnc_typep,size_t* psize_tp2,int* pintp) {abort();}
-
-
-int
-nc3_def_compound(int ncid,size_t psize_t,const char* pnm,nc_type* pnc_typep) {abort();}
-
-int
-nc3_insert_compound(int ncid,nc_type pnc_type,const char* pnm,size_t psize_t,nc_type pnc_type2) {abort();}
-
-int
-nc3_insert_array_compound(int ncid,nc_type pnc_type,const char* pnm,size_t psize_t,nc_type pnc_type2,int pint,const int* pintp) {abort();}
-
-int
-nc3_inq_typeid(int ncid,const char* pnm,nc_type* pnc_typep) {abort();}
-
-int
-nc3_inq_compound_field(int ncid,nc_type pnc_type,int pint,char* pnm,size_t* psize_tp,nc_type* pnc_typep,int* pintp,int* pintp2) {abort();}
-
-int
-nc3_inq_compound_fieldindex(int ncid,nc_type pnc_type,const char* pnm,int* pintp) {abort();}
-
-int
-nc3_def_vlen(int ncid,const char* pnm,nc_type base_typeid,nc_type* pnc_typep) {abort();}
-
-int
-nc3_put_vlen_element(int ncid,int varid,void* pvoidp,size_t psize_t,const void* voidp) {abort();}
-
-int
-nc3_get_vlen_element(int ncid,int varid,const void* pvoidp,size_t* psize_tp,void* pvoidp2) {abort();}
-
-int
-nc3_def_enum(int ncid,nc_type pnc_type,const char* pnm,nc_type* pnc_typep) {abort();}
-
-int
-nc3_insert_enum(int ncid,nc_type pnc_type,const char* pnm,const void* voidp) {abort();}
-
-int
-nc3_inq_enum_member(int ncid,nc_type pnc_type,int pint,char* pnm,void* pvoidp) {abort();}
-
-int
-nc3_inq_enum_ident(int ncid,nc_type pnc_type,long long plonglong,char* pcharp) {abort();}
-
-int
-nc3_def_opaque(int ncid,size_t psize_t,const char* pnm,nc_type* pnc_typep) {abort();}
-
-int
-nc3_def_var_deflate(int ncid,int varid,int pint,int pint2,int pint3) {abort();}
-
-int
-nc3_inq_var_deflate(int ncid,int varid,int* pintp,int* pintp2,int* pintp3) {abort();}
-
-int
-nc3_inq_var_szip(int ncid,int varid,int* pintp,int* pintp2) {abort();}
-
-int
-nc3_def_var_fletcher32(int ncid,int varid,int pint) {abort();}
-
-int
-nc3_inq_var_fletcher32(int ncid,int varid,int* pintp) {abort();}
-
-int
-nc3_def_var_chunking(int ncid,int varid,int pint,const size_t* size_tp) {abort();}
-
-int
-nc3_inq_var_chunking(int ncid,int varid,int* pintp,size_t* psize_tp) {abort();}
-
-int
-nc3_def_var_fill(int ncid,int varid,int pint,const void* pvoidp) {abort();}
-
-int
-nc3_inq_var_fill(int ncid,int varid,int* pintp,void* pvoidp) {abort();}
-
-int
-nc3_def_var_endian(int ncid,int varid,int pint) {abort();}
-
-int
-nc3_inq_var_endian(int ncid,int varid,int* pintp) {abort();}
-
-int
-nc3_set_var_chunk_cache(int ncid,int varid,size_t psize_t,size_t psize_t2,float pfloat) {abort();}
-
-int
-nc3_get_var_chunk_cache(int ncid,int varid,size_t* psize_tp,size_t* psize_tp2, size_t* psize_tp3, float* pfloatp) {abort();}
-
-int
-nc3_inq_unlimdims(int ncid ,int* nump,int* dimsp) {abort();}
-
-int 
-nc3_inq_unlimdim(int ncid, int *unlimdimidp) {abort();}
-
-int
-nc3_show_metadata(int ncid) {abort();}
-
-int
-nc3_put_att_text(int ncid, int varid, const char *name,
-		size_t len, const char *op) {abort();}
-
-int
-nc3_get_att_text(int ncid, int varid, const char *name, char *ip) {abort();}
-
-int
-nc3_put_att_uchar(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const unsigned char *op) {abort();}
-
-int
-nc3_get_att_uchar(int ncid, int varid, const char *name, unsigned char *ip) {abort();}
-
-int
-nc3_put_att_schar(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const signed char *op) {abort();}
-
-int
-nc3_get_att_schar(int ncid, int varid, const char *name, signed char *ip) {abort();}
-
-int
-nc3_put_att_short(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const short *op) {abort();}
-
-int
-nc3_get_att_short(int ncid, int varid, const char *name, short *ip) {abort();}
-
-int
-nc3_put_att_int(int ncid, int varid, const char *name, nc_type xtype,
-	       size_t len, const int *op) {abort();}
-
-int
-nc3_get_att_int(int ncid, int varid, const char *name, int *ip) {abort();}
-
-int
-nc3_put_att_long(int ncid, int varid, const char *name, nc_type xtype,
-		size_t len, const long *op) {abort();}
-
-int
-nc3_get_att_long(int ncid, int varid, const char *name, long *ip) {abort();}
-
-int
-nc3_put_att_float(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const float *op) {abort();}
-
-int
-nc3_get_att_float(int ncid, int varid, const char *name, float *ip) {abort();}
-
-int
-nc3_put_att_double(int ncid, int varid, const char *name, nc_type xtype,
-		  size_t len, const double *op) {abort();}
-
-int
-nc3_get_att_double(int ncid, int varid, const char *name, double *ip) {abort();}
-
-int
-nc3_put_att_ubyte(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const unsigned char *op) {abort();}
-
-int
-nc3_get_att_ubyte(int ncid, int varid, const char *name, 
-		 unsigned char *ip) {abort();}
-
-int
-nc3_put_att_ushort(int ncid, int varid, const char *name, nc_type xtype,
-		  size_t len, const unsigned short *op) {abort();}
-
-int
-nc3_get_att_ushort(int ncid, int varid, const char *name, unsigned short *ip) {abort();}
-
-int
-nc3_put_att_uint(int ncid, int varid, const char *name, nc_type xtype,
-		size_t len, const unsigned int *op) {abort();}
-
-int
-nc3_get_att_uint(int ncid, int varid, const char *name, unsigned int *ip) {abort();}
-
-int
-nc3_put_att_longlong(int ncid, int varid, const char *name, nc_type xtype,
-		 size_t len, const long long *op) {abort();}
-
-int
-nc3_get_att_longlong(int ncid, int varid, const char *name, long long *ip) {abort();}
-
-int
-nc3_put_att_ulonglong(int ncid, int varid, const char *name, nc_type xtype,
-		     size_t len, const unsigned long long *op) {abort();}
-
-int
-nc3_get_att_ulonglong(int ncid, int varid, const char *name, 
-		     unsigned long long *ip) {abort();}
-
-int
-nc3_put_att_string(int ncid, int varid, const char *name, 
-		  size_t len, const char **op) {abort();}
-
-int
-nc3_get_att_string(int ncid, int varid, const char *name, char **ip) {abort();}
-
-
-int
-nc3_put_var1_text(int ncid, int varid, const size_t *indexp, const char *op) {abort();}
-
-int
-nc3_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip) {abort();}
-
-int
-nc3_put_var1_uchar(int ncid, int varid, const size_t *indexp,
-		  const unsigned char *op) {abort();}
-
-int
-nc3_get_var1_uchar(int ncid, int varid, const size_t *indexp,
-		  unsigned char *ip) {abort();}
-
-int
-nc3_put_var1_schar(int ncid, int varid, const size_t *indexp,
-		  const signed char *op) {abort();}
-
-int
-nc3_get_var1_schar(int ncid, int varid, const size_t *indexp,
-		  signed char *ip) {abort();}
-
-int
-nc3_put_var1_short(int ncid, int varid, const size_t *indexp,
-		  const short *op) {abort();}
-
-int
-nc3_get_var1_short(int ncid, int varid, const size_t *indexp,
-		  short *ip) {abort();}
-
-int
-nc3_put_var1_int(int ncid, int varid, const size_t *indexp, const int *op) {abort();}
-
-int
-nc3_get_var1_int(int ncid, int varid, const size_t *indexp, int *ip) {abort();}
-
-int
-nc3_put_var1_long(int ncid, int varid, const size_t *indexp, const long *op) {abort();}
-
-int
-nc3_get_var1_long(int ncid, int varid, const size_t *indexp, long *ip) {abort();}
-
-int
-nc3_put_var1_float(int ncid, int varid, const size_t *indexp, const float *op) {abort();}
-
-int
-nc3_get_var1_float(int ncid, int varid, const size_t *indexp, float *ip) {abort();}
-
-int
-nc3_put_var1_double(int ncid, int varid, const size_t *indexp, const double *op) {abort();}
-
-int
-nc3_get_var1_double(int ncid, int varid, const size_t *indexp, double *ip) {abort();}
-
-int
-nc3_put_var1_ubyte(int ncid, int varid, const size_t *indexp, 
-		  const unsigned char *op) {abort();}
-
-int
-nc3_get_var1_ubyte(int ncid, int varid, const size_t *indexp, 
-		  unsigned char *ip) {abort();}
-
-int
-nc3_put_var1_ushort(int ncid, int varid, const size_t *indexp, 
-		   const unsigned short *op) {abort();}
-
-int
-nc3_get_var1_ushort(int ncid, int varid, const size_t *indexp, 
-		   unsigned short *ip) {abort();}
-
-int
-nc3_put_var1_uint(int ncid, int varid, const size_t *indexp, 
-		 const unsigned int *op) {abort();}
-
-int
-nc3_get_var1_uint(int ncid, int varid, const size_t *indexp, 
-		 unsigned int *ip) {abort();}
-
-int
-nc3_put_var1_longlong(int ncid, int varid, const size_t *indexp, 
-		     const long long *op) {abort();}
-
-int
-nc3_get_var1_longlong(int ncid, int varid, const size_t *indexp, 
-		  long long *ip) {abort();}
-
-int
-nc3_put_var1_ulonglong(int ncid, int varid, const size_t *indexp, 
-		   const unsigned long long *op) {abort();}
-
-int
-nc3_get_var1_ulonglong(int ncid, int varid, const size_t *indexp, 
-		   unsigned long long *ip) {abort();}
-
-int
-nc3_put_var1_string(int ncid, int varid, const size_t *indexp, 
-		   const char **op) {abort();}
-
-int
-nc3_get_var1_string(int ncid, int varid, const size_t *indexp, 
-		   char **ip) {abort();}
-
-/* End {put,get}_var1 */
-/* Begin {put,get}_vara */
-
-int
-nc3_put_vara_text(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const char *op) {abort();}
-
-int
-nc3_get_vara_text(int ncid, int varid,
-	const size_t *startp, const size_t *countp, char *ip) {abort();}
-
-int
-nc3_put_vara_uchar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const unsigned char *op) {abort();}
-
-int
-nc3_get_vara_uchar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, unsigned char *ip) {abort();}
-
-int
-nc3_put_vara_schar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const signed char *op) {abort();}
-
-int
-nc3_get_vara_schar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, signed char *ip) {abort();}
-
-int
-nc3_put_vara_short(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const short *op) {abort();}
-
-int
-nc3_get_vara_short(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, short *ip) {abort();}
-
-int
-nc3_put_vara_int(int ncid, int varid, const size_t *startp, 
-		const size_t *countp, const int *op) {abort();}
-
-int
-nc3_get_vara_int(int ncid, int varid, const size_t *startp, 
-		const size_t *countp, int *ip) {abort();}
-
-int
-nc3_put_vara_long(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const long *op) {abort();}
-
-int
-nc3_get_vara_long(int ncid, int varid,
-	const size_t *startp, const size_t *countp, long *ip) {abort();}
-
-int
-nc3_put_vara_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const float *op) {abort();}
-
-int
-nc3_get_vara_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, float *ip) {abort();}
-
-int
-nc3_put_vara_double(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const double *op) {abort();}
-
-int
-nc3_get_vara_double(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, double *ip) {abort();}
-
-int
-nc3_put_vara_ubyte(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const unsigned char *op) {abort();}
-
-int
-nc3_get_vara_ubyte(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, unsigned char *ip) {abort();}
-
-int
-nc3_put_vara_ushort(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const unsigned short *op) {abort();}
-
-int
-nc3_get_vara_ushort(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, unsigned short *ip) {abort();}
-
-int
-nc3_put_vara_uint(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const unsigned int *op) {abort();}
-
-int
-nc3_get_vara_uint(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, unsigned int *ip) {abort();}
-
-int
-nc3_put_vara_longlong(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const long long *op) {abort();}
-
-int
-nc3_get_vara_longlong(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, long long *ip) {abort();}
-
-int
-nc3_put_vara_ulonglong(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const unsigned long long *op) {abort();}
-
-int
-nc3_get_vara_ulonglong(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, unsigned long long *ip) {abort();}
-
-int
-nc3_put_vara_string(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const char **op) {abort();}
-
-int
-nc3_get_vara_string(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, char **ip) {abort();}
-
-/* End {put,get}_vara */
-/* Begin {put,get}_vars */
-
-int
-nc3_put_vars_text(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const char *op) {abort();}
-
-int
-nc3_get_vars_text(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	char *ip) {abort();}
-
-int
-nc3_put_vars_uchar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const unsigned char *op) {abort();}
-
-int
-nc3_get_vars_uchar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	unsigned char *ip) {abort();}
-
-int
-nc3_put_vars_schar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const signed char *op) {abort();}
-
-int
-nc3_get_vars_schar(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	signed char *ip) {abort();}
-
-int
-nc3_put_vars_short(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const short *op) {abort();}
-
-int
-nc3_get_vars_short(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  short *ip) {abort();}
-
-int
-nc3_put_vars_int(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const int *op) {abort();}
-
-int
-nc3_get_vars_int(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	int *ip) {abort();}
-
-int
-nc3_put_vars_long(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const long *op) {abort();}
-
-int
-nc3_get_vars_long(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	long *ip) {abort();}
-
-int
-nc3_put_vars_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const float *op) {abort();}
-
-int
-nc3_get_vars_float(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	float *ip) {abort();}
-
-int
-nc3_put_vars_double(int ncid, int varid,
-	const size_t *startp, const size_t *countp, const ptrdiff_t *stridep,
-	const double *op) {abort();}
-
-int
-nc3_get_vars_double(int ncid, int varid,	const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   double *ip) {abort();}
-
-int
-nc3_put_vars_ubyte(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  const unsigned char *op) {abort();}
-
-int
-nc3_get_vars_ubyte(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  unsigned char *ip) {abort();}
-
-int
-nc3_put_vars_ushort(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const unsigned short *op) {abort();}
-
-int
-nc3_get_vars_ushort(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   unsigned short *ip) {abort();}
-
-int
-nc3_put_vars_uint(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep, 
-		 const unsigned int *op) {abort();}
-
-int
-nc3_get_vars_uint(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep, 
-		 unsigned int *ip) {abort();}
-
-int
-nc3_put_vars_longlong(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  const long long *op) {abort();}
-
-int
-nc3_get_vars_longlong(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  long long *ip) {abort();}
-
-int
-nc3_put_vars_ulonglong(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const unsigned long long *op) {abort();}
-
-int
-nc3_get_vars_ulonglong(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   unsigned long long *ip) {abort();}
-
-int
-nc3_put_vars_string(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const char **op) {abort();}
-
-int
-nc3_get_vars_string(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   char **ip) {abort();}
-
-/* End {put,get}_vars */
-/* Begin {put,get}_varm */
-
-int
-nc3_put_varm_text(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, const char *op) {abort();}
-
-int
-nc3_get_varm_text(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, char *ip) {abort();}
-
-int
-nc3_put_varm_uchar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const unsigned char *op) {abort();}
-
-int
-nc3_get_varm_uchar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, unsigned char *ip) {abort();}
-
-int
-nc3_put_varm_schar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const signed char *op) {abort();}
-
-int
-nc3_get_varm_schar(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, signed char *ip) {abort();}
-
-int
-nc3_put_varm_short(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const short *op) {abort();}
-
-int
-nc3_get_varm_short(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, short *ip) {abort();}
-
-int
-nc3_put_varm_int(int ncid, int varid, const size_t *startp, 
-		const size_t *countp, const ptrdiff_t *stridep,
-		const ptrdiff_t *imapp, const int *op) {abort();}
-
-int
-nc3_get_varm_int(int ncid, int varid, const size_t *startp, 
-		const size_t *countp, const ptrdiff_t *stridep,
-		const ptrdiff_t *imapp, int *ip) {abort();}
-
-int
-nc3_put_varm_long(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, const long *op) {abort();}
-
-int
-nc3_get_varm_long(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep,
-		 const ptrdiff_t *imapp, long *ip) {abort();}
-
-int
-nc3_put_varm_float(int ncid, int varid,const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, const float *op) {abort();}
-
-int
-nc3_get_varm_float(int ncid, int varid,const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep,
-		  const ptrdiff_t *imapp, float *ip) {abort();}
-
-int
-nc3_put_varm_double(int ncid, int varid,	const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t *imapp, const double *op) {abort();}
-
-int
-nc3_get_varm_double(int ncid, int varid,	const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep,
-		   const ptrdiff_t * imapp, double *ip) {abort();}
-
-int
-nc3_put_varm_ubyte(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  const ptrdiff_t * imapp, const unsigned char *op) {abort();}
-
-int
-nc3_get_varm_ubyte(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  const ptrdiff_t * imapp, unsigned char *ip) {abort();}
-
-int
-nc3_put_varm_ushort(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const ptrdiff_t * imapp, const unsigned short *op) {abort();}
-
-int
-nc3_get_varm_ushort(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const ptrdiff_t * imapp, unsigned short *ip) {abort();}
-
-int
-nc3_put_varm_uint(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep, 
-		 const ptrdiff_t * imapp, const unsigned int *op) {abort();}
-
-int
-nc3_get_varm_uint(int ncid, int varid, const size_t *startp, 
-		 const size_t *countp, const ptrdiff_t *stridep, 
-		 const ptrdiff_t * imapp, unsigned int *ip) {abort();}
-
-int
-nc3_put_varm_longlong(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  const ptrdiff_t * imapp, const long long *op) {abort();}
-
-int
-nc3_get_varm_longlong(int ncid, int varid, const size_t *startp, 
-		  const size_t *countp, const ptrdiff_t *stridep, 
-		  const ptrdiff_t * imapp, long long *ip) {abort();}
-
-int
-nc3_put_varm_ulonglong(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const ptrdiff_t * imapp, const unsigned long long *op) {abort();}
-
-int
-nc3_get_varm_ulonglong(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const ptrdiff_t * imapp, unsigned long long *ip) {abort();}
-
-int
-nc3_put_varm_string(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const ptrdiff_t * imapp, const char **op) {abort();}
-
-int
-nc3_get_varm_string(int ncid, int varid, const size_t *startp, 
-		   const size_t *countp, const ptrdiff_t *stridep, 
-		   const ptrdiff_t * imapp, char **ip) {abort();}
-
-/* End {put,get}_varm */
-/* Begin {put,get}_var */
-
-int
-nc3_put_var_text(int ncid, int varid, const char *op) {abort();}
-
-int
-nc3_get_var_text(int ncid, int varid, char *ip) {abort();}
-
-int
-nc3_put_var_uchar(int ncid, int varid, const unsigned char *op) {abort();}
-
-int
-nc3_get_var_uchar(int ncid, int varid, unsigned char *ip) {abort();}
-
-int
-nc3_put_var_schar(int ncid, int varid, const signed char *op) {abort();}
-
-int
-nc3_get_var_schar(int ncid, int varid, signed char *ip) {abort();}
-
-int
-nc3_put_var_short(int ncid, int varid, const short *op) {abort();}
-
-int
-nc3_get_var_short(int ncid, int varid, short *ip) {abort();}
-
-int
-nc3_put_var_int(int ncid, int varid, const int *op) {abort();}
-
-int
-nc3_get_var_int(int ncid, int varid, int *ip) {abort();}
-
-int
-nc3_put_var_long(int ncid, int varid, const long *op) {abort();}
-
-int
-nc3_get_var_long(int ncid, int varid, long *ip) {abort();}
-
-int
-nc3_put_var_float(int ncid, int varid, const float *op) {abort();}
-
-int
-nc3_get_var_float(int ncid, int varid, float *ip) {abort();}
-
-int
-nc3_put_var_double(int ncid, int varid, const double *op) {abort();}
-
-int
-nc3_get_var_double(int ncid, int varid, double *ip) {abort();}
-
-int
-nc3_put_var_ubyte(int ncid, int varid, const unsigned char *op) {abort();}
-
-int
-nc3_get_var_ubyte(int ncid, int varid, unsigned char *ip) {abort();}
-
-int
-nc3_put_var_ushort(int ncid, int varid, const unsigned short *op) {abort();}
-
-int
-nc3_get_var_ushort(int ncid, int varid, unsigned short *ip) {abort();}
-
-int
-nc3_put_var_uint(int ncid, int varid, const unsigned int *op) {abort();}
-
-int
-nc3_get_var_uint(int ncid, int varid, unsigned int *ip) {abort();}
-
-int
-nc3_put_var_longlong(int ncid, int varid, const long long *op) {abort();}
-
-int
-nc3_get_var_longlong(int ncid, int varid, long long *ip) {abort();}
-
-int
-nc3_put_var_ulonglong(int ncid, int varid, const unsigned long long *op) {abort();}
-
-int
-nc3_get_var_ulonglong(int ncid, int varid, unsigned long long *ip) {abort();}
-
-int
-nc3_put_var_string(int ncid, int varid, const char **op) {abort();}
-
-int
-nc3_get_var_string(int ncid, int varid, char **ip) {abort();}
-
-int
-nc3__create_mp(const char *path, int cmode, size_t initialsz, int basepe,
-	 size_t *chunksizehintp, int *ncidp) {abort();}
-
-int
-nc3__open_mp(const char *path, int mode, int basepe,
-	size_t *chunksizehintp, int *ncidp) {abort();}
-
-int
-nc3_enddef(int ncid) {abort();}
diff --git a/libsrc4/nc4attr.c b/libsrc4/nc4attr.c
index 3648d15..ea7ba0f 100644
--- a/libsrc4/nc4attr.c
+++ b/libsrc4/nc4attr.c
@@ -1,34 +1,121 @@
-/*
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-HDF5 backend for netCDF, depending on your point of view.
-
-This file handles the nc4 attribute functions.
-
-Remember that with atts, type conversion can take place when writing
-them, and when reading them.
-
-Copyright 2003-2011, University Corporation for Atmospheric
-Research. See COPYRIGHT file for copying and redistribution
-conditions.
-*/
-
+/**
+ * @file
+ *
+ * @internal This file is part of netcdf-4, a netCDF-like interface
+ * for HDF5, or a HDF5 backend for netCDF, depending on your point of
+ * view.
+ *
+ * This file handles the nc4 attribute functions.
+ *
+ * Remember that with atts, type conversion can take place when
+ * writing them, and when reading them.
+ *
+ * Copyright 2003-2011, University Corporation for Atmospheric
+ * Research. See COPYRIGHT file for copying and redistribution
+ * conditions.
+ *
+ * @author Ed Hartnett
+ */
 #include "nc4internal.h"
 #include "nc.h"
 #include "nc4dispatch.h"
 #include "ncdispatch.h"
 
-static int nc4_get_att_special(NC_HDF5_FILE_INFO_T*, const char*,
-                               nc_type*, nc_type, size_t*, int*, int, void*);
-
 int nc4typelen(nc_type type);
 
-/* Get or put attribute metadata from our linked list of file
-   info. Always locate the attribute by name, never by attnum.
-   The mem_type is ignored if data=NULL. */
+/**
+ * @internal Get special informatation about the attrobute.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param name Name of attribute.
+ * @param filetypep Pointer that gets type of the attribute data in
+ * file.
+ * @param mem_type Type of attribute data in memory.
+ * @param lenp Pointer that gets length of attribute array.
+ * @param attnump Pointer that gets the attribute number.
+ * @param is_long True if attribute data is of type NC_LONG.
+ * @param data Attribute data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Dennis Heimbigner
+ */
+static int
+nc4_get_att_special(NC_HDF5_FILE_INFO_T* h5, const char* name,
+                    nc_type* filetypep, nc_type mem_type, size_t* lenp,
+                    int* attnump, int is_long, void* data)
+{
+   /* Fail if asking for att id */
+   if(attnump)
+      return NC_EATTMETA;
+
+   if(strcmp(name,NCPROPS)==0) {
+      char* propdata = NULL;
+      int stat = NC_NOERR;
+      int len;
+      if(h5->fileinfo->propattr.version == 0)
+         return NC_ENOTATT;
+      if(mem_type == NC_NAT) mem_type = NC_CHAR;
+      if(mem_type != NC_CHAR)
+         return NC_ECHAR;
+      if(filetypep) *filetypep = NC_CHAR;
+      stat = NC4_buildpropinfo(&h5->fileinfo->propattr, &propdata);
+      if(stat != NC_NOERR) return stat;
+      len = strlen(propdata);
+      if(lenp) *lenp = len;
+      if(data) strncpy((char*)data,propdata,len+1);
+      free(propdata);
+   } else if(strcmp(name,ISNETCDF4ATT)==0
+             || strcmp(name,SUPERBLOCKATT)==0) {
+      unsigned long long iv = 0;
+      if(filetypep) *filetypep = NC_INT;
+      if(lenp) *lenp = 1;
+      if(strcmp(name,SUPERBLOCKATT)==0)
+         iv = (unsigned long long)h5->fileinfo->superblockversion;
+      else /* strcmp(name,ISNETCDF4ATT)==0 */
+         iv = NC4_isnetcdf4(h5);
+      if(mem_type == NC_NAT) mem_type = NC_INT;
+      if(data)
+         switch (mem_type) {
+         case NC_BYTE: *((char*)data) = (char)iv; break;
+         case NC_SHORT: *((short*)data) = (short)iv; break;
+         case NC_INT: *((int*)data) = (int)iv; break;
+         case NC_UBYTE: *((unsigned char*)data) = (unsigned char)iv; break;
+         case NC_USHORT: *((unsigned short*)data) = (unsigned short)iv; break;
+         case NC_UINT: *((unsigned int*)data) = (unsigned int)iv; break;
+         case NC_INT64: *((long long*)data) = (long long)iv; break;
+         case NC_UINT64: *((unsigned long long*)data) = (unsigned long long)iv; break;
+         default:
+            return NC_ERANGE;
+         }
+   }
+   return NC_NOERR;
+}
+
+/**
+ * @internal Get or put attribute metadata from our linked list of
+ * file info. Always locate the attribute by name, never by attnum.
+ * The mem_type is ignored if data=NULL.
+ *
+ * @param ncid File and group ID.
+ * @param nc Pointer to file's NC struct.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param xtype Pointer that gets (file) type of attribute.
+ * @param mem_type The type of attribute data in memory.
+ * @param lenp Pointer that gets length of attribute array.
+ * @param attnum Pointer that gets the index number of this attribute.
+ * @param is_long True only if the type is NC_LONG.
+ * @param data Pointer that gets attribute data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
-nc4_get_att(int ncid, NC *nc, int varid, const char *name,
-	    nc_type *xtype, nc_type mem_type, size_t *lenp,
-	    int *attnum, int is_long, void *data)
+nc4_get_att(int ncid, NC *nc, int varid, const char *name, nc_type *xtype,
+            nc_type mem_type, size_t *lenp, int *attnum, int is_long,
+            void *data)
 {
    NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
@@ -48,7 +135,7 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
    }
 
    LOG((3, "%s: ncid 0x%x varid %d name %s attnum %d mem_type %d",
-	__func__, ncid, varid, name, my_attnum, mem_type));
+        __func__, ncid, varid, name, my_attnum, mem_type));
 
    /* Find info for this file and group, and set pointer to each. */
    h5 = NC4_DATA(nc);
@@ -57,37 +144,37 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
 
    /* Check varid */
    if (varid != NC_GLOBAL) {
-       if (varid < 0 || varid >= grp->vars.nelems)
-	   return NC_ENOTVAR;
-       if (grp->vars.value[varid] == NULL)
-           return NC_ENOTVAR;
-       assert(grp->vars.value[varid]->varid == varid);
+      if (varid < 0 || varid >= grp->vars.nelems)
+         return NC_ENOTVAR;
+      if (grp->vars.value[varid] == NULL)
+         return NC_ENOTVAR;
+      assert(grp->vars.value[varid]->varid == varid);
    }
 
    if (name == NULL)
-       BAIL(NC_EBADNAME);
+      BAIL(NC_EBADNAME);
 
    /* Normalize name. */
    if ((retval = nc4_normalize_name(name, norm_name)))
       BAIL(retval);
 
    if(nc->ext_ncid == ncid && varid == NC_GLOBAL) {
-	const char** sp;
-	for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
-	    if(strcmp(name,*sp)==0) {
-		return nc4_get_att_special(h5, norm_name, xtype, mem_type, lenp, attnum, is_long, data);
-	    }
-	}
-    }
+      const char** sp;
+      for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
+         if(strcmp(name,*sp)==0) {
+            return nc4_get_att_special(h5, norm_name, xtype, mem_type, lenp, attnum, is_long, data);
+         }
+      }
+   }
 
    /* Find the attribute, if it exists.
       <strike>If we don't find it, we are major failures.</strike>
    */
    if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att))) {
-     if(retval == NC_ENOTATT)
-	return retval;
-     else
-      BAIL(retval);
+      if(retval == NC_ENOTATT)
+         return retval;
+      else
+         BAIL(retval);
    }
 
    /* If mem_type is NC_NAT, it means we want to use the attribute's
@@ -101,7 +188,7 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
     * Send him an NC_ECHAR error...*/
    if (data && att->len &&
        ((att->nc_typeid == NC_CHAR && mem_type != NC_CHAR) ||
-	(att->nc_typeid != NC_CHAR && mem_type == NC_CHAR)))
+        (att->nc_typeid != NC_CHAR && mem_type == NC_CHAR)))
       BAIL(NC_ECHAR); /* take that, you freak! */
 
    /* Copy the info. */
@@ -127,23 +214,23 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
    if (data && att->len && mem_type != att->nc_typeid &&
        mem_type != NC_NAT &&
        !(mem_type == NC_CHAR &&
-	 (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE)))
+         (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE)))
    {
       if (!(bufr = malloc((size_t)(att->len * type_size))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
       need_to_convert++;
       if ((retval = nc4_convert_type(att->data, bufr, att->nc_typeid,
-				     mem_type, (size_t)att->len, &range_error,
-				     NULL, (h5->cmode & NC_CLASSIC_MODEL), 0, is_long)))
-	 BAIL(retval);
+                                     mem_type, (size_t)att->len, &range_error,
+                                     NULL, (h5->cmode & NC_CLASSIC_MODEL), 0, is_long)))
+         BAIL(retval);
 
       /* For strict netcdf-3 rules, ignore erange errors between UBYTE
        * and BYTE types. */
       if ((h5->cmode & NC_CLASSIC_MODEL) &&
-	  (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE) &&
-	  (mem_type == NC_UBYTE || mem_type == NC_BYTE) &&
-	  range_error)
-	 range_error = 0;
+          (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE) &&
+          (mem_type == NC_UBYTE || mem_type == NC_BYTE) &&
+          range_error)
+         range_error = 0;
    }
    else
    {
@@ -158,57 +245,57 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
    {
       if (att->vldata)
       {
-	 size_t base_typelen;
-	 hvl_t *vldest = data;
-	 NC_TYPE_INFO_T *type;
+         size_t base_typelen;
+         hvl_t *vldest = data;
+         NC_TYPE_INFO_T *type;
 
          /* Get the type object for the attribute's type */
-	 if ((retval = nc4_find_type(h5, att->nc_typeid, &type)))
-	   BAIL(retval);
+         if ((retval = nc4_find_type(h5, att->nc_typeid, &type)))
+            BAIL(retval);
 
          /* Retrieve the size of the base type */
          if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
             BAIL(retval);
 
-	 for (i = 0; i < att->len; i++)
-	 {
-	    vldest[i].len = att->vldata[i].len;
-	    if (!(vldest[i].p = malloc(vldest[i].len * base_typelen)))
-	       BAIL(NC_ENOMEM);
-	    memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen);
-	 }
+         for (i = 0; i < att->len; i++)
+         {
+            vldest[i].len = att->vldata[i].len;
+            if (!(vldest[i].p = malloc(vldest[i].len * base_typelen)))
+               BAIL(NC_ENOMEM);
+            memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen);
+         }
       }
       else if (att->stdata)
       {
-	 for (i = 0; i < att->len; i++)
-	 {
+         for (i = 0; i < att->len; i++)
+         {
             /* Check for NULL pointer for string (valid in HDF5) */
             if(att->stdata[i])
             {
-                if (!(((char **)data)[i] = strdup(att->stdata[i])))
-                   BAIL(NC_ENOMEM);
+               if (!(((char **)data)[i] = strdup(att->stdata[i])))
+                  BAIL(NC_ENOMEM);
             }
             else
-                ((char **)data)[i] = att->stdata[i];
-	 }
+               ((char **)data)[i] = att->stdata[i];
+         }
       }
       else
       {
-	 /* For long types, we need to handle this special... */
-	 if (is_long && att->nc_typeid == NC_INT)
-	 {
-	    long *lp = data;
-	    int *ip = bufr;
-
-	    for (i = 0; i < att->len; i++)
-	       *lp++ = *ip++;
-	 }
-	 else
-	    memcpy(data, bufr, (size_t)(att->len * type_size));
+         /* For long types, we need to handle this special... */
+         if (is_long && att->nc_typeid == NC_INT)
+         {
+            long *lp = data;
+            int *ip = bufr;
+
+            for (i = 0; i < att->len; i++)
+               *lp++ = *ip++;
+         }
+         else
+            memcpy(data, bufr, (size_t)(att->len * type_size));
       }
    }
 
- exit:
+exit:
    if (need_to_convert)
       free(bufr);
    if (range_error)
@@ -216,11 +303,27 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
    return retval;
 }
 
-/* Put attribute metadata into our global metadata. */
+/**
+ * @internal Put attribute metadata into our global metadata.
+ *
+ * @param ncid File and group ID.
+ * @param nc Pointer to file's NC struct.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param file_type Type of the attribute data in file.
+ * @param mem_type Type of attribute data in memory.
+ * @param len Length of attribute array.
+ * @param is_long True if attribute is of type NC_LONG.
+ * @param data Attribute data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 static int
 nc4_put_att(int ncid, NC *nc, int varid, const char *name,
-	    nc_type file_type, nc_type mem_type, size_t len, int is_long,
-	    const void *data)
+            nc_type file_type, nc_type mem_type, size_t len, int is_long,
+            const void *data)
 {
    NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
@@ -238,8 +341,8 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
    assert(nc && NC4_DATA(nc));
 
    LOG((1, "nc4_put_att: ncid 0x%x varid %d name %s "
-	"file_type %d mem_type %d len %d", ncid, varid,
-	name, file_type, mem_type, len));
+        "file_type %d mem_type %d len %d", ncid, varid,
+        name, file_type, mem_type, len));
 
    /* If len is not zero, then there must be some data. */
    if (len && !data)
@@ -252,7 +355,7 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
 
    /* If the file is read-only, return an error. */
    if (h5->no_write)
-     return NC_EPERM;
+      return NC_EPERM;
 
    /* Find att, if it exists. */
    if (varid == NC_GLOBAL)
@@ -260,7 +363,7 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
    else
    {
       if (varid < 0 || varid >= grp->vars.nelems)
-	return NC_ENOTVAR;
+         return NC_ENOTVAR;
       var = grp->vars.value[varid];
       if (!var) return NC_ENOTVAR;
       attlist = &var->att;
@@ -275,50 +378,50 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
       return retval;
 
    if(nc->ext_ncid == ncid && varid == NC_GLOBAL) {
-	const char** sp;
-	for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
-	    if(strcmp(name,*sp)==0) {
-		return NC_ENOTATT; /* Not settable */
-	    }
-	}
-    }
+      const char** sp;
+      for(sp = NC_RESERVED_SPECIAL_LIST;*sp;sp++) {
+         if(strcmp(name,*sp)==0) {
+            return NC_ENOTATT; /* Not settable */
+         }
+      }
+   }
 
    for (att = *attlist; att; att = att->l.next)
-     if (!strcmp(att->name, norm_name))
-       break;
+      if (!strcmp(att->name, norm_name))
+         break;
 
    /* If len is not zero, then there must be some data. */
    if (len && !data)
       return NC_EINVAL;
 
    LOG((1, "nc4_put_att: ncid 0x%x varid %d name %s "
-	"file_type %d mem_type %d len %d", ncid, varid,
-	name, file_type, mem_type, len));
+        "file_type %d mem_type %d len %d", ncid, varid,
+        name, file_type, mem_type, len));
 
    if (!att)
    {
       /* If this is a new att, require define mode. */
       if (!(h5->flags & NC_INDEF))
       {
-	 if (h5->cmode & NC_CLASSIC_MODEL)
-	    return NC_EINDEFINE;
-	 if ((retval = NC4_redef(ncid)))
-	    BAIL(retval);
+         if (h5->cmode & NC_CLASSIC_MODEL)
+            return NC_EINDEFINE;
+         if ((retval = NC4_redef(ncid)))
+            BAIL(retval);
       }
       new_att = NC_TRUE;
    }
    else
    {
       /* For an existing att, if we're not in define mode, the len
-	 must not be greater than the existing len for classic model. */
-     if (!(h5->flags & NC_INDEF) &&
-         len * nc4typelen(file_type) > (size_t)att->len * nc4typelen(att->nc_typeid))
-       {
+         must not be greater than the existing len for classic model. */
+      if (!(h5->flags & NC_INDEF) &&
+          len * nc4typelen(file_type) > (size_t)att->len * nc4typelen(att->nc_typeid))
+      {
          if (h5->cmode & NC_CLASSIC_MODEL)
-           return NC_EINDEFINE;
+            return NC_EINDEFINE;
          if ((retval = NC4_redef(ncid)))
-           BAIL(retval);
-       }
+            BAIL(retval);
+      }
    }
 
    /* We must have two valid types to continue. */
@@ -332,7 +435,7 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
    /* No character conversions are allowed. */
    if (file_type != mem_type &&
        (file_type == NC_CHAR || mem_type == NC_CHAR ||
-	file_type == NC_STRING || mem_type == NC_STRING))
+        file_type == NC_STRING || mem_type == NC_STRING))
       return NC_ECHAR;
 
    /* For classic mode file, only allow atts with classic types to be
@@ -346,9 +449,9 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
    {
       LOG((3, "adding attribute %s to the list...", norm_name));
       if ((res = nc4_att_list_add(attlist, &att)))
-        BAIL (res);
+         BAIL (res);
       if (!(att->name = strdup(norm_name)))
-        return NC_ENOMEM;
+         return NC_ENOMEM;
    }
 
    /* Now fill in the metadata. */
@@ -360,14 +463,14 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
    {
       for (i = 0; i < att->len; i++)
          if(att->stdata[i])
-	    free(att->stdata[i]);
+            free(att->stdata[i]);
       free(att->stdata);
       att->stdata = NULL;
    }
    if (att->vldata)
    {
       for (i = 0; i < att->len; i++)
-	 nc_free_vlen(&att->vldata[i]);
+         nc_free_vlen(&att->vldata[i]);
       free(att->vldata);
       att->vldata = NULL;
    }
@@ -388,72 +491,72 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
 
       /* Fill value must be same type and have exactly one value */
       if (att->nc_typeid != var->type_info->nc_typeid)
-        return NC_EBADTYPE;
+         return NC_EBADTYPE;
       if (att->len != 1)
-        return NC_EINVAL;
+         return NC_EINVAL;
 
       /* If we already wrote to the dataset, then return an error. */
       if (var->written_to)
-        return NC_ELATEFILL;
+         return NC_ELATEFILL;
 
       /* If fill value hasn't been set, allocate space. Of course,
        * vlens have to be different... */
       if ((retval = nc4_get_typelen_mem(grp->nc4_info, var->type_info->nc_typeid, 0,
                                         &type_size)))
-        return retval;
+         return retval;
 
       /* Already set a fill value? Now I'll have to free the old
        * one. Make up your damn mind, would you? */
       if (var->fill_value)
-        {
-          if (var->type_info->nc_type_class == NC_VLEN)
-            {
-              if ((retval = nc_free_vlen(var->fill_value)))
-                return retval;
-            }
-          else if (var->type_info->nc_type_class == NC_STRING)
-            {
-              if (*(char **)var->fill_value)
-                free(*(char **)var->fill_value);
-            }
-          free(var->fill_value);
-        }
+      {
+         if (var->type_info->nc_type_class == NC_VLEN)
+         {
+            if ((retval = nc_free_vlen(var->fill_value)))
+               return retval;
+         }
+         else if (var->type_info->nc_type_class == NC_STRING)
+         {
+            if (*(char **)var->fill_value)
+               free(*(char **)var->fill_value);
+         }
+         free(var->fill_value);
+      }
 
       /* Allocate space for the fill value. */
       if (var->type_info->nc_type_class == NC_VLEN)
-        size = sizeof(hvl_t);
+         size = sizeof(hvl_t);
       else if (var->type_info->nc_type_class == NC_STRING)
-        size = sizeof(char *);
+         size = sizeof(char *);
       else
-        size = type_size;
+         size = type_size;
 
       if (!(var->fill_value = calloc(1, size)))
-        return NC_ENOMEM;
+         return NC_ENOMEM;
 
       /* Copy the fill_value. */
       LOG((4, "Copying fill value into metadata for variable %s", var->name));
       if (var->type_info->nc_type_class == NC_VLEN)
-        {
-          nc_vlen_t *in_vlen = (nc_vlen_t *)data, *fv_vlen = (nc_vlen_t *)(var->fill_value);
+      {
+         nc_vlen_t *in_vlen = (nc_vlen_t *)data, *fv_vlen = (nc_vlen_t *)(var->fill_value);
 
-          fv_vlen->len = in_vlen->len;
-          if (!(fv_vlen->p = malloc(size * in_vlen->len)))
+         fv_vlen->len = in_vlen->len;
+         if (!(fv_vlen->p = malloc(size * in_vlen->len)))
             return NC_ENOMEM;
-          memcpy(fv_vlen->p, in_vlen->p, in_vlen->len * size);
-        }
+         memcpy(fv_vlen->p, in_vlen->p, in_vlen->len * size);
+      }
       else if (var->type_info->nc_type_class == NC_STRING)
-        {
-          if(NULL != (*(char **)data))
-            {
-              if (!(*(char **)(var->fill_value) = malloc(strlen(*(char **)data) + 1)))
-                return NC_ENOMEM;
-              strcpy(*(char **)var->fill_value, *(char **)data);
-            }
-          else
+      {
+         if(NULL != (*(char **)data))
+         {
+            if (!(*(char **)(var->fill_value) = malloc(strlen(*(char **)data) + 1)))
+               return NC_ENOMEM;
+            strcpy(*(char **)var->fill_value, *(char **)data);
+         }
+         else
             *(char **)var->fill_value = NULL;
-        }
+      }
       else
-        memcpy(var->fill_value, data, type_size);
+         memcpy(var->fill_value, data, type_size);
 
       /* Indicate that the fill value was changed, if the variable has already
        * been created in the file, so the dataset gets deleted and re-created. */
@@ -475,12 +578,12 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
       if (type_class == NC_VLEN)
       {
          const hvl_t *vldata1;
-	 NC_TYPE_INFO_T *type;
-	 size_t base_typelen;
+         NC_TYPE_INFO_T *type;
+         size_t base_typelen;
 
          /* Get the type object for the attribute's type */
-	 if ((retval = nc4_find_type(h5, file_type, &type)))
-	   BAIL(retval);
+         if ((retval = nc4_find_type(h5, file_type, &type)))
+            BAIL(retval);
 
          /* Retrieve the size of the base type */
          if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
@@ -499,29 +602,29 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
       }
       else if (type_class == NC_STRING)
       {
-        LOG((4, "copying array of NC_STRING"));
-        if (!(att->stdata = malloc(sizeof(char *) * att->len))) {
-          BAIL(NC_ENOMEM);
-        }
-
-        /* If we are overwriting an existing attribute,
-           specifically an NC_CHAR, we need to clean up
-           the pre-existing att->data. */
-        if (!new_att && att->data) {
-          free(att->data);
-          att->data = NULL;
-        }
-
-        for (i = 0; i < att->len; i++)
-          {
+         LOG((4, "copying array of NC_STRING"));
+         if (!(att->stdata = malloc(sizeof(char *) * att->len))) {
+            BAIL(NC_ENOMEM);
+         }
+
+         /* If we are overwriting an existing attribute,
+            specifically an NC_CHAR, we need to clean up
+            the pre-existing att->data. */
+         if (!new_att && att->data) {
+            free(att->data);
+            att->data = NULL;
+         }
+
+         for (i = 0; i < att->len; i++)
+         {
             if(NULL != ((char **)data)[i]) {
-              LOG((5, "copying string %d of size %d", i, strlen(((char **)data)[i]) + 1));
-              if (!(att->stdata[i] = strdup(((char **)data)[i])))
-                BAIL(NC_ENOMEM);
+               LOG((5, "copying string %d of size %d", i, strlen(((char **)data)[i]) + 1));
+               if (!(att->stdata[i] = strdup(((char **)data)[i])))
+                  BAIL(NC_ENOMEM);
             }
             else
-              att->stdata[i] = ((char **)data)[i];
-          }
+               att->stdata[i] = ((char **)data)[i];
+         }
       }
       else
       {
@@ -549,9 +652,9 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
 
    /* Mark attributes on variable dirty, so they get written */
    if(var)
-       var->attr_dirty = NC_TRUE;
+      var->attr_dirty = NC_TRUE;
 
- exit:
+exit:
    /* If there was an error return it, otherwise return any potential
       range error value. If none, return NC_NOERR as usual.*/
    if (retval)
@@ -561,8 +664,20 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
    return NC_NOERR;
 }
 
-/* Learn about an att. All the nc4 nc_inq_ functions just call
- * nc4_get_att to get the metadata on an attribute. */
+/**
+ * @internal Learn about an att. All the nc4 nc_inq_ functions just
+ * call nc4_get_att to get the metadata on an attribute.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param xtypep Pointer that gets type of attribute.
+ * @param lenp Pointer that gets length of attribute data array.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp)
 {
@@ -583,7 +698,17 @@ NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp
    return nc4_get_att(ncid, nc, varid, name, xtypep, NC_NAT, lenp, NULL, 0, NULL);
 }
 
-/* Learn an attnum, given a name. */
+/**
+ * @internal Learn an attnum, given a name.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param attnump Pointer that gets the attribute index number.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
 {
@@ -603,12 +728,23 @@ NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
 
    /* Handle netcdf-4 files. */
    stat = nc4_get_att(ncid, nc, varid, name, NULL, NC_NAT,
-		      NULL, attnump, 0, NULL);
+                      NULL, attnump, 0, NULL);
    return stat;
 }
 
 
-/* Given an attnum, find the att's name. */
+/**
+ * @internal Given an attnum, find the att's name.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param attnum The index number of the attribute.
+ * @param name Pointer that gets name of attrribute.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_attname(int ncid, int varid, int attnum, char *name)
 {
@@ -618,7 +754,7 @@ NC4_inq_attname(int ncid, int varid, int attnum, char *name)
    int retval = NC_NOERR;
 
    LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d",
-	ncid, varid, attnum));
+        ncid, varid, attnum));
 
    /* Find metadata. */
    if (!(nc = nc4_find_nc_file(ncid,NULL)))
@@ -639,11 +775,21 @@ NC4_inq_attname(int ncid, int varid, int attnum, char *name)
    return NC_NOERR;
 }
 
-/* I think all atts should be named the exact same thing, to avoid
-   confusion! */
+/**
+ * @internal I think all atts should be named the exact same thing, to
+ * avoid confusion!
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param newname New name for attribute.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
-NC4_rename_att(int ncid, int varid, const char *name,
-	      const char *newname)
+NC4_rename_att(int ncid, int varid, const char *name, const char *newname)
 {
    NC *nc;
    NC_GRP_INFO_T *grp;
@@ -658,7 +804,7 @@ NC4_rename_att(int ncid, int varid, const char *name,
       return NC_EINVAL;
 
    LOG((2, "nc_rename_att: ncid 0x%x varid %d name %s newname %s",
-	ncid, varid, name, newname));
+        ncid, varid, name, newname));
 
    /* If the new name is too long, that's an error. */
    if (strlen(newname) > NC_MAX_NAME)
@@ -672,7 +818,7 @@ NC4_rename_att(int ncid, int varid, const char *name,
 
    /* If the file is read-only, return an error. */
    if (h5->no_write)
-     return NC_EPERM;
+      return NC_EPERM;
 
    /* Check and normalize the name. */
    if ((retval = nc4_check_name(newname, norm_newname)))
@@ -686,7 +832,7 @@ NC4_rename_att(int ncid, int varid, const char *name,
    else
    {
       if (varid < 0 || varid >= grp->vars.nelems)
-	return NC_ENOTVAR;
+         return NC_ENOTVAR;
       var = grp->vars.value[varid];
       if (!var) return NC_ENOTVAR;
       assert(var->varid == varid);
@@ -694,14 +840,14 @@ NC4_rename_att(int ncid, int varid, const char *name,
    }
    for (att = list; att; att = att->l.next)
       if (!strncmp(att->name, norm_newname, NC_MAX_NAME))
-	 return NC_ENAMEINUSE;
+         return NC_ENAMEINUSE;
 
    /* Normalize name and find the attribute. */
    if ((retval = nc4_normalize_name(name, norm_name)))
       return retval;
    for (att = list; att; att = att->l.next)
       if (!strncmp(att->name, norm_name, NC_MAX_NAME))
-	 break;
+         break;
    if (!att)
       return NC_ENOTATT;
 
@@ -717,14 +863,14 @@ NC4_rename_att(int ncid, int varid, const char *name,
       if (varid == NC_GLOBAL)
       {
          if (H5Adelete(grp->hdf_grpid, att->name) < 0)
-	    return NC_EHDFERR;
+            return NC_EHDFERR;
       }
       else
       {
-	 if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
-	    return retval;
+         if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
+            return retval;
          if (H5Adelete(datasetid, att->name) < 0)
-	    return NC_EHDFERR;
+            return NC_EHDFERR;
       }
       att->created = NC_FALSE;
    }
@@ -738,16 +884,24 @@ NC4_rename_att(int ncid, int varid, const char *name,
 
    /* Mark attributes on variable dirty, so they get written */
    if(var)
-       var->attr_dirty = NC_TRUE;
+      var->attr_dirty = NC_TRUE;
 
    return retval;
 }
 
-/* Delete an att. Rub it out. Push the button on it. Liquidate
-   it. Bump it off. Take it for a one-way ride. Terminate it. Drop the
-   bomb on it. You get the idea.
-   Ed Hartnett, 10/1/3
-*/
+/**
+ * @internal Delete an att. Rub it out. Push the button on
+ * it. Liquidate it. Bump it off. Take it for a one-way
+ * ride. Terminate it.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute to delete.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 NC4_del_att(int ncid, int varid, const char *name)
 {
@@ -764,7 +918,7 @@ NC4_del_att(int ncid, int varid, const char *name)
       return NC_EINVAL;
 
    LOG((2, "nc_del_att: ncid 0x%x varid %d name %s",
-	ncid, varid, name));
+        ncid, varid, name));
 
    /* Find metadata for this file. */
    if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
@@ -780,9 +934,9 @@ NC4_del_att(int ncid, int varid, const char *name)
    if (!(h5->flags & NC_INDEF))
    {
       if (h5->cmode & NC_CLASSIC_MODEL)
-	 return NC_ENOTINDEFINE;
+         return NC_ENOTINDEFINE;
       if ((retval = NC4_redef(ncid)))
-	 BAIL(retval);
+         BAIL(retval);
    }
 
    /* Get either the global or a variable attribute list. Also figure
@@ -795,19 +949,19 @@ NC4_del_att(int ncid, int varid, const char *name)
    else
    {
       if (varid < 0 || varid >= grp->vars.nelems)
-	return NC_ENOTVAR;
+         return NC_ENOTVAR;
       var = grp->vars.value[varid];
       if (!var) return NC_ENOTVAR;
       attlist = &var->att;
       assert(var->varid == varid);
       if (var->created)
-	 locid = var->hdf_datasetid;
+         locid = var->hdf_datasetid;
    }
 
    /* Now find the attribute by name or number. */
    for (att = *attlist; att; att = att->l.next)
       if (!strcmp(att->name, name))
-	 break;
+         break;
 
    /* If att is NULL, we couldn't find the attribute. */
    if (!att)
@@ -819,7 +973,7 @@ NC4_del_att(int ncid, int varid, const char *name)
       assert(locid);
 
       if(H5Adelete(locid, att->name) < 0)
-	 BAIL(NC_EATTMETA);
+         BAIL(NC_EATTMETA);
    }
 
    /* Renumber all following attributes. */
@@ -830,16 +984,32 @@ NC4_del_att(int ncid, int varid, const char *name)
    if ((retval = nc4_att_list_del(attlist, att)))
       BAIL(retval);
 
- exit:
+exit:
    if (datasetid > 0) H5Dclose(datasetid);
    return retval;
 }
 
-/* Write an attribute with type conversion. */
+/**
+ * @internal Write an attribute with type conversion.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param file_type Type of the attribute data in file.
+ * @param mem_type Type of attribute data in memory.
+ * @param mem_type_is_long True if attribute data in memory is of type
+ * NC_LONG.
+ * @param len Length of attribute array.
+ * @param op Attribute data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 static int
 nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type,
-	       nc_type mem_type, int mem_type_is_long, size_t len,
-	       const void *op)
+               nc_type mem_type, int mem_type_is_long, size_t len,
+               const void *op)
 {
    NC *nc;
    NC_HDF5_FILE_INFO_T *h5;
@@ -859,108 +1029,70 @@ nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type,
 
    /* Check varid */
    if (varid != NC_GLOBAL) {
-       /* Find info for this file and group, and set pointer to each. */
-       NC_GRP_INFO_T *grp;
-       if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
-          return NC_EBADGRPID;
-
-       if (varid < 0 || varid >= grp->vars.nelems)
-	   return NC_ENOTVAR;
-       if (grp->vars.value[varid] == NULL)
-           return NC_ENOTVAR;
-       assert(grp->vars.value[varid]->varid == varid);
+      /* Find info for this file and group, and set pointer to each. */
+      NC_GRP_INFO_T *grp;
+      if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
+         return NC_EBADGRPID;
+
+      if (varid < 0 || varid >= grp->vars.nelems)
+         return NC_ENOTVAR;
+      if (grp->vars.value[varid] == NULL)
+         return NC_ENOTVAR;
+      assert(grp->vars.value[varid]->varid == varid);
    }
 
    if (!name || strlen(name) > NC_MAX_NAME)
       return NC_EBADNAME;
 
    LOG((3, "nc4_put_att_tc: ncid 0x%x varid %d name %s file_type %d "
-	"mem_type %d len %d", ncid, varid, name, file_type, mem_type, len));
+        "mem_type %d len %d", ncid, varid, name, file_type, mem_type, len));
 
    if(nc->ext_ncid == ncid && varid == NC_GLOBAL) {
       const char** reserved = NC_RESERVED_ATT_LIST;
       for(;*reserved;reserved++) {
-	if(strcmp(name,*reserved)==0)
-	    return NC_ENAMEINUSE;
+         if(strcmp(name,*reserved)==0)
+            return NC_ENAMEINUSE;
       }
    }
 
    if(varid != NC_GLOBAL) {
       const char** reserved = NC_RESERVED_VARATT_LIST;
       for(;*reserved;reserved++) {
-	if(strcmp(name,*reserved)==0)
-	    return NC_ENAMEINUSE;
+         if(strcmp(name,*reserved)==0)
+            return NC_ENAMEINUSE;
       }
    }
 
    /* Otherwise, handle things the netcdf-4 way. */
    return nc4_put_att(ncid, nc, varid, name, file_type, mem_type, len,
-		      mem_type_is_long, op);
-}
-
-static int
-nc4_get_att_special(NC_HDF5_FILE_INFO_T* h5, const char* name,
-                    nc_type* filetypep, nc_type mem_type, size_t* lenp,
-                    int* attnump, int is_long, void* data)
-{
-    /* Fail if asking for att id */
-    if(attnump)
-	return NC_EATTMETA;
-
-    if(strcmp(name,NCPROPS)==0) {
-	char* propdata = NULL;
-	int stat = NC_NOERR;
-	int len;
-	if(h5->fileinfo->propattr.version == 0)
-	    return NC_ENOTATT;
-	if(mem_type == NC_NAT) mem_type = NC_CHAR;
-	if(mem_type != NC_CHAR)
-	    return NC_ECHAR;
-	if(filetypep) *filetypep = NC_CHAR;
-	stat = NC4_buildpropinfo(&h5->fileinfo->propattr, &propdata);
-	if(stat != NC_NOERR) return stat;
-	len = strlen(propdata);
-	if(lenp) *lenp = len;
-	if(data) strncpy((char*)data,propdata,len+1);
-	free(propdata);
-    } else if(strcmp(name,ISNETCDF4ATT)==0
-              || strcmp(name,SUPERBLOCKATT)==0) {
-	unsigned long long iv = 0;
-	if(filetypep) *filetypep = NC_INT;
-	if(lenp) *lenp = 1;
-	if(strcmp(name,SUPERBLOCKATT)==0)
-	    iv = (unsigned long long)h5->fileinfo->superblockversion;
-	else /* strcmp(name,ISNETCDF4ATT)==0 */
-	    iv = NC4_isnetcdf4(h5);
-	if(mem_type == NC_NAT) mem_type = NC_INT;
-	if(data)
-	switch (mem_type) {
-	case NC_BYTE: *((char*)data) = (char)iv; break;
-	case NC_SHORT: *((short*)data) = (short)iv; break;
-	case NC_INT: *((int*)data) = (int)iv; break;
-	case NC_UBYTE: *((unsigned char*)data) = (unsigned char)iv; break;
-	case NC_USHORT: *((unsigned short*)data) = (unsigned short)iv; break;
-	case NC_UINT: *((unsigned int*)data) = (unsigned int)iv; break;
-	case NC_INT64: *((long long*)data) = (long long)iv; break;
-	case NC_UINT64: *((unsigned long long*)data) = (unsigned long long)iv; break;
-	default:
-	    return NC_ERANGE;
-	}
-    }
-    return NC_NOERR;
+                      mem_type_is_long, op);
 }
 
-/* Read an attribute of any type, with type conversion. This may be
- * called by any of the nc_get_att_* functions. */
+/**
+ * @internal Read an attribute of any type, with type conversion. This
+ * may be called by any of the nc_get_att_* functions.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param mem_type Type of attribute data in memory.
+ * @param mem_type_is_long True if attribute data in memory is of type
+ * NC_LONG.
+ * @param ip Attribute data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 nc4_get_att_tc(int ncid, int varid, const char *name, nc_type mem_type,
-	       int mem_type_is_long, void *ip)
+               int mem_type_is_long, void *ip)
 {
    NC *nc;
    NC_HDF5_FILE_INFO_T *h5;
 
    LOG((3, "nc4_get_att_tc: ncid 0x%x varid %d name %s mem_type %d",
-	ncid, varid, name, mem_type));
+        ncid, varid, name, mem_type));
 
    /* Find metadata. */
    if (!(nc = nc4_find_nc_file(ncid,NULL)))
@@ -971,16 +1103,44 @@ nc4_get_att_tc(int ncid, int varid, const char *name, nc_type mem_type,
    assert(h5);
 
    return nc4_get_att(ncid, nc, varid, name, NULL, mem_type,
-		      NULL, NULL, mem_type_is_long, ip);
+                      NULL, NULL, mem_type_is_long, ip);
 }
 
+/**
+ * @internal Write an attribute.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param xtype Type of the attribute.
+ * @param nelems Number of elements in attribute array.
+ * @param value Attribute data.
+ * @param memtype Type of data in memory.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 NC4_put_att(int ncid, int varid, const char *name, nc_type xtype,
-	           size_t nelems, const void *value, nc_type memtype)
+            size_t nelems, const void *value, nc_type memtype)
 {
    return nc4_put_att_tc(ncid, varid, name, xtype, memtype, 0, nelems, value);
 }
 
+/**
+ * @internal Get an attribute.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name of attribute.
+ * @param value Pointer that gets attribute data.
+ * @param memtype The type the data should be converted to as it is read.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type memtype)
 {
diff --git a/libsrc4/nc4dim.c b/libsrc4/nc4dim.c
index 8d17c9a..0841de3 100644
--- a/libsrc4/nc4dim.c
+++ b/libsrc4/nc4dim.c
@@ -1,22 +1,34 @@
-/*
-
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-HDF5 backend for netCDF, depending on your point of view.
-
-This file handles the nc4 dimension functions.
-
-Copyright 2003-5, University Corporation for Atmospheric Research. See
-the COPYRIGHT file for copying and redistribution conditions.
-
-$Id: nc4dim.c,v 1.41 2010/05/25 17:54:23 dmh Exp $
+/* Copyright 2003-2018, University Corporation for Atmospheric
+ * Research. See the COPYRIGHT file for copying and redistribution
+ * conditions. */
+/**
+ * @file 
+ * @internal This file is part of netcdf-4, a netCDF-like interface
+ * for HDF5, or a HDF5 backend for netCDF, depending on your point of
+ * view.
+ *
+ * This file handles the nc4 dimension functions.
+ *
+ * @author Ed Hartnett
 */
 
 #include "nc4internal.h"
 #include "nc4dispatch.h"
 
-/* Netcdf-4 files might have more than one unlimited dimension, but
-   return the first one anyway. */
-/* Note that this code is inconsistent with nc_inq */
+/**
+ * @internal Netcdf-4 files might have more than one unlimited
+ * dimension, but return the first one anyway.
+ *  
+ * @note that this code is inconsistent with nc_inq 
+ *
+ * @param ncid File and group ID.
+ * @param unlimdimidp Pointer that gets ID of first unlimited
+ * dimension, or -1.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int 
 NC4_inq_unlimdim(int ncid, int *unlimdimidp)
 {
@@ -52,8 +64,28 @@ NC4_inq_unlimdim(int ncid, int *unlimdimidp)
    return NC_NOERR;
 }
 
-/* Dimensions are defined in attributes attached to the appropriate
-   group in the data file. */
+/**
+ * @internal Dimensions are defined in attributes attached to the
+ * appropriate group in the data file.
+ *
+ * @param ncid File and group ID.
+ * @param name Name of the new dimension.
+ * @param len Length of the new dimension.
+ * @param idp Pointer that gets the ID of the new dimension. Ignored
+ * if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @return ::NC_EINVAL Invalid input.
+ * @return ::NC_EPERM Read-only file.
+ * @return ::NC_EUNLIMIT Only one unlimited dim for classic model.
+ * @return ::NC_ENOTINDEFINE Not in define mode.
+ * @return ::NC_EDIMSIZE Dim length too large.
+ * @return ::NC_ENAMEINUSE Name already in use in group.
+ * @author Ed Hartnett
+ */
 int
 NC4_def_dim(int ncid, const char *name, size_t len, int *idp)
 {
@@ -71,8 +103,7 @@ NC4_def_dim(int ncid, const char *name, size_t len, int *idp)
    /* Find our global metadata structure. */
    if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
       return retval;
-
-   assert(h5 && nc /*& grp*/);
+   assert(h5 && nc && grp);
 
    /* If the file is read-only, return an error. */
    if (h5->no_write)
@@ -135,7 +166,18 @@ NC4_def_dim(int ncid, const char *name, size_t len, int *idp)
    return retval;
 }
 
-/* Given dim name, find its id. */
+/**
+ * @internal Given dim name, find its id.
+ *
+ * @param ncid File and group ID.
+ * @param name Name of the dimension to find.
+ * @param idp Pointer that gets dimension ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADDIM Dimension not found.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_dimid(int ncid, const char *name, int *idp)
 {
@@ -176,9 +218,21 @@ NC4_inq_dimid(int ncid, const char *name, int *idp)
    return NC_EBADDIM;
 }
 
-/* Find out name and len of a dim. For an unlimited dimension, the
-   length is the largest length so far written. If the name of lenp
-   pointers are NULL, they will be ignored. */
+/**
+ * @internal Find out name and len of a dim. For an unlimited
+ * dimension, the length is the largest length so far written. If the
+ * name of lenp pointers are NULL, they will be ignored.
+ *
+ * @param ncid File and group ID.
+ * @param dimid Dimension ID.
+ * @param name Pointer that gets name of the dimension.
+ * @param lenp Pointer that gets length of dimension.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EDIMSIZE Dimension length too large.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
 {
@@ -234,7 +288,25 @@ NC4_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
    return ret;
 }
 
-/* Rename a dimension, for those who like to prevaricate. */
+/**
+ * @internal Rename a dimension, for those who like to prevaricate.
+ *
+ * @param ncid File and group ID.
+ * @param dimid Dimension ID.
+ * @param name New dimension name.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @return ::NC_EINVAL Name must be provided.
+ * @return ::NC_ENAMEINUSE Name is already in use in group.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADDIM Dimension not found.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @return ::NC_EDIMMETA Unable to delete HDF5 dataset.
+ * @author Ed Hartnett
+ */
 int
 NC4_rename_dim(int ncid, int dimid, const char *name)
 {
@@ -254,9 +326,7 @@ NC4_rename_dim(int ncid, int dimid, const char *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(nc);
-   assert(h5 && grp);
+   assert(nc && h5 && grp);
    
    /* Trying to write to a read-only file? No way, Jose! */
    if (h5->no_write)
@@ -279,33 +349,30 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
       return NC_EBADDIM;
    dim = tmp_dim;
 
-   /* Check for renaming dimension w/o variable */
+   /* Check for renaming dimension w/o variable. */
    if (dim->hdf_dimscaleid)
    {
       /* Sanity check */
       assert(!dim->coord_var);
+      LOG((3, "dim %s is a dim without variable", dim->name));
 
-      /* Close the HDF5 dataset */
-      if (H5Dclose(dim->hdf_dimscaleid) < 0) 
-         return NC_EHDFERR;
-      dim->hdf_dimscaleid = 0;
-            
-      /* Now delete the dataset (it will be recreated later, if necessary) */
-      if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
-         return NC_EDIMMETA;
+      /* Delete the dimscale-only dataset. */
+      if ((retval = delete_existing_dimscale_dataset(grp, dimid, dim)))
+         return retval;
    }
 
    /* Give the dimension its new name in metadata. UTF8 normalization
     * has been done. */
-   if(dim->name)
-      free(dim->name);
+   assert(dim->name);
+   free(dim->name);
    if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
       return NC_ENOMEM;
    strcpy(dim->name, norm_name);
-
    dim->hash = hash_fast(norm_name, strlen(norm_name));
+   LOG((3, "dim is now named %s", dim->name));
    
-   /* Check if dimension was a coordinate variable, but names are different now */
+   /* Check if dimension was a coordinate variable, but names are
+    * different now */
    if (dim->coord_var && strcmp(dim->name, dim->coord_var->name))
    {
       /* Break up the coordinate variable */
@@ -313,24 +380,24 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
          return retval;
    }
 
-   /* Check if dimension should become a coordinate variable */
+   /* Check if dimension should become a coordinate variable. */
    if (!dim->coord_var)
    {
       NC_VAR_INFO_T *var;
 
-      /* Attempt to find a variable with the same name as the dimension in
-       * the current group. */
+      /* Attempt to find a variable with the same name as the
+       * dimension in the current group. */
       if ((retval = nc4_find_var(grp, dim->name, &var)))
          return retval;
 
-      /* Check if we found a variable and the variable has the dimension in
-       * index 0. */
+      /* Check if we found a variable and the variable has the
+       * dimension in index 0. */
       if (var && var->dim[0] == dim)
       {
           /* Sanity check */
           assert(var->dimids[0] == dim->dimid);
 
-          /* Reform the coordinate variable */
+          /* Reform the coordinate variable. */
           if ((retval = nc4_reform_coord_var(grp, var, dim)))
              return retval;
       }
@@ -339,10 +406,21 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
    return NC_NOERR;
 }
 
-/* Returns an array of unlimited dimension ids.The user can get the
-   number of unlimited dimensions by first calling this with NULL for
-   the second pointer.
-*/
+/**
+ * @internal Returns an array of unlimited dimension ids.The user can
+ * get the number of unlimited dimensions by first calling this with
+ * NULL for the second pointer.
+ *
+ * @param ncid File and group ID.
+ * @param nunlimdimsp Pointer that gets the number of unlimited
+ * dimensions. Ignored if NULL.
+ * @param unlimdimidsp Pointer that gets arrray of unlimited dimension
+ * ID. Ignored if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 int 
 NC4_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp) 
 {
diff --git a/libsrc4/nc4dispatch.c b/libsrc4/nc4dispatch.c
index 80b4f97..24f8310 100644
--- a/libsrc4/nc4dispatch.c
+++ b/libsrc4/nc4dispatch.c
@@ -94,6 +94,7 @@ NC4_def_var_fletcher32,
 NC4_def_var_chunking,
 NC4_def_var_fill,
 NC4_def_var_endian,
+NC4_def_var_filter,
 NC4_set_var_chunk_cache,
 NC4_get_var_chunk_cache,
 
@@ -101,6 +102,12 @@ NC4_get_var_chunk_cache,
 
 NC_Dispatch* NC4_dispatch_table = NULL; /* moved here from ddispatch.c */
 
+/**
+ * @internal Initialize netCDF-4.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_initialize(void)
 {
@@ -108,6 +115,12 @@ NC4_initialize(void)
     return NC_NOERR;
 }
 
+/**
+ * @internal Finalize netCDF-4.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_finalize(void)
 {
diff --git a/libsrc4/nc4file.c b/libsrc4/nc4file.c
index faeb4bf..cb26bf9 100644
--- a/libsrc4/nc4file.c
+++ b/libsrc4/nc4file.c
@@ -1,140 +1,485 @@
-/** \file
-The netCDF-4 file functions.
-
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or
-a HDF5 backend for netCDF, depending on your point of view.
-
-Copyright 2003, University Corporation for Atmospheric Research. See
-COPYRIGHT file for copying and redistribution conditions.
-
-*/
-
+/**
+ * @file
+ * @internal The netCDF-4 file functions.
+ *
+ * This file is part of netcdf-4, a netCDF-like interface for HDF5, or
+ * a HDF5 backend for netCDF, depending on your point of view.
+ *
+ * Copyright 2003, University Corporation for Atmospheric Research. See
+ * COPYRIGHT file for copying and redistribution conditions.
+ * @author Ed Hartnett
+ */
 #include "config.h"
 #include <errno.h>  /* netcdf functions sometimes return system errors */
-
 #include "nc.h"
 #include "nc4internal.h"
 #include "nc4dispatch.h"
-
-extern int nc4_vararray_add(NC_GRP_INFO_T *grp,
-			    NC_VAR_INFO_T *var);
-
-/* must be after nc4internal.h */
-#include <H5DSpublic.h>
+#include <H5DSpublic.h> /* must be after nc4internal.h */
 #include <H5Fpublic.h>
 #ifdef USE_HDF4
 #include <mfhdf.h>
 #endif
 #include <hdf5_hl.h>
 
-/* When we have open objects at file close, should
-   we log them or print to stdout. Default is to log
-*/
-#define LOGOPEN 1
+extern int nc4_vararray_add(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
 
-/* This is to track opened HDF5 objects to make sure they are
- * closed. */
-#ifdef EXTRA_TESTS
-extern int num_plists;
-extern int num_spaces;
-#endif /* EXTRA_TESTS */
+/** @internal When we have open objects at file close, should
+    we log them or print to stdout. Default is to log. */
+#define LOGOPEN 1
 
-#define MIN_DEFLATE_LEVEL 0
-#define MAX_DEFLATE_LEVEL 9
+#define CD_NELEMS_ZLIB 1 /**< Number of parameters needed for ZLIB filter. */
 
-/*Forward*/
-static int read_hdf5_att(NC_GRP_INFO_T *grp, hid_t attid, NC_ATT_INFO_T *att);
-static void hdf5free(void* memory);
+/**
+ * @internal Wrap HDF5 allocated memory free operations 
+ *
+ * @param memory Pointer to memory to be freed.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+*/
+static void
+hdf5free(void* memory)
+{
+#ifndef JNA
+   /* On Windows using the microsoft runtime, it is an error
+      for one library to free memory allocated by a different library.*/
+#ifdef HDF5_HAS_H5FREE
+   if(memory != NULL) H5free_memory(memory);
+#else
+#ifndef _MSC_VER
+   if(memory != NULL) free(memory);
+#endif
+#endif
+#endif
+}
 
 /* Custom iteration callback data */
 typedef struct {
-  NC_GRP_INFO_T *grp;
-  NC_VAR_INFO_T *var;
+   NC_GRP_INFO_T *grp;
+   NC_VAR_INFO_T *var;
 } att_iter_info;
 
+
+/**
+ * @internal Given an HDF5 type, set a pointer to netcdf type. 
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param native_typeid HDF5 type ID.
+ * @param xtype Pointer that gets netCDF type.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @return ::NC_EBADTYPID Type not found.
+ * @author Ed Hartnett
+*/
+static int
+get_netcdf_type(NC_HDF5_FILE_INFO_T *h5, hid_t native_typeid,
+                nc_type *xtype)
+{
+   NC_TYPE_INFO_T *type;
+   H5T_class_t class;
+   htri_t is_str, equal = 0;
+
+   assert(h5 && xtype);
+
+   if ((class = H5Tget_class(native_typeid)) < 0)
+      return NC_EHDFERR;
+
+   /* H5Tequal doesn't work with H5T_C_S1 for some reason. But
+    * H5Tget_class will return H5T_STRING if this is a string. */
+   if (class == H5T_STRING)
+   {
+      if ((is_str = H5Tis_variable_str(native_typeid)) < 0)
+         return NC_EHDFERR;
+      if (is_str)
+         *xtype = NC_STRING;
+      else
+         *xtype = NC_CHAR;
+      return NC_NOERR;
+   }
+   else if (class == H5T_INTEGER || class == H5T_FLOAT)
+   {
+      /* For integers and floats, we don't have to worry about
+       * endianness if we compare native types. */
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_SCHAR)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_BYTE;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_SHORT)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_SHORT;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_INT)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_INT;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_FLOAT)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_FLOAT;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_DOUBLE)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_DOUBLE;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_UCHAR)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_UBYTE;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_USHORT)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_USHORT;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_UINT)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_UINT;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_LLONG)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_INT64;
+         return NC_NOERR;
+      }
+      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_ULLONG)) < 0)
+         return NC_EHDFERR;
+      if (equal)
+      {
+         *xtype = NC_UINT64;
+         return NC_NOERR;
+      }
+   }
+
+   /* Maybe we already know about this type. */
+   if (!equal)
+      if((type = nc4_rec_find_hdf_type(h5->root_grp, native_typeid)))
+      {
+         *xtype = type->nc_typeid;
+         return NC_NOERR;
+      }
+
+   *xtype = NC_NAT;
+   return NC_EBADTYPID;
+}
+
+/**
+ * @internal Read an attribute. This is called by att_read_var_callbk().
+ *
+ * @param grp Pointer to group info struct.
+ * @param attid Attribute ID.
+ * @param att Pointer that gets att info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @author Ed Hartnett
+*/
+static int
+read_hdf5_att(NC_GRP_INFO_T *grp, hid_t attid, NC_ATT_INFO_T *att)
+{
+   hid_t spaceid = 0, file_typeid = 0;
+   hsize_t dims[1] = {0}; /* netcdf attributes always 1-D. */
+   int retval = NC_NOERR;
+   size_t type_size;
+   int att_ndims;
+   hssize_t att_npoints;
+   H5T_class_t att_class;
+   int fixed_len_string = 0;
+   size_t fixed_size = 0;
+
+   assert(att->name);
+   LOG((5, "%s: att->attnum %d att->name %s att->nc_typeid %d att->len %d",
+        __func__, att->attnum, att->name, (int)att->nc_typeid, att->len));
+
+   /* Get type of attribute in file. */
+   if ((file_typeid = H5Aget_type(attid)) < 0)
+      return NC_EATTMETA;
+   if ((att->native_hdf_typeid = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0)
+      BAIL(NC_EHDFERR);
+   if ((att_class = H5Tget_class(att->native_hdf_typeid)) < 0)
+      BAIL(NC_EATTMETA);
+   if (att_class == H5T_STRING && !H5Tis_variable_str(att->native_hdf_typeid))
+   {
+      fixed_len_string++;
+      if (!(fixed_size = H5Tget_size(att->native_hdf_typeid)))
+         BAIL(NC_EATTMETA);
+   }
+   if ((retval = get_netcdf_type(grp->nc4_info, att->native_hdf_typeid, &(att->nc_typeid))))
+      BAIL(retval);
+
+
+   /* Get len. */
+   if ((spaceid = H5Aget_space(attid)) < 0)
+      BAIL(NC_EATTMETA);
+   if ((att_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0)
+      BAIL(NC_EATTMETA);
+   if ((att_npoints = H5Sget_simple_extent_npoints(spaceid)) < 0)
+      BAIL(NC_EATTMETA);
+
+   /* If both att_ndims and att_npoints are zero, then this is a
+    * zero length att. */
+   if (att_ndims == 0 && att_npoints == 0)
+      dims[0] = 0;
+   else if (att->nc_typeid == NC_STRING)
+      dims[0] = att_npoints;
+   else if (att->nc_typeid == NC_CHAR)
+   {
+      /* NC_CHAR attributes are written as a scalar in HDF5, of type
+       * H5T_C_S1, of variable length. */
+      if (att_ndims == 0)
+      {
+         if (!(dims[0] = H5Tget_size(file_typeid)))
+            BAIL(NC_EATTMETA);
+      }
+      else
+      {
+         /* This is really a string type! */
+         att->nc_typeid = NC_STRING;
+         dims[0] = att_npoints;
+      }
+   }
+   else
+   {
+      H5S_class_t space_class;
+
+      /* All netcdf attributes are scalar or 1-D only. */
+      if (att_ndims > 1)
+         BAIL(NC_EATTMETA);
+
+      /* Check class of HDF5 dataspace */
+      if ((space_class = H5Sget_simple_extent_type(spaceid)) < 0)
+         BAIL(NC_EATTMETA);
+
+      /* Check for NULL HDF5 dataspace class (should be weeded out earlier) */
+      if (H5S_NULL == space_class)
+         BAIL(NC_EATTMETA);
+
+      /* check for SCALAR HDF5 dataspace class */
+      if (H5S_SCALAR == space_class)
+         dims[0] = 1;
+      else /* Must be "simple" dataspace */
+      {
+         /* Read the size of this attribute. */
+         if (H5Sget_simple_extent_dims(spaceid, dims, NULL) < 0)
+            BAIL(NC_EATTMETA);
+      }
+   }
+
+   /* Tell the user what the length if this attribute is. */
+   att->len = dims[0];
+
+   /* Allocate some memory if the len is not zero, and read the
+      attribute. */
+   if (dims[0])
+   {
+      if ((retval = nc4_get_typelen_mem(grp->nc4_info, att->nc_typeid, 0,
+                                        &type_size)))
+         return retval;
+      if (att_class == H5T_VLEN)
+      {
+         if (!(att->vldata = malloc((unsigned int)(att->len * sizeof(hvl_t)))))
+            BAIL(NC_ENOMEM);
+         if (H5Aread(attid, att->native_hdf_typeid, att->vldata) < 0)
+            BAIL(NC_EATTMETA);
+      }
+      else if (att->nc_typeid == NC_STRING)
+      {
+         if (!(att->stdata = calloc(att->len, sizeof(char *))))
+            BAIL(NC_ENOMEM);
+         /* For a fixed length HDF5 string, the read requires
+          * contiguous memory. Meanwhile, the netCDF API requires that
+          * nc_free_string be called on string arrays, which would not
+          * work if one contiguous memory block were used. So here I
+          * convert the contiguous block of strings into an array of
+          * malloced strings (each string with its own malloc). Then I
+          * copy the data and free the contiguous memory. This
+          * involves copying the data, which is bad, but this only
+          * occurs for fixed length string attributes, and presumably
+          * these are small. (And netCDF-4 does not create them - it
+          * always uses variable length strings. */
+         if (fixed_len_string)
+         {
+            int i;
+            char *contig_buf, *cur;
+
+            /* Alloc space for the contiguous memory read. */
+            if (!(contig_buf = malloc(att->len * fixed_size * sizeof(char))))
+               BAIL(NC_ENOMEM);
+
+            /* Read the fixed-len strings as one big block. */
+            if (H5Aread(attid, att->native_hdf_typeid, contig_buf) < 0) {
+               free(contig_buf);
+               BAIL(NC_EATTMETA);
+            }
+
+            /* Copy strings, one at a time, into their new home. Alloc
+               space for each string. The user will later free this
+               space with nc_free_string. */
+            cur = contig_buf;
+            for (i = 0; i < att->len; i++)
+            {
+               if (!(att->stdata[i] = malloc(fixed_size))) {
+                  free(contig_buf);
+                  BAIL(NC_ENOMEM);
+               }
+               strncpy(att->stdata[i], cur, fixed_size);
+               cur += fixed_size;
+            }
+
+            /* Free contiguous memory buffer. */
+            free(contig_buf);
+         }
+         else
+         {
+            /* Read variable-length string atts. */
+            if (H5Aread(attid, att->native_hdf_typeid, att->stdata) < 0)
+               BAIL(NC_EATTMETA);
+         }
+      }
+      else
+      {
+         if (!(att->data = malloc((unsigned int)(att->len * type_size))))
+            BAIL(NC_ENOMEM);
+         if (H5Aread(attid, att->native_hdf_typeid, att->data) < 0)
+            BAIL(NC_EATTMETA);
+      }
+   }
+
+   if (H5Tclose(file_typeid) < 0)
+      BAIL(NC_EHDFERR);
+   if (H5Sclose(spaceid) < 0)
+      return NC_EHDFERR;
+
+   return NC_NOERR;
+
+exit:
+   if (H5Tclose(file_typeid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (spaceid > 0 && H5Sclose(spaceid) < 0)
+      BAIL2(NC_EHDFERR);
+   return retval;
+}
+
+/**
+ * @internal Callback function for reading attributes. This is used by read_var().
+ *
+ * @param loc_id HDF5 attribute ID.
+ * @param att_name Name of the attrigute.
+ * @param ainfo HDF5 info struct for attribute.
+ * @param att_data The attribute data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @return ::NC_EATTMETA HDF5 can't open attribute.
+ * @return ::NC_EBADTYPID Can't read attribute type.
+ */
 static herr_t
 att_read_var_callbk(hid_t loc_id, const char *att_name, const H5A_info_t *ainfo, void *att_data)
 {
 
-  hid_t attid = 0;
-  int retval = NC_NOERR;
-  NC_ATT_INFO_T *att;
-  att_iter_info *att_info = (att_iter_info *)att_data;
-  const char** reserved;
-
+   hid_t attid = 0;
+   int retval = NC_NOERR;
+   NC_ATT_INFO_T *att;
+   att_iter_info *att_info = (att_iter_info *)att_data;
+   const char** reserved;
 
-  /* Should we ignore this attribute? */
-  for(reserved=NC_RESERVED_VARATT_LIST;*reserved;reserved++) {
-    if (strcmp(att_name, *reserved)==0) break;
-  }
+   /* Should we ignore this attribute? */
+   for(reserved=NC_RESERVED_VARATT_LIST;*reserved;reserved++) {
+      if (strcmp(att_name, *reserved)==0) break;
+   }
 
-  if(*reserved == NULL) {
+   if(*reserved == NULL) {
       /* Open the att by name. */
       if ((attid = H5Aopen(loc_id, att_name, H5P_DEFAULT)) < 0)
-	BAIL(NC_EATTMETA);
+         BAIL(NC_EATTMETA);
       LOG((4, "%s::  att_name %s", __func__, att_name));
       /* Add to the end of the list of atts for this var. */
       if ((retval = nc4_att_list_add(&att_info->var->att, &att)))
-	BAIL(retval);
+         BAIL(retval);
       /* Fill in the information we know. */
       att->attnum = att_info->var->natts++;
       if (!(att->name = strdup(att_name)))
-	BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
 
       /* Read the rest of the info about the att,
        * including its values. */
       if ((retval = read_hdf5_att(att_info->grp, attid, att)))
-	{
-	  if (NC_EBADTYPID == retval)
-            {
-	      if ((retval = nc4_att_list_del(&att_info->var->att, att)))
-		BAIL(retval);
-            }
-	  else
-	    BAIL(retval);
-	}
+      {
+         if (NC_EBADTYPID == retval)
+         {
+            if ((retval = nc4_att_list_del(&att_info->var->att, att)))
+               BAIL(retval);
+            att = NULL;
+         }
+         else
+            BAIL(retval);
+      }
 
-      att->created = NC_TRUE;
+      if (att)
+         att->created = NC_TRUE;
 
       if (attid > 0 && H5Aclose(attid) < 0)
-	BAIL2(NC_EHDFERR);
+         BAIL2(NC_EHDFERR);
 
-    } /* endif not HDF5 att */
-  
-  return NC_NOERR;
+   } /* endif not HDF5 att */
 
- exit:
-  if (attid > 0 && H5Aclose(attid) < 0)
-    BAIL2(NC_EHDFERR);
+   return NC_NOERR;
+
+exit:
+   if (attid > 0 && H5Aclose(attid) < 0)
+      BAIL2(NC_EHDFERR);
 
-  return retval;
+   return retval;
 }
 
-/* Define the illegal mode flags */
+/** @internal These flags may not be set for open mode. */
 static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_64BIT_OFFSET);
 
+/** @internal These flags may not be set for create. */
 static const int ILLEGAL_CREATE_FLAGS = (NC_NOWRITE|NC_MMAP|NC_INMEMORY|NC_64BIT_OFFSET|NC_CDF5);
 
 extern void reportopenobjects(int log, hid_t);
 
-/*! Struct to track information about objects in a group, for nc4_rec_read_metadata()
-
- \internal
-
+/**
+ * @internal Struct to track information about objects in a group, for
+ * nc4_rec_read_metadata()
 */
 typedef struct NC4_rec_read_metadata_obj_info
 {
-    hid_t oid;                          /* HDF5 object ID */
-    char oname[NC_MAX_NAME + 1];        /* Name of object */
-    H5G_stat_t statbuf;                 /* Information about the object */
-    struct NC4_rec_read_metadata_obj_info *next;        /* Pointer to next node in list */
+   hid_t oid;                          /* HDF5 object ID */
+   char oname[NC_MAX_NAME + 1];        /* Name of object */
+   H5G_stat_t statbuf;                 /* Information about the object */
+   struct NC4_rec_read_metadata_obj_info *next;        /* Pointer to next node in list */
 } NC4_rec_read_metadata_obj_info_t;
 
-/*! User data struct for call to H5Literate() in nc4_rec_read_metadata()
-
-\internal
-
-Tracks the groups, named datatypes and datasets in the group, for later use.
+/**
+ * @internal User data struct for call to H5Literate() in
+ * nc4_rec_read_metadata(). Tracks the groups, named datatypes and
+ * datasets in the group, for later use.
 */
 typedef struct NC4_rec_read_metadata_ud
 {
@@ -145,69 +490,237 @@ typedef struct NC4_rec_read_metadata_ud
 /* Forward */
 static int NC4_enddef(int ncid);
 static int nc4_rec_read_metadata(NC_GRP_INFO_T *grp);
-static int close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort);
 
-/* Define the names of attributes to ignore
- * added by the HDF5 dimension scale; these
- * attached to variables.
- * They cannot be modified thru the netcdf-4 API.
+/**
+ * @internal This function will write all changed metadata, and
+ * (someday) reread all metadata from the file. 
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
+static int
+sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
+{
+   int retval;
+
+   assert(h5);
+   LOG((3, "%s", __func__));
+
+   /* If we're in define mode, that's an error, for strict nc3 rules,
+    * otherwise, end define mode. */
+   if (h5->flags & NC_INDEF)
+   {
+      if (h5->cmode & NC_CLASSIC_MODEL)
+         return NC_EINDEFINE;
+
+      /* Turn define mode off. */
+      h5->flags ^= NC_INDEF;
+
+      /* Redef mode needs to be tracked separately for nc_abort. */
+      h5->redef = NC_FALSE;
+   }
+
+#ifdef LOGGING
+   /* This will print out the names, types, lens, etc of the vars and
+      atts in the file, if the logging level is 2 or greater. */
+   log_metadata_nc(h5->root_grp->nc4_info->controller);
+#endif
+
+   /* Write any metadata that has changed. */
+   if (!(h5->cmode & NC_NOWRITE))
+   {
+      nc_bool_t bad_coord_order = NC_FALSE;     /* if detected, propagate to all groups to consistently store dimids */
+
+      if ((retval = nc4_rec_write_groups_types(h5->root_grp)))
+         return retval;
+      if ((retval = nc4_rec_detect_need_to_preserve_dimids(h5->root_grp, &bad_coord_order)))
+         return retval;
+      if ((retval = nc4_rec_write_metadata(h5->root_grp, bad_coord_order)))
+         return retval;
+   }
+
+   if (H5Fflush(h5->hdfid, H5F_SCOPE_GLOBAL) < 0)
+      return NC_EHDFERR;
+
+   return retval;
+}
+
+/**
+ * @internal This function will free all allocated metadata memory,
+ * and close the HDF5 file. The group that is passed in must be the
+ * root group of the file. 
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param abort True if this is an abort.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
+static int
+close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort)
+{
+   int retval = NC_NOERR;
+
+   assert(h5 && h5->root_grp);
+   LOG((3, "%s: h5->path %s abort %d", __func__, h5->controller->path, abort));
+
+   /* According to the docs, always end define mode on close. */
+   if (h5->flags & NC_INDEF)
+      h5->flags ^= NC_INDEF;
+
+   /* Sync the file, unless we're aborting, or this is a read-only
+    * file. */
+   if (!h5->no_write && !abort)
+      if ((retval = sync_netcdf4_file(h5)))
+         goto exit;
+
+   /* Delete all the list contents for vars, dims, and atts, in each
+    * group. */
+   if ((retval = nc4_rec_grp_del(&h5->root_grp, h5->root_grp)))
+      goto exit;
+
+   /* Close hdf file. */
+#ifdef USE_HDF4
+   if (h5->hdf4)
+   {
+      if (SDend(h5->sdid))
+         BAIL_QUIET(NC_EHDFERR);
+   }
+   else
+#endif /* USE_HDF4 */
+   {
+#ifdef USE_PARALLEL4
+      /* Free the MPI Comm & Info objects, if we opened the file in parallel */
+      if(h5->parallel)
+      {
+         if(MPI_COMM_NULL != h5->comm)
+            MPI_Comm_free(&h5->comm);
+         if(MPI_INFO_NULL != h5->info)
+            MPI_Info_free(&h5->info);
+      }
+#endif
+
+      if(h5->fileinfo) free(h5->fileinfo);
+
+      if (H5Fclose(h5->hdfid) < 0)
+      {
+         int nobjs;
+
+         nobjs = H5Fget_obj_count(h5->hdfid, H5F_OBJ_ALL);
+         /* Apparently we can get an error even when nobjs == 0 */
+         if(nobjs < 0) {
+            BAIL_QUIET(NC_EHDFERR);
+         } else if(nobjs > 0) {
+#ifdef LOGGING
+            char msg[1024];
+            int logit = 1;
+            /* If the close doesn't work, probably there are still some HDF5
+             * objects open, which means there's a bug in the library. So
+             * print out some info on to help the poor programmer figure it
+             * out. */
+            snprintf(msg,sizeof(msg),"There are %d HDF5 objects open!", nobjs);
+#ifdef LOGOPEN
+            LOG((0, msg));
+#else
+            fprintf(stdout,msg);
+            logit = 0;
+#endif
+            reportopenobjects(logit,h5->hdfid);
+#endif
+         }
+      }
+   }
+exit:
+   /* Free the nc4_info struct; above code should have reclaimed
+      everything else */
+   if(!retval && h5 != NULL)
+      free(h5);
+   return retval;
+}
+
+/**
+ * @internal Define the names of attributes to ignore added by the
+ * HDF5 dimension scale; these attached to variables. They cannot be
+ * modified thru the netcdf-4 API.
  */
 const char* NC_RESERVED_VARATT_LIST[] = {
-NC_ATT_REFERENCE_LIST,
-NC_ATT_CLASS,
-NC_ATT_DIMENSION_LIST,
-NC_ATT_NAME,
-NC_ATT_COORDINATES,
-NC_DIMID_ATT_NAME,
-NULL
+   NC_ATT_REFERENCE_LIST,
+   NC_ATT_CLASS,
+   NC_ATT_DIMENSION_LIST,
+   NC_ATT_NAME,
+   NC_ATT_COORDINATES,
+   NC_DIMID_ATT_NAME,
+   NULL
 };
 
-/* Define the names of attributes to ignore
- * because they are "hidden" global attributes.
- * They can be read, but not modified thru the netcdf-4 API.
+/**
+ * @internal Define the names of attributes to ignore because they are
+ * "hidden" global attributes. They can be read, but not modified thru
+ * the netcdf-4 API.
  */
 const char* NC_RESERVED_ATT_LIST[] = {
-NC_ATT_FORMAT,
-NC3_STRICT_ATT_NAME,
-NCPROPS,
-ISNETCDF4ATT,
-SUPERBLOCKATT,
-NULL
+   NC_ATT_FORMAT,
+   NC3_STRICT_ATT_NAME,
+   NCPROPS,
+   ISNETCDF4ATT,
+   SUPERBLOCKATT,
+   NULL
 };
 
-/* Define the subset of the reserved list that is readable by name only */
+/** 
+ * @internal Define the subset of the reserved list that is readable
+ * by name only 
+*/
 const char* NC_RESERVED_SPECIAL_LIST[] = {
-ISNETCDF4ATT,
-SUPERBLOCKATT,
-NCPROPS,
-NULL
+   ISNETCDF4ATT,
+   SUPERBLOCKATT,
+   NCPROPS,
+   NULL
 };
 
-/* These are the default chunk cache sizes for HDF5 files created or
- * opened with netCDF-4. */
-size_t nc4_chunk_cache_size = CHUNK_CACHE_SIZE;
-size_t nc4_chunk_cache_nelems = CHUNK_CACHE_NELEMS;
-float nc4_chunk_cache_preemption = CHUNK_CACHE_PREEMPTION;
+size_t nc4_chunk_cache_size = CHUNK_CACHE_SIZE;            /**< Default chunk cache size. */
+size_t nc4_chunk_cache_nelems = CHUNK_CACHE_NELEMS;        /**< Default chunk cache number of elements. */
+float nc4_chunk_cache_preemption = CHUNK_CACHE_PREEMPTION; /**< Default chunk cache preemption. */
+
+#define NUM_TYPES 12 /**< Number of netCDF atomic types. */
 
-/* For performance, fill this array only the first time, and keep it
- * in global memory for each further use. */
-#define NUM_TYPES 12
+/** @internal Native HDF5 constants for atomic types. For performance,
+ * fill this array only the first time, and keep it in global memory
+ * for each further use. */
 static hid_t h5_native_type_constant_g[NUM_TYPES];
+
+/** @internal NetCDF atomic type names. */
 static const char nc_type_name_g[NUM_TYPES][NC_MAX_NAME + 1] = {"char", "byte", "short",
-    "int", "float", "double", "ubyte",
-    "ushort", "uint", "int64",
-    "uint64", "string"};
+                                                                "int", "float", "double", "ubyte",
+                                                                "ushort", "uint", "int64",
+                                                                "uint64", "string"};
+
+/** @internal NetCDF atomic types. */
 static const nc_type nc_type_constant_g[NUM_TYPES] = {NC_CHAR, NC_BYTE, NC_SHORT,
-    NC_INT, NC_FLOAT, NC_DOUBLE, NC_UBYTE,
-    NC_USHORT, NC_UINT, NC_INT64,
-    NC_UINT64, NC_STRING};
-static const int nc_type_size_g[NUM_TYPES] = {sizeof(char), sizeof(char), sizeof(short),
-    sizeof(int), sizeof(float), sizeof(double), sizeof(unsigned char),
-    sizeof(unsigned short), sizeof(unsigned int), sizeof(long long),
-    sizeof(unsigned long long), sizeof(char *)};
+                                                      NC_INT, NC_FLOAT, NC_DOUBLE, NC_UBYTE,
+                                                      NC_USHORT, NC_UINT, NC_INT64,
+                                                      NC_UINT64, NC_STRING};
 
-/* Set chunk cache size. Only affects files opened/created *after* it
- * is called.  */
+/** @internal NetCDF atomic type sizes. */
+static const int nc_type_size_g[NUM_TYPES] = {sizeof(char), sizeof(char), sizeof(short),
+                                              sizeof(int), sizeof(float), sizeof(double), sizeof(unsigned char),
+                                              sizeof(unsigned short), sizeof(unsigned int), sizeof(long long),
+                                              sizeof(unsigned long long), sizeof(char *)};
+
+/**
+ * Set chunk cache size. Only affects files opened/created *after* it
+ * is called.  
+ * 
+ * @param size Size in bytes to set cache.
+ * @param nelems Number of elements to hold in cache.
+ * @param preemption Premption stragety (between 0 and 1).
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EINVAL Bad preemption.
+ * @author Ed Hartnett
+ */
 int
 nc_set_chunk_cache(size_t size, size_t nelems, float preemption)
 {
@@ -219,8 +732,17 @@ nc_set_chunk_cache(size_t size, size_t nelems, float preemption)
    return NC_NOERR;
 }
 
-/* Get chunk cache size. Only affects files opened/created *after* it
- * is called.  */
+/**
+ * Get chunk cache size. Only affects files opened/created *after* it
+ * is called.  
+ *
+ * @param sizep Pointer that gets size in bytes to set cache.
+ * @param nelemsp Pointer that gets number of elements to hold in cache.
+ * @param preemptionp Pointer that gets premption stragety (between 0 and 1).
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc_get_chunk_cache(size_t *sizep, size_t *nelemsp, float *preemptionp)
 {
@@ -235,7 +757,17 @@ nc_get_chunk_cache(size_t *sizep, size_t *nelemsp, float *preemptionp)
    return NC_NOERR;
 }
 
-/* Required for fortran to avoid size_t issues. */
+/**
+ * @internal Set the chunk cache. Required for fortran to avoid size_t
+ * issues.
+ *
+ * @param size Cache size.
+ * @param nelems Number of elements.
+ * @param preemption Preemption * 100.
+ *
+ * @return NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc_set_chunk_cache_ints(int size, int nelems, int preemption)
 {
@@ -247,6 +779,17 @@ nc_set_chunk_cache_ints(int size, int nelems, int preemption)
    return NC_NOERR;
 }
 
+/**
+ * @internal Get the chunk cache settings. Required for fortran to
+ * avoid size_t issues.
+ *
+ * @param sizep Pointer that gets cache size.
+ * @param nelemsp Pointer that gets number of elements.
+ * @param preemptionp Pointer that gets preemption * 100.
+ *
+ * @return NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc_get_chunk_cache_ints(int *sizep, int *nelemsp, int *preemptionp)
 {
@@ -260,110 +803,53 @@ nc_get_chunk_cache_ints(int *sizep, int *nelemsp, int *preemptionp)
    return NC_NOERR;
 }
 
-/* This will return the length of a netcdf data type in bytes. */
+/**
+ * @internal This will return the length of a netcdf data type in bytes.
+ *
+ * @param type A netcdf atomic type.
+ *
+ * @return Type size in bytes, or -1 if type not found.
+ * @author Ed Hartnett
+ */
 int
 nc4typelen(nc_type type)
 {
    switch(type){
-      case NC_BYTE:
-      case NC_CHAR:
-      case NC_UBYTE:
-	 return 1;
-      case NC_USHORT:
-      case NC_SHORT:
-	 return 2;
-      case NC_FLOAT:
-      case NC_INT:
-      case NC_UINT:
-	 return 4;
-      case NC_DOUBLE:
-      case NC_INT64:
-      case NC_UINT64:
-	 return 8;
+   case NC_BYTE:
+   case NC_CHAR:
+   case NC_UBYTE:
+      return 1;
+   case NC_USHORT:
+   case NC_SHORT:
+      return 2;
+   case NC_FLOAT:
+   case NC_INT:
+   case NC_UINT:
+      return 4;
+   case NC_DOUBLE:
+   case NC_INT64:
+   case NC_UINT64:
+      return 8;
    }
    return -1;
 }
 
-/* Given a filename, check to see if it is a HDF5 file. */
-#define MAGIC_NUMBER_LEN 4
-#define NC_HDF5_FILE 1
-#define NC_HDF4_FILE 2
-static int
-nc_check_for_hdf(const char *path, int flags, void* parameters, int *hdf_file)
-{
-   char blob[MAGIC_NUMBER_LEN];
-#ifdef USE_PARALLEL4
-   int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
-   NC_MPI_INFO* mpiinfo = (NC_MPI_INFO*)parameters;
-   MPI_Comm comm = MPI_COMM_WORLD;
-   MPI_Info info = MPI_INFO_NULL;
-#endif
-   int inmemory = ((flags & NC_INMEMORY) == NC_INMEMORY);
-   NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
-
-#ifdef USE_PARALLEL4
-   if(use_parallel) {
-       comm = mpiinfo->comm;
-       info = mpiinfo->info;
-   }
-#endif
-
-   assert(hdf_file);
-   LOG((3, "%s: path %s", __func__, path));
-
-   /* HDF5 function handles possible user block at beginning of file */
-   if(!inmemory && H5Fis_hdf5(path))
-   {
-       *hdf_file = NC_HDF5_FILE;
-   } else {
-
-/* Get the 4-byte blob from the beginning of the file. Don't use posix
- * for parallel, use the MPI functions instead. */
-#ifdef USE_PARALLEL4
-       if (!inmemory && use_parallel)
-       {
-	   MPI_File fh;
-	   MPI_Status status;
-	   int retval;
-	   if ((retval = MPI_File_open(comm, (char *)path, MPI_MODE_RDONLY,
-				       info, &fh)) != MPI_SUCCESS)
-	       return NC_EPARINIT;
-	   if ((retval = MPI_File_read(fh, blob, MAGIC_NUMBER_LEN, MPI_CHAR,
-				       &status)) != MPI_SUCCESS)
-	       return NC_EPARINIT;
-	   if ((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
-	       return NC_EPARINIT;
-       }
-       else
-#endif /* USE_PARALLEL4 */
-       if(!inmemory) {
-	   FILE *fp;
-	   if (!(fp = fopen(path, "r")) ||
-	       fread(blob, MAGIC_NUMBER_LEN, 1, fp) != 1) {
-
-	     if(fp) fclose(fp);
-	     return errno;
-	   }
-	   fclose(fp);
-       } else { /*inmemory*/
-	  if(meminfo->size < MAGIC_NUMBER_LEN)
-	    return NC_ENOTNC;
-	  memcpy(blob,meminfo->memory,MAGIC_NUMBER_LEN);
-       }
-
-       /* Check for HDF4. */
-       if (memcmp(blob, "\016\003\023\001", 4)==0)
-	   *hdf_file = NC_HDF4_FILE;
-       else if (memcmp(blob, "HDF", 3)==0)
-	   *hdf_file = NC_HDF5_FILE;
-       else
-	   *hdf_file = 0;
-   }
-   return NC_NOERR;
-}
-
-/* Create a HDF5/netcdf-4 file. */
-
+/**
+ * @internal Create a netCDF-4/HDF5 file.
+ *
+ * @param path The file name of the new file.
+ * @param cmode The creation mode flag.
+ * @param comm MPI communicator (parallel IO only).
+ * @param info MPI info (parallel IO only).
+ * @param nc Pointer to an instance of NC.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EINVAL Invalid input (check cmode).
+ * @return ::NC_EEXIST File exists and NC_NOCLOBBER used.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @ingroup netcdf4
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 static int
 nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
                 NC *nc)
@@ -380,24 +866,22 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
    int persist = 0; /* Should diskless try to persist its data into file?*/
 #endif
 
-   assert(nc);
+   assert(nc && path);
+   LOG((3, "%s: path %s mode 0x%x", __func__, path, cmode));
 
    if(cmode & NC_DISKLESS)
-       flags = H5F_ACC_TRUNC;
+      flags = H5F_ACC_TRUNC;
    else if(cmode & NC_NOCLOBBER)
-       flags = H5F_ACC_EXCL;
+      flags = H5F_ACC_EXCL;
    else
-       flags = H5F_ACC_TRUNC;
-
-   LOG((3, "%s: path %s mode 0x%x", __func__, path, cmode));
-   assert(nc && path);
+      flags = H5F_ACC_TRUNC;
 
    /* If this file already exists, and NC_NOCLOBBER is specified,
       return an error. */
    if (cmode & NC_DISKLESS) {
 #ifndef USE_PARALLEL4
-	if(cmode & NC_WRITE)
-	    persist = 1;
+      if(cmode & NC_WRITE)
+         persist = 1;
 #endif
    } else if ((cmode & NC_NOCLOBBER) && (fp = fopen(path, "r"))) {
       fclose(fp);
@@ -415,16 +899,8 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
     * fail if there are any open objects in the file. */
    if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists++;
-#endif
-#ifdef EXTRA_TESTS
    if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI))
       BAIL(NC_EHDFERR);
-#else
-   if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG))
-      BAIL(NC_EHDFERR);
-#endif /* EXTRA_TESTS */
 
 #ifdef USE_PARALLEL4
    /* If this is a parallel file create, set up the file creation
@@ -434,16 +910,16 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
       nc4_info->parallel = NC_TRUE;
       if (cmode & NC_MPIIO)  /* MPI/IO */
       {
-	 LOG((4, "creating parallel file with MPI/IO"));
-	 if (H5Pset_fapl_mpio(fapl_id, comm, info) < 0)
-	    BAIL(NC_EPARINIT);
+         LOG((4, "creating parallel file with MPI/IO"));
+         if (H5Pset_fapl_mpio(fapl_id, comm, info) < 0)
+            BAIL(NC_EPARINIT);
       }
 #ifdef USE_PARALLEL_POSIX
       else /* MPI/POSIX */
       {
-	 LOG((4, "creating parallel file with MPI/posix"));
-	 if (H5Pset_fapl_mpiposix(fapl_id, comm, 0) < 0)
-	    BAIL(NC_EPARINIT);
+         LOG((4, "creating parallel file with MPI/posix"));
+         if (H5Pset_fapl_mpiposix(fapl_id, comm, 0) < 0)
+            BAIL(NC_EPARINIT);
       }
 #else /* USE_PARALLEL_POSIX */
       /* Should not happen! Code in NC4_create/NC4_open should alias the
@@ -472,14 +948,14 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
    }
 #else /* only set cache for non-parallel... */
    if(cmode & NC_DISKLESS) {
-	 if (H5Pset_fapl_core(fapl_id, 4096, persist))
-	    BAIL(NC_EDISKLESS);
+      if (H5Pset_fapl_core(fapl_id, 4096, persist))
+         BAIL(NC_EDISKLESS);
    }
    if (H5Pset_cache(fapl_id, 0, nc4_chunk_cache_nelems, nc4_chunk_cache_size,
-		    nc4_chunk_cache_preemption) < 0)
+                    nc4_chunk_cache_preemption) < 0)
       BAIL(NC_EHDFERR);
    LOG((4, "%s: set HDF raw chunk cache to size %d nelems %d preemption %f",
-	__func__, nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption));
+        __func__, nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption));
 #endif /* USE_PARALLEL4 */
 
 #ifdef HDF5_HAS_LIBVER_BOUNDS
@@ -490,9 +966,6 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
    /* Create the property list. */
    if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0)
       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists++;
-#endif
 
    /* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
    if (H5Pset_obj_track_times(fcpl_id,0)<0)
@@ -502,10 +975,10 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
     * H5P_CRT_ORDER_TRACKED in the creation property list. This turns
     * on HDF5 creation ordering. */
    if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
-					    H5P_CRT_ORDER_INDEXED)) < 0)
+                                            H5P_CRT_ORDER_INDEXED)) < 0)
       BAIL(NC_EHDFERR);
    if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
-					    H5P_CRT_ORDER_INDEXED)) < 0)
+                                            H5P_CRT_ORDER_INDEXED)) < 0)
       BAIL(NC_EHDFERR);
 
    /* Create the file. */
@@ -515,22 +988,18 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
 #endif
 
    if ((nc4_info->hdfid = H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
-        /*Change the return error from NC_EFILEMETADATA to
-          System error EACCES because that is the more likely problem */
+      /*Change the return error from NC_EFILEMETADATA to
+        System error EACCES because that is the more likely problem */
       BAIL(EACCES);
 
    /* Open the root group. */
    if ((nc4_info->root_grp->hdf_grpid = H5Gopen2(nc4_info->hdfid, "/",
-						     H5P_DEFAULT)) < 0)
+                                                 H5P_DEFAULT)) < 0)
       BAIL(NC_EFILEMETA);
 
    /* Release the property lists. */
    if (H5Pclose(fapl_id) < 0 || H5Pclose(fcpl_id) < 0)
       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists--;
-   num_plists--;
-#endif
 
    /* Define mode gets turned on automatically on create. */
    nc4_info->flags |= NC_INDEF;
@@ -545,34 +1014,35 @@ exit: /*failure exit*/
    if (comm_duped) MPI_Comm_free(&nc4_info->comm);
    if (info_duped) MPI_Info_free(&nc4_info->info);
 #endif
-#ifdef EXTRA_TESTS
-   num_plists--;
-#endif
    if (fapl_id != H5P_DEFAULT) H5Pclose(fapl_id);
    if(!nc4_info) return retval;
    close_netcdf4_file(nc4_info,1); /* treat like abort */
    return retval;
 }
 
-/** \ingroup netcdf4
-Create a netCDF-4/HDF5 file.
-
-\param path The file name of the new file.
-\param cmode The creation mode flag.
-\param initialsz Ignored by this function.
-\param basepe Ignored by this function.
-\param chunksizehintp Ignored by this function.
-\param use_parallel 0 for sequential, non-zero for parallel I/O.
-\param parameters pointer to struct holding extra data (e.g. for parallel I/O)
-layer. Ignored if NULL.
-\param dispatch Pointer to the dispatch table for this file.
-\param nc_file Pointer to an instance of NC.
-\return NC_INVAL Invalid input (check cmode).
-*/
+/**
+ * @internal Create a netCDF-4/HDF5 file.
+ *
+ * @param path The file name of the new file.
+ * @param cmode The creation mode flag.
+ * @param initialsz Ignored by this function.
+ * @param basepe Ignored by this function.
+ * @param chunksizehintp Ignored by this function.
+ * @param use_parallel 0 for sequential, non-zero for parallel I/O.
+ * @param parameters pointer to struct holding extra data (e.g. for parallel I/O)
+ * layer. Ignored if NULL.
+ * @param dispatch Pointer to the dispatch table for this file.
+ * @param nc_file Pointer to an instance of NC.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EINVAL Invalid input (check cmode).
+ * @ingroup netcdf4
+ * @author Ed Hartnett
+ */
 int
 NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
-	   size_t *chunksizehintp, int use_parallel, void *parameters,
-	   NC_Dispatch *dispatch, NC* nc_file)
+           size_t *chunksizehintp, int use_parallel, void *parameters,
+           NC_Dispatch *dispatch, NC* nc_file)
 {
    MPI_Comm comm = MPI_COMM_WORLD;
    MPI_Info info = MPI_INFO_NULL;
@@ -581,7 +1051,7 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
    assert(nc_file && path);
 
    LOG((1, "%s: path %s cmode 0x%x comm %d info %d",
-	__func__, path, cmode, comm, info));
+        __func__, path, cmode, comm, info));
 
 #ifdef USE_PARALLEL4
    if (parameters)
@@ -593,19 +1063,19 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
 
    /* If this is our first file, turn off HDF5 error messages. */
    if (!nc4_hdf5_initialized)
-	nc4_hdf5_initialize();
+      nc4_hdf5_initialize();
 
    /* Check the cmode for validity. */
    if((cmode & ILLEGAL_CREATE_FLAGS) != 0)
-      {res = NC_EINVAL; goto done;}
+   {res = NC_EINVAL; goto done;}
 
    /* Cannot have both */
    if((cmode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX))
-      {res = NC_EINVAL; goto done;}
+   {res = NC_EINVAL; goto done;}
 
    /* Currently no parallel diskless io */
    if((cmode & (NC_MPIIO | NC_MPIPOSIX)) && (cmode & NC_DISKLESS))
-      {res = NC_EINVAL; goto done;}
+   {res = NC_EINVAL; goto done;}
 
 #ifndef USE_PARALLEL_POSIX
 /* If the HDF5 library has been compiled without the MPI-POSIX VFD, alias
@@ -638,15 +1108,29 @@ done:
    return res;
 }
 
-/* This function is called by read_dataset when a dimension scale
- * dataset is encountered. It reads in the dimension data (creating a
- * new NC_DIM_INFO_T object), and also checks to see if this is a
- * dimension without a variable - that is, a coordinate dimension
- * which does not have any coordinate data. */
+/**
+ * @internal This function is called by read_dataset when a dimension
+ * scale dataset is encountered. It reads in the dimension data
+ * (creating a new NC_DIM_INFO_T object), and also checks to see if
+ * this is a dimension without a variable - that is, a coordinate
+ * dimension which does not have any coordinate data.
+ *
+ * @param grp Pointer to group info struct.
+ * @param datasetid The HDF5 dataset ID.
+ * @param obj_name
+ * @param statbuf
+ * @param scale_size Size of dimension scale.
+ * @param max_scale_size Maximum size of dim scale.
+ * @param dim Pointer to pointer that gets new dim info struct.
+ *
+ * @returns ::NC_NOERR No error.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @author Ed Hartnett
+ */
 static int
 read_scale(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
-        const H5G_stat_t *statbuf, hsize_t scale_size, hsize_t max_scale_size,
-        NC_DIM_INFO_T **dim)
+           const H5G_stat_t *statbuf, hsize_t scale_size, hsize_t max_scale_size,
+           NC_DIM_INFO_T **dim)
 {
    NC_DIM_INFO_T *new_dim;              /* Dimension added to group */
    char dimscale_name_att[NC_MAX_NAME + 1] = "";    /* Dimscale name, for checking if dim without var */
@@ -737,9 +1221,9 @@ exit:
    /* On error, undo any dimscale creation */
    if (retval < 0 && dimscale_created)
    {
-       /* Delete the dimension */
-       if ((retval = nc4_dim_list_del(&grp->dim, new_dim)))
-           BAIL2(retval);
+      /* Delete the dimension */
+      if ((retval = nc4_dim_list_del(&grp->dim, new_dim)))
+         BAIL2(retval);
 
       /* Reset the group's information */
       grp->nc4_info->next_dimid = initial_next_dimid;
@@ -748,8 +1232,16 @@ exit:
    return retval;
 }
 
-/* This function reads the hacked in coordinates attribute I use for
- * multi-dimensional coordinates. */
+/**
+ * @internal This function reads the hacked in coordinates attribute I
+ * use for multi-dimensional coordinates. 
+ *
+ * @param grp Group info pointer.
+ * @param var Var info pointer.
+ *
+ * @return NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int
 read_coord_dimids(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 {
@@ -766,9 +1258,6 @@ read_coord_dimids(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 
    /* How many dimensions are there? */
    if (!ret && (spaceid = H5Aget_space(coord_attid)) < 0) ret++;
-#ifdef EXTRA_TESTS
-   num_spaces++;
-#endif
    if (!ret && (npoints = H5Sget_simple_extent_npoints(spaceid)) < 0) ret++;
 
    /* Check that the number of points is the same as the number of dimensions
@@ -780,22 +1269,29 @@ read_coord_dimids(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 
    /* Update var->dim field based on the var->dimids */
    for (d = 0; d < var->ndims; d++) {
-     /* Ok if does not find a dim at this time, but if found set it */
-     nc4_find_dim(grp, var->dimids[d], &var->dim[d], NULL);
+      /* Ok if does not find a dim at this time, but if found set it */
+      nc4_find_dim(grp, var->dimids[d], &var->dim[d], NULL);
    }
 
    /* Set my HDF5 IDs free! */
    if (spaceid >= 0 && H5Sclose(spaceid) < 0) ret++;
-#ifdef EXTRA_TESTS
-   num_spaces--;
-#endif
    if (coord_att_typeid >= 0 && H5Tclose(coord_att_typeid) < 0) ret++;
    if (coord_attid >= 0 && H5Aclose(coord_attid) < 0) ret++;
    return ret ? NC_EATTMETA : NC_NOERR;
 }
 
-/* This function is called when reading a file's metadata for each
- * dimension scale attached to a variable.*/
+/**
+ * @internal This function is called when reading a file's metadata
+ * for each dimension scale attached to a variable.
+ *
+ * @param did HDF5 ID for dimscale.
+ * @param dim
+ * @param dsid
+ * @param dimscale_hdf5_objids
+ *
+ * @return 0 for success, -1 for error.
+ * @author Ed Hartnett
+*/
 static herr_t
 dimscale_visitor(hid_t did, unsigned dim, hid_t dsid,
                  void *dimscale_hdf5_objids)
@@ -814,126 +1310,24 @@ dimscale_visitor(hid_t did, unsigned dim, hid_t dsid,
    return 0;
 }
 
-/* Given an HDF5 type, set a pointer to netcdf type. */
-static int
-get_netcdf_type(NC_HDF5_FILE_INFO_T *h5, hid_t native_typeid,
-		nc_type *xtype)
-{
-   NC_TYPE_INFO_T *type;
-   H5T_class_t class;
-   htri_t is_str, equal = 0;
-
-   assert(h5 && xtype);
-
-   if ((class = H5Tget_class(native_typeid)) < 0)
-      return NC_EHDFERR;
-
-   /* H5Tequal doesn't work with H5T_C_S1 for some reason. But
-    * H5Tget_class will return H5T_STRING if this is a string. */
-   if (class == H5T_STRING)
-   {
-      if ((is_str = H5Tis_variable_str(native_typeid)) < 0)
-         return NC_EHDFERR;
-      if (is_str)
-         *xtype = NC_STRING;
-      else
-         *xtype = NC_CHAR;
-      return NC_NOERR;
-   }
-   else if (class == H5T_INTEGER || class == H5T_FLOAT)
-   {
-      /* For integers and floats, we don't have to worry about
-       * endianness if we compare native types. */
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_SCHAR)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_BYTE;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_SHORT)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_SHORT;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_INT)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_INT;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_FLOAT)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_FLOAT;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_DOUBLE)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_DOUBLE;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_UCHAR)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_UBYTE;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_USHORT)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_USHORT;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_UINT)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_UINT;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_LLONG)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_INT64;
-         return NC_NOERR;
-      }
-      if ((equal = H5Tequal(native_typeid, H5T_NATIVE_ULLONG)) < 0)
-         return NC_EHDFERR;
-      if (equal)
-      {
-         *xtype = NC_UINT64;
-         return NC_NOERR;
-      }
-   }
-
-   /* Maybe we already know about this type. */
-   if (!equal)
-      if((type = nc4_rec_find_hdf_type(h5->root_grp, native_typeid)))
-      {
-         *xtype = type->nc_typeid;
-         return NC_NOERR;
-      }
-
-   *xtype = NC_NAT;
-   return NC_EBADTYPID;
-}
-
-/* Given an HDF5 type, set a pointer to netcdf type_info struct,
+/**
+ * @internal Given an HDF5 type, set a pointer to netcdf type_info struct,
  * either an existing one (for user-defined types) or a newly created
- * one. */
+ * one. 
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param datasetid HDF5 dataset ID.
+ * @param type_info Pointer to pointer that gets type info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @return ::NC_EBADTYPID Type not found.
+ * @author Ed Hartnett
+*/
 static int
 get_type_info2(NC_HDF5_FILE_INFO_T *h5, hid_t datasetid,
-	       NC_TYPE_INFO_T **type_info)
+               NC_TYPE_INFO_T **type_info)
 {
    htri_t is_str, equal = 0;
    H5T_class_t class;
@@ -958,311 +1352,127 @@ get_type_info2(NC_HDF5_FILE_INFO_T *h5, hid_t datasetid,
       h5_native_type_constant_g[5] = H5T_NATIVE_DOUBLE;
       h5_native_type_constant_g[6] = H5T_NATIVE_UCHAR;
       h5_native_type_constant_g[7] = H5T_NATIVE_USHORT;
-      h5_native_type_constant_g[8] = H5T_NATIVE_UINT;
-      h5_native_type_constant_g[9] = H5T_NATIVE_LLONG;
-      h5_native_type_constant_g[10] = H5T_NATIVE_ULLONG;
-   }
-
-   /* Get the HDF5 typeid - we'll need it later. */
-   if ((hdf_typeid = H5Dget_type(datasetid)) < 0)
-      return NC_EHDFERR;
-
-   /* Get the native typeid. Will be equivalent to hdf_typeid when
-    * creating but not necessarily when reading, a variable. */
-   if ((native_typeid = H5Tget_native_type(hdf_typeid, H5T_DIR_DEFAULT)) < 0)
-      return NC_EHDFERR;
-
-   /* Is this type an integer, string, compound, or what? */
-   if ((class = H5Tget_class(native_typeid)) < 0)
-      return NC_EHDFERR;
-
-   /* Is this an atomic type? */
-   if (class == H5T_STRING || class == H5T_INTEGER || class == H5T_FLOAT)
-   {
-      /* Allocate a phony NC_TYPE_INFO_T struct to hold type info. */
-      if (!(*type_info = calloc(1, sizeof(NC_TYPE_INFO_T))))
-	 return NC_ENOMEM;
-
-      /* H5Tequal doesn't work with H5T_C_S1 for some reason. But
-       * H5Tget_class will return H5T_STRING if this is a string. */
-      if (class == H5T_STRING)
-      {
-	 if ((is_str = H5Tis_variable_str(native_typeid)) < 0)
-	    return NC_EHDFERR;
-	 /* Make sure fixed-len strings will work like variable-len strings */
-	 if (is_str || H5Tget_size(hdf_typeid) > 1)
-         {
-            /* Set a class for the type */
-	    t = NUM_TYPES - 1;
-            (*type_info)->nc_type_class = NC_STRING;
-         }
-	 else
-         {
-            /* Set a class for the type */
-	    t = 0;
-            (*type_info)->nc_type_class = NC_CHAR;
-         }
-      }
-      else if (class == H5T_INTEGER || class == H5T_FLOAT)
-      {
-	 for (t = 1; t < NUM_TYPES - 1; t++)
-	 {
-	    if ((equal = H5Tequal(native_typeid, h5_native_type_constant_g[t])) < 0)
-	       return NC_EHDFERR;
-	    if (equal)
-	       break;
-	 }
-
-     /* Find out about endianness.
-      * As of HDF 1.8.6, this works with all data types
-      * Not just H5T_INTEGER.
-      *
-      * See https://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-GetOrder
-      */
-     if((order = H5Tget_order(hdf_typeid)) < 0)
-         return NC_EHDFERR;
-
-     if(order == H5T_ORDER_LE)
-         (*type_info)->endianness = NC_ENDIAN_LITTLE;
-     else if(order == H5T_ORDER_BE)
-         (*type_info)->endianness = NC_ENDIAN_BIG;
-     else
-         return NC_EBADTYPE;
-
-     if(class == H5T_INTEGER)
-          (*type_info)->nc_type_class = NC_INT;
-     else
-        (*type_info)->nc_type_class = NC_FLOAT;
-    }
-      (*type_info)->nc_typeid = nc_type_constant_g[t];
-      (*type_info)->size = nc_type_size_g[t];
-      if (!((*type_info)->name = strdup(nc_type_name_g[t])))
-	 return NC_ENOMEM;
-      (*type_info)->hdf_typeid = hdf_typeid;
-      (*type_info)->native_hdf_typeid = native_typeid;
-      return NC_NOERR;
-   }
-   else
-   {
-      NC_TYPE_INFO_T *type;
-
-      /* This is a user-defined type. */
-      if((type = nc4_rec_find_hdf_type(h5->root_grp, native_typeid)))
-	 *type_info = type;
-
-      /* The type entry in the array of user-defined types already has
-       * an open data typeid (and native typeid), so close the ones we
-       * opened above. */
-      if (H5Tclose(native_typeid) < 0)
-	 return NC_EHDFERR;
-      if (H5Tclose(hdf_typeid) < 0)
-	 return NC_EHDFERR;
-
-      if (type)
-         return NC_NOERR;
-   }
-
-   return NC_EBADTYPID;
-}
-
-/* Read an attribute. */
-static int
-read_hdf5_att(NC_GRP_INFO_T *grp, hid_t attid, NC_ATT_INFO_T *att)
-{
-   hid_t spaceid = 0, file_typeid = 0;
-   hsize_t dims[1] = {0}; /* netcdf attributes always 1-D. */
-   int retval = NC_NOERR;
-   size_t type_size;
-   int att_ndims;
-   hssize_t att_npoints;
-   H5T_class_t att_class;
-   int fixed_len_string = 0;
-   size_t fixed_size = 0;
-
-   assert(att->name);
-   LOG((5, "%s: att->attnum %d att->name %s att->nc_typeid %d att->len %d",
-        __func__, att->attnum, att->name, (int)att->nc_typeid, att->len));
-
-   /* Get type of attribute in file. */
-   if ((file_typeid = H5Aget_type(attid)) < 0)
-      return NC_EATTMETA;
-   if ((att->native_hdf_typeid = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0)
-      BAIL(NC_EHDFERR);
-   if ((att_class = H5Tget_class(att->native_hdf_typeid)) < 0)
-      BAIL(NC_EATTMETA);
-   if (att_class == H5T_STRING && !H5Tis_variable_str(att->native_hdf_typeid))
-   {
-      fixed_len_string++;
-      if (!(fixed_size = H5Tget_size(att->native_hdf_typeid)))
-	 BAIL(NC_EATTMETA);
-   }
-   if ((retval = get_netcdf_type(grp->nc4_info, att->native_hdf_typeid, &(att->nc_typeid))))
-      BAIL(retval);
-
-
-   /* Get len. */
-   if ((spaceid = H5Aget_space(attid)) < 0)
-      BAIL(NC_EATTMETA);
-#ifdef EXTRA_TESTS
-   num_spaces++;
-#endif
-   if ((att_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0)
-      BAIL(NC_EATTMETA);
-   if ((att_npoints = H5Sget_simple_extent_npoints(spaceid)) < 0)
-      BAIL(NC_EATTMETA);
-
-   /* If both att_ndims and att_npoints are zero, then this is a
-    * zero length att. */
-   if (att_ndims == 0 && att_npoints == 0)
-      dims[0] = 0;
-   else if (att->nc_typeid == NC_STRING)
-       dims[0] = att_npoints;
-   else if (att->nc_typeid == NC_CHAR)
-   {
-      /* NC_CHAR attributes are written as a scalar in HDF5, of type
-       * H5T_C_S1, of variable length. */
-     if (att_ndims == 0)
-       {
-         if (!(dims[0] = H5Tget_size(file_typeid)))
-           BAIL(NC_EATTMETA);
-       }
-     else
-       {
-         /* This is really a string type! */
-         att->nc_typeid = NC_STRING;
-         dims[0] = att_npoints;
-       }
-   }
-   else
-   {
-      H5S_class_t space_class;
-
-      /* All netcdf attributes are scalar or 1-D only. */
-      if (att_ndims > 1)
-	 BAIL(NC_EATTMETA);
-
-      /* Check class of HDF5 dataspace */
-      if ((space_class = H5Sget_simple_extent_type(spaceid)) < 0)
-	 BAIL(NC_EATTMETA);
+      h5_native_type_constant_g[8] = H5T_NATIVE_UINT;
+      h5_native_type_constant_g[9] = H5T_NATIVE_LLONG;
+      h5_native_type_constant_g[10] = H5T_NATIVE_ULLONG;
+   }
 
-      /* Check for NULL HDF5 dataspace class (should be weeded out earlier) */
-      if (H5S_NULL == space_class)
-	 BAIL(NC_EATTMETA);
+   /* Get the HDF5 typeid - we'll need it later. */
+   if ((hdf_typeid = H5Dget_type(datasetid)) < 0)
+      return NC_EHDFERR;
 
-      /* check for SCALAR HDF5 dataspace class */
-      if (H5S_SCALAR == space_class)
-          dims[0] = 1;
-      else /* Must be "simple" dataspace */
-      {
-          /* Read the size of this attribute. */
-          if (H5Sget_simple_extent_dims(spaceid, dims, NULL) < 0)
-             BAIL(NC_EATTMETA);
-      }
-   }
+   /* Get the native typeid. Will be equivalent to hdf_typeid when
+    * creating but not necessarily when reading, a variable. */
+   if ((native_typeid = H5Tget_native_type(hdf_typeid, H5T_DIR_DEFAULT)) < 0)
+      return NC_EHDFERR;
 
-   /* Tell the user what the length if this attribute is. */
-   att->len = dims[0];
+   /* Is this type an integer, string, compound, or what? */
+   if ((class = H5Tget_class(native_typeid)) < 0)
+      return NC_EHDFERR;
 
-   /* Allocate some memory if the len is not zero, and read the
-      attribute. */
-   if (dims[0])
+   /* Is this an atomic type? */
+   if (class == H5T_STRING || class == H5T_INTEGER || class == H5T_FLOAT)
    {
-      if ((retval = nc4_get_typelen_mem(grp->nc4_info, att->nc_typeid, 0,
-					&type_size)))
-	 return retval;
-      if (att_class == H5T_VLEN)
-      {
-	 if (!(att->vldata = malloc((unsigned int)(att->len * sizeof(hvl_t)))))
-	    BAIL(NC_ENOMEM);
-	 if (H5Aread(attid, att->native_hdf_typeid, att->vldata) < 0)
-	    BAIL(NC_EATTMETA);
-      }
-      else if (att->nc_typeid == NC_STRING)
+      /* Allocate a phony NC_TYPE_INFO_T struct to hold type info. */
+      if (!(*type_info = calloc(1, sizeof(NC_TYPE_INFO_T))))
+         return NC_ENOMEM;
+
+      /* H5Tequal doesn't work with H5T_C_S1 for some reason. But
+       * H5Tget_class will return H5T_STRING if this is a string. */
+      if (class == H5T_STRING)
       {
-	 if (!(att->stdata = calloc(att->len, sizeof(char *))))
-	    BAIL(NC_ENOMEM);
-	 /* For a fixed length HDF5 string, the read requires
-	  * contiguous memory. Meanwhile, the netCDF API requires that
-	  * nc_free_string be called on string arrays, which would not
-	  * work if one contiguous memory block were used. So here I
-	  * convert the contiguous block of strings into an array of
-	  * malloced strings (each string with its own malloc). Then I
-	  * copy the data and free the contiguous memory. This
-	  * involves copying the data, which is bad, but this only
-	  * occurs for fixed length string attributes, and presumably
-	  * these are small. (And netCDF-4 does not create them - it
-	  * always uses variable length strings. */
-	 if (fixed_len_string)
-	 {
-	    int i;
-	    char *contig_buf, *cur;
-
-	    /* Alloc space for the contiguous memory read. */
-	    if (!(contig_buf = malloc(att->len * fixed_size * sizeof(char))))
-	       BAIL(NC_ENOMEM);
-
-	    /* Read the fixed-len strings as one big block. */
-	    if (H5Aread(attid, att->native_hdf_typeid, contig_buf) < 0) {
-          free(contig_buf);
-          BAIL(NC_EATTMETA);
-        }
-
-	    /* Copy strings, one at a time, into their new home. Alloc
-	       space for each string. The user will later free this
-	       space with nc_free_string. */
-	    cur = contig_buf;
-	    for (i = 0; i < att->len; i++)
-	    {
-          if (!(att->stdata[i] = malloc(fixed_size))) {
-            free(contig_buf);
-            BAIL(NC_ENOMEM);
-          }
-           strncpy(att->stdata[i], cur, fixed_size);
-	       cur += fixed_size;
-	    }
-
-	    /* Free contiguous memory buffer. */
-	    free(contig_buf);
-	 }
-	 else
-	 {
-	    /* Read variable-length string atts. */
-	    if (H5Aread(attid, att->native_hdf_typeid, att->stdata) < 0)
-	       BAIL(NC_EATTMETA);
-	 }
+         if ((is_str = H5Tis_variable_str(native_typeid)) < 0)
+            return NC_EHDFERR;
+         /* Make sure fixed-len strings will work like variable-len strings */
+         if (is_str || H5Tget_size(hdf_typeid) > 1)
+         {
+            /* Set a class for the type */
+            t = NUM_TYPES - 1;
+            (*type_info)->nc_type_class = NC_STRING;
+         }
+         else
+         {
+            /* Set a class for the type */
+            t = 0;
+            (*type_info)->nc_type_class = NC_CHAR;
+         }
       }
-      else
+      else if (class == H5T_INTEGER || class == H5T_FLOAT)
       {
-	 if (!(att->data = malloc((unsigned int)(att->len * type_size))))
-	    BAIL(NC_ENOMEM);
-	 if (H5Aread(attid, att->native_hdf_typeid, att->data) < 0)
-	    BAIL(NC_EATTMETA);
+         for (t = 1; t < NUM_TYPES - 1; t++)
+         {
+            if ((equal = H5Tequal(native_typeid, h5_native_type_constant_g[t])) < 0)
+               return NC_EHDFERR;
+            if (equal)
+               break;
+         }
+
+         /* Find out about endianness.
+          * As of HDF 1.8.6, this works with all data types
+          * Not just H5T_INTEGER.
+          *
+          * See https://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-GetOrder
+          */
+         if((order = H5Tget_order(hdf_typeid)) < 0)
+            return NC_EHDFERR;
+
+         if(order == H5T_ORDER_LE)
+            (*type_info)->endianness = NC_ENDIAN_LITTLE;
+         else if(order == H5T_ORDER_BE)
+            (*type_info)->endianness = NC_ENDIAN_BIG;
+         else
+            return NC_EBADTYPE;
+
+         if(class == H5T_INTEGER)
+            (*type_info)->nc_type_class = NC_INT;
+         else
+            (*type_info)->nc_type_class = NC_FLOAT;
       }
+      (*type_info)->nc_typeid = nc_type_constant_g[t];
+      (*type_info)->size = nc_type_size_g[t];
+      if (!((*type_info)->name = strdup(nc_type_name_g[t])))
+         return NC_ENOMEM;
+      (*type_info)->hdf_typeid = hdf_typeid;
+      (*type_info)->native_hdf_typeid = native_typeid;
+      return NC_NOERR;
    }
+   else
+   {
+      NC_TYPE_INFO_T *type;
 
-   if (H5Tclose(file_typeid) < 0)
-      BAIL(NC_EHDFERR);
-   if (H5Sclose(spaceid) < 0)
-      return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-   num_spaces--;
-#endif
+      /* This is a user-defined type. */
+      if((type = nc4_rec_find_hdf_type(h5->root_grp, native_typeid)))
+         *type_info = type;
 
-   return NC_NOERR;
+      /* The type entry in the array of user-defined types already has
+       * an open data typeid (and native typeid), so close the ones we
+       * opened above. */
+      if (H5Tclose(native_typeid) < 0)
+         return NC_EHDFERR;
+      if (H5Tclose(hdf_typeid) < 0)
+         return NC_EHDFERR;
 
-  exit:
-   if (H5Tclose(file_typeid) < 0)
-      BAIL2(NC_EHDFERR);
-   if (spaceid > 0 && H5Sclose(spaceid) < 0)
-      BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_spaces--;
-#endif
-   return retval;
+      if (type)
+         return NC_NOERR;
+   }
+
+   return NC_EBADTYPID;
 }
 
-/* Read information about a user defined type from the HDF5 file, and
- * stash it in the group's list of types. */
+/**
+ * @internal Read information about a user defined type from the HDF5
+ * file, and stash it in the group's list of types.
+ *
+ * @param grp Pointer to group info struct.
+ * @param hdf_typeid HDF5 type ID.
+ * @param type_name Pointer that gets the type name.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @return ::NC_EBADTYPID Type not found.
+ * @author Ed Hartnett
+*/
 static int
 read_type(NC_GRP_INFO_T *grp, hid_t hdf_typeid, char *type_name)
 {
@@ -1300,253 +1510,266 @@ read_type(NC_GRP_INFO_T *grp, hid_t hdf_typeid, char *type_name)
       return NC_EHDFERR;
    switch (class)
    {
-      case H5T_STRING:
-         type->nc_type_class = NC_STRING;
-         break;
+   case H5T_STRING:
+      type->nc_type_class = NC_STRING;
+      break;
 
-      case H5T_COMPOUND:
-         {
-            int nmembers;
-            unsigned int m;
-	    char* member_name = NULL;
+   case H5T_COMPOUND:
+   {
+      int nmembers;
+      unsigned int m;
+      char* member_name = NULL;
 #ifdef JNA
-            char jna[1001];
+      char jna[1001];
 #endif
 
-            type->nc_type_class = NC_COMPOUND;
+      type->nc_type_class = NC_COMPOUND;
 
-            if ((nmembers = H5Tget_nmembers(hdf_typeid)) < 0)
-               return NC_EHDFERR;
-            LOG((5, "compound type has %d members", nmembers));
-            for (m = 0; m < nmembers; m++)
-            {
-               hid_t member_hdf_typeid;
-               hid_t member_native_typeid;
-               size_t member_offset;
-               H5T_class_t mem_class;
-               nc_type member_xtype;
-
-
-               /* Get the typeid and native typeid of this member of the
-                * compound type. */
-               if ((member_hdf_typeid = H5Tget_member_type(type->native_hdf_typeid, m)) < 0)
-                  return NC_EHDFERR;
-
-               if ((member_native_typeid = H5Tget_native_type(member_hdf_typeid, H5T_DIR_DEFAULT)) < 0)
-                  return NC_EHDFERR;
-
-               /* Get the name of the member.*/
-               member_name = H5Tget_member_name(type->native_hdf_typeid, m);
-               if (!member_name || strlen(member_name) > NC_MAX_NAME) {
-                  retval = NC_EBADNAME;
-		  break;
-	       }
-#ifdef JNA
-	       else {
-		strncpy(jna,member_name,1000);
-		member_name = jna;
-               }
-#endif
+      if ((nmembers = H5Tget_nmembers(hdf_typeid)) < 0)
+         return NC_EHDFERR;
+      LOG((5, "compound type has %d members", nmembers));
+      for (m = 0; m < nmembers; m++)
+      {
+         hid_t member_hdf_typeid;
+         hid_t member_native_typeid;
+         size_t member_offset;
+         H5T_class_t mem_class;
+         nc_type member_xtype;
 
-               /* Offset in bytes on *this* platform. */
-               member_offset = H5Tget_member_offset(type->native_hdf_typeid, m);
-
-               /* Get dimensional data if this member is an array of something. */
-               if ((mem_class = H5Tget_class(member_hdf_typeid)) < 0)
-                  return NC_EHDFERR;
-               if (mem_class == H5T_ARRAY)
-               {
-                  int ndims, dim_size[NC_MAX_VAR_DIMS];
-                  hsize_t dims[NC_MAX_VAR_DIMS];
-                  int d;
-
-                  if ((ndims = H5Tget_array_ndims(member_hdf_typeid)) < 0) {
-                     retval = NC_EHDFERR;
-		     break;
-		  }
-                  if (H5Tget_array_dims(member_hdf_typeid, dims, NULL) != ndims) {
-                     retval = NC_EHDFERR;
-		     break;
-		  }
-                  for (d = 0; d < ndims; d++)
-                     dim_size[d] = dims[d];
-
-                  /* What is the netCDF typeid of this member? */
-                  if ((retval = get_netcdf_type(grp->nc4_info, H5Tget_super(member_hdf_typeid),
-                                                &member_xtype)))
-		     break;
-
-                  /* Add this member to our list of fields in this compound type. */
-                  if ((retval = nc4_field_list_add(&type->u.c.field, type->u.c.num_fields++, member_name,
-                                                   member_offset, H5Tget_super(member_hdf_typeid),
-                                                   H5Tget_super(member_native_typeid),
-                                                   member_xtype, ndims, dim_size)))
-                     break;
-               }
-               else
-               {
-                  /* What is the netCDF typeid of this member? */
-                  if ((retval = get_netcdf_type(grp->nc4_info, member_native_typeid,
-                                                &member_xtype)))
-                     break;
-
-                  /* Add this member to our list of fields in this compound type. */
-                  if ((retval = nc4_field_list_add(&type->u.c.field, type->u.c.num_fields++, member_name,
-                                                   member_offset, member_hdf_typeid, member_native_typeid,
-                                                   member_xtype, 0, NULL)))
-                     break;
-               }
 
-	       hdf5free(member_name);
-	       member_name = NULL;
-            }
-	    hdf5free(member_name);
-	    member_name = NULL;	    	
-	    if(retval) /* error exit from loop */
-		return retval;
+         /* Get the typeid and native typeid of this member of the
+          * compound type. */
+         if ((member_hdf_typeid = H5Tget_member_type(type->native_hdf_typeid, m)) < 0)
+            return NC_EHDFERR;
+
+         if ((member_native_typeid = H5Tget_native_type(member_hdf_typeid, H5T_DIR_DEFAULT)) < 0)
+            return NC_EHDFERR;
+
+         /* Get the name of the member.*/
+         member_name = H5Tget_member_name(type->native_hdf_typeid, m);
+         if (!member_name || strlen(member_name) > NC_MAX_NAME) {
+            retval = NC_EBADNAME;
+            break;
          }
-         break;
+#ifdef JNA
+         else {
+            strncpy(jna,member_name,1000);
+            member_name = jna;
+         }
+#endif
 
-      case H5T_VLEN:
+         /* Offset in bytes on *this* platform. */
+         member_offset = H5Tget_member_offset(type->native_hdf_typeid, m);
+
+         /* Get dimensional data if this member is an array of something. */
+         if ((mem_class = H5Tget_class(member_hdf_typeid)) < 0)
+            return NC_EHDFERR;
+         if (mem_class == H5T_ARRAY)
          {
-            htri_t ret;
+            int ndims, dim_size[NC_MAX_VAR_DIMS];
+            hsize_t dims[NC_MAX_VAR_DIMS];
+            int d;
 
-            /* For conveninence we allow user to pass vlens of strings
-             * with null terminated strings. This means strings are
-             * treated slightly differently by the API, although they are
-             * really just VLENs of characters. */
-            if ((ret = H5Tis_variable_str(hdf_typeid)) < 0)
-               return NC_EHDFERR;
-            if (ret)
-               type->nc_type_class = NC_STRING;
-            else
-            {
-               hid_t base_hdf_typeid;
-               nc_type base_nc_type = NC_NAT;
-
-               type->nc_type_class = NC_VLEN;
-
-               /* Find the base type of this vlen (i.e. what is this a
-                * vlen of?) */
-               if (!(base_hdf_typeid = H5Tget_super(native_typeid)))
-                  return NC_EHDFERR;
-
-               /* What size is this type? */
-               if (!(type_size = H5Tget_size(base_hdf_typeid)))
-                  return NC_EHDFERR;
-
-               /* What is the netcdf corresponding type. */
-               if ((retval = get_netcdf_type(grp->nc4_info, base_hdf_typeid,
-                                             &base_nc_type)))
-                  return retval;
-               LOG((5, "base_hdf_typeid 0x%x type_size %d base_nc_type %d",
-                    base_hdf_typeid, type_size, base_nc_type));
-
-               /* Remember the base types for this vlen */
-               type->u.v.base_nc_typeid = base_nc_type;
-               type->u.v.base_hdf_typeid = base_hdf_typeid;
+            if ((ndims = H5Tget_array_ndims(member_hdf_typeid)) < 0) {
+               retval = NC_EHDFERR;
+               break;
             }
+            if (H5Tget_array_dims(member_hdf_typeid, dims, NULL) != ndims) {
+               retval = NC_EHDFERR;
+               break;
+            }
+            for (d = 0; d < ndims; d++)
+               dim_size[d] = dims[d];
+
+            /* What is the netCDF typeid of this member? */
+            if ((retval = get_netcdf_type(grp->nc4_info, H5Tget_super(member_hdf_typeid),
+                                          &member_xtype)))
+               break;
+
+            /* Add this member to our list of fields in this compound type. */
+            if ((retval = nc4_field_list_add(&type->u.c.field, type->u.c.num_fields++, member_name,
+                                             member_offset, H5Tget_super(member_hdf_typeid),
+                                             H5Tget_super(member_native_typeid),
+                                             member_xtype, ndims, dim_size)))
+               break;
+         }
+         else
+         {
+            /* What is the netCDF typeid of this member? */
+            if ((retval = get_netcdf_type(grp->nc4_info, member_native_typeid,
+                                          &member_xtype)))
+               break;
+
+            /* Add this member to our list of fields in this compound type. */
+            if ((retval = nc4_field_list_add(&type->u.c.field, type->u.c.num_fields++, member_name,
+                                             member_offset, member_hdf_typeid, member_native_typeid,
+                                             member_xtype, 0, NULL)))
+               break;
          }
-         break;
 
-      case H5T_OPAQUE:
-         type->nc_type_class = NC_OPAQUE;
-         break;
+         hdf5free(member_name);
+         member_name = NULL;
+      }
+      hdf5free(member_name);
+      member_name = NULL;
+      if(retval) /* error exit from loop */
+         return retval;
+   }
+   break;
 
-      case H5T_ENUM:
-         {
-            hid_t base_hdf_typeid;
-            nc_type base_nc_type = NC_NAT;
-            void *value;
-            int i;
-	    char *member_name = NULL;
-#ifdef JNA
-            char jna[1001];
-#endif
+   case H5T_VLEN:
+   {
+      htri_t ret;
+
+      /* For conveninence we allow user to pass vlens of strings
+       * with null terminated strings. This means strings are
+       * treated slightly differently by the API, although they are
+       * really just VLENs of characters. */
+      if ((ret = H5Tis_variable_str(hdf_typeid)) < 0)
+         return NC_EHDFERR;
+      if (ret)
+         type->nc_type_class = NC_STRING;
+      else
+      {
+         hid_t base_hdf_typeid;
+         nc_type base_nc_type = NC_NAT;
+
+         type->nc_type_class = NC_VLEN;
+
+         /* Find the base type of this vlen (i.e. what is this a
+          * vlen of?) */
+         if (!(base_hdf_typeid = H5Tget_super(native_typeid)))
+            return NC_EHDFERR;
+
+         /* What size is this type? */
+         if (!(type_size = H5Tget_size(base_hdf_typeid)))
+            return NC_EHDFERR;
+
+         /* What is the netcdf corresponding type. */
+         if ((retval = get_netcdf_type(grp->nc4_info, base_hdf_typeid,
+                                       &base_nc_type)))
+            return retval;
+         LOG((5, "base_hdf_typeid 0x%x type_size %d base_nc_type %d",
+              base_hdf_typeid, type_size, base_nc_type));
+
+         /* Remember the base types for this vlen */
+         type->u.v.base_nc_typeid = base_nc_type;
+         type->u.v.base_hdf_typeid = base_hdf_typeid;
+      }
+   }
+   break;
 
-            type->nc_type_class = NC_ENUM;
+   case H5T_OPAQUE:
+      type->nc_type_class = NC_OPAQUE;
+      break;
 
-            /* Find the base type of this enum (i.e. what is this a
-             * enum of?) */
-            if (!(base_hdf_typeid = H5Tget_super(hdf_typeid)))
-               return NC_EHDFERR;
-            /* What size is this type? */
-            if (!(type_size = H5Tget_size(base_hdf_typeid)))
-               return NC_EHDFERR;
-            /* What is the netcdf corresponding type. */
-            if ((retval = get_netcdf_type(grp->nc4_info, base_hdf_typeid,
-                                          &base_nc_type)))
-               return retval;
-            LOG((5, "base_hdf_typeid 0x%x type_size %d base_nc_type %d",
-                 base_hdf_typeid, type_size, base_nc_type));
+   case H5T_ENUM:
+   {
+      hid_t base_hdf_typeid;
+      nc_type base_nc_type = NC_NAT;
+      void *value;
+      int i;
+      char *member_name = NULL;
+#ifdef JNA
+      char jna[1001];
+#endif
 
-            /* Remember the base types for this enum */
-            type->u.e.base_nc_typeid = base_nc_type;
-            type->u.e.base_hdf_typeid = base_hdf_typeid;
+      type->nc_type_class = NC_ENUM;
 
-            /* Find out how many member are in the enum. */
-            if ((type->u.e.num_members = H5Tget_nmembers(hdf_typeid)) < 0)
-               return NC_EHDFERR;
+      /* Find the base type of this enum (i.e. what is this a
+       * enum of?) */
+      if (!(base_hdf_typeid = H5Tget_super(hdf_typeid)))
+         return NC_EHDFERR;
+      /* What size is this type? */
+      if (!(type_size = H5Tget_size(base_hdf_typeid)))
+         return NC_EHDFERR;
+      /* What is the netcdf corresponding type. */
+      if ((retval = get_netcdf_type(grp->nc4_info, base_hdf_typeid,
+                                    &base_nc_type)))
+         return retval;
+      LOG((5, "base_hdf_typeid 0x%x type_size %d base_nc_type %d",
+           base_hdf_typeid, type_size, base_nc_type));
+
+      /* Remember the base types for this enum */
+      type->u.e.base_nc_typeid = base_nc_type;
+      type->u.e.base_hdf_typeid = base_hdf_typeid;
+
+      /* Find out how many member are in the enum. */
+      if ((type->u.e.num_members = H5Tget_nmembers(hdf_typeid)) < 0)
+         return NC_EHDFERR;
 
-            /* Allocate space for one value. */
-            if (!(value = calloc(1, type_size)))
-               return NC_ENOMEM;
+      /* Allocate space for one value. */
+      if (!(value = calloc(1, type_size)))
+         return NC_ENOMEM;
 
-            /* Read each name and value defined in the enum. */
-            for (i = 0; i < type->u.e.num_members; i++)
-            {
+      /* Read each name and value defined in the enum. */
+      for (i = 0; i < type->u.e.num_members; i++)
+      {
 
-               /* Get the name and value from HDF5. */
-               if (!(member_name = H5Tget_member_name(hdf_typeid, i)))
-               {
-                  retval = NC_EHDFERR;
-		  break;
-               }
+         /* Get the name and value from HDF5. */
+         if (!(member_name = H5Tget_member_name(hdf_typeid, i)))
+         {
+            retval = NC_EHDFERR;
+            break;
+         }
 #ifdef JNA
-		strncpy(jna,member_name,1000);
-		member_name = jna;
+         strncpy(jna,member_name,1000);
+         member_name = jna;
 #endif
 
-               if (strlen(member_name) > NC_MAX_NAME)
-               {
-                  retval = NC_EBADNAME;
-		  break;
-               }
-               if (H5Tget_member_value(hdf_typeid, i, value) < 0)
-               {
-                  retval = NC_EHDFERR;
-		  break;
-               }
-
-               /* Insert new field into this type's list of fields. */
-               if ((retval = nc4_enum_member_add(&type->u.e.enum_member, type->size,
-                                                 member_name, value)))
-               {
-		  break;
-               }
+         if (strlen(member_name) > NC_MAX_NAME)
+         {
+            retval = NC_EBADNAME;
+            break;
+         }
+         if (H5Tget_member_value(hdf_typeid, i, value) < 0)
+         {
+            retval = NC_EHDFERR;
+            break;
+         }
 
-	       hdf5free(member_name);
-	       member_name = NULL;
-            }
-	    hdf5free(member_name);
-	    member_name = NULL;
-        if(value) free(value);
-        if(retval) /* error exit from loop */
-          return retval;
+         /* Insert new field into this type's list of fields. */
+         if ((retval = nc4_enum_member_add(&type->u.e.enum_member, type->size,
+                                           member_name, value)))
+         {
+            break;
          }
-         break;
 
-      default:
-         LOG((0, "unknown class"));
-         return NC_EBADCLASS;
+         hdf5free(member_name);
+         member_name = NULL;
+      }
+      hdf5free(member_name);
+      member_name = NULL;
+      if(value) free(value);
+      if(retval) /* error exit from loop */
+         return retval;
+   }
+   break;
+
+   default:
+      LOG((0, "unknown class"));
+      return NC_EBADCLASS;
    }
    return retval;
 }
 
-/* This function is called by read_dataset, (which is called by
- * nc4_rec_read_metadata) when a netCDF variable is found in the
+/**
+ * @internal This function is called by read_dataset(), (which is called
+ * by nc4_rec_read_metadata()) when a netCDF variable is found in the
  * file. This function reads in all the metadata about the var,
- * including the attributes. */
+ * including the attributes. 
+ *
+ * @param grp Pointer to group info struct.
+ * @param datasetid HDF5 dataset ID.
+ * @param obj_name Name of the HDF5 object to read.
+ * @param ndims Number of dimensions.
+ * @param dim 
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @author Ed Hartnett
+*/
 static int
 read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
          size_t ndims, NC_DIM_INFO_T *dim)
@@ -1554,19 +1777,12 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
    NC_VAR_INFO_T *var = NULL;
    hid_t access_pid = 0;
    int incr_id_rc = 0;          /* Whether the dataset ID's ref count has been incremented */
-   int natts, a, d;
-   const char** reserved;
-
-   NC_ATT_INFO_T *att;
+   int d;
    att_iter_info att_info;         /* Custom iteration information */
-   char att_name[NC_MAX_HDF5_NAME + 1];
-
-#define CD_NELEMS_ZLIB 1
-#define CD_NELEMS_SZIP 4
    H5Z_filter_t filter;
    int num_filters;
-   unsigned int cd_values[CD_NELEMS_SZIP];
-   size_t cd_nelems = CD_NELEMS_SZIP;
+   unsigned int cd_values_zip[CD_NELEMS_ZLIB];
+   size_t cd_nelems = CD_NELEMS_ZLIB;
    hid_t propid = 0;
    H5D_fill_value_t fill_status;
    H5D_layout_t layout;
@@ -1595,21 +1811,18 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
    if (var->ndims)
    {
       if (!(var->dim = calloc(var->ndims, sizeof(NC_DIM_INFO_T *))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
       if (!(var->dimids = calloc(var->ndims, sizeof(int))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
    }
 
    /* Get the current chunk cache settings. */
    if ((access_pid = H5Dget_access_plist(datasetid)) < 0)
       BAIL(NC_EVARMETA);
-#ifdef EXTRA_TESTS
-   num_plists++;
-#endif
 
    /* Learn about current chunk cache settings. */
    if ((H5Pget_chunk_cache(access_pid, &(var->chunk_cache_nelems),
-			   &(var->chunk_cache_size), &rdcc_w0)) < 0)
+                           &(var->chunk_cache_size), &rdcc_w0)) < 0)
       BAIL(NC_EHDFERR);
    var->chunk_cache_preemption = rdcc_w0;
 
@@ -1617,7 +1830,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
     * same name as a dimension. It's legal in netcdf, and requires
     * that the HDF5 dataset name be changed. */
    if (strlen(obj_name) > strlen(NON_COORD_PREPEND) &&
-         !strncmp(obj_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)))
+       !strncmp(obj_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)))
    {
       /* Allocate space for the name. */
       if (!(var->name = malloc(((strlen(obj_name) - strlen(NON_COORD_PREPEND))+ 1) * sizeof(char))))
@@ -1643,12 +1856,9 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
    var->hash = hash_fast(var->name, strlen(var->name));
    /* Find out what filters are applied to this HDF5 dataset,
     * fletcher32, deflate, and/or shuffle. All other filters are
-    * ignored. */
+    * just dumped */
    if ((propid = H5Dget_create_plist(datasetid)) < 0)
       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists++;
-#endif /* EXTRA_TESTS */
 
    /* Get the chunking info for non-scalar vars. */
    if ((layout = H5Pget_layout(propid)) < -1)
@@ -1658,7 +1868,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
       if (H5Pget_chunk(propid, NC_MAX_VAR_DIMS, chunksize) < 0)
          BAIL(NC_EHDFERR);
       if (!(var->chunksizes = malloc(var->ndims * sizeof(size_t))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
       for (d = 0; d < var->ndims; d++)
          var->chunksizes[d] = chunksize[d];
    }
@@ -1672,42 +1882,46 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
    for (f = 0; f < num_filters; f++)
    {
       if ((filter = H5Pget_filter2(propid, f, NULL, &cd_nelems,
-                                   cd_values, 0, NULL, NULL)) < 0)
+                                   cd_values_zip, 0, NULL, NULL)) < 0)
          BAIL(NC_EHDFERR);
       switch (filter)
       {
-         case H5Z_FILTER_SHUFFLE:
-            var->shuffle = NC_TRUE;
-            break;
+      case H5Z_FILTER_SHUFFLE:
+         var->shuffle = NC_TRUE;
+         break;
 
-         case H5Z_FILTER_FLETCHER32:
-            var->fletcher32 = NC_TRUE;
-            break;
+      case H5Z_FILTER_FLETCHER32:
+         var->fletcher32 = NC_TRUE;
+         break;
 
-         case H5Z_FILTER_DEFLATE:
-            var->deflate = NC_TRUE;
-            if (cd_nelems != CD_NELEMS_ZLIB || cd_values[0] > MAX_DEFLATE_LEVEL)
-               BAIL(NC_EHDFERR);
-            var->deflate_level = cd_values[0];
-            break;
+      case H5Z_FILTER_DEFLATE:
+         var->deflate = NC_TRUE;
+         if (cd_nelems != CD_NELEMS_ZLIB || cd_values_zip[0] > NC_MAX_DEFLATE_LEVEL)
+            BAIL(NC_EHDFERR);
+         var->deflate_level = cd_values_zip[0];
+         break;
 
-         case H5Z_FILTER_SZIP:
-            var->szip = NC_TRUE;
-            if (cd_nelems != CD_NELEMS_SZIP)
+      default:
+         var->filterid = filter;
+         var->nparams = cd_nelems;
+         if(cd_nelems == 0)
+            var->params = NULL;
+         else {
+            /* We have to re-read the parameters based on actual nparams */
+            var->params = (unsigned int*)calloc(1,sizeof(unsigned int)*var->nparams);
+            if(var->params == NULL)
+               BAIL(NC_ENOMEM);
+            if((filter = H5Pget_filter2(propid, f, NULL, &cd_nelems,
+                                        var->params, 0, NULL, NULL)) < 0)
                BAIL(NC_EHDFERR);
-	    var->options_mask = cd_values[0];
-            var->pixels_per_block = cd_values[1];
-            break;
-
-         default:
-            LOG((1, "Yikes! Unknown filter type found on dataset!"));
-            break;
+         }
+         break;
       }
    }
 
    /* Learn all about the type of this variable. */
    if ((retval = get_type_info2(grp->nc4_info, datasetid,
-				&var->type_info)))
+                                &var->type_info)))
       BAIL(retval);
 
    /* Indicate that the variable has a pointer to the type */
@@ -1723,27 +1937,27 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
       /* Allocate space to hold the fill value. */
       if (!var->fill_value)
       {
-	 if (var->type_info->nc_type_class == NC_VLEN)
-	 {
-	    if (!(var->fill_value = malloc(sizeof(nc_vlen_t))))
-	       BAIL(NC_ENOMEM);
-	 }
-	 else if (var->type_info->nc_type_class == NC_STRING)
-	 {
-	    if (!(var->fill_value = malloc(sizeof(char *))))
-	       BAIL(NC_ENOMEM);
-	 }
-	 else
-	 {
+         if (var->type_info->nc_type_class == NC_VLEN)
+         {
+            if (!(var->fill_value = malloc(sizeof(nc_vlen_t))))
+               BAIL(NC_ENOMEM);
+         }
+         else if (var->type_info->nc_type_class == NC_STRING)
+         {
+            if (!(var->fill_value = malloc(sizeof(char *))))
+               BAIL(NC_ENOMEM);
+         }
+         else
+         {
             assert(var->type_info->size);
-	    if (!(var->fill_value = malloc(var->type_info->size)))
-	       BAIL(NC_ENOMEM);
-	 }
+            if (!(var->fill_value = malloc(var->type_info->size)))
+               BAIL(NC_ENOMEM);
+         }
       }
 
       /* Get the fill value from the HDF5 property lust. */
       if (H5Pget_fill_value(propid, var->type_info->native_hdf_typeid,
-			    var->fill_value) < 0)
+                            var->fill_value) < 0)
          BAIL(NC_EHDFERR);
    }
    else
@@ -1756,8 +1970,8 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
       var->dimscale = NC_TRUE;
       if (var->ndims > 1)
       {
-	 if ((retval = read_coord_dimids(grp, var)))
-	    BAIL(retval);
+         if ((retval = read_coord_dimids(grp, var)))
+            BAIL(retval);
       }
       else
       {
@@ -1765,7 +1979,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
          assert(0 == strcmp(var->name, dim->name));
 
          var->dimids[0] = dim->dimid;
-	 var->dim[0] = dim;
+         var->dim[0] = dim;
       }
       dim->coord_var = var;
    }
@@ -1810,10 +2024,13 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
    att_info.var = var;
    att_info.grp = grp;
 
-   if ((H5Aiterate2(var->hdf_datasetid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, att_read_var_callbk, &att_info)) < 0)
-     BAIL(NC_EATTMETA);
+   if ((H5Aiterate2(var->hdf_datasetid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL,
+                    att_read_var_callbk, &att_info)) < 0)
+      BAIL(NC_EATTMETA);
 
-   nc4_vararray_add(grp, var);
+   /* Add a var to the variable array, growing it as needed. */
+   if ((retval = nc4_vararray_add(grp, var)))
+      BAIL(retval);
 
    /* Is this a deflated variable with a chunksize greater than the
     * current cache size? */
@@ -1823,26 +2040,29 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
 exit:
    if (retval)
    {
-       if (incr_id_rc && H5Idec_ref(datasetid) < 0)
-          BAIL2(NC_EHDFERR);
-       if (var && nc4_var_del(var))
-          BAIL2(NC_EHDFERR);
+      if (incr_id_rc && H5Idec_ref(datasetid) < 0)
+         BAIL2(NC_EHDFERR);
+      if (var && nc4_var_del(var))
+         BAIL2(NC_EHDFERR);
    }
    if (access_pid && H5Pclose(access_pid) < 0)
       BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists--;
-#endif
    if (propid > 0 && H5Pclose(propid) < 0)
       BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists--;
-#endif
    return retval;
 }
 
-/* This function is called by nc4_rec_read_metadata to read all the
- * group level attributes (the NC_GLOBAL atts for this group). */
+/**
+ * @internal This function is called by nc4_rec_read_metadata to read
+ * all the group level attributes (the NC_GLOBAL atts for this
+ * group). 
+ *
+ * @param grp Pointer to group info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @author Ed Hartnett
+*/
 static int
 read_grp_atts(NC_GRP_INFO_T *grp)
 {
@@ -1866,14 +2086,14 @@ read_grp_atts(NC_GRP_INFO_T *grp)
 
       /* See if this a hidden, global attribute */
       if(grp->nc4_info->root_grp == grp) {
-	const char** reserved = NC_RESERVED_ATT_LIST;
-	hidden = 0;
-	for(;*reserved;reserved++) {
-	    if(strcmp(*reserved,obj_name)==0) {
-		hidden = 1;
-		break;
-	    }
-	}
+         const char** reserved = NC_RESERVED_ATT_LIST;
+         hidden = 0;
+         for(;*reserved;reserved++) {
+            if(strcmp(*reserved,obj_name)==0) {
+               hidden = 1;
+               break;
+            }
+         }
       }
 
       /* This may be an attribute telling us that strict netcdf-3
@@ -1881,30 +2101,30 @@ read_grp_atts(NC_GRP_INFO_T *grp)
        * but not add this attribute to the metadata. It's not a user
        * attribute, but an internal netcdf-4 one. */
       if(strcmp(obj_name, NC3_STRICT_ATT_NAME)==0)
-             grp->nc4_info->cmode |= NC_CLASSIC_MODEL;
+         grp->nc4_info->cmode |= NC_CLASSIC_MODEL;
       else if(!hidden) {
          /* Add an att struct at the end of the list, and then go to it. */
          if ((retval = nc4_att_list_add(&grp->att, &att)))
             BAIL(retval);
 
-	 /* Add the info about this attribute. */
-	 max_len = strlen(obj_name) > NC_MAX_NAME ? NC_MAX_NAME : strlen(obj_name);
-	 if (!(att->name = malloc((max_len + 1) * sizeof(char))))
-	    BAIL(NC_ENOMEM);
+         /* Add the info about this attribute. */
+         max_len = strlen(obj_name) > NC_MAX_NAME ? NC_MAX_NAME : strlen(obj_name);
+         if (!(att->name = malloc((max_len + 1) * sizeof(char))))
+            BAIL(NC_ENOMEM);
          strncpy(att->name, obj_name, max_len);
          att->name[max_len] = 0;
          att->attnum = grp->natts++;
          retval = read_hdf5_att(grp, attid, att);
          if(retval == NC_EBADTYPID) {
-               if((retval = nc4_att_list_del(&grp->att, att)))
-                  BAIL(retval);
-	 } else if(retval) {
+            if((retval = nc4_att_list_del(&grp->att, att)))
                BAIL(retval);
+         } else if(retval) {
+            BAIL(retval);
          } else {
-             att->created = NC_TRUE;
-	     if ((retval = nc4_find_type(grp->nc4_info, att->nc_typeid, &type)))
-            	BAIL(retval);
-	 }
+            att->created = NC_TRUE;
+            if ((retval = nc4_find_type(grp->nc4_info, att->nc_typeid, &type)))
+               BAIL(retval);
+         }
       }
       /* Unconditionally close the open attribute */
       H5Aclose(attid);
@@ -1913,17 +2133,29 @@ read_grp_atts(NC_GRP_INFO_T *grp)
 
 exit:
    if (attid > 0) {
-	if(H5Aclose(attid) < 0)
-            BAIL2(NC_EHDFERR);
+      if(H5Aclose(attid) < 0)
+         BAIL2(NC_EHDFERR);
    }
    return retval;
 }
 
-/* This function is called when nc4_rec_read_metadata encounters an HDF5
- * dataset when reading a file. */
+/**
+ * @internal This function is called when nc4_rec_read_metadata
+ * encounters an HDF5 dataset when reading a file.
+ * 
+ * @param grp Pointer to group info struct.
+ * @param datasetid HDF5 dataset ID.
+ * @param obj_name Object name.
+ * @param statbuf HDF5 status buffer.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EHDFERR HDF5 returned error.
+ * @author Ed Hartnett
+*/
 static int
 read_dataset(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
-    const H5G_stat_t *statbuf)
+             const H5G_stat_t *statbuf)
 {
    NC_DIM_INFO_T *dim = NULL;   /* Dimension created for scales */
    hid_t spaceid = 0;
@@ -1934,9 +2166,6 @@ read_dataset(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
    /* Get the dimension information for this dataset. */
    if ((spaceid = H5Dget_space(datasetid)) < 0)
       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_spaces++;
-#endif
    if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0)
       BAIL(NC_EHDFERR);
 
@@ -1963,22 +2192,30 @@ read_dataset(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
     * dimension in netCDF but not a variable. (Spooky!) */
    if (NULL == dim || (dim && !dim->hdf_dimscaleid))
       if ((retval = read_var(grp, datasetid, obj_name, ndims, dim)))
-	 BAIL(retval);
+         BAIL(retval);
 
 exit:
    if (spaceid && H5Sclose(spaceid) <0)
       BAIL2(retval);
-#ifdef EXTRA_TESTS
-   num_spaces--;
-#endif
 
    return retval;
 }
 
+/**
+ * @internal Add callback function to list.
+ *
+ * @param head
+ * @param tail
+ * @param oinfo The object info.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+ */
 static int
 nc4_rec_read_metadata_cb_list_add(NC4_rec_read_metadata_obj_info_t **head,
-                  NC4_rec_read_metadata_obj_info_t **tail,
-                  const NC4_rec_read_metadata_obj_info_t *oinfo)
+                                  NC4_rec_read_metadata_obj_info_t **tail,
+                                  const NC4_rec_read_metadata_obj_info_t *oinfo)
 {
    NC4_rec_read_metadata_obj_info_t *new_oinfo;    /* Pointer to info for object */
 
@@ -1991,26 +2228,38 @@ nc4_rec_read_metadata_cb_list_add(NC4_rec_read_metadata_obj_info_t **head,
 
    if (*tail)
    {
-       assert(*head);
-       (*tail)->next = new_oinfo;
-       *tail = new_oinfo;
+      assert(*head);
+      (*tail)->next = new_oinfo;
+      *tail = new_oinfo;
    }
    else
    {
-       assert(NULL == *head);
-       *head = *tail = new_oinfo;
+      assert(NULL == *head);
+      *head = *tail = new_oinfo;
    }
 
    return (NC_NOERR);
 }
 
+/**
+ * @internal Callback function called from nc4_rec_read_metadata().
+ *
+ * @param grpid HDF5 group ID.
+ * @param name Name of object.
+ * @param info Info struct for object.
+ * @param _op_data Pointer to data.
+ *
+ * @return ::NC_NOERR No error.
+ * @return H5_ITER_ERROR HDF5 error.
+ * @author Ed Hartnett
+ */
 static int
 nc4_rec_read_metadata_cb(hid_t grpid, const char *name, const H5L_info_t *info,
-		      void *_op_data)
+                         void *_op_data)
 {
-    NC4_rec_read_metadata_ud_t *udata = (NC4_rec_read_metadata_ud_t *)_op_data; /* Pointer to user data for callback */
-    NC4_rec_read_metadata_obj_info_t oinfo;    /* Pointer to info for object */
-    int retval = H5_ITER_CONT;
+   NC4_rec_read_metadata_ud_t *udata = (NC4_rec_read_metadata_ud_t *)_op_data; /* Pointer to user data for callback */
+   NC4_rec_read_metadata_obj_info_t oinfo;    /* Pointer to info for object */
+   int retval = H5_ITER_CONT;
 
    /* Reset the memory for the object's info */
    memset(&oinfo, 0, sizeof(oinfo));
@@ -2028,56 +2277,56 @@ nc4_rec_read_metadata_cb(hid_t grpid, const char *name, const H5L_info_t *info,
    /* Add object to list, for later */
    switch(oinfo.statbuf.type)
    {
-      case H5G_GROUP:
-         LOG((3, "found group %s", oinfo.oname));
-
-         /* Defer descending into child group immediately, so that the types
-          *     in the current group can be processed and be ready for use by
-          *     vars in the child group(s).
-          */
-         if (nc4_rec_read_metadata_cb_list_add(&udata->grps_head, &udata->grps_tail, &oinfo))
-             BAIL(H5_ITER_ERROR);
-         break;
+   case H5G_GROUP:
+      LOG((3, "found group %s", oinfo.oname));
 
-      case H5G_DATASET:
-         LOG((3, "found dataset %s", oinfo.oname));
+      /* Defer descending into child group immediately, so that the types
+       *     in the current group can be processed and be ready for use by
+       *     vars in the child group(s).
+       */
+      if (nc4_rec_read_metadata_cb_list_add(&udata->grps_head, &udata->grps_tail, &oinfo))
+         BAIL(H5_ITER_ERROR);
+      break;
 
-         /* Learn all about this dataset, which may be a dimscale
-          * (i.e. dimension metadata), or real data. */
-         if ((retval = read_dataset(udata->grp, oinfo.oid, oinfo.oname, &oinfo.statbuf)))
-         {
-            /* Allow NC_EBADTYPID to transparently skip over datasets
-             *  which have a datatype that netCDF-4 doesn't undertand
-             *  (currently), but break out of iteration for other
-             *  errors.
-             */
-            if(NC_EBADTYPID != retval)
-               BAIL(H5_ITER_ERROR);
-            else
-               retval = H5_ITER_CONT;
-         }
+   case H5G_DATASET:
+      LOG((3, "found dataset %s", oinfo.oname));
 
-         /* Close the object */
-         if (H5Oclose(oinfo.oid) < 0)
-	    BAIL(H5_ITER_ERROR);
-         break;
+      /* Learn all about this dataset, which may be a dimscale
+       * (i.e. dimension metadata), or real data. */
+      if ((retval = read_dataset(udata->grp, oinfo.oid, oinfo.oname, &oinfo.statbuf)))
+      {
+         /* Allow NC_EBADTYPID to transparently skip over datasets
+          *  which have a datatype that netCDF-4 doesn't undertand
+          *  (currently), but break out of iteration for other
+          *  errors.
+          */
+         if(NC_EBADTYPID != retval)
+            BAIL(H5_ITER_ERROR);
+         else
+            retval = H5_ITER_CONT;
+      }
 
-      case H5G_TYPE:
-         LOG((3, "found datatype %s", oinfo.oname));
+      /* Close the object */
+      if (H5Oclose(oinfo.oid) < 0)
+         BAIL(H5_ITER_ERROR);
+      break;
 
-         /* Process the named datatype */
-         if (read_type(udata->grp, oinfo.oid, oinfo.oname))
-            BAIL(H5_ITER_ERROR);
+   case H5G_TYPE:
+      LOG((3, "found datatype %s", oinfo.oname));
 
-         /* Close the object */
-         if (H5Oclose(oinfo.oid) < 0)
-	    BAIL(H5_ITER_ERROR);
-         break;
+      /* Process the named datatype */
+      if (read_type(udata->grp, oinfo.oid, oinfo.oname))
+         BAIL(H5_ITER_ERROR);
 
-      default:
-         LOG((0, "Unknown object class %d in %s!", oinfo.statbuf.type, __func__));
+      /* Close the object */
+      if (H5Oclose(oinfo.oid) < 0)
          BAIL(H5_ITER_ERROR);
-    }
+      break;
+
+   default:
+      LOG((0, "Unknown object class %d in %s!", oinfo.statbuf.type, __func__));
+      BAIL(H5_ITER_ERROR);
+   }
 
 exit:
    if (retval)
@@ -2089,136 +2338,153 @@ exit:
    return (retval);
 }
 
-/* This is the main function to recursively read all the metadata for the file. */
-/* The links in the 'grp' are iterated over and added to the file's metadata
- *      information.  Note that child groups are not immediately processed, but
- *      are deferred until all the other links in the group are handled (so that
- *      vars in the child groups are guaranteed to have types that they use in
- *      a parent group in place).
+/**
+ * @internal This is the main function to recursively read all the
+ * metadata for the file.  The links in the 'grp' are iterated over
+ * and added to the file's metadata information.  Note that child
+ * groups are not immediately processed, but are deferred until all
+ * the other links in the group are handled (so that vars in the child
+ * groups are guaranteed to have types that they use in a parent group
+ * in place).
+ *
+ * @param grp Pointer to a group.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
  */
 static int
 nc4_rec_read_metadata(NC_GRP_INFO_T *grp)
 {
-    NC4_rec_read_metadata_ud_t udata;   /* User data for iteration */
-    NC4_rec_read_metadata_obj_info_t *oinfo;    /* Pointer to info for object */
-    hsize_t idx=0;
-    hid_t pid = 0;
-    unsigned crt_order_flags = 0;
-    H5_index_t iter_index;
-    int i, retval = NC_NOERR; /* everything worked! */
-
-    assert(grp && grp->name);
-    LOG((3, "%s: grp->name %s", __func__, grp->name));
-
-    /* Portably initialize user data for later */
-    memset(&udata, 0, sizeof(udata));
-
-    /* Open this HDF5 group and retain its grpid. It will remain open
-     * with HDF5 until this file is nc_closed. */
-    if (!grp->hdf_grpid)
-    {
-        if (grp->parent)
-        {
-            if ((grp->hdf_grpid = H5Gopen2(grp->parent->hdf_grpid,
-					grp->name, H5P_DEFAULT)) < 0)
-                BAIL(NC_EHDFERR);
-        }
-        else
-        {
-	    if ((grp->hdf_grpid = H5Gopen2(grp->nc4_info->hdfid,
-					   "/", H5P_DEFAULT)) < 0)
-                BAIL(NC_EHDFERR);
-        }
-    }
-    assert(grp->hdf_grpid > 0);
-
-    /* Get the group creation flags, to check for creation ordering */
-    pid = H5Gget_create_plist(grp->hdf_grpid);
-    H5Pget_link_creation_order(pid, &crt_order_flags);
-    if (H5Pclose(pid) < 0)
-	BAIL(NC_EHDFERR);
-
-    /* Set the iteration index to use */
-    if (crt_order_flags & H5P_CRT_ORDER_TRACKED)
-        iter_index = H5_INDEX_CRT_ORDER;
-    else
-    {
-        NC_HDF5_FILE_INFO_T *h5 = grp->nc4_info;
-
-        /* Without creation ordering, file must be read-only. */
-        if (!h5->no_write)
-            BAIL(NC_ECANTWRITE);
-
-        iter_index = H5_INDEX_NAME;
-    }
-
-    /* Set user data for iteration */
-    udata.grp = grp;
-
-    /* Iterate over links in this group, building lists for the types,
-     *  datasets and groups encountered
-     */
-    if (H5Literate(grp->hdf_grpid, iter_index, H5_ITER_INC, &idx,
-            nc4_rec_read_metadata_cb, (void *)&udata) < 0)
-	BAIL(NC_EHDFERR);
-
-    /* Process the child groups found */
-    /* (Deferred until now, so that the types in the current group get
-     *  processed and are available for vars in the child group(s).)
-     */
-    for (oinfo = udata.grps_head; oinfo; oinfo = udata.grps_head)
-    {
-        NC_GRP_INFO_T *child_grp;
-        NC_HDF5_FILE_INFO_T *h5 = grp->nc4_info;
-
-        /* Add group to file's hierarchy */
-        if ((retval = nc4_grp_list_add(&(grp->children), h5->next_nc_grpid++,
-                        grp, grp->nc4_info->controller, oinfo->oname, &child_grp)))
-            BAIL(retval);
+   NC4_rec_read_metadata_ud_t udata;   /* User data for iteration */
+   NC4_rec_read_metadata_obj_info_t *oinfo;    /* Pointer to info for object */
+   hsize_t idx=0;
+   hid_t pid = 0;
+   unsigned crt_order_flags = 0;
+   H5_index_t iter_index;
+   int i, retval = NC_NOERR; /* everything worked! */
+
+   assert(grp && grp->name);
+   LOG((3, "%s: grp->name %s", __func__, grp->name));
+
+   /* Portably initialize user data for later */
+   memset(&udata, 0, sizeof(udata));
+
+   /* Open this HDF5 group and retain its grpid. It will remain open
+    * with HDF5 until this file is nc_closed. */
+   if (!grp->hdf_grpid)
+   {
+      if (grp->parent)
+      {
+         if ((grp->hdf_grpid = H5Gopen2(grp->parent->hdf_grpid,
+                                        grp->name, H5P_DEFAULT)) < 0)
+            BAIL(NC_EHDFERR);
+      }
+      else
+      {
+         if ((grp->hdf_grpid = H5Gopen2(grp->nc4_info->hdfid,
+                                        "/", H5P_DEFAULT)) < 0)
+            BAIL(NC_EHDFERR);
+      }
+   }
+   assert(grp->hdf_grpid > 0);
 
-        /* Recursively read the child group's metadata */
-        if ((retval = nc4_rec_read_metadata(child_grp)))
-            BAIL(retval);
+   /* Get the group creation flags, to check for creation ordering */
+   pid = H5Gget_create_plist(grp->hdf_grpid);
+   H5Pget_link_creation_order(pid, &crt_order_flags);
+   if (H5Pclose(pid) < 0)
+      BAIL(NC_EHDFERR);
+
+   /* Set the iteration index to use */
+   if (crt_order_flags & H5P_CRT_ORDER_TRACKED)
+      iter_index = H5_INDEX_CRT_ORDER;
+   else
+   {
+      NC_HDF5_FILE_INFO_T *h5 = grp->nc4_info;
 
-        /* Close the object */
-        if (H5Oclose(oinfo->oid) < 0)
-	    BAIL(NC_EHDFERR);
+      /* Without creation ordering, file must be read-only. */
+      if (!h5->no_write)
+         BAIL(NC_ECANTWRITE);
 
-        /* Advance to next node, free current node */
-        udata.grps_head = oinfo->next;
-        free(oinfo);
-    }
+      iter_index = H5_INDEX_NAME;
+   }
+
+   /* Set user data for iteration */
+   udata.grp = grp;
+
+   /* Iterate over links in this group, building lists for the types,
+    *  datasets and groups encountered
+    */
+   if (H5Literate(grp->hdf_grpid, iter_index, H5_ITER_INC, &idx,
+                  nc4_rec_read_metadata_cb, (void *)&udata) < 0)
+      BAIL(NC_EHDFERR);
+
+   /* Process the child groups found */
+   /* (Deferred until now, so that the types in the current group get
+    *  processed and are available for vars in the child group(s).)
+    */
+   for (oinfo = udata.grps_head; oinfo; oinfo = udata.grps_head)
+   {
+      NC_GRP_INFO_T *child_grp;
+      NC_HDF5_FILE_INFO_T *h5 = grp->nc4_info;
+
+      /* Add group to file's hierarchy */
+      if ((retval = nc4_grp_list_add(&(grp->children), h5->next_nc_grpid++,
+                                     grp, grp->nc4_info->controller, oinfo->oname, &child_grp)))
+         BAIL(retval);
+
+      /* Recursively read the child group's metadata */
+      if ((retval = nc4_rec_read_metadata(child_grp)))
+         BAIL(retval);
+
+      /* Close the object */
+      if (H5Oclose(oinfo->oid) < 0)
+         BAIL(NC_EHDFERR);
+
+      /* Advance to next node, free current node */
+      udata.grps_head = oinfo->next;
+      free(oinfo);
+   }
 
-    /* Scan the group for global (i.e. group-level) attributes. */
-    if ((retval = read_grp_atts(grp)))
-	BAIL(retval);
+   /* Scan the group for global (i.e. group-level) attributes. */
+   if ((retval = read_grp_atts(grp)))
+      BAIL(retval);
 
    /* when exiting define mode, mark all variable written */
    for (i=0; i<grp->vars.nelems; i++)
       grp->vars.value[i]->written_to = NC_TRUE;
 
 exit:
-    /* Clean up local information on error, if anything remains */
-    if (retval)
-    {
-        for (oinfo = udata.grps_head; oinfo; oinfo = udata.grps_head)
-        {
-            /* Close the object */
-            if (H5Oclose(oinfo->oid) < 0)
-                BAIL2(NC_EHDFERR);
-
-            /* Advance to next node, free current node */
-            udata.grps_head = oinfo->next;
-            free(oinfo);
-        }
-    }
-
-    return retval;
+   /* Clean up local information on error, if anything remains */
+   if (retval)
+   {
+      for (oinfo = udata.grps_head; oinfo; oinfo = udata.grps_head)
+      {
+         /* Close the object */
+         if (H5Oclose(oinfo->oid) < 0)
+            BAIL2(NC_EHDFERR);
+
+         /* Advance to next node, free current node */
+         udata.grps_head = oinfo->next;
+         free(oinfo);
+      }
+   }
+
+   return retval;
 }
 
-/* Open a netcdf-4 file. Things have already been kicked off in
- * ncfunc.c in nc_open, but here the netCDF-4 part of opening a file
- * is handled. */
+/**
+ * @internal Open a netcdf-4 file. Things have already been kicked off
+ * in ncfunc.c in nc_open, but here the netCDF-4 part of opening a
+ * file is handled. 
+ *
+ * @param path The file name of the new file.
+ * @param mode The open mode flag.
+ * @param parameters File parameters.
+ * @param nc Pointer to NC file info.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett, Dennis Heimbigner
+*/
 static int
 nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
 {
@@ -2250,16 +2516,8 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
    if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
       BAIL(NC_EHDFERR);
 
-#ifdef EXTRA_TESTS
-   num_plists++;
-#endif
-#ifdef EXTRA_TESTS
    if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI))
       BAIL(NC_EHDFERR);
-#else
-   if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG))
-      BAIL(NC_EHDFERR);
-#endif
 
 #ifdef USE_PARALLEL4
    /* If this is a parallel file create, set up the file creation
@@ -2269,16 +2527,16 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
       nc4_info->parallel = NC_TRUE;
       if (mode & NC_MPIIO)  /* MPI/IO */
       {
-	 LOG((4, "opening parallel file with MPI/IO"));
-	 if (H5Pset_fapl_mpio(fapl_id, mpiinfo->comm, mpiinfo->info) < 0)
-	    BAIL(NC_EPARINIT);
+         LOG((4, "opening parallel file with MPI/IO"));
+         if (H5Pset_fapl_mpio(fapl_id, mpiinfo->comm, mpiinfo->info) < 0)
+            BAIL(NC_EPARINIT);
       }
 #ifdef USE_PARALLEL_POSIX
       else /* MPI/POSIX */
       {
-	 LOG((4, "opening parallel file with MPI/posix"));
-	 if (H5Pset_fapl_mpiposix(fapl_id, mpiinfo->comm, 0) < 0)
-	    BAIL(NC_EPARINIT);
+         LOG((4, "opening parallel file with MPI/posix"));
+         if (H5Pset_fapl_mpiposix(fapl_id, mpiinfo->comm, 0) < 0)
+            BAIL(NC_EPARINIT);
       }
 #else /* USE_PARALLEL_POSIX */
       /* Should not happen! Code in NC4_create/NC4_open should alias the
@@ -2307,10 +2565,10 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
    }
 #else /* only set cache for non-parallel. */
    if (H5Pset_cache(fapl_id, 0, nc4_chunk_cache_nelems, nc4_chunk_cache_size,
-		    nc4_chunk_cache_preemption) < 0)
+                    nc4_chunk_cache_preemption) < 0)
       BAIL(NC_EHDFERR);
    LOG((4, "%s: set HDF raw chunk cache to size %d nelems %d preemption %f",
-	__func__, nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption));
+        __func__, nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption));
 #endif /* USE_PARALLEL4 */
 
    /* The NetCDF-3.x prototype contains an mode option NC_SHARE for
@@ -2320,11 +2578,11 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
    H5Pset_all_coll_metadata_ops(fapl_id, 1 );
 #endif
    if(inmemory) {
-       if((nc4_info->hdfid = H5LTopen_file_image(meminfo->memory,meminfo->size,
-			H5LT_FILE_IMAGE_DONT_COPY|H5LT_FILE_IMAGE_DONT_RELEASE
-			)) < 0)
-           BAIL(NC_EHDFERR);
-       nc4_info->no_write = NC_TRUE;
+      if((nc4_info->hdfid = H5LTopen_file_image(meminfo->memory,meminfo->size,
+                                                H5LT_FILE_IMAGE_DONT_COPY|H5LT_FILE_IMAGE_DONT_RELEASE
+             )) < 0)
+         BAIL(NC_EHDFERR);
+      nc4_info->no_write = NC_TRUE;
    } else if ((nc4_info->hdfid = H5Fopen(path, flags, fapl_id)) < 0)
       BAIL(NC_EHDFERR);
 
@@ -2353,9 +2611,6 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
    /* Close the property list. */
    if (H5Pclose(fapl_id) < 0)
       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_plists--;
-#endif
 
    NC4_get_fileinfo(nc4_info,NULL);
 
@@ -2366,9 +2621,6 @@ exit:
    if (comm_duped) MPI_Comm_free(&nc4_info->comm);
    if (info_duped) MPI_Info_free(&nc4_info->info);
 #endif
-#ifdef EXTRA_TESTS
-   num_plists--;
-#endif
    if (fapl_id != H5P_DEFAULT) H5Pclose(fapl_id);
    if (!nc4_info) return retval;
    close_netcdf4_file(nc4_info,1); /*  treat like abort*/
@@ -2376,22 +2628,23 @@ exit:
 }
 
 #ifdef USE_HDF4
-/*! Given an HDF4 type, set a pointer to netcdf type.
+/**
+ * @internal Given an HDF4 type, set a pointer to netcdf type.
  *
- * Given an HDF4 type, set a pointer to a netcdf type.
  * See http://www.hdfgroup.org/training/HDFtraining/UsersGuide/Fundmtls.fm3.html
  * for more information re: HDF4 types.
  *
- * \param NC_HDF5_FILE_INFO_T* Pointer to h5
- * \param int32 TypeID for hdf4 datatype.
- * \param nc_type* Pointer to netcdf type, where result will be stored.
- * \param NC_TYPE_INFO_T* (Optiona) Type info for the variable.
- * \return Error code, 0 on success.
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param hdf4_typeid Type ID for hdf4 datatype.
+ * @param xtype Pointer to netcdf type, where result will be stored.
+ * @param type_info Pointer to type info for the variable.
  *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
  */
 static int
 get_netcdf_type_from_hdf4(NC_HDF5_FILE_INFO_T *h5, int32 hdf4_typeid,
-			  nc_type *xtype, NC_TYPE_INFO_T *type_info)
+                          nc_type *xtype, NC_TYPE_INFO_T *type_info)
 {
    int t = 0;
 
@@ -2401,116 +2654,125 @@ get_netcdf_type_from_hdf4(NC_HDF5_FILE_INFO_T *h5, int32 hdf4_typeid,
     * Not sure why it wouldn't be NC_ENDIAN_NATIVE, although
     * I can hazard a guess or two.
     */
-
    int endianness = NC_ENDIAN_BIG;
    assert(h5 && xtype);
 
    switch(hdf4_typeid)
    {
    case DFNT_CHAR:
-       *xtype = NC_CHAR;
-       t = 0;
-       break;
+      *xtype = NC_CHAR;
+      t = 0;
+      break;
    case DFNT_UCHAR:
    case DFNT_UINT8:
-       *xtype = NC_UBYTE;
-       t = 6;
-       break;
+      *xtype = NC_UBYTE;
+      t = 6;
+      break;
    case DFNT_LUINT8:
-       *xtype = NC_UBYTE;
-       t = 6;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_UBYTE;
+      t = 6;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_INT8:
-       *xtype = NC_BYTE;
-       t = 1;
-       break;
+      *xtype = NC_BYTE;
+      t = 1;
+      break;
    case DFNT_LINT8:
-       *xtype = NC_BYTE;
-       t = 1;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_BYTE;
+      t = 1;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_INT16:
-       *xtype = NC_SHORT;
-       t = 2;
-       break;
+      *xtype = NC_SHORT;
+      t = 2;
+      break;
    case DFNT_LINT16:
-       *xtype = NC_SHORT;
-       t = 2;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_SHORT;
+      t = 2;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_UINT16:
-       *xtype = NC_USHORT;
-       t = 7;
-       break;
+      *xtype = NC_USHORT;
+      t = 7;
+      break;
    case DFNT_LUINT16:
-       *xtype = NC_USHORT;
-       t = 7;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_USHORT;
+      t = 7;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_INT32:
-       *xtype = NC_INT;
-       t = 3;
-       break;
+      *xtype = NC_INT;
+      t = 3;
+      break;
    case DFNT_LINT32:
-        *xtype = NC_INT;
-       t = 3;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_INT;
+      t = 3;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_UINT32:
-       *xtype = NC_UINT;
-       t = 8;
-       break;
+      *xtype = NC_UINT;
+      t = 8;
+      break;
    case DFNT_LUINT32:
-        *xtype = NC_UINT;
-       t = 8;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_UINT;
+      t = 8;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_FLOAT32:
-       *xtype = NC_FLOAT;
-       t = 4;
-       break;
+      *xtype = NC_FLOAT;
+      t = 4;
+      break;
    case DFNT_LFLOAT32:
-       *xtype = NC_FLOAT;
-       t = 4;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_FLOAT;
+      t = 4;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    case DFNT_FLOAT64:
-       *xtype = NC_DOUBLE;
-       t = 5;
-       break;
+      *xtype = NC_DOUBLE;
+      t = 5;
+      break;
    case DFNT_LFLOAT64:
-       *xtype = NC_DOUBLE;
-       t = 5;
-       endianness = NC_ENDIAN_LITTLE;
-       break;
+      *xtype = NC_DOUBLE;
+      t = 5;
+      endianness = NC_ENDIAN_LITTLE;
+      break;
    default:
-       *xtype = NC_NAT;
-       return NC_EBADTYPID;
+      *xtype = NC_NAT;
+      return NC_EBADTYPID;
    }
 
    if (type_info)
    {
       if (hdf4_typeid == DFNT_FLOAT32)
-	 type_info->nc_type_class = NC_FLOAT;
+         type_info->nc_type_class = NC_FLOAT;
       else if (hdf4_typeid == DFNT_FLOAT64)
-	 type_info->nc_type_class = NC_DOUBLE;
+         type_info->nc_type_class = NC_DOUBLE;
       else if (hdf4_typeid == DFNT_CHAR)
-	 type_info->nc_type_class = NC_STRING;
+         type_info->nc_type_class = NC_STRING;
       else
-	 type_info->nc_type_class = NC_INT;
+         type_info->nc_type_class = NC_INT;
       type_info->endianness = endianness;
       type_info->nc_typeid = *xtype;
       type_info->size = nc_type_size_g[t];
       if (!(type_info->name = strdup(nc_type_name_g[t])))
-        return NC_ENOMEM;
+         return NC_ENOMEM;
    }
 
    return NC_NOERR;
 }
 
-/* Open a HDF4 file. Things have already been kicked off in nc_open,
- * but here the netCDF-4 part of opening a file is handled. */
+/**
+ * @internal Open a HDF4 file. Things have already been kicked off in
+ * nc_open, but here the netCDF-4 part of opening a file is
+ * handled. 
+ *
+ * @param path The file name of the new file.
+ * @param mode The open mode flag.
+ * @param nc Pointer that gets the NC file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int
 nc4_open_hdf4_file(const char *path, int mode, NC *nc)
 {
@@ -2556,29 +2818,29 @@ nc4_open_hdf4_file(const char *path, int mode, NC *nc)
 
       /* Add to the end of the list of atts for this var. */
       if ((retval = nc4_att_list_add(&h5->root_grp->att, &att)))
-	 return retval;
+         return retval;
       att->attnum = grp->natts++;
       att->created = NC_TRUE;
 
       /* Learn about this attribute. */
       if (!(att->name = malloc(NC_MAX_HDF4_NAME * sizeof(char))))
-	 return NC_ENOMEM;
+         return NC_ENOMEM;
       if (SDattrinfo(h5->sdid, a, att->name, &att_data_type, &att_count))
-	 return NC_EATTMETA;
+         return NC_EATTMETA;
       if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type,
-					      &att->nc_typeid, NULL)))
-	 return retval;
+                                              &att->nc_typeid, NULL)))
+         return retval;
       att->len = att_count;
 
       /* Allocate memory to hold the data. */
       if ((retval = nc4_get_typelen_mem(h5, att->nc_typeid, 0, &att_type_size)))
-	 return retval;
+         return retval;
       if (!(att->data = malloc(att_type_size * att->len)))
-	 return NC_ENOMEM;
+         return NC_ENOMEM;
 
       /* Read the data. */
       if (SDreadattr(h5->sdid, a, att->data))
-	 return NC_EHDFERR;
+         return NC_EHDFERR;
    }
 
    /* Read each dataset. */
@@ -2587,12 +2849,12 @@ nc4_open_hdf4_file(const char *path, int mode, NC *nc)
       NC_VAR_INFO_T *var;
       int32 data_type, num_atts;
       /* Problem: Number of dims is returned by the call that requires
-	 a pre-allocated array, 'dimsize'.
-       From SDS_SD website:
-       http://www.hdfgroup.org/training/HDFtraining/UsersGuide/SDS_SD.fm3.html
-       The maximum rank is 32, or MAX_VAR_DIMS (as defined in netcdf.h).
+         a pre-allocated array, 'dimsize'.
+         From SDS_SD website:
+         http://www.hdfgroup.org/training/HDFtraining/UsersGuide/SDS_SD.fm3.html
+         The maximum rank is 32, or MAX_VAR_DIMS (as defined in netcdf.h).
 
-       int32 dimsize[MAX_VAR_DIMS];
+         int32 dimsize[MAX_VAR_DIMS];
       */
       int32 *dimsize = NULL;
       size_t var_type_size;
@@ -2600,34 +2862,36 @@ nc4_open_hdf4_file(const char *path, int mode, NC *nc)
 
       /* Add a variable. */
       if ((retval = nc4_var_add(&var)))
-	return retval;
+         return retval;
 
       var->varid = grp->nvars++;
       var->created = NC_TRUE;
       var->written_to = NC_TRUE;
 
-      nc4_vararray_add(grp, var);
+      /* Add a var to the variable array, growing it as needed. */
+      if ((retval = nc4_vararray_add(grp, var)))
+         return retval;
 
       /* Open this dataset in HDF4 file. */
       if ((var->sdsid = SDselect(h5->sdid, v)) == FAIL)
-	return NC_EVARMETA;
+         return NC_EVARMETA;
 
       /* Get shape, name, type, and attribute info about this dataset. */
       if (!(var->name = malloc(NC_MAX_HDF4_NAME + 1)))
-	return NC_ENOMEM;
+         return NC_ENOMEM;
 
       /* Invoke SDgetInfo with null dimsize to get rank. */
       if (SDgetinfo(var->sdsid, var->name, &rank, NULL, &data_type, &num_atts))
-	return NC_EVARMETA;
+         return NC_EVARMETA;
 
       var->hash = hash_fast(var->name, strlen(var->name));
 
       if(!(dimsize = (int32*)malloc(sizeof(int32)*rank)))
-	return NC_ENOMEM;
+         return NC_ENOMEM;
 
       if (SDgetinfo(var->sdsid, var->name, &rank, dimsize, &data_type, &num_atts)) {
-	if(dimsize) free(dimsize);
-	return NC_EVARMETA;
+         if(dimsize) free(dimsize);
+         return NC_EVARMETA;
       }
 
       var->ndims = rank;
@@ -2635,168 +2899,168 @@ nc4_open_hdf4_file(const char *path, int mode, NC *nc)
 
       /* Fill special type_info struct for variable type information. */
       if (!(var->type_info = calloc(1, sizeof(NC_TYPE_INFO_T)))) {
-	if(dimsize) free(dimsize);
-	return NC_ENOMEM;
+         if(dimsize) free(dimsize);
+         return NC_ENOMEM;
       }
 
       if ((retval = get_netcdf_type_from_hdf4(h5, data_type, &var->type_info->nc_typeid, var->type_info))) {
-	if(dimsize) free(dimsize);
-	return retval;
+         if(dimsize) free(dimsize);
+         return retval;
       }
 
       /* Indicate that the variable has a pointer to the type */
       var->type_info->rc++;
 
       if ((retval = nc4_get_typelen_mem(h5, var->type_info->nc_typeid, 0, &var_type_size))) {
-	if(dimsize) free(dimsize);
-	return retval;
+         if(dimsize) free(dimsize);
+         return retval;
       }
 
       var->type_info->size = var_type_size;
       LOG((3, "reading HDF4 dataset %s, rank %d netCDF type %d", var->name,
-	   rank, var->type_info->nc_typeid));
+           rank, var->type_info->nc_typeid));
 
       /* Get the fill value. */
       if (!(var->fill_value = malloc(var_type_size))) {
-	if(dimsize) free(dimsize);
-	return NC_ENOMEM;
+         if(dimsize) free(dimsize);
+         return NC_ENOMEM;
       }
 
       if (SDgetfillvalue(var->sdsid, var->fill_value))
       {
-	 /* Whoops! No fill value! */
-	 free(var->fill_value);
-	 var->fill_value = NULL;
+         /* Whoops! No fill value! */
+         free(var->fill_value);
+         var->fill_value = NULL;
       }
 
       /* Allocate storage for dimension info in this variable. */
       if (var->ndims)
       {
-	if (!(var->dim = malloc(sizeof(NC_DIM_INFO_T *) * var->ndims))) {
-	  if(dimsize) free(dimsize);
-	  return NC_ENOMEM;
-	}
-
-	if (!(var->dimids = malloc(sizeof(int) * var->ndims))) {
-	  if(dimsize) free(dimsize);
-	  return NC_ENOMEM;
-	}
+         if (!(var->dim = malloc(sizeof(NC_DIM_INFO_T *) * var->ndims))) {
+            if(dimsize) free(dimsize);
+            return NC_ENOMEM;
+         }
+
+         if (!(var->dimids = malloc(sizeof(int) * var->ndims))) {
+            if(dimsize) free(dimsize);
+            return NC_ENOMEM;
+         }
       }
 
 
       /* Find its dimensions. */
       for (d = 0; d < var->ndims; d++)
       {
-	 int32 dimid, dim_len, dim_data_type, dim_num_attrs;
-	 char dim_name[NC_MAX_NAME + 1];
-	 NC_DIM_INFO_T *dim;
-
-	 if ((dimid = SDgetdimid(var->sdsid, d)) == FAIL) {
-	   if(dimsize) free(dimsize);
-	   return NC_EDIMMETA;
-	 }
-	 if (SDdiminfo(dimid, dim_name, &dim_len, &dim_data_type,
-		       &dim_num_attrs))
-	   {
-	     if(dimsize) free(dimsize);
-	     return NC_EDIMMETA;
-	   }
-
-	 /* Do we already have this dimension? HDF4 explicitly uses
-	  * the name to tell. */
-	 for (dim = grp->dim; dim; dim = dim->l.next)
-	    if (!strcmp(dim->name, dim_name))
-	       break;
-
-	 /* If we didn't find this dimension, add one. */
-	 if (!dim)
-	 {
-	    LOG((4, "adding dimension %s for HDF4 dataset %s",
-		 dim_name, var->name));
-	    if ((retval = nc4_dim_list_add(&grp->dim, &dim)))
-	       return retval;
-	    dim->dimid = grp->nc4_info->next_dimid++;
-	    if (strlen(dim_name) > NC_MAX_HDF4_NAME)
-	       return NC_EMAXNAME;
-	    if (!(dim->name = strdup(dim_name)))
-	       return NC_ENOMEM;
-	    if (dim_len)
-	       dim->len = dim_len;
-	    else
-	       dim->len = *dimsize;
-	    dim->hash = hash_fast(dim_name, strlen(dim_name));
-	 }
-
-	 /* Tell the variable the id of this dimension. */
-	 var->dimids[d] = dim->dimid;
-	 var->dim[d] = dim;
+         int32 dimid, dim_len, dim_data_type, dim_num_attrs;
+         char dim_name[NC_MAX_NAME + 1];
+         NC_DIM_INFO_T *dim;
+
+         if ((dimid = SDgetdimid(var->sdsid, d)) == FAIL) {
+            if(dimsize) free(dimsize);
+            return NC_EDIMMETA;
+         }
+         if (SDdiminfo(dimid, dim_name, &dim_len, &dim_data_type,
+                       &dim_num_attrs))
+         {
+            if(dimsize) free(dimsize);
+            return NC_EDIMMETA;
+         }
+
+         /* Do we already have this dimension? HDF4 explicitly uses
+          * the name to tell. */
+         for (dim = grp->dim; dim; dim = dim->l.next)
+            if (!strcmp(dim->name, dim_name))
+               break;
+
+         /* If we didn't find this dimension, add one. */
+         if (!dim)
+         {
+            LOG((4, "adding dimension %s for HDF4 dataset %s",
+                 dim_name, var->name));
+            if ((retval = nc4_dim_list_add(&grp->dim, &dim)))
+               return retval;
+            dim->dimid = grp->nc4_info->next_dimid++;
+            if (strlen(dim_name) > NC_MAX_HDF4_NAME)
+               return NC_EMAXNAME;
+            if (!(dim->name = strdup(dim_name)))
+               return NC_ENOMEM;
+            if (dim_len)
+               dim->len = dim_len;
+            else
+               dim->len = *dimsize;
+            dim->hash = hash_fast(dim_name, strlen(dim_name));
+         }
+
+         /* Tell the variable the id of this dimension. */
+         var->dimids[d] = dim->dimid;
+         var->dim[d] = dim;
       }
 
       /* Read the atts. */
       for (a = 0; a < num_atts; a++)
       {
-	 int32 att_data_type, att_count;
-	 size_t att_type_size;
+         int32 att_data_type, att_count;
+         size_t att_type_size;
 
-	 /* Add to the end of the list of atts for this var. */
+         /* Add to the end of the list of atts for this var. */
          if ((retval = nc4_att_list_add(&var->att, &att))) {
-	   if(dimsize) free(dimsize);
-	   return retval;
-	 }
-	 att->attnum = var->natts++;
-	 att->created = NC_TRUE;
-
-	 /* Learn about this attribute. */
-	 if (!(att->name = malloc(NC_MAX_HDF4_NAME * sizeof(char)))) {
-	   if(dimsize) free(dimsize);
-	   return NC_ENOMEM;
-	 }
-	 if (SDattrinfo(var->sdsid, a, att->name, &att_data_type, &att_count)) {
-	   if(dimsize) free(dimsize);
-	    return NC_EATTMETA;
-	 }
-	 if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type,
-						 &att->nc_typeid, NULL))) {
-	   if(dimsize) free(dimsize);
-	   return retval;
-	 }
-
-	 att->len = att_count;
-
-	 /* Allocate memory to hold the data. */
-	 if ((retval = nc4_get_typelen_mem(h5, att->nc_typeid, 0, &att_type_size))) {
-	   if(dimsize) free(dimsize);
-	   return retval;
-	 }
-	 if (!(att->data = malloc(att_type_size * att->len))) {
-	   if(dimsize) free(dimsize);
-	   return NC_ENOMEM;
-	 }
-
-	 /* Read the data. */
-	 if (SDreadattr(var->sdsid, a, att->data)) {
-	   if(dimsize) free(dimsize);
-	   return NC_EHDFERR;
-	 }
+            if(dimsize) free(dimsize);
+            return retval;
+         }
+         att->attnum = var->natts++;
+         att->created = NC_TRUE;
+
+         /* Learn about this attribute. */
+         if (!(att->name = malloc(NC_MAX_HDF4_NAME * sizeof(char)))) {
+            if(dimsize) free(dimsize);
+            return NC_ENOMEM;
+         }
+         if (SDattrinfo(var->sdsid, a, att->name, &att_data_type, &att_count)) {
+            if(dimsize) free(dimsize);
+            return NC_EATTMETA;
+         }
+         if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type,
+                                                 &att->nc_typeid, NULL))) {
+            if(dimsize) free(dimsize);
+            return retval;
+         }
+
+         att->len = att_count;
+
+         /* Allocate memory to hold the data. */
+         if ((retval = nc4_get_typelen_mem(h5, att->nc_typeid, 0, &att_type_size))) {
+            if(dimsize) free(dimsize);
+            return retval;
+         }
+         if (!(att->data = malloc(att_type_size * att->len))) {
+            if(dimsize) free(dimsize);
+            return NC_ENOMEM;
+         }
+
+         /* Read the data. */
+         if (SDreadattr(var->sdsid, a, att->data)) {
+            if(dimsize) free(dimsize);
+            return NC_EHDFERR;
+         }
       }
       if(dimsize) free(dimsize);
 
       {
-        /* HDF4 files can be chunked */
-	HDF_CHUNK_DEF chunkdefs;
-	int flag;
-        if(!SDgetchunkinfo(var->sdsid, &chunkdefs, &flag)) {
-	    if(flag == HDF_NONE)
-		var->contiguous = NC_TRUE;
+         /* HDF4 files can be chunked */
+         HDF_CHUNK_DEF chunkdefs;
+         int flag;
+         if(!SDgetchunkinfo(var->sdsid, &chunkdefs, &flag)) {
+            if(flag == HDF_NONE)
+               var->contiguous = NC_TRUE;
             else if((flag & HDF_CHUNK) != 0) {
-		var->contiguous = NC_FALSE;
-		if (!(var->chunksizes = malloc(var->ndims * sizeof(size_t))))
-	 	    return NC_ENOMEM;
-	        for (d = 0; d < var->ndims; d++) {
-		    var->chunksizes[d] = chunkdefs.chunk_lengths[d];
-		}
-	    }
-	}
+               var->contiguous = NC_FALSE;
+               if (!(var->chunksizes = malloc(var->ndims * sizeof(size_t))))
+                  return NC_ENOMEM;
+               for (d = 0; d < var->ndims; d++) {
+                  var->chunksizes[d] = chunkdefs.chunk_lengths[d];
+               }
+            }
+         }
       }
 
    } /* next var */
@@ -2807,16 +3071,34 @@ nc4_open_hdf4_file(const char *path, int mode, NC *nc)
    log_metadata_nc(h5->root_grp->nc4_info->controller);
 #endif
    return NC_NOERR;
-   return NC_ENOTBUILT;
 }
 #endif /* USE_HDF4 */
 
+/**
+ * @internal Open a netCDF-4 file.
+ *
+ * @param path The file name of the new file.
+ * @param mode The open mode flag.
+ * @param basepe Ignored by this function.
+ * @param chunksizehintp Ignored by this function.
+ * @param use_parallel 0 for sequential, non-zero for parallel I/O.
+ * @param parameters pointer to struct holding extra data (e.g. for parallel I/O)
+ * layer. Ignored if NULL.
+ * @param dispatch Pointer to the dispatch table for this file.
+ * @param nc_file Pointer to an instance of NC.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
-	 int use_parallel, void *parameters, NC_Dispatch *dispatch, NC *nc_file)
+         int use_parallel, void *parameters, NC_Dispatch *dispatch, NC *nc_file)
 {
    int res;
-   int hdf_file = 0;
+   int is_hdf5_file = 0;
+#ifdef USE_HDF4
+   int is_hdf4_file = 0;
+#endif /* USE_HDF4 */
 #ifdef USE_PARALLEL4
    NC_MPI_INFO mpidfalt = {MPI_COMM_WORLD, MPI_INFO_NULL};
 #endif
@@ -2827,24 +3109,24 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
    assert(nc_file && path);
 
    LOG((1, "%s: path %s mode %d params %x",
-	__func__, path, mode, parameters));
+        __func__, path, mode, parameters));
 
 #ifdef USE_PARALLEL4
    if (!inmemory && use_parallel && parameters == NULL)
-	parameters = &mpidfalt;
+      parameters = &mpidfalt;
 #endif /* USE_PARALLEL4 */
 
    /* If this is our first file, initialize HDF5. */
    if (!nc4_hdf5_initialized)
-	nc4_hdf5_initialize();
+      nc4_hdf5_initialize();
 
    /* Check the mode for validity */
    if((mode & ILLEGAL_OPEN_FLAGS) != 0)
-      {res = NC_EINVAL; goto done;}
+   {res = NC_EINVAL; goto done;}
 
    /* Cannot have both */
    if((mode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX))
-      {res = NC_EINVAL; goto done;}
+   {res = NC_EINVAL; goto done;}
 
 #ifndef USE_PARALLEL_POSIX
 /* If the HDF5 library has been compiled without the MPI-POSIX VFD, alias
@@ -2858,31 +3140,42 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
 #endif /* USE_PARALLEL_POSIX */
 
    /* Figure out if this is a hdf4 or hdf5 file. */
-   if ((res = nc_check_for_hdf(path, use_parallel, parameters, &hdf_file)))
-	goto done;
-
+   if(nc_file->model == NC_FORMATX_NC4)
+      is_hdf5_file = 1;
+#ifdef USE_HDF4
+   else if(nc_file->model == NC_FORMATX_NC_HDF4)
+      is_hdf4_file = 1;
+#endif /* USE_HDF4 */
    /* Depending on the type of file, open it. */
    nc_file->int_ncid = nc_file->ext_ncid;
-   if (hdf_file == NC_HDF5_FILE)
-       res = nc4_open_file(path, mode, parameters, nc_file);
+   if (is_hdf5_file)
+      res = nc4_open_file(path, mode, parameters, nc_file);
 #ifdef USE_HDF4
-   else if (hdf_file == NC_HDF4_FILE && inmemory)
-	{res = NC_EDISKLESS; goto done;}
-   else if (hdf_file == NC_HDF4_FILE)
-       res = nc4_open_hdf4_file(path, mode, nc_file);
+   else if (is_hdf4_file && inmemory)
+   {res = NC_EDISKLESS; goto done;}
+   else if (is_hdf4_file)
+      res = nc4_open_hdf4_file(path, mode, nc_file);
 #endif /* USE_HDF4 */
    else
-       assert(0); /* should never happen */
+      res = NC_ENOTNC;
 done:
    return res;
 }
 
-/* Unfortunately HDF only allows specification of fill value only when
-   a dataset is created. Whereas in netcdf, you first create the
-   variable and then (optionally) specify the fill value. To
-   accomplish this in HDF5 I have to delete the dataset, and recreate
-   it, with the fill value specified. */
-/* QAK: This looks completely unused in the code. (?) */
+/**
+ * @internal Unfortunately HDF only allows specification of fill value
+ * only when a dataset is created. Whereas in netcdf, you first create
+ * the variable and then (optionally) specify the fill value. To
+ * accomplish this in HDF5 I have to delete the dataset, and recreate
+ * it, with the fill value specified. 
+ *
+ * @param ncid File and group ID.
+ * @param fillmode File mode.
+ * @param old_modep Pointer that gets old mode. Ignored if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_set_fill(int ncid, int fillmode, int *old_modep)
 {
@@ -2913,12 +3206,19 @@ NC4_set_fill(int ncid, int fillmode, int *old_modep)
    return NC_NOERR;
 }
 
-/* Put the file back in redef mode. This is done automatically for
- * netcdf-4 files, if the user forgets. */
+/**
+ * @internal Put the file back in redef mode. This is done
+ * automatically for netcdf-4 files, if the user forgets. 
+ *
+ * @param ncid File and group ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_redef(int ncid)
 {
-  NC_HDF5_FILE_INFO_T* nc4_info;
+   NC_HDF5_FILE_INFO_T* nc4_info;
 
    LOG((1, "%s: ncid 0x%x", __func__, ncid));
 
@@ -2945,11 +3245,22 @@ NC4_redef(int ncid)
    return NC_NOERR;
 }
 
-/* For netcdf-4 files, this just calls nc_enddef, ignoring the extra
- * parameters. */
+/**
+ * @internal For netcdf-4 files, this just calls nc_enddef, ignoring
+ * the extra parameters. 
+ *
+ * @param ncid File and group ID.
+ * @param h_minfree Ignored for netCDF-4 files.
+ * @param v_align Ignored for netCDF-4 files.
+ * @param v_minfree Ignored for netCDF-4 files.
+ * @param r_align Ignored for netCDF-4 files.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4__enddef(int ncid, size_t h_minfree, size_t v_align,
-	    size_t v_minfree, size_t r_align)
+            size_t v_minfree, size_t r_align)
 {
    if (nc4_find_nc_file(ncid,NULL) == NULL)
       return NC_EBADID;
@@ -2957,11 +3268,18 @@ NC4__enddef(int ncid, size_t h_minfree, size_t v_align,
    return NC4_enddef(ncid);
 }
 
-/* Take the file out of define mode. This is called automatically for
- * netcdf-4 files, if the user forgets. */
+/**
+ * @internal Take the file out of define mode. This is called
+ * automatically for netcdf-4 files, if the user forgets. 
+ *
+ * @param ncid File and group ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int NC4_enddef(int ncid)
 {
-  NC *nc;
+   NC *nc;
    NC_HDF5_FILE_INFO_T* nc4_info;
    NC_GRP_INFO_T *grp;
    int i;
@@ -2983,57 +3301,15 @@ static int NC4_enddef(int ncid)
    return nc4_enddef_netcdf4_file(nc4_info);
 }
 
-/* This function will write all changed metadata, and (someday) reread
- * all metadata from the file. */
-static int
-sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
-{
-   int retval;
-
-   assert(h5);
-   LOG((3, "%s", __func__));
-
-   /* If we're in define mode, that's an error, for strict nc3 rules,
-    * otherwise, end define mode. */
-   if (h5->flags & NC_INDEF)
-   {
-      if (h5->cmode & NC_CLASSIC_MODEL)
-	 return NC_EINDEFINE;
-
-      /* Turn define mode off. */
-      h5->flags ^= NC_INDEF;
-
-      /* Redef mode needs to be tracked separately for nc_abort. */
-      h5->redef = NC_FALSE;
-   }
-
-#ifdef LOGGING
-   /* This will print out the names, types, lens, etc of the vars and
-      atts in the file, if the logging level is 2 or greater. */
-   log_metadata_nc(h5->root_grp->nc4_info->controller);
-#endif
-
-   /* Write any metadata that has changed. */
-   if (!(h5->cmode & NC_NOWRITE))
-   {
-      nc_bool_t bad_coord_order = NC_FALSE;	/* if detected, propagate to all groups to consistently store dimids */
-
-      if ((retval = nc4_rec_write_groups_types(h5->root_grp)))
-	 return retval;
-      if ((retval = nc4_rec_detect_need_to_preserve_dimids(h5->root_grp, &bad_coord_order)))
-	 return retval;
-      if ((retval = nc4_rec_write_metadata(h5->root_grp, bad_coord_order)))
-	 return retval;
-   }
-
-   if (H5Fflush(h5->hdfid, H5F_SCOPE_GLOBAL) < 0)
-      return NC_EHDFERR;
-
-   return retval;
-}
-
-/* Flushes all buffers associated with the file, after writing all
-   changed metadata. This may only be called in data mode. */
+/**
+ * @internal Flushes all buffers associated with the file, after
+ * writing all changed metadata. This may only be called in data mode.
+ *
+ * @param ncid File and group ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_sync(int ncid)
 {
@@ -3051,105 +3327,27 @@ NC4_sync(int ncid)
    if (nc4_info && nc4_info->flags & NC_INDEF)
    {
       if (nc4_info->cmode & NC_CLASSIC_MODEL)
-	 return NC_EINDEFINE;
+         return NC_EINDEFINE;
       if ((retval = NC4_enddef(ncid)))
-	 return retval;
+         return retval;
    }
 
    return sync_netcdf4_file(nc4_info);
 }
 
-/* This function will free all allocated metadata memory, and close
-   the HDF5 file. The group that is passed in must be the root group
-   of the file. */
-static int
-close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort)
-{
-   int retval = NC_NOERR;
-
-   assert(h5 && h5->root_grp);
-   LOG((3, "%s: h5->path %s abort %d", __func__, h5->controller->path, abort));
-
-   /* According to the docs, always end define mode on close. */
-   if (h5->flags & NC_INDEF)
-      h5->flags ^= NC_INDEF;
-
-   /* Sync the file, unless we're aborting, or this is a read-only
-    * file. */
-   if (!h5->no_write && !abort)
-      if ((retval = sync_netcdf4_file(h5)))
-	goto exit;
-
-   /* Delete all the list contents for vars, dims, and atts, in each
-    * group. */
-   if ((retval = nc4_rec_grp_del(&h5->root_grp, h5->root_grp)))
-	goto exit;
-
-   /* Close hdf file. */
-#ifdef USE_HDF4
-   if (h5->hdf4)
-   {
-      if (SDend(h5->sdid))
-         BAIL_QUIET(NC_EHDFERR);
-   }
-   else
-#endif /* USE_HDF4 */
-   {
-#ifdef USE_PARALLEL4
-      /* Free the MPI Comm & Info objects, if we opened the file in parallel */
-      if(h5->parallel)
-      {
-          if(MPI_COMM_NULL != h5->comm)
-              MPI_Comm_free(&h5->comm);
-          if(MPI_INFO_NULL != h5->info)
-              MPI_Info_free(&h5->info);
-      }
-#endif
-
-      if(h5->fileinfo) free(h5->fileinfo);
-
-      if (H5Fclose(h5->hdfid) < 0)
-      {
-	int nobjs;
-
-	nobjs = H5Fget_obj_count(h5->hdfid, H5F_OBJ_ALL);
-	/* Apparently we can get an error even when nobjs == 0 */
-	if(nobjs < 0) {
-          BAIL_QUIET(NC_EHDFERR);
-	} else if(nobjs > 0) {
-#ifdef LOGGING
-	 char msg[1024];
-	 int logit = 1;
-	 /* If the close doesn't work, probably there are still some HDF5
-	  * objects open, which means there's a bug in the library. So
-	  * print out some info on to help the poor programmer figure it
-	  * out. */
-	snprintf(msg,sizeof(msg),"There are %d HDF5 objects open!", nobjs);
-#ifdef LOGOPEN
-         LOG((0, msg));
-#else
-         fprintf(stdout,msg);
-	 logit = 0;
-#endif
-	 reportopenobjects(logit,h5->hdfid);
-#endif
-      }
-    }
-   }
-exit:
-   /* Free the nc4_info struct; above code should have reclaimed
-      everything else */
-   if(h5 != NULL)
-       free(h5);
-   return retval;
-}
-
-/* From the netcdf-3 docs: The function nc_abort just closes the
-   netCDF dataset, if not in define mode. If the dataset is being
-   created and is still in define mode, the dataset is deleted. If
-   define mode was entered by a call to nc_redef, the netCDF dataset
-   is restored to its state before definition mode was entered and the
-   dataset is closed. */
+/**
+ * @internal From the netcdf-3 docs: The function nc_abort just closes
+ * the netCDF dataset, if not in define mode. If the dataset is being
+ * created and is still in define mode, the dataset is deleted. If
+ * define mode was entered by a call to nc_redef, the netCDF dataset
+ * is restored to its state before definition mode was entered and the
+ * dataset is closed. 
+ *
+ * @param ncid File and group ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 NC4_abort(int ncid)
 {
@@ -3182,12 +3380,19 @@ NC4_abort(int ncid)
    /* Delete the file, if we should. */
    if (delete_file)
       if (remove(path) < 0)
-          return NC_ECANTREMOVE;
+         return NC_ECANTREMOVE;
 
    return retval;
 }
 
-/* Close the netcdf file, writing any changes first. */
+/**
+ * @internal Close the netcdf file, writing any changes first. 
+ *
+ * @param ncid File and group ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_close(int ncid)
 {
@@ -3215,8 +3420,23 @@ NC4_close(int ncid)
    return NC_NOERR;
 }
 
-/* It's possible for any of these pointers to be NULL, in which case
-   don't try to figure out that value. */
+/**
+ * @internal Learn number of dimensions, variables, global attributes,
+ * and the ID of the first unlimited dimension (if any).
+ *
+ * @note It's possible for any of these pointers to be NULL, in which
+ * case don't try to figure out that value.
+ *
+ * @param ncid File and group ID.
+ * @param ndimsp Pointer that gets number of dimensions.
+ * @param nvarsp Pointer that gets number of variables.
+ * @param nattsp Pointer that gets number of global attributes.
+ * @param unlimdimidp Pointer that gets first unlimited dimension ID,
+ * or -1 if there are no unlimied dimensions.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
 {
@@ -3240,7 +3460,7 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
    {
       *ndimsp = 0;
       for (dim = grp->dim; dim; dim = dim->l.next)
-	 (*ndimsp)++;
+         (*ndimsp)++;
    }
    if (nvarsp)
    {
@@ -3248,15 +3468,15 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
       *nvarsp = 0;
       for (i=0; i < grp->vars.nelems; i++)
       {
-	if (grp->vars.value[i])
-	  (*nvarsp)++;
+         if (grp->vars.value[i])
+            (*nvarsp)++;
       }
    }
    if (nattsp)
-     {
+   {
       *nattsp = 0;
       for (att = grp->att; att; att = att->l.next)
-	 (*nattsp)++;
+         (*nattsp)++;
    }
 
    if (unlimdimidp)
@@ -3265,21 +3485,28 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
       *unlimdimidp = -1;
 
       /* If there's more than one unlimited dim, which was not possible
-	 with netcdf-3, then only the last unlimited one will be reported
-	 back in xtendimp. */
+         with netcdf-3, then only the last unlimited one will be reported
+         back in xtendimp. */
       /* Note that this code is inconsistent with nc_inq_unlimid() */
       for (dim = grp->dim; dim; dim = dim->l.next)
-	 if (dim->unlimited)
-	 {
-	    *unlimdimidp = dim->dimid;
-	    break;
-	 }
+         if (dim->unlimited)
+         {
+            *unlimdimidp = dim->dimid;
+            break;
+         }
    }
 
    return NC_NOERR;
 }
 
-/* This function will do the enddef stuff for a netcdf-4 file. */
+/**
+ * @internal This function will do the enddef stuff for a netcdf-4 file. 
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
 {
@@ -3299,42 +3526,3 @@ nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
    return sync_netcdf4_file(h5);
 }
 
-#ifdef EXTRA_TESTS
-int
-nc_exit()
-{
-   if (num_plists || num_spaces)
-      return NC_EHDFERR;
-
-   return NC_NOERR;
-}
-#endif /* EXTRA_TESTS */
-
-#ifdef USE_PARALLEL4
-int
-nc_use_parallel_enabled()
-{
-   return 0;
-}
-#endif /* USE_PARALLEL4 */
-
-
-/*
-Wrap HDF5 allocated memory free operations
-*/
-
-static void
-hdf5free(void* memory)
-{
-#ifndef JNA
-    /* On Windows using the microsoft runtime, it is an error
-       for one library to free memory allocated by a different library.*/
-#ifdef HDF5_HAS_H5FREE
-    if(memory != NULL) H5free_memory(memory);
-#else
-#ifndef _MSC_VER
-	if(memory != NULL) free(memory);
-#endif
-#endif
-#endif
-}
diff --git a/libsrc4/nc4grp.c b/libsrc4/nc4grp.c
index ab85881..a422fd7 100644
--- a/libsrc4/nc4grp.c
+++ b/libsrc4/nc4grp.c
@@ -1,20 +1,33 @@
-/*
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-HDF5 backend for netCDF, depending on your point of view.
-
-This file handles the nc4 groups.
-
-Copyright 2005, University Corporation for Atmospheric Research. See
-netcdf-4/docs/COPYRIGHT file for copying and redistribution
-conditions.
-
-$Id: nc4grp.c,v 1.44 2010/05/25 17:54:23 dmh Exp $
+/* Copyright 2005-2018, University Corporation for Atmospheric
+ * Research. See COPYRIGHT file for copying and redistribution
+ * conditions. */
+/**
+ * @file 
+ * @internal This file is part of netcdf-4, a netCDF-like interface
+ * for HDF5, or a HDF5 backend for netCDF, depending on your point of
+ * view.
+ *
+ * This file handles groups.
+ * 
+ * @author Ed Hartnett
 */
-
 #include "nc4internal.h"
 #include "nc4dispatch.h"
 
-/* Create a group. It's ncid is returned in the new_ncid pointer. */
+/**
+ * @internal Create a group. Its ncid is returned in the new_ncid
+ * pointer. 
+ *
+ * @param parent_ncid Parent group.
+ * @param name Name of new group.
+ * @param new_ncid Pointer that gets ncid for new group.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ESTRICTNC3 Classic model in use for this file.
+ * @return ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @author Ed Hartnett
+*/
 int
 NC4_def_grp(int parent_ncid, const char *name, int *new_ncid)
 {
@@ -28,8 +41,7 @@ NC4_def_grp(int parent_ncid, const char *name, int *new_ncid)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(parent_ncid, &grp, &h5)))
       return retval;
-   if (!h5)
-      return NC_ENOTNC4;
+   assert(h5);
 
    /* Check and normalize the name. */
    if ((retval = nc4_check_name(name, norm_name)))
@@ -61,7 +73,21 @@ NC4_def_grp(int parent_ncid, const char *name, int *new_ncid)
    return NC_NOERR;
 }
 
-/* Rename a group. */
+/**
+ * @internal Rename a group. 
+ *
+ * @param grpid Group ID.
+ * @param name New name for group.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @return ::NC_EPERM File opened read-only.
+ * @return ::NC_EBADGRPID Renaming root forbidden.
+ * @return ::NC_EHDFERR HDF5 function returned error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+*/
 int
 NC4_rename_grp(int grpid, const char *name)
 {
@@ -75,22 +101,22 @@ NC4_rename_grp(int grpid, const char *name)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(grpid, &grp, &h5)))
       return retval;
-   if (!h5)
-      return NC_ENOTNC4;
+   assert(h5);
 
    if (h5->no_write)
       return NC_EPERM; /* attempt to write to a read-only file */
 
    /* Do not allow renaming the root group */
-   if(grp->parent == NULL)
+   if (grp->parent == NULL)
 	return NC_EBADGRPID;
 
    /* Check and normalize the name. */
    if ((retval = nc4_check_name(name, norm_name)))
       return retval;
 
-   /* Check that this name is not in use as a var, grp, or type. */
-   if ((retval = nc4_check_dup_name(grp, norm_name)))
+   /* Check that this name is not in use as a var, grp, or type in the
+    * parent group (i.e. the group that grp is in). */
+   if ((retval = nc4_check_dup_name(grp->parent, norm_name)))
       return retval;
 
    /* If it's not in define mode, switch to define mode. */
@@ -129,8 +155,20 @@ NC4_rename_grp(int grpid, const char *name)
    return NC_NOERR;
 }
 
-/* Given an ncid and group name (NULL gets root group), return
- * the ncid of that group. */
+/**
+ * @internal Given an ncid and group name (NULL gets root group),
+ * return the ncid of that group. 
+ *
+ * @param ncid File and group ID.
+ * @param name Pointer that gets name.
+ * @param grp_ncid Pointer that gets group ncid.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @return ::NC_ENOGRP Group not found.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_ncid(int ncid, const char *name, int *grp_ncid)
 {
@@ -144,10 +182,7 @@ NC4_inq_ncid(int ncid, const char *name, int *grp_ncid)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
-
-   /* Groups only work with netCDF-4/HDF5 files... */
-   if (!h5)
-      return NC_ENOTNC4;
+   assert(h5);
 
    /* Normalize name. */
    if ((retval = nc4_normalize_name(name, norm_name)))
@@ -166,8 +201,18 @@ NC4_inq_ncid(int ncid, const char *name, int *grp_ncid)
    return NC_ENOGRP;
 }
 
-/* Given a location id, return the number of groups it contains, and
- * an array of their locids. */
+/**
+ * @internal Given a location id, return the number of groups it
+ * contains, and an array of their locids. 
+ *
+ * @param ncid File and group ID.
+ * @param numgrps Pointer that gets number of groups. Ignored if NULL.
+ * @param ncids Pointer that gets array of ncids. Ignored if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_grps(int ncid, int *numgrps, int *ncids)
 {
@@ -181,14 +226,7 @@ NC4_inq_grps(int ncid, int *numgrps, int *ncids)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
-
-   /* For netCDF-3 files, just report zero groups. */
-   if (!h5)
-   {
-      if (numgrps)
-	 *numgrps = 0;
-      return NC_NOERR;
-   }
+   assert(h5);
 
    /* Count the number of groups in this group. */
    for (g = grp->children; g; g = g->l.next)
@@ -210,7 +248,17 @@ NC4_inq_grps(int ncid, int *numgrps, int *ncids)
    return NC_NOERR;
 }
 
-/* Given locid, find name of group. (Root group is named "/".) */
+/**
+ * @internal Given locid, find name of group. (Root group is named
+ * "/".) 
+ *
+ * @param ncid File and group ID.
+ * @param name Pointer that gets name.
+
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_grpname(int ncid, char *name)
 {
@@ -223,21 +271,30 @@ NC4_inq_grpname(int ncid, char *name)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
+   assert(h5);
+
+   /* Copy the name. */
    if (name)
-   {
-      if (!h5)
-	 strcpy(name, "/");
-      else
-	 strcpy(name, grp->name);
-   }
+      strcpy(name, grp->name);
 
    return NC_NOERR;
 }
 
-/* Find the full path name to the group represented by ncid. Either
- * pointer argument may be NULL; pass a NULL for the third parameter
- * to get the length of the full path name. The length will not
- * include room for a null pointer. */
+/**
+ * @internal Find the full path name to the group represented by
+ * ncid. Either pointer argument may be NULL; pass a NULL for the
+ * third parameter to get the length of the full path name. The length
+ * will not include room for a null pointer. 
+ *
+ * @param ncid File and group ID.
+ * @param lenp Pointer that gets length of full name.
+ * @param full_name Pointer that gets name.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_grpname_full(int ncid, size_t *lenp, char *full_name)
 {
@@ -291,10 +348,20 @@ NC4_inq_grpname_full(int ncid, size_t *lenp, char *full_name)
    return ret;
 }
 
-/* Find the parent ncid of a group. For the root group, return
- * NC_ENOGRP error.  *Now* I know what kind of tinfoil hat wearing nut
- * job would call this function with a NULL pointer for parent_ncid -
- * Russ Rew!! */
+/**
+ * @internal Find the parent ncid of a group. For the root group,
+ * return NC_ENOGRP error.  *Now* I know what kind of tinfoil hat
+ * wearing nut job would call this function with a NULL pointer for
+ * parent_ncid - Russ Rew!! 
+ *
+ * @param ncid File and group ID.
+ * @param parent_ncid Pointer that gets the ncid of parent group.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ENOGRP Root has no parent.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_grp_parent(int ncid, int *parent_ncid)
 {
@@ -307,11 +374,8 @@ NC4_inq_grp_parent(int ncid, int *parent_ncid)
    /* Find info for this file and group. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
-
-   /* Groups only work with netCDF-4/HDF5 files... */
-   if (!h5)
-      return NC_ENOGRP;
-
+   assert(h5);
+   
    /* Set the parent ncid, if there is one. */
    if (grp->parent)
    {
@@ -324,7 +388,20 @@ NC4_inq_grp_parent(int ncid, int *parent_ncid)
    return NC_NOERR;
 }
 
-/* Given a full name and ncid, find group ncid. */
+/**
+ * @internal Given a full name and ncid, find group ncid. 
+ *
+ * @param ncid File and group ID.
+ * @param full_name Full name of group.
+ * @param grp_ncid Pointer that gets ncid of group.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ENOGRP Group not found.
+ * @return ::NC_ENOMEM Out of memory.
+ * @return ::NC_EINVAL Name is required.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid)
 {
@@ -340,6 +417,7 @@ NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid)
    /* Find info for this file and group, and set pointer to each. */
    if ((ret = nc4_find_grp_h5(ncid, &grp, &h5)))
       return ret;
+   assert(h5);
 
    /* Copy full_name because strtok messes with the value it works
     * with, and we don't want to mess up full_name. */
@@ -383,7 +461,17 @@ NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid)
    return NC_NOERR;
 }
 
-/* Get a list of ids for all the variables in a group. */
+/**
+ * @internal Get a list of ids for all the variables in a group. 
+ *
+ * @param ncid File and group ID.
+ * @param nvars Pointer that gets number of vars in group.
+ * @param varids Pointer that gets array of var IDs.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_varids(int ncid, int *nvars, int *varids)
 {
@@ -399,29 +487,17 @@ NC4_inq_varids(int ncid, int *nvars, int *varids)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
+   assert(h5);
 
-   if (!h5)
+   /* This is a netCDF-4 group. Round up them doggies and count
+    * 'em. The list is in correct (i.e. creation) order. */
+   for (i=0; i < grp->vars.nelems; i++)
    {
-      /* If this is a netcdf-3 file, there is only one group, the root
-       * group, and its vars have ids 0 thru nvars - 1. */
-      if ((retval = NC4_inq(ncid, NULL, &num_vars, NULL, NULL)))
-	 return retval;
+      var = grp->vars.value[i];
+      if (!var) continue;
       if (varids)
-	 for (v = 0; v < num_vars; v++)
-	    varids[v] = v;
-   }
-   else
-   {
-      /* This is a netCDF-4 group. Round up them doggies and count
-       * 'em. The list is in correct (i.e. creation) order. */
-      for (i=0; i < grp->vars.nelems; i++)
-      {
-	var = grp->vars.value[i];
-	if (!var) continue;
-	if (varids)
-	  varids[num_vars] = var->varid;
-	num_vars++;
-      }
+         varids[num_vars] = var->varid;
+      num_vars++;
    }
 
    /* If the user wants to know how many vars in the group, tell
@@ -432,8 +508,17 @@ NC4_inq_varids(int ncid, int *nvars, int *varids)
    return NC_NOERR;
 }
 
-/* This is the comparison function used for sorting dim ids. Integer
-   comparison: returns negative if b > a and positive if a > b. */
+/**
+ * @internal This is the comparison function used for sorting dim
+ * ids. Integer comparison: returns negative if b > a and positive if
+ * a > b. 
+ *
+ * @param a A pointer to an item to compare to b.
+ * @param b A pointer to an item to compare to a.
+ *
+ * @return a - b
+ * @author Ed Hartnett
+*/
 int int_cmp(const void *a, const void *b)
 {
    const int *ia = (const int *)a; 
@@ -441,9 +526,21 @@ int int_cmp(const void *a, const void *b)
    return *ia  - *ib; 
 }
 
-/* Find all dimids for a location. This finds all dimensions in a
- * group, with or without any of its parents, depending on last
- * parameter. */
+/**
+ * @internal Find all dimids for a location. This finds all dimensions
+ * in a group, with or without any of its parents, depending on last
+ * parameter. 
+ *
+ * @param ncid File and group ID.
+ * @param ndims Pointer that gets number of dimensions available in group.
+ * @param dimids Pointer that gets dim IDs.
+ * @param include_parents If non-zero, include dimensions from parent
+ * groups.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+*/
 int 
 NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents)
 {
@@ -459,44 +556,32 @@ NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
+   assert(h5);
 
-   if (!h5)
-   {
-      /* If this is a netcdf-3 file, then the dimids are going to be 0
-       * thru ndims-1, so just provide them. */
-      if ((retval = NC4_inq(ncid, &num, NULL, NULL, NULL)))
-	 return retval;
-      if (dimids)
-	 for (d = 0; d < num; d++)
-	    dimids[d] = d;
-   }
-   else
+   /* First count them. */
+   for (dim = grp->dim; dim; dim = dim->l.next)
+      num++;
+   if (include_parents)
+      for (g = grp->parent; g; g = g->parent)
+         for (dim = g->dim; dim; dim = dim->l.next)
+            num++;
+   
+   /* If the user wants the dimension ids, get them. */
+   if (dimids)
    {
-      /* First count them. */
+      int n = 0;
+      
+      /* Get dimension ids from this group. */
       for (dim = grp->dim; dim; dim = dim->l.next)
-	 num++;
+         dimids[n++] = dim->dimid;
+      
+      /* Get dimension ids from parent groups. */
       if (include_parents)
-	 for (g = grp->parent; g; g = g->parent)
-	    for (dim = g->dim; dim; dim = dim->l.next)
-	       num++;
+         for (g = grp->parent; g; g = g->parent)
+            for (dim = g->dim; dim; dim = dim->l.next)
+               dimids[n++] = dim->dimid;
       
-      /* If the user wants the dimension ids, get them. */
-      if (dimids)
-      {
-	 int n = 0;
-
-	 /* Get dimension ids from this group. */
-	 for (dim = grp->dim; dim; dim = dim->l.next)
-	    dimids[n++] = dim->dimid;
-
-	 /* Get dimension ids from parent groups. */
-	 if (include_parents)
-	    for (g = grp->parent; g; g = g->parent)
-	       for (dim = g->dim; dim; dim = dim->l.next)
-		  dimids[n++] = dim->dimid;
-	 
-	 qsort(dimids, num, sizeof(int), int_cmp);
-      }
+      qsort(dimids, num, sizeof(int), int_cmp);
    }
 
    /* If the user wants the number of dims, give it. */
diff --git a/libsrc4/nc4hdf.c b/libsrc4/nc4hdf.c
index 53e5f12..e98a9e6 100644
--- a/libsrc4/nc4hdf.c
+++ b/libsrc4/nc4hdf.c
@@ -1,17 +1,19 @@
-/*
-  This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-  HDF5 backend for netCDF, depending on your point of view.
-
-  This file contains functions internal to the netcdf4 library. None of
-  the functions in this file are exposed in the exetnal API. These
-  functions handle the HDF interface.
-
-  Copyright 2003, University Corporation for Atmospheric
-  Research. See the COPYRIGHT file for copying and redistribution
-  conditions.
-
-  $Id: nc4hdf.c,v 1.273 2010/05/27 21:34:14 dmh Exp $
-*/
+/**
+ *
+ * @file
+ * This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
+ * HDF5 backend for netCDF, depending on your point of view.
+ *
+ * This file contains functions internal to the netcdf4 library. None of
+ * the functions in this file are exposed in the exetnal API. These
+ * functions handle the HDF interface.
+ *
+ * Copyright 2003, University Corporation for Atmospheric
+ * Research. See the COPYRIGHT file for copying and redistribution
+ * conditions.
+ *
+ * @author Ed Hartnett, Dennis Heimbigner, Ward Fisher
+ */
 
 #include "config.h"
 #include "nc4internal.h"
@@ -23,667 +25,765 @@
 #include "netcdf_par.h"
 #endif
 
-#define NC3_STRICT_ATT_NAME "_nc3_strict"
+#define NC3_STRICT_ATT_NAME "_nc3_strict" /**< @internal Indicates classic model. */
+
+#define NC_HDF5_MAX_NAME 1024 /**< @internal Max size of HDF5 name. */
 
-#define NC_HDF5_MAX_NAME 1024
+#define MAXNAME 1024 /**< Max HDF5 name. */
 
-/* This is to track opened HDF5 objects to make sure they are
- * closed. */
-#ifdef EXTRA_TESTS
-int num_plists;
-int num_spaces;
-#endif /* EXTRA_TESTS */
+/** @internal HDF5 object types. */
+static unsigned int OTYPES[5] = {H5F_OBJ_FILE, H5F_OBJ_DATASET, H5F_OBJ_GROUP,
+                                 H5F_OBJ_DATATYPE, H5F_OBJ_ATTR};
 
-/*! Flag attributes in a linked list as dirty.
+/**
+ * @internal Flag attributes in a linked list as dirty.
  *
- * Given a linked list of attributes, flag each
- * dirty.
+ * @param attlist List of attributes, may be NULL.
  *
- * @param[in] attlist List of attributes, may be NULL.
- * @return Returns NC_NOERR on succes, error on failure.
+ * @return NC_NOERR No error.
  */
-static int flag_atts_dirty(NC_ATT_INFO_T **attlist) {
+static int
+flag_atts_dirty(NC_ATT_INFO_T **attlist) {
 
-  NC_ATT_INFO_T *att = NULL;
+   NC_ATT_INFO_T *att = NULL;
 
-  if(attlist == NULL) {
-    return NC_NOERR;
-  }
+   if(attlist == NULL) {
+      return NC_NOERR;
+   }
 
-  for(att = *attlist; att; att = att->l.next) {
-    att->dirty = NC_TRUE;
-  }
+   for(att = *attlist; att; att = att->l.next) {
+      att->dirty = NC_TRUE;
+   }
 
-  return NC_NOERR;
+   return NC_NOERR;
 
 }
 
-/* This function is needed to handle one special case: what if the
- * user defines a dim, writes metadata, then goes back into define
- * mode and adds a coordinate var for the already existing dim. In
- * that case, I need to recreate the dim's dimension scale dataset,
- * and then I need to go to every var in the file which uses that
- * dimension, and attach the new dimension scale. */
+/**
+ * @internal This function is needed to handle one special case: what
+ * if the user defines a dim, writes metadata, then goes back into
+ * define mode and adds a coordinate var for the already existing
+ * dim. In that case, I need to recreate the dim's dimension scale
+ * dataset, and then I need to go to every var in the file which uses
+ * that dimension, and attach the new dimension scale.
+ *
+ * @param grp Pointer to group info struct.
+ * @param dimid Dimension ID.
+ * @param dimscaleid HDF5 dimension scale ID.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+ */
 int
 rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
 {
-  NC_VAR_INFO_T *var;
-  NC_GRP_INFO_T *child_grp;
-  int d, i;
-  int retval;
-
-  assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0);
-  LOG((3, "%s: grp->name %s", __func__, grp->name));
-
-  /* If there are any child groups, attach dimscale there, if needed. */
-  for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
-    if ((retval = rec_reattach_scales(child_grp, dimid, dimscaleid)))
-      return retval;
-
-  /* Find any vars that use this dimension id. */
-  for (i=0; i < grp->vars.nelems; i++)
-  {
-    var = grp->vars.value[i];
-    if (!var) continue;
-    for (d = 0; d < var->ndims; d++)
-      if (var->dimids[d] == dimid && !var->dimscale)
-        {
-          LOG((2, "%s: attaching scale for dimid %d to var %s",
-               __func__, var->dimids[d], var->name));
-          if (var->created)
+   NC_VAR_INFO_T *var;
+   NC_GRP_INFO_T *child_grp;
+   int d, i;
+   int retval;
+
+   assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0);
+   LOG((3, "%s: grp->name %s", __func__, grp->name));
+
+   /* If there are any child groups, attach dimscale there, if needed. */
+   for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
+      if ((retval = rec_reattach_scales(child_grp, dimid, dimscaleid)))
+         return retval;
+
+   /* Find any vars that use this dimension id. */
+   for (i=0; i < grp->vars.nelems; i++)
+   {
+      var = grp->vars.value[i];
+      if (!var) continue;
+      for (d = 0; d < var->ndims; d++)
+         if (var->dimids[d] == dimid && !var->dimscale)
+         {
+            LOG((2, "%s: attaching scale for dimid %d to var %s",
+                 __func__, var->dimids[d], var->name));
+            if (var->created)
             {
-              if (H5DSattach_scale(var->hdf_datasetid, dimscaleid, d) < 0)
-                return NC_EHDFERR;
-              var->dimscale_attached[d] = NC_TRUE;
+               if (H5DSattach_scale(var->hdf_datasetid, dimscaleid, d) < 0)
+                  return NC_EHDFERR;
+               var->dimscale_attached[d] = NC_TRUE;
             }
-        }
-  }
-  return NC_NOERR;
+         }
+   }
+   return NC_NOERR;
 }
 
-/* This function is needed to handle one special case: what if the
- * user defines a dim, writes metadata, then goes back into define
- * mode and adds a coordinate var for the already existing dim. In
- * that case, I need to recreate the dim's dimension scale dataset,
- * and then I need to go to every var in the file which uses that
- * dimension, and attach the new dimension scale. */
+/**
+ * @internal This function is needed to handle one special case: what
+ * if the user defines a dim, writes metadata, then goes back into
+ * define mode and adds a coordinate var for the already existing
+ * dim. In that case, I need to recreate the dim's dimension scale
+ * dataset, and then I need to go to every var in the file which uses
+ * that dimension, and attach the new dimension scale.
+ *
+ * @param grp Pointer to group info struct.
+ * @param dimid Dimension ID.
+ * @param dimscaleid HDF5 dimension scale ID.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+ */
 int
 rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
 {
-  NC_VAR_INFO_T *var;
-  NC_GRP_INFO_T *child_grp;
-  int d, i;
-  int retval;
-
-  assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0);
-  LOG((3, "%s: grp->name %s", __func__, grp->name));
-
-  /* If there are any child groups, detach dimscale there, if needed. */
-  for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
-    if ((retval = rec_detach_scales(child_grp, dimid, dimscaleid)))
-      return retval;
-
-  /* Find any vars that use this dimension id. */
-  for (i=0; i < grp->vars.nelems; i++)
-  {
-    var = grp->vars.value[i];
-    if (!var) continue;
-    for (d = 0; d < var->ndims; d++)
-      if (var->dimids[d] == dimid && !var->dimscale)
-        {
-          LOG((2, "%s: detaching scale for dimid %d to var %s",
-               __func__, var->dimids[d], var->name));
-          if (var->created)
-            if (var->dimscale_attached && var->dimscale_attached[d])
-              {
-                if (H5DSdetach_scale(var->hdf_datasetid, dimscaleid, d) < 0)
-                  return NC_EHDFERR;
-                var->dimscale_attached[d] = NC_FALSE;
-              }
-        }
-  }
-  return NC_NOERR;
+   NC_VAR_INFO_T *var;
+   NC_GRP_INFO_T *child_grp;
+   int d, i;
+   int retval;
+
+   assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0);
+   LOG((3, "%s: grp->name %s", __func__, grp->name));
+
+   /* If there are any child groups, detach dimscale there, if needed. */
+   for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
+      if ((retval = rec_detach_scales(child_grp, dimid, dimscaleid)))
+         return retval;
+
+   /* Find any vars that use this dimension id. */
+   for (i=0; i < grp->vars.nelems; i++)
+   {
+      var = grp->vars.value[i];
+      if (!var) continue;
+      for (d = 0; d < var->ndims; d++)
+         if (var->dimids[d] == dimid && !var->dimscale)
+         {
+            LOG((2, "%s: detaching scale for dimid %d to var %s",
+                 __func__, var->dimids[d], var->name));
+            if (var->created)
+               if (var->dimscale_attached && var->dimscale_attached[d])
+               {
+                  if (H5DSdetach_scale(var->hdf_datasetid, dimscaleid, d) < 0)
+                     return NC_EHDFERR;
+                  var->dimscale_attached[d] = NC_FALSE;
+               }
+         }
+   }
+   return NC_NOERR;
 }
 
-/* Open the dataset and leave it open. */
+/**
+ * @internal Open a HDF5 dataset and leave it open.
+ *
+ * @param grp Pointer to group info struct.
+ * @param varid Variable ID.
+ * @param dataset Pointer that gets the HDF5 dataset ID.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+ */
 int
 nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset)
 {
-  NC_VAR_INFO_T *var;
+   NC_VAR_INFO_T *var;
 
-  /* Find the requested varid. */
+   /* Find the requested varid. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
    if (!var) return NC_ENOTVAR;
    assert(var->varid == varid);
 
-  /* Open this dataset if necessary. */
-  if (!var->hdf_datasetid)
-    if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name,
-                                       H5P_DEFAULT)) < 0)
-      return NC_ENOTVAR;
+   /* Open this dataset if necessary. */
+   if (!var->hdf_datasetid)
+      if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name,
+                                         H5P_DEFAULT)) < 0)
+         return NC_ENOTVAR;
 
-  *dataset = var->hdf_datasetid;
+   *dataset = var->hdf_datasetid;
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
-/* Get the default fill value for an atomic type. Memory for
- * fill_value must already be allocated, or you are DOOMED!!!*/
+/**
+ * @internal Get the default fill value for an atomic type. Memory for
+ * fill_value must already be allocated, or you are DOOMED!
+ *
+ * @param type_info Pointer to type info struct.
+ * @param fill_value Pointer that gets the default fill value.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EINVAL Can't find atomic type.
+ * @author Ed Hartnett
+ */
 int
 nc4_get_default_fill_value(const NC_TYPE_INFO_T *type_info, void *fill_value)
 {
-  switch (type_info->nc_typeid)
-    {
-    case NC_CHAR:
+   switch (type_info->nc_typeid)
+   {
+   case NC_CHAR:
       *(char *)fill_value = NC_FILL_CHAR;
       break;
 
-    case NC_STRING:
+   case NC_STRING:
       *(char **)fill_value = strdup(NC_FILL_STRING);
       break;
 
-    case NC_BYTE:
+   case NC_BYTE:
       *(signed char *)fill_value = NC_FILL_BYTE;
       break;
 
-    case NC_SHORT:
+   case NC_SHORT:
       *(short *)fill_value = NC_FILL_SHORT;
       break;
 
-    case NC_INT:
+   case NC_INT:
       *(int *)fill_value = NC_FILL_INT;
       break;
 
-    case NC_UBYTE:
+   case NC_UBYTE:
       *(unsigned char *)fill_value = NC_FILL_UBYTE;
       break;
 
-    case NC_USHORT:
+   case NC_USHORT:
       *(unsigned short *)fill_value = NC_FILL_USHORT;
       break;
 
-    case NC_UINT:
+   case NC_UINT:
       *(unsigned int *)fill_value = NC_FILL_UINT;
       break;
 
-    case NC_INT64:
+   case NC_INT64:
       *(long long *)fill_value = NC_FILL_INT64;
       break;
 
-    case NC_UINT64:
+   case NC_UINT64:
       *(unsigned long long *)fill_value = NC_FILL_UINT64;
       break;
 
-    case NC_FLOAT:
+   case NC_FLOAT:
       *(float *)fill_value = NC_FILL_FLOAT;
       break;
 
-    case NC_DOUBLE:
+   case NC_DOUBLE:
       *(double *)fill_value = NC_FILL_DOUBLE;
       break;
 
-    default:
+   default:
       return NC_EINVAL;
-    }
+   }
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
-/* What fill value should be used for a variable? */
+/**
+ * @internal What fill value should be used for a variable?
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param var Pointer to variable info struct.
+ * @param fillp Pointer that gets pointer to fill value.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+ */
 static int
 get_fill_value(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp)
 {
-  size_t size;
-  int retval;
-
-  /* Find out how much space we need for this type's fill value. */
-  if (var->type_info->nc_type_class == NC_VLEN)
-    size = sizeof(nc_vlen_t);
-  else if (var->type_info->nc_type_class == NC_STRING)
-    size = sizeof(char *);
-  else
-    {
+   size_t size;
+   int retval;
+
+   /* Find out how much space we need for this type's fill value. */
+   if (var->type_info->nc_type_class == NC_VLEN)
+      size = sizeof(nc_vlen_t);
+   else if (var->type_info->nc_type_class == NC_STRING)
+      size = sizeof(char *);
+   else
+   {
       if ((retval = nc4_get_typelen_mem(h5, var->type_info->nc_typeid, 0, &size)))
-        return retval;
-    }
-  assert(size);
-
-  /* Allocate the space. */
-  if (!((*fillp) = calloc(1, size)))
-    return NC_ENOMEM;
-
-  /* If the user has set a fill_value for this var, use, otherwise
-   * find the default fill value. */
-  if (var->fill_value)
-    {
+         return retval;
+   }
+   assert(size);
+
+   /* Allocate the space. */
+   if (!((*fillp) = calloc(1, size)))
+      return NC_ENOMEM;
+
+   /* If the user has set a fill_value for this var, use, otherwise
+    * find the default fill value. */
+   if (var->fill_value)
+   {
       LOG((4, "Found a fill value for var %s", var->name));
       if (var->type_info->nc_type_class == NC_VLEN)
-        {
-          nc_vlen_t *in_vlen = (nc_vlen_t *)(var->fill_value), *fv_vlen = (nc_vlen_t *)(*fillp);
-
-          fv_vlen->len = in_vlen->len;
-          if (!(fv_vlen->p = malloc(size * in_vlen->len)))
-            {
-              free(*fillp);
-              *fillp = NULL;
-              return NC_ENOMEM;
-            }
-          memcpy(fv_vlen->p, in_vlen->p, in_vlen->len * size);
-        }
+      {
+         nc_vlen_t *in_vlen = (nc_vlen_t *)(var->fill_value), *fv_vlen = (nc_vlen_t *)(*fillp);
+
+         fv_vlen->len = in_vlen->len;
+         if (!(fv_vlen->p = malloc(size * in_vlen->len)))
+         {
+            free(*fillp);
+            *fillp = NULL;
+            return NC_ENOMEM;
+         }
+         memcpy(fv_vlen->p, in_vlen->p, in_vlen->len * size);
+      }
       else if (var->type_info->nc_type_class == NC_STRING)
-        {
-          if (*(char **)var->fill_value)
+      {
+         if (*(char **)var->fill_value)
             if (!(**(char ***)fillp = strdup(*(char **)var->fill_value)))
-              {
-                free(*fillp);
-                *fillp = NULL;
-                return NC_ENOMEM;
-              }
-        }
+            {
+               free(*fillp);
+               *fillp = NULL;
+               return NC_ENOMEM;
+            }
+      }
       else
-        memcpy((*fillp), var->fill_value, size);
-    }
-  else
-    {
+         memcpy((*fillp), var->fill_value, size);
+   }
+   else
+   {
       if (nc4_get_default_fill_value(var->type_info, *fillp))
-        {
-          /* Note: release memory, but don't return error on failure */
-          free(*fillp);
-          *fillp = NULL;
-        }
-    }
-
-  return NC_NOERR;
+      {
+         /* Note: release memory, but don't return error on failure */
+         free(*fillp);
+         *fillp = NULL;
+      }
+   }
+
+   return NC_NOERR;
 }
 
-/* Given a netcdf type, return appropriate HDF typeid. */
-/* (All hdf_typeid's returned from this routine must be H5Tclosed by the caller) */
+/**
+ * @internal Given a netcdf type, return appropriate HDF typeid.  (All
+ * hdf_typeid's returned from this routine must be H5Tclosed by the
+ * caller).
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param xtype NetCDF type ID.
+ * @param hdf_typeid Pointer that gets the HDF5 type ID.
+ * @param endianness Desired endianness in HDF5 type.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_ECHAR Conversions of NC_CHAR forbidden.
+ * @returns NC_EVARMETA HDF5 returning error creating datatype.
+ * @returns NC_EHDFERR HDF5 returning error.
+ * @returns NC_EBADTYE Type not found.
+ * @author Ed Hartnett
+ */
 int
 nc4_get_hdf_typeid(NC_HDF5_FILE_INFO_T *h5, nc_type xtype,
                    hid_t *hdf_typeid, int endianness)
 {
-  NC_TYPE_INFO_T *type;
-  hid_t typeid = 0;
-  int retval = NC_NOERR;
+   NC_TYPE_INFO_T *type;
+   hid_t typeid = 0;
+   int retval = NC_NOERR;
 
-  assert(hdf_typeid && h5);
+   assert(hdf_typeid && h5);
 
-  *hdf_typeid = -1;
+   *hdf_typeid = -1;
 
-  /* Determine an appropriate HDF5 datatype */
-  if (xtype == NC_NAT)
-    /* NAT = 'Not A Type' (c.f. NaN) */
-    return NC_EBADTYPE;
-  else if (xtype == NC_CHAR || xtype == NC_STRING)
-    {
+   /* Determine an appropriate HDF5 datatype */
+   if (xtype == NC_NAT)
+      /* NAT = 'Not A Type' (c.f. NaN) */
+      return NC_EBADTYPE;
+   else if (xtype == NC_CHAR || xtype == NC_STRING)
+   {
       /* NC_CHAR & NC_STRING types create a new HDF5 datatype */
       if (xtype == NC_CHAR)
-        {
-          if ((typeid = H5Tcopy(H5T_C_S1)) < 0)
+      {
+         if ((typeid = H5Tcopy(H5T_C_S1)) < 0)
             return NC_EHDFERR;
-          if (H5Tset_strpad(typeid, H5T_STR_NULLTERM) < 0)
+         if (H5Tset_strpad(typeid, H5T_STR_NULLTERM) < 0)
+            BAIL(NC_EVARMETA);
+         if(H5Tset_cset(typeid, H5T_CSET_ASCII) < 0)
             BAIL(NC_EVARMETA);
-	  if(H5Tset_cset(typeid, H5T_CSET_ASCII) < 0)
-	    BAIL(NC_EVARMETA);
 
-          /* Take ownership of the newly created HDF5 datatype */
-          *hdf_typeid = typeid;
-          typeid = 0;
-        }
+         /* Take ownership of the newly created HDF5 datatype */
+         *hdf_typeid = typeid;
+         typeid = 0;
+      }
       else
-        {
-          if ((typeid = H5Tcopy(H5T_C_S1)) < 0)
+      {
+         if ((typeid = H5Tcopy(H5T_C_S1)) < 0)
             return NC_EHDFERR;
-          if (H5Tset_size(typeid, H5T_VARIABLE) < 0)
+         if (H5Tset_size(typeid, H5T_VARIABLE) < 0)
+            BAIL(NC_EVARMETA);
+         if(H5Tset_cset(typeid, H5T_CSET_UTF8) < 0)
             BAIL(NC_EVARMETA);
-	  if(H5Tset_cset(typeid, H5T_CSET_UTF8) < 0)
-	    BAIL(NC_EVARMETA);
-
-          /* Take ownership of the newly created HDF5 datatype */
-          *hdf_typeid = typeid;
-          typeid = 0;
-        }
-    }
-  else
-    {
+
+         /* Take ownership of the newly created HDF5 datatype */
+         *hdf_typeid = typeid;
+         typeid = 0;
+      }
+   }
+   else
+   {
       /* All other types use an existing HDF5 datatype */
       switch (xtype)
-        {
-        case NC_BYTE: /* signed 1 byte integer */
-          if (endianness == NC_ENDIAN_LITTLE)
+      {
+      case NC_BYTE: /* signed 1 byte integer */
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_I8LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_I8BE;
-          else
+         else
             typeid = H5T_NATIVE_SCHAR;
-          break;
+         break;
 
-        case NC_SHORT: /* signed 2 byte integer */
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_SHORT: /* signed 2 byte integer */
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_I16LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_I16BE;
-          else
+         else
             typeid = H5T_NATIVE_SHORT;
-          break;
+         break;
 
-        case NC_INT:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_INT:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_I32LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_I32BE;
-          else
+         else
             typeid = H5T_NATIVE_INT;
-          break;
+         break;
 
-        case NC_UBYTE:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_UBYTE:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_U8LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_U8BE;
-          else
+         else
             typeid = H5T_NATIVE_UCHAR;
-          break;
+         break;
 
-        case NC_USHORT:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_USHORT:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_U16LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_U16BE;
-          else
+         else
             typeid = H5T_NATIVE_USHORT;
-          break;
+         break;
 
-        case NC_UINT:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_UINT:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_U32LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_U32BE;
-          else
+         else
             typeid = H5T_NATIVE_UINT;
-          break;
+         break;
 
-        case NC_INT64:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_INT64:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_I64LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_I64BE;
-          else
+         else
             typeid = H5T_NATIVE_LLONG;
-          break;
+         break;
 
-        case NC_UINT64:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_UINT64:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_STD_U64LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_STD_U64BE;
-          else
+         else
             typeid = H5T_NATIVE_ULLONG;
-          break;
+         break;
 
-        case NC_FLOAT:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_FLOAT:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_IEEE_F32LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_IEEE_F32BE;
-          else
+         else
             typeid = H5T_NATIVE_FLOAT;
-          break;
+         break;
 
-        case NC_DOUBLE:
-          if (endianness == NC_ENDIAN_LITTLE)
+      case NC_DOUBLE:
+         if (endianness == NC_ENDIAN_LITTLE)
             typeid = H5T_IEEE_F64LE;
-          else if (endianness == NC_ENDIAN_BIG)
+         else if (endianness == NC_ENDIAN_BIG)
             typeid = H5T_IEEE_F64BE;
-          else
+         else
             typeid = H5T_NATIVE_DOUBLE;
-          break;
+         break;
 
-        default:
-          /* Maybe this is a user defined type? */
-          if (nc4_find_type(h5, xtype, &type))
+      default:
+         /* Maybe this is a user defined type? */
+         if (nc4_find_type(h5, xtype, &type))
             return NC_EBADTYPE;
-          if (!type)
+         if (!type)
             return NC_EBADTYPE;
-          typeid = type->hdf_typeid;
-          break;
-        }
+         typeid = type->hdf_typeid;
+         break;
+      }
       assert(typeid);
 
       /* Copy the HDF5 datatype, so the function operates uniformly */
       if ((*hdf_typeid = H5Tcopy(typeid)) < 0)
-        return NC_EHDFERR;
+         return NC_EHDFERR;
       typeid = 0;
-    }
-  assert(*hdf_typeid != -1);
+   }
+   assert(*hdf_typeid != -1);
 
- exit:
-  if (typeid > 0 && H5Tclose(typeid) < 0)
-    BAIL2(NC_EHDFERR);
-  return retval;
+exit:
+   if (typeid > 0 && H5Tclose(typeid) < 0)
+      BAIL2(NC_EHDFERR);
+   return retval;
 }
 
-/* Do some common check for nc4_put_vara and nc4_get_vara. These
- * checks have to be done when both reading and writing data. */
+/**
+ * @internal Do some common check for nc4_put_vara and
+ * nc4_get_vara. These checks have to be done when both reading and
+ * writing data.
+ *
+ * @param mem_nc_type Pointer to type of data in memory.
+ * @param var Pointer to var info struct.
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 check_for_vara(nc_type *mem_nc_type, NC_VAR_INFO_T *var, NC_HDF5_FILE_INFO_T *h5)
 {
-  int retval;
-
-  /* If mem_nc_type is NC_NAT, it means we want to use the file type
-   * as the mem type as well. */
-  assert(mem_nc_type);
-  if (*mem_nc_type == NC_NAT)
-    *mem_nc_type = var->type_info->nc_typeid;
-  assert(*mem_nc_type);
-
-  /* No NC_CHAR conversions, you pervert! */
-  if (var->type_info->nc_typeid != *mem_nc_type &&
-      (var->type_info->nc_typeid == NC_CHAR || *mem_nc_type == NC_CHAR))
-    return NC_ECHAR;
-
-  /* If we're in define mode, we can't read or write data. */
-  if (h5->flags & NC_INDEF)
-    {
+   int retval;
+
+   /* If mem_nc_type is NC_NAT, it means we want to use the file type
+    * as the mem type as well. */
+   assert(mem_nc_type);
+   if (*mem_nc_type == NC_NAT)
+      *mem_nc_type = var->type_info->nc_typeid;
+   assert(*mem_nc_type);
+
+   /* No NC_CHAR conversions, you pervert! */
+   if (var->type_info->nc_typeid != *mem_nc_type &&
+       (var->type_info->nc_typeid == NC_CHAR || *mem_nc_type == NC_CHAR))
+      return NC_ECHAR;
+
+   /* If we're in define mode, we can't read or write data. */
+   if (h5->flags & NC_INDEF)
+   {
       if (h5->cmode & NC_CLASSIC_MODEL)
-        return NC_EINDEFINE;
+         return NC_EINDEFINE;
       if ((retval = nc4_enddef_netcdf4_file(h5)))
-        return retval;
-    }
+         return retval;
+   }
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
 #ifdef LOGGING
-/* Print some debug info about dimensions to the log. */
+/**
+ * @intarnal Print some debug info about dimensions to the log. 
+ */
 static void
 log_dim_info(NC_VAR_INFO_T *var, hsize_t *fdims, hsize_t *fmaxdims,
              hsize_t *start, hsize_t *count)
 {
-  int d2;
+   int d2;
 
-  /* Print some debugging info... */
-  LOG((4, "%s: var name %s ndims %d", __func__, var->name, var->ndims));
-  LOG((4, "File space, and requested:"));
-  for (d2 = 0; d2 < var->ndims; d2++)
-    {
+   /* Print some debugging info... */
+   LOG((4, "%s: var name %s ndims %d", __func__, var->name, var->ndims));
+   LOG((4, "File space, and requested:"));
+   for (d2 = 0; d2 < var->ndims; d2++)
+   {
       LOG((4, "fdims[%d]=%Ld fmaxdims[%d]=%Ld", d2, fdims[d2], d2,
            fmaxdims[d2]));
       LOG((4, "start[%d]=%Ld  count[%d]=%Ld", d2, start[d2], d2, count[d2]));
-    }
+   }
 }
 #endif /* LOGGING */
 
 #ifdef USE_PARALLEL4
+/**
+ * @internal Set the parallel access for a var (collective
+ * vs. independent).
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param var Pointer to var info struct.
+ * @param xfer_plistid H5FD_MPIO_COLLECTIVE or H5FD_MPIO_INDEPENDENT.
+ *
+ * @returns NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 set_par_access(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, hid_t xfer_plistid)
 {
-  /* If netcdf is built with parallel I/O, then parallel access can
-   * be used, and, if this file was opened or created for parallel
-   * access, we need to set the transfer mode. */
-  if (h5->parallel)
-    {
+   /* If netcdf is built with parallel I/O, then parallel access can
+    * be used, and, if this file was opened or created for parallel
+    * access, we need to set the transfer mode. */
+   if (h5->parallel)
+   {
       H5FD_mpio_xfer_t hdf5_xfer_mode;
 
       /* Decide on collective or independent. */
       hdf5_xfer_mode = (var->parallel_access != NC_INDEPENDENT) ?
-        H5FD_MPIO_COLLECTIVE : H5FD_MPIO_INDEPENDENT;
+         H5FD_MPIO_COLLECTIVE : H5FD_MPIO_INDEPENDENT;
 
       /* Set the mode in the transfer property list. */
       if (H5Pset_dxpl_mpio(xfer_plistid, hdf5_xfer_mode) < 0)
-        return NC_EPARINIT;
+         return NC_EPARINIT;
 
       LOG((4, "%s: %d H5FD_MPIO_COLLECTIVE: %d H5FD_MPIO_INDEPENDENT: %d",
            __func__, (int)hdf5_xfer_mode, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_INDEPENDENT));
-    }
-  return NC_NOERR;
+   }
+   return NC_NOERR;
 }
 #endif
 
-/* Write an array of data to a variable. When it comes right down to
- * it, this is what netCDF-4 is all about, this is *the* function, the
- * big enchilda, the grand poo-bah, the alpha dog, the head honcho,
- * the big cheese, the mighty kahuna, the top bananna, the high
- * muckity-muck, numero uno. Well, you get the idea.  */
+/**
+ * @internal Write an array of data to a variable.
+ *
+ * @param nc Pointer to the file NC struct.
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param startp Array of start indicies.
+ * @param countp Array of counts.
+ * @param mem_nc_type The type of the data in memory.
+ * @param is_long True only if NC_LONG is the memory type.
+ * @param data The data to be written.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Var not found.
+ * @returns ::NC_EHDFERR HDF5 function returned error.
+ * @returns ::NC_EINVALCOORDS Incorrect start.
+ * @returns ::NC_EEDGE Incorrect start/count.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @returns ::NC_EMPI MPI library error (parallel only)
+ * @returns ::NC_ECANTEXTEND Can't extend dimension for write.
+ * @returns ::NC_ERANGE Data conversion error.
+ * @author Ed Hartnett
+ */
 int
 nc4_put_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;
-  NC_HDF5_FILE_INFO_T *h5;
-  NC_VAR_INFO_T *var;
-  NC_DIM_INFO_T *dim;
-  hid_t file_spaceid = 0, mem_spaceid = 0, xfer_plistid = 0;
-  long long unsigned xtend_size[NC_MAX_VAR_DIMS];
-  hsize_t fdims[NC_MAX_VAR_DIMS], fmaxdims[NC_MAX_VAR_DIMS];
-  hsize_t start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS];
-  char *name_to_use;
-  int need_to_extend = 0;
-  int extend_possible = 0;
-  int retval = NC_NOERR, range_error = 0, i, d2;
-  void *bufr = NULL;
+   NC_GRP_INFO_T *grp;
+   NC_HDF5_FILE_INFO_T *h5;
+   NC_VAR_INFO_T *var;
+   NC_DIM_INFO_T *dim;
+   hid_t file_spaceid = 0, mem_spaceid = 0, xfer_plistid = 0;
+   long long unsigned xtend_size[NC_MAX_VAR_DIMS];
+   hsize_t fdims[NC_MAX_VAR_DIMS], fmaxdims[NC_MAX_VAR_DIMS];
+   hsize_t start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS];
+   char *name_to_use;
+   int need_to_extend = 0;
+#ifdef USE_PARALLEL4
+   int extend_possible = 0;
+#endif
+   int retval = NC_NOERR, range_error = 0, i, d2;
+   void *bufr = NULL;
 #ifndef HDF5_CONVERT
-  int need_to_convert = 0;
-  size_t len = 1;
+   int need_to_convert = 0;
+   size_t len = 1;
 #endif
 #ifdef HDF5_CONVERT
-  hid_t mem_typeid = 0;
+   hid_t mem_typeid = 0;
 #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);
+   /* 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);
 
-  LOG((3, "%s: var->name %s mem_nc_type %d is_long %d",
-       __func__, var->name, mem_nc_type, is_long));
+   LOG((3, "%s: var->name %s mem_nc_type %d is_long %d",
+        __func__, var->name, mem_nc_type, is_long));
 
-  /* Check some stuff about the type and the file. If the file must
-   * be switched from define mode, it happens here. */
-  if ((retval = check_for_vara(&mem_nc_type, var, h5)))
-    return retval;
+   /* Check some stuff about the type and the file. If the file must
+    * be switched from define mode, it happens here. */
+   if ((retval = check_for_vara(&mem_nc_type, var, h5)))
+      return retval;
 
-  /* Convert from size_t and ptrdiff_t to hssize_t, and hsize_t. */
-  for (i = 0; i < var->ndims; i++)
-    {
+   /* Convert from size_t and ptrdiff_t to hssize_t, and hsize_t. */
+   for (i = 0; i < var->ndims; i++)
+   {
       start[i] = startp[i];
       count[i] = countp[i];
-    }
-
-  /* Open this dataset if necessary, also checking for a weird case:
-   * a non-coordinate (and non-scalar) variable that has the same
-   * name as a dimension. */
-  if (var->hdf5_name && strlen(var->hdf5_name) >= strlen(NON_COORD_PREPEND) &&
-      strncmp(var->hdf5_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)) == 0 &&
-      var->ndims)
-    name_to_use = var->hdf5_name;
-  else
-    name_to_use = var->name;
-  if (!var->hdf_datasetid)
-    if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, name_to_use, H5P_DEFAULT)) < 0)
-      return NC_ENOTVAR;
-
-  /* Get file space of data. */
-  if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
-    BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_spaces++;
-#endif
+   }
+
+   /* Open this dataset if necessary, also checking for a weird case:
+    * a non-coordinate (and non-scalar) variable that has the same
+    * name as a dimension. */
+   if (var->hdf5_name && strlen(var->hdf5_name) >= strlen(NON_COORD_PREPEND) &&
+       strncmp(var->hdf5_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)) == 0 &&
+       var->ndims)
+      name_to_use = var->hdf5_name;
+   else
+      name_to_use = var->name;
+   if (!var->hdf_datasetid)
+      if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, name_to_use, H5P_DEFAULT)) < 0)
+         return NC_ENOTVAR;
+
+   /* Get file space of data. */
+   if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
+      BAIL(NC_EHDFERR);
 
-  /* Check to ensure the user selection is
-   * valid. H5Sget_simple_extent_dims gets the sizes of all the dims
-   * and put them in fdims. */
-  if (H5Sget_simple_extent_dims(file_spaceid, fdims, fmaxdims) < 0)
-    BAIL(NC_EHDFERR);
+   /* Check to ensure the user selection is
+    * valid. H5Sget_simple_extent_dims gets the sizes of all the dims
+    * and put them in fdims. */
+   if (H5Sget_simple_extent_dims(file_spaceid, fdims, fmaxdims) < 0)
+      BAIL(NC_EHDFERR);
 
 #ifdef LOGGING
-  log_dim_info(var, fdims, fmaxdims, start, count);
+   log_dim_info(var, fdims, fmaxdims, start, count);
 #endif
 
-  /* Check dimension bounds. Remember that unlimited dimensions can
-   * put data beyond their current length. */
-  for (d2 = 0; d2 < var->ndims; d2++)
-    {
+   /* Check dimension bounds. Remember that unlimited dimensions can
+    * put data beyond their current length. */
+   for (d2 = 0; d2 < var->ndims; d2++)
+   {
       dim = var->dim[d2];
       assert(dim && dim->dimid == var->dimids[d2]);
       if (!dim->unlimited)
-        {
+      {
 #ifdef RELAX_COORD_BOUND
-          if (start[d2] > (hssize_t)fdims[d2] ||
-              (start[d2] == (hssize_t)fdims[d2] && count[d2] > 0))
+         if (start[d2] > (hssize_t)fdims[d2] ||
+             (start[d2] == (hssize_t)fdims[d2] && count[d2] > 0))
 #else
-          if (start[d2] >= (hssize_t)fdims[d2])
+            if (start[d2] >= (hssize_t)fdims[d2])
 #endif
-            BAIL_QUIET(NC_EINVALCOORDS);
-          if (start[d2] + count[d2] > fdims[d2])
+               BAIL_QUIET(NC_EINVALCOORDS);
+         if (start[d2] + count[d2] > fdims[d2])
             BAIL_QUIET(NC_EEDGE);
-        }
-    }
-
-  /* Now you would think that no one would be crazy enough to write
-     a scalar dataspace with one of the array function calls, but you
-     would be wrong. So let's check to see if the dataset is
-     scalar. If it is, we won't try to set up a hyperslab. */
-  if (H5Sget_simple_extent_type(file_spaceid) == H5S_SCALAR)
-    {
+      }
+   }
+
+   /* Now you would think that no one would be crazy enough to write
+      a scalar dataspace with one of the array function calls, but you
+      would be wrong. So let's check to see if the dataset is
+      scalar. If it is, we won't try to set up a hyperslab. */
+   if (H5Sget_simple_extent_type(file_spaceid) == H5S_SCALAR)
+   {
       if ((mem_spaceid = H5Screate(H5S_SCALAR)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces++;
-#endif
-    }
-  else
-    {
+         BAIL(NC_EHDFERR);
+   }
+   else
+   {
       if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET, start, NULL,
                               count, NULL) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       /* Create a space for the memory, just big enough to hold the slab
          we want. */
       if ((mem_spaceid = H5Screate_simple(var->ndims, count, NULL)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces++;
-#endif
-    }
+         BAIL(NC_EHDFERR);
+   }
 
 #ifndef HDF5_CONVERT
-  /* Are we going to convert any data? (No converting of compound or
-   * opaque types.) */
-  if ((mem_nc_type != var->type_info->nc_typeid || (var->type_info->nc_typeid == NC_INT && is_long)) &&
-      mem_nc_type != NC_COMPOUND && mem_nc_type != NC_OPAQUE)
-    {
+   /* Are we going to convert any data? (No converting of compound or
+    * opaque types.) */
+   if ((mem_nc_type != var->type_info->nc_typeid || (var->type_info->nc_typeid == NC_INT && is_long)) &&
+       mem_nc_type != NC_COMPOUND && mem_nc_type != NC_OPAQUE)
+   {
       size_t file_type_size;
 
       /* We must convert - allocate a buffer. */
       need_to_convert++;
       if (var->ndims)
-        for (d2=0; d2<var->ndims; d2++)
-          len *= countp[d2];
+         for (d2=0; d2<var->ndims; d2++)
+            len *= countp[d2];
       LOG((4, "converting data for var %s type=%d len=%d", var->name,
            var->type_info->nc_typeid, len));
 
@@ -696,361 +796,364 @@ nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
        * the data in the file. If we're writing, we need bufr to be
        * big enough to hold all the data in the file's type. */
       if(len > 0)
-        if (!(bufr = malloc(len * file_type_size)))
-          BAIL(NC_ENOMEM);
-    }
-  else
+         if (!(bufr = malloc(len * file_type_size)))
+            BAIL(NC_ENOMEM);
+   }
+   else
 #endif /* ifndef HDF5_CONVERT */
-    bufr = data;
+      bufr = data;
 
 #ifdef HDF5_CONVERT
-  /* Get the HDF type of the data in memory. */
-  if ((retval = nc4_get_hdf_typeid(h5, mem_nc_type, &mem_typeid,
-                                   var->type_info->endianness)))
-    BAIL(retval);
+   /* Get the HDF type of the data in memory. */
+   if ((retval = nc4_get_hdf_typeid(h5, mem_nc_type, &mem_typeid,
+                                    var->type_info->endianness)))
+      BAIL(retval);
 #endif
 
-  /* Create the data transfer property list. */
-  if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0)
-    BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_plists++;
-#endif
+   /* Create the data transfer property list. */
+   if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0)
+      BAIL(NC_EHDFERR);
 
-  /* Apply the callback function which will detect range
-   * errors. Which one to call depends on the length of the
-   * destination buffer type. */
+   /* Apply the callback function which will detect range
+    * errors. Which one to call depends on the length of the
+    * destination buffer type. */
 #ifdef HDF5_CONVERT
-  if (H5Pset_type_conv_cb(xfer_plistid, except_func, &range_error) < 0)
-    BAIL(NC_EHDFERR);
+   if (H5Pset_type_conv_cb(xfer_plistid, except_func, &range_error) < 0)
+      BAIL(NC_EHDFERR);
 #endif
 
 #ifdef USE_PARALLEL4
-  /* Set up parallel I/O, if needed. */
-  if ((retval = set_par_access(h5, var, xfer_plistid)))
-    BAIL(retval);
+   /* Set up parallel I/O, if needed. */
+   if ((retval = set_par_access(h5, var, xfer_plistid)))
+      BAIL(retval);
 #endif
 
-  /* Read/write this hyperslab into memory. */
-  /* Does the dataset have to be extended? If it's already
-     extended to the required size, it will do no harm to reextend
-     it to that size. */
-  if (var->ndims)
-    {
+   /* Read/write this hyperslab into memory. */
+   /* Does the dataset have to be extended? If it's already
+      extended to the required size, it will do no harm to reextend
+      it to that size. */
+   if (var->ndims)
+   {
       for (d2 = 0; d2 < var->ndims; d2++)
-        {
-          dim = var->dim[d2];
-	  assert(dim && dim->dimid == var->dimids[d2]);
-          if (dim->unlimited)
+      {
+         dim = var->dim[d2];
+         assert(dim && dim->dimid == var->dimids[d2]);
+         if (dim->unlimited)
+         {
+#ifdef USE_PARALLEL4
+            extend_possible = 1;
+#endif
+            if (start[d2] + count[d2] > fdims[d2])
             {
-	      extend_possible = 1;
-              if (start[d2] + count[d2] > fdims[d2])
-                {
-                  xtend_size[d2] = (long long unsigned)(start[d2] + count[d2]);
-                  need_to_extend++;
-                }
-              else
-                xtend_size[d2] = (long long unsigned)fdims[d2];
-
-              if (start[d2] + count[d2] > dim->len)
-                {
-                  dim->len = start[d2] + count[d2];
-                  dim->extended = NC_TRUE;
-                }
+               xtend_size[d2] = (long long unsigned)(start[d2] + count[d2]);
+               need_to_extend++;
             }
-          else
+            else
+               xtend_size[d2] = (long long unsigned)fdims[d2];
+
+            if (start[d2] + count[d2] > dim->len)
             {
-              xtend_size[d2] = (long long unsigned)dim->len;
+               dim->len = start[d2] + count[d2];
+               dim->extended = NC_TRUE;
             }
-        }
+         }
+         else
+         {
+            xtend_size[d2] = (long long unsigned)dim->len;
+         }
+      }
 
 #ifdef USE_PARALLEL4
       /* Check if anyone wants to extend */
       if (extend_possible && h5->parallel && NC_COLLECTIVE == var->parallel_access)
-        {
-          /* Form consensus opinion among all processes about whether to perform
-           * collective I/O
-           */
-          if(MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, &need_to_extend, 1, MPI_INT, MPI_BOR, h5->comm))
+      {
+         /* Form consensus opinion among all processes about whether to perform
+          * collective I/O
+          */
+         if(MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, &need_to_extend, 1, MPI_INT, MPI_BOR, h5->comm))
             BAIL(NC_EMPI);
-        }
+      }
 #endif /* USE_PARALLEL4 */
 
       /* If we need to extend it, we also need a new file_spaceid
          to reflect the new size of the space. */
       if (need_to_extend)
-        {
-          LOG((4, "extending dataset"));
+      {
+         LOG((4, "extending dataset"));
 #ifdef USE_PARALLEL4
-          if (h5->parallel)
-            {
-              if(NC_COLLECTIVE != var->parallel_access)
-                BAIL(NC_ECANTEXTEND);
-
-              /* Reach consensus about dimension sizes to extend to */
-              if(MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, xtend_size, var->ndims, MPI_UNSIGNED_LONG_LONG, MPI_MAX, h5->comm))
-                BAIL(NC_EMPI);
-            }
+         if (h5->parallel)
+         {
+            if(NC_COLLECTIVE != var->parallel_access)
+               BAIL(NC_ECANTEXTEND);
+
+            /* Reach consensus about dimension sizes to extend to */
+            if(MPI_SUCCESS != MPI_Allreduce(MPI_IN_PLACE, xtend_size, var->ndims, MPI_UNSIGNED_LONG_LONG, MPI_MAX, h5->comm))
+               BAIL(NC_EMPI);
+         }
 #endif /* USE_PARALLEL4 */
-          /* Convert xtend_size back to hsize_t for use with H5Dset_extent */
-          for (d2 = 0; d2 < var->ndims; d2++)
+         /* Convert xtend_size back to hsize_t for use with H5Dset_extent */
+         for (d2 = 0; d2 < var->ndims; d2++)
             fdims[d2] = (hsize_t)xtend_size[d2];
 
-          if (H5Dset_extent(var->hdf_datasetid, fdims) < 0)
+         if (H5Dset_extent(var->hdf_datasetid, fdims) < 0)
             BAIL(NC_EHDFERR);
-          if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0)
+         if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0)
             BAIL2(NC_EHDFERR);
-          if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
+         if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
             BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-          if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
-                                  start, NULL, count, NULL) < 0)
+         if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
+                                 start, NULL, count, NULL) < 0)
             BAIL(NC_EHDFERR);
-        }
-    }
+      }
+   }
 
 #ifndef HDF5_CONVERT
-  /* Do we need to convert the data? */
-  if (need_to_convert)
-    {
+   /* Do we need to convert the data? */
+   if (need_to_convert)
+   {
       if ((retval = nc4_convert_type(data, bufr, mem_nc_type, var->type_info->nc_typeid,
                                      len, &range_error, var->fill_value,
                                      (h5->cmode & NC_CLASSIC_MODEL), is_long, 0)))
-        BAIL(retval);
-    }
+         BAIL(retval);
+   }
 #endif
 
-  /* Write the data. At last! */
-  LOG((4, "about to H5Dwrite datasetid 0x%x mem_spaceid 0x%x "
-       "file_spaceid 0x%x", var->hdf_datasetid, mem_spaceid, file_spaceid));
-  if (H5Dwrite(var->hdf_datasetid, var->type_info->hdf_typeid,
-               mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0)
-    BAIL(NC_EHDFERR);
-
-  /* Remember that we have written to this var so that Fill Value
-   * can't be set for it. */
-  if (!var->written_to)
-    var->written_to = NC_TRUE;
-
-  /* For strict netcdf-3 rules, ignore erange errors between UBYTE
-   * and BYTE types. */
-  if ((h5->cmode & NC_CLASSIC_MODEL) &&
-      (var->type_info->nc_typeid == NC_UBYTE || var->type_info->nc_typeid == NC_BYTE) &&
-      (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) &&
-      range_error)
-    range_error = 0;
-
- exit:
+   /* Write the data. At last! */
+   LOG((4, "about to H5Dwrite datasetid 0x%x mem_spaceid 0x%x "
+        "file_spaceid 0x%x", var->hdf_datasetid, mem_spaceid, file_spaceid));
+   if (H5Dwrite(var->hdf_datasetid, var->type_info->hdf_typeid,
+                mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0)
+      BAIL(NC_EHDFERR);
+
+   /* Remember that we have written to this var so that Fill Value
+    * can't be set for it. */
+   if (!var->written_to)
+      var->written_to = NC_TRUE;
+
+   /* For strict netcdf-3 rules, ignore erange errors between UBYTE
+    * and BYTE types. */
+   if ((h5->cmode & NC_CLASSIC_MODEL) &&
+       (var->type_info->nc_typeid == NC_UBYTE || var->type_info->nc_typeid == NC_BYTE) &&
+       (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) &&
+       range_error)
+      range_error = 0;
+
+exit:
 #ifdef HDF5_CONVERT
-  if (mem_typeid > 0 && H5Tclose(mem_typeid) < 0)
-    BAIL2(NC_EHDFERR);
-#endif
-  if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  if (mem_spaceid > 0 && H5Sclose(mem_spaceid) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  if (xfer_plistid && (H5Pclose(xfer_plistid) < 0))
-    BAIL2(NC_EPARINIT);
-#ifdef EXTRA_TESTS
-  num_plists--;
+   if (mem_typeid > 0 && H5Tclose(mem_typeid) < 0)
+      BAIL2(NC_EHDFERR);
 #endif
+   if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (mem_spaceid > 0 && H5Sclose(mem_spaceid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (xfer_plistid && (H5Pclose(xfer_plistid) < 0))
+      BAIL2(NC_EPARINIT);
 #ifndef HDF5_CONVERT
-  if (need_to_convert && bufr) free(bufr);
+   if (need_to_convert && bufr) free(bufr);
 #endif
 
-  /* If there was an error return it, otherwise return any potential
-     range error value. If none, return NC_NOERR as usual.*/
-  if (retval)
-    return retval;
-  if (range_error)
-    return NC_ERANGE;
-  return NC_NOERR;
+   /* If there was an error return it, otherwise return any potential
+      range error value. If none, return NC_NOERR as usual.*/
+   if (retval)
+      return retval;
+   if (range_error)
+      return NC_ERANGE;
+   return NC_NOERR;
 }
 
+/**
+ * @internal Read an array of data from a variable.
+ *
+ * @param nc Pointer to the file NC struct.
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param startp Array of start indicies.
+ * @param countp Array of counts.
+ * @param mem_nc_type The type of the data in memory. (Convert to this
+ * type from file type.)
+ * @param is_long True only if NC_LONG is the memory type.
+ * @param data The data to be written.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Var not found.
+ * @returns ::NC_EHDFERR HDF5 function returned error.
+ * @returns ::NC_EINVALCOORDS Incorrect start.
+ * @returns ::NC_EEDGE Incorrect start/count.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @returns ::NC_EMPI MPI library error (parallel only)
+ * @returns ::NC_ECANTEXTEND Can't extend dimension for write.
+ * @returns ::NC_ERANGE Data conversion error.
+ * @author Ed Hartnett
+ */
 int
 nc4_get_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;
-  NC_HDF5_FILE_INFO_T *h5;
-  NC_VAR_INFO_T *var;
-  NC_DIM_INFO_T *dim;
-  hid_t file_spaceid = 0, mem_spaceid = 0;
-  hid_t xfer_plistid = 0;
-  size_t file_type_size;
-  hsize_t *xtend_size = NULL, count[NC_MAX_VAR_DIMS];
-  hsize_t fdims[NC_MAX_VAR_DIMS], fmaxdims[NC_MAX_VAR_DIMS];
-  hsize_t start[NC_MAX_VAR_DIMS];
-  char *name_to_use;
-  void *fillvalue = NULL;
-  int no_read = 0, provide_fill = 0;
-  int fill_value_size[NC_MAX_VAR_DIMS];
-  int scalar = 0, retval = NC_NOERR, range_error = 0, i, d2;
-  void *bufr = NULL;
+   NC_GRP_INFO_T *grp;
+   NC_HDF5_FILE_INFO_T *h5;
+   NC_VAR_INFO_T *var;
+   NC_DIM_INFO_T *dim;
+   hid_t file_spaceid = 0, mem_spaceid = 0;
+   hid_t xfer_plistid = 0;
+   size_t file_type_size;
+   hsize_t *xtend_size = NULL, count[NC_MAX_VAR_DIMS];
+   hsize_t fdims[NC_MAX_VAR_DIMS], fmaxdims[NC_MAX_VAR_DIMS];
+   hsize_t start[NC_MAX_VAR_DIMS];
+   char *name_to_use;
+   void *fillvalue = NULL;
+   int no_read = 0, provide_fill = 0;
+   int fill_value_size[NC_MAX_VAR_DIMS];
+   int scalar = 0, retval = NC_NOERR, range_error = 0, i, d2;
+   void *bufr = NULL;
 #ifdef HDF5_CONVERT
-  hid_t mem_typeid = 0;
+   hid_t mem_typeid = 0;
 #endif
 #ifndef HDF5_CONVERT
-  int need_to_convert = 0;
-  size_t len = 1;
+   int need_to_convert = 0;
+   size_t len = 1;
 #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);
+   /* 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);
 
-  LOG((3, "%s: var->name %s mem_nc_type %d is_long %d",
-       __func__, var->name, mem_nc_type, is_long));
+   LOG((3, "%s: var->name %s mem_nc_type %d is_long %d",
+        __func__, var->name, mem_nc_type, is_long));
 
-  /* Check some stuff about the type and the file. */
-  if ((retval = check_for_vara(&mem_nc_type, var, h5)))
-    return retval;
+   /* Check some stuff about the type and the file. */
+   if ((retval = check_for_vara(&mem_nc_type, var, h5)))
+      return retval;
 
-  /* Convert from size_t and ptrdiff_t to hssize_t, and hsize_t. */
-  for (i = 0; i < var->ndims; i++)
-    {
+   /* Convert from size_t and ptrdiff_t to hssize_t, and hsize_t. */
+   for (i = 0; i < var->ndims; i++)
+   {
       start[i] = startp[i];
       count[i] = countp[i];
-    }
-
-  /* Open this dataset if necessary, also checking for a weird case:
-   * a non-coordinate (and non-scalar) variable that has the same
-   * name as a dimension. */
-  if (var->hdf5_name && strlen(var->hdf5_name) >= strlen(NON_COORD_PREPEND) &&
-      strncmp(var->hdf5_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)) == 0 &&
-      var->ndims)
-    name_to_use = var->hdf5_name;
-  else
-    name_to_use = var->name;
-  if (!var->hdf_datasetid)
-    if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, name_to_use, H5P_DEFAULT)) < 0)
-      return NC_ENOTVAR;
-
-  /* Get file space of data. */
-  if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
-    BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_spaces++;
-#endif
+   }
+
+   /* Open this dataset if necessary, also checking for a weird case:
+    * a non-coordinate (and non-scalar) variable that has the same
+    * name as a dimension. */
+   if (var->hdf5_name && strlen(var->hdf5_name) >= strlen(NON_COORD_PREPEND) &&
+       strncmp(var->hdf5_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)) == 0 &&
+       var->ndims)
+      name_to_use = var->hdf5_name;
+   else
+      name_to_use = var->name;
+   if (!var->hdf_datasetid)
+      if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, name_to_use, H5P_DEFAULT)) < 0)
+         return NC_ENOTVAR;
+
+   /* Get file space of data. */
+   if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
+      BAIL(NC_EHDFERR);
 
-  /* Check to ensure the user selection is
-   * valid. H5Sget_simple_extent_dims gets the sizes of all the dims
-   * and put them in fdims. */
-  if (H5Sget_simple_extent_dims(file_spaceid, fdims, fmaxdims) < 0)
-    BAIL(NC_EHDFERR);
+   /* Check to ensure the user selection is
+    * valid. H5Sget_simple_extent_dims gets the sizes of all the dims
+    * and put them in fdims. */
+   if (H5Sget_simple_extent_dims(file_spaceid, fdims, fmaxdims) < 0)
+      BAIL(NC_EHDFERR);
 
 #ifdef LOGGING
-  log_dim_info(var, fdims, fmaxdims, start, count);
+   log_dim_info(var, fdims, fmaxdims, start, count);
 #endif
 
-  /* Check dimension bounds. Remember that unlimited dimensions can
-   * put data beyond their current length. */
-  for (d2 = 0; d2 < var->ndims; d2++) {
-    dim = var->dim[d2];
-    assert(dim && dim->dimid == var->dimids[d2]);
-    if (dim->unlimited)
+   /* Check dimension bounds. Remember that unlimited dimensions can
+    * put data beyond their current length. */
+   for (d2 = 0; d2 < var->ndims; d2++) {
+      dim = var->dim[d2];
+      assert(dim && dim->dimid == var->dimids[d2]);
+      if (dim->unlimited)
       {
-        size_t ulen;
+         size_t ulen;
 
-        /* We can't go beyond the largest current extent of
-           the unlimited dim. */
-	if ((retval = NC4_inq_dim(ncid, dim->dimid, NULL, &ulen)))
-	  BAIL(retval);
+         /* We can't go beyond the largest current extent of
+            the unlimited dim. */
+         if ((retval = NC4_inq_dim(ncid, dim->dimid, NULL, &ulen)))
+            BAIL(retval);
 
-        /* Check for out of bound requests. */
+         /* Check for out of bound requests. */
 #ifdef RELAX_COORD_BOUND
-        if (start[d2] > (hssize_t)ulen ||
-            (start[d2] == (hssize_t)ulen && count[d2] > 0))
+         if (start[d2] > (hssize_t)ulen ||
+             (start[d2] == (hssize_t)ulen && count[d2] > 0))
 #else
-        if (start[d2] >= (hssize_t)ulen && ulen > 0)
+            if (start[d2] >= (hssize_t)ulen && ulen > 0)
 #endif
-          BAIL_QUIET(NC_EINVALCOORDS);
-        if (start[d2] + count[d2] > ulen)
-          BAIL_QUIET(NC_EEDGE);
-
-        /* Things get a little tricky here. If we're getting
-           a GET request beyond the end of this var's
-           current length in an unlimited dimension, we'll
-           later need to return the fill value for the
-           variable. */
-        if (start[d2] >= (hssize_t)fdims[d2])
-          fill_value_size[d2] = count[d2];
-        else if (start[d2] + count[d2] > fdims[d2])
-          fill_value_size[d2] = count[d2] - (fdims[d2] - start[d2]);
-        else
-          fill_value_size[d2] = 0;
-        count[d2] -= fill_value_size[d2];
-        if (fill_value_size[d2])
-          provide_fill++;
+               BAIL_QUIET(NC_EINVALCOORDS);
+         if (start[d2] + count[d2] > ulen)
+            BAIL_QUIET(NC_EEDGE);
+
+         /* Things get a little tricky here. If we're getting
+            a GET request beyond the end of this var's
+            current length in an unlimited dimension, we'll
+            later need to return the fill value for the
+            variable. */
+         if (start[d2] >= (hssize_t)fdims[d2])
+            fill_value_size[d2] = count[d2];
+         else if (start[d2] + count[d2] > fdims[d2])
+            fill_value_size[d2] = count[d2] - (fdims[d2] - start[d2]);
+         else
+            fill_value_size[d2] = 0;
+         count[d2] -= fill_value_size[d2];
+         if (fill_value_size[d2])
+            provide_fill++;
       }
-    else
+      else
       {
-        /* Check for out of bound requests. */
+         /* Check for out of bound requests. */
 #ifdef RELAX_COORD_BOUND
-        if (start[d2] > (hssize_t)fdims[d2] ||
-            (start[d2] == (hssize_t)fdims[d2] && count[d2] > 0))
+         if (start[d2] > (hssize_t)fdims[d2] ||
+             (start[d2] == (hssize_t)fdims[d2] && count[d2] > 0))
 #else
-        if (start[d2] >= (hssize_t)fdims[d2])
+            if (start[d2] >= (hssize_t)fdims[d2])
 #endif
-          BAIL_QUIET(NC_EINVALCOORDS);
-        if (start[d2] + count[d2] > fdims[d2])
-          BAIL_QUIET(NC_EEDGE);
+               BAIL_QUIET(NC_EINVALCOORDS);
+         if (start[d2] + count[d2] > fdims[d2])
+            BAIL_QUIET(NC_EEDGE);
 
-        /* Set the fill value boundary */
-        fill_value_size[d2] = count[d2];
+         /* Set the fill value boundary */
+         fill_value_size[d2] = count[d2];
       }
-  }
+   }
 
-  /* A little quirk: if any of the count values are zero, don't
-   * read. */
-  for (d2 = 0; d2 < var->ndims; d2++)
-    if (count[d2] == 0)
-      no_read++;
+   /* A little quirk: if any of the count values are zero, don't
+    * read. */
+   for (d2 = 0; d2 < var->ndims; d2++)
+      if (count[d2] == 0)
+         no_read++;
 
-  /* Later on, we will need to know the size of this type in the
-   * file. */
-  assert(var->type_info->size);
-  file_type_size = var->type_info->size;
+   /* Later on, we will need to know the size of this type in the
+    * file. */
+   assert(var->type_info->size);
+   file_type_size = var->type_info->size;
 
-  if (!no_read)
-    {
+   if (!no_read)
+   {
       /* Now you would think that no one would be crazy enough to write
          a scalar dataspace with one of the array function calls, but you
          would be wrong. So let's check to see if the dataset is
          scalar. If it is, we won't try to set up a hyperslab. */
       if (H5Sget_simple_extent_type(file_spaceid) == H5S_SCALAR)
-        {
-          if ((mem_spaceid = H5Screate(H5S_SCALAR)) < 0)
+      {
+         if ((mem_spaceid = H5Screate(H5S_SCALAR)) < 0)
             BAIL(NC_EHDFERR);
-          scalar++;
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-        }
+         scalar++;
+      }
       else
-        {
-          if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
-                                  start, NULL, count, NULL) < 0)
+      {
+         if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
+                                 start, NULL, count, NULL) < 0)
             BAIL(NC_EHDFERR);
-          /* Create a space for the memory, just big enough to hold the slab
-             we want. */
-          if ((mem_spaceid = H5Screate_simple(var->ndims, count, NULL)) < 0)
+         /* Create a space for the memory, just big enough to hold the slab
+            we want. */
+         if ((mem_spaceid = H5Screate_simple(var->ndims, count, NULL)) < 0)
             BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-        }
+      }
 
       /* Fix bug when reading HDF5 files with variable of type
        * fixed-length string.  We need to make it look like a
@@ -1061,13 +1164,13 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp,
       if(var->type_info->nc_type_class == NC_STRING &&
          H5Tget_size(var->type_info->hdf_typeid) > 1 &&
          !H5Tis_variable_str(var->type_info->hdf_typeid)) {
-        hsize_t fstring_len;
+         hsize_t fstring_len;
 
-        if ((fstring_len = H5Tget_size(var->type_info->hdf_typeid)) == 0)
-	      BAIL(NC_EHDFERR);
-        if (!(*(char **)data = malloc(1 + fstring_len)))
-          BAIL(NC_ENOMEM);
-        bufr = *(char **)data;
+         if ((fstring_len = H5Tget_size(var->type_info->hdf_typeid)) == 0)
+            BAIL(NC_EHDFERR);
+         if (!(*(char **)data = malloc(1 + fstring_len)))
+            BAIL(NC_ENOMEM);
+         bufr = *(char **)data;
       }
 
 #ifndef HDF5_CONVERT
@@ -1075,60 +1178,57 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp,
        * opaque types.) */
       if ((mem_nc_type != var->type_info->nc_typeid || (var->type_info->nc_typeid == NC_INT && is_long)) &&
           mem_nc_type != NC_COMPOUND && mem_nc_type != NC_OPAQUE)
-        {
-          /* We must convert - allocate a buffer. */
-          need_to_convert++;
-          if (var->ndims)
+      {
+         /* We must convert - allocate a buffer. */
+         need_to_convert++;
+         if (var->ndims)
             for (d2 = 0; d2 < var->ndims; d2++)
-              len *= countp[d2];
-          LOG((4, "converting data for var %s type=%d len=%d", var->name,
-               var->type_info->nc_typeid, len));
-
-          /* If we're reading, we need bufr to have enough memory to store
-           * the data in the file. If we're writing, we need bufr to be
-           * big enough to hold all the data in the file's type. */
-          if(len > 0)
+               len *= countp[d2];
+         LOG((4, "converting data for var %s type=%d len=%d", var->name,
+              var->type_info->nc_typeid, len));
+
+         /* If we're reading, we need bufr to have enough memory to store
+          * the data in the file. If we're writing, we need bufr to be
+          * big enough to hold all the data in the file's type. */
+         if(len > 0)
             if (!(bufr = malloc(len * file_type_size)))
-              BAIL(NC_ENOMEM);
-        }
+               BAIL(NC_ENOMEM);
+      }
       else
 #endif /* ifndef HDF5_CONVERT */
-        if(!bufr)
-	      bufr = data;
+         if(!bufr)
+            bufr = data;
 
       /* Get the HDF type of the data in memory. */
 #ifdef HDF5_CONVERT
       if ((retval = nc4_get_hdf_typeid(h5, mem_nc_type, &mem_typeid,
                                        var->type_info->endianness)))
-        BAIL(retval);
+         BAIL(retval);
 #endif
 
       /* Create the data transfer property list. */
       if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_plists++;
-#endif
+         BAIL(NC_EHDFERR);
 
 #ifdef HDF5_CONVERT
       /* Apply the callback function which will detect range
        * errors. Which one to call depends on the length of the
        * destination buffer type. */
       if (H5Pset_type_conv_cb(xfer_plistid, except_func, &range_error) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 #endif
 
 #ifdef USE_PARALLEL4
       /* Set up parallel I/O, if needed. */
       if ((retval = set_par_access(h5, var, xfer_plistid)))
-        BAIL(retval);
+         BAIL(retval);
 #endif
 
       /* Read this hyperslab into memory. */
       LOG((5, "About to H5Dread some data..."));
       if (H5Dread(var->hdf_datasetid, var->type_info->native_hdf_typeid,
                   mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
 #ifndef HDF5_CONVERT
       /* Eventually the block below will go away. Right now it's
@@ -1137,20 +1237,20 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp,
          being added to HDF5 at the HDF5 World Hall of Coding right
          now, by a staff of thousands of programming gnomes. */
       if (need_to_convert)
-        {
-          if ((retval = nc4_convert_type(bufr, data, var->type_info->nc_typeid, mem_nc_type,
-                                         len, &range_error, var->fill_value,
-                                         (h5->cmode & NC_CLASSIC_MODEL), 0, is_long)))
+      {
+         if ((retval = nc4_convert_type(bufr, data, var->type_info->nc_typeid, mem_nc_type,
+                                        len, &range_error, var->fill_value,
+                                        (h5->cmode & NC_CLASSIC_MODEL), 0, is_long)))
             BAIL(retval);
 
-          /* For strict netcdf-3 rules, ignore erange errors between UBYTE
-           * and BYTE types. */
-          if ((h5->cmode & NC_CLASSIC_MODEL) &&
-              (var->type_info->nc_typeid == NC_UBYTE || var->type_info->nc_typeid == NC_BYTE) &&
-              (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) &&
-              range_error)
+         /* For strict netcdf-3 rules, ignore erange errors between UBYTE
+          * and BYTE types. */
+         if ((h5->cmode & NC_CLASSIC_MODEL) &&
+             (var->type_info->nc_typeid == NC_UBYTE || var->type_info->nc_typeid == NC_BYTE) &&
+             (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) &&
+             range_error)
             range_error = 0;
-        }
+      }
 #endif
 
       /* For strict netcdf-3 rules, ignore erange errors between UBYTE
@@ -1159,1019 +1259,1062 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp,
           (var->type_info->nc_typeid == NC_UBYTE || var->type_info->nc_typeid == NC_BYTE) &&
           (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) &&
           range_error)
-        range_error = 0;
+         range_error = 0;
 
-    } /* endif ! no_read */
+   } /* endif ! no_read */
 
-    else {
+   else {
 #ifdef USE_PARALLEL4 /* Start block contributed by HDF group. */
-        /* For collective IO read, some processes may not have any element for reading.
-           Collective requires all processes to participate, so we use H5Sselect_none
-           for these processes. */
-        if(var->parallel_access == NC_COLLECTIVE) {
-
-           /* Create the data transfer property list. */
-           if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0)
-                BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-           num_plists++;
-#endif
+      /* For collective IO read, some processes may not have any element for reading.
+         Collective requires all processes to participate, so we use H5Sselect_none
+         for these processes. */
+      if(var->parallel_access == NC_COLLECTIVE) {
 
-           if ((retval = set_par_access(h5, var, xfer_plistid)))
-                BAIL(retval);
+         /* Create the data transfer property list. */
+         if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0)
+            BAIL(NC_EHDFERR);
 
-           if (H5Sselect_none(file_spaceid)<0)
-              BAIL(NC_EHDFERR);
+         if ((retval = set_par_access(h5, var, xfer_plistid)))
+            BAIL(retval);
 
-           /* Since no element will be selected, we just get the memory space the same as the file space.
-           */
-           if((mem_spaceid = H5Dget_space(var->hdf_datasetid))<0)
-             BAIL(NC_EHDFERR);
-           if (H5Sselect_none(mem_spaceid)<0)
-              BAIL(NC_EHDFERR);
+         if (H5Sselect_none(file_spaceid)<0)
+            BAIL(NC_EHDFERR);
 
-#ifdef EXTRA_TESTS
-             num_spaces++;
-#endif
-            /* Read this hyperslab into memory. */
-            LOG((5, "About to H5Dread some data..."));
-            if (H5Dread(var->hdf_datasetid, var->type_info->native_hdf_typeid,
-                  mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0)
-                BAIL(NC_EHDFERR);
-        }
+         /* Since no element will be selected, we just get the memory space the same as the file space.
+          */
+         if((mem_spaceid = H5Dget_space(var->hdf_datasetid))<0)
+            BAIL(NC_EHDFERR);
+         if (H5Sselect_none(mem_spaceid)<0)
+            BAIL(NC_EHDFERR);
+
+         /* Read this hyperslab into memory. */
+         LOG((5, "About to H5Dread some data..."));
+         if (H5Dread(var->hdf_datasetid, var->type_info->native_hdf_typeid,
+                     mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0)
+            BAIL(NC_EHDFERR);
+      }
 #endif /* End ifdef USE_PARALLEL4 */
-    }
-  /* Now we need to fake up any further data that was asked for,
-     using the fill values instead. First skip past the data we
-     just read, if any. */
-  if (!scalar && provide_fill)
-    {
+   }
+   /* Now we need to fake up any further data that was asked for,
+      using the fill values instead. First skip past the data we
+      just read, if any. */
+   if (!scalar && provide_fill)
+   {
       void *filldata;
       size_t real_data_size = 0;
       size_t fill_len;
 
       /* Skip past the real data we've already read. */
       if (!no_read)
-        for (real_data_size = file_type_size, d2 = 0; d2 < var->ndims; d2++)
-          real_data_size *= (count[d2] - start[d2]);
+         for (real_data_size = file_type_size, d2 = 0; d2 < var->ndims; d2++)
+            real_data_size *= (count[d2] - start[d2]);
 
       /* Get the fill value from the HDF5 variable. Memory will be
        * allocated. */
       if (get_fill_value(h5, var, &fillvalue) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       /* How many fill values do we need? */
       for (fill_len = 1, d2 = 0; d2 < var->ndims; d2++)
-        fill_len *= (fill_value_size[d2] ? fill_value_size[d2] : 1);
+         fill_len *= (fill_value_size[d2] ? fill_value_size[d2] : 1);
 
       /* Copy the fill value into the rest of the data buffer. */
       filldata = (char *)data + real_data_size;
       for (i = 0; i < fill_len; i++)
-        {
+      {
 
-          if (var->type_info->nc_type_class == NC_STRING)
+         if (var->type_info->nc_type_class == NC_STRING)
+         {
+            if (*(char **)fillvalue)
             {
-              if (*(char **)fillvalue)
-                {
-                  if (!(*(char **)filldata = strdup(*(char **)fillvalue)))
-                    BAIL(NC_ENOMEM);
-                }
-              else
-                *(char **)filldata = NULL;
+               if (!(*(char **)filldata = strdup(*(char **)fillvalue)))
+                  BAIL(NC_ENOMEM);
             }
-          else if(var->type_info->nc_type_class == NC_VLEN) {
+            else
+               *(char **)filldata = NULL;
+         }
+         else if(var->type_info->nc_type_class == NC_VLEN) {
             if(fillvalue) {
-              memcpy(filldata,fillvalue,file_type_size);
+               memcpy(filldata,fillvalue,file_type_size);
             } else {
-              *(char **)filldata = NULL;
+               *(char **)filldata = NULL;
             }
-          } else
+         } else
             memcpy(filldata, fillvalue, file_type_size);
-          filldata = (char *)filldata + file_type_size;
-        }
-    }
+         filldata = (char *)filldata + file_type_size;
+      }
+   }
 
- exit:
+exit:
 #ifdef HDF5_CONVERT
-  if (mem_typeid > 0 && H5Tclose(mem_typeid) < 0)
-    BAIL2(NC_EHDFERR);
+   if (mem_typeid > 0 && H5Tclose(mem_typeid) < 0)
+      BAIL2(NC_EHDFERR);
 #endif
-  if (file_spaceid > 0)
-    {
+   if (file_spaceid > 0)
+   {
       if (H5Sclose(file_spaceid) < 0)
-        BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces--;
-#endif
-    }
-  if (mem_spaceid > 0)
-    {
+         BAIL2(NC_EHDFERR);
+   }
+   if (mem_spaceid > 0)
+   {
       if (H5Sclose(mem_spaceid) < 0)
-        BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces--;
-#endif
-    }
-  if (xfer_plistid > 0)
-    {
+         BAIL2(NC_EHDFERR);
+   }
+   if (xfer_plistid > 0)
+   {
       if (H5Pclose(xfer_plistid) < 0)
-        BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_plists--;
-#endif
-    }
+         BAIL2(NC_EHDFERR);
+   }
 #ifndef HDF5_CONVERT
-  if (need_to_convert && bufr != NULL)
-    free(bufr);
+   if (need_to_convert && bufr != NULL)
+      free(bufr);
 #endif
-  if (xtend_size)
-    free(xtend_size);
-  if (fillvalue)
-    {
+   if (xtend_size)
+      free(xtend_size);
+   if (fillvalue)
+   {
       if (var->type_info->nc_type_class == NC_VLEN)
-        nc_free_vlen((nc_vlen_t *)fillvalue);
+         nc_free_vlen((nc_vlen_t *)fillvalue);
       else if (var->type_info->nc_type_class == NC_STRING && *(char **)fillvalue)
-        free(*(char **)fillvalue);
+         free(*(char **)fillvalue);
       free(fillvalue);
-    }
-
-  /* If there was an error return it, otherwise return any potential
-     range error value. If none, return NC_NOERR as usual.*/
-  if (retval)
-    return retval;
-  if (range_error)
-    return NC_ERANGE;
-  return NC_NOERR;
+   }
+
+   /* If there was an error return it, otherwise return any potential
+      range error value. If none, return NC_NOERR as usual.*/
+   if (retval)
+      return retval;
+   if (range_error)
+      return NC_ERANGE;
+   return NC_NOERR;
 }
 
-/* Read or write an attribute. */
+/**
+ * @internal Write an attribute. 
+ *
+ * @param grp Pointer to group info struct.
+ * @param varid Variable ID or NC_GLOBAL.
+ * @param att Pointer to attribute info struct.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_ENOTVAR Variable not found.
+ * @returns ::NC_EPERM Read-only file.
+ * @returns ::NC_EHDFERR HDF5 returned error.
+ * @returns ::NC_EATTMETA HDF5 returned error with attribute calls.
+ * @author Ed Hartnett
+ */
 static int
 put_att_grpa(NC_GRP_INFO_T *grp, int varid, NC_ATT_INFO_T *att)
 {
-  hid_t datasetid = 0, locid;
-  hid_t attid = 0, spaceid = 0, file_typeid = 0;
-  hsize_t dims[1]; /* netcdf attributes always 1-D. */
-  htri_t attr_exists;
-  int retval = NC_NOERR;
-  void *data;
-  int phoney_data = 99;
-
-  assert(att->name);
-  LOG((3, "%s: varid %d att->attnum %d att->name %s att->nc_typeid %d att->len %d",
-       __func__, varid, att->attnum, att->name,
-       att->nc_typeid, att->len));
-
-  /* If the file is read-only, return an error. */
-  if (grp->nc4_info->no_write)
-    BAIL(NC_EPERM);
-
-  /* Get the hid to attach the attribute to, or read it from. */
-  if (varid == NC_GLOBAL)
-    locid = grp->hdf_grpid;
-  else
-    {
+   hid_t datasetid = 0, locid;
+   hid_t attid = 0, spaceid = 0, file_typeid = 0;
+   hsize_t dims[1]; /* netcdf attributes always 1-D. */
+   htri_t attr_exists;
+   int retval = NC_NOERR;
+   void *data;
+   int phoney_data = 99;
+
+   assert(att->name);
+   LOG((3, "%s: varid %d att->attnum %d att->name %s att->nc_typeid %d att->len %d",
+        __func__, varid, att->attnum, att->name,
+        att->nc_typeid, att->len));
+
+   /* If the file is read-only, return an error. */
+   if (grp->nc4_info->no_write)
+      BAIL(NC_EPERM);
+
+   /* Get the hid to attach the attribute to, or read it from. */
+   if (varid == NC_GLOBAL)
+      locid = grp->hdf_grpid;
+   else
+   {
       if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
-        BAIL(retval);
+         BAIL(retval);
       locid = datasetid;
-    }
+   }
 
-  /* Delete the att if it exists already. */
-  if ((attr_exists = H5Aexists(locid, att->name)) < 0)
-    BAIL(NC_EHDFERR);
-  if (attr_exists)
-    {
+   /* Delete the att if it exists already. */
+   if ((attr_exists = H5Aexists(locid, att->name)) < 0)
+      BAIL(NC_EHDFERR);
+   if (attr_exists)
+   {
       if (H5Adelete(locid, att->name) < 0)
-        BAIL(NC_EHDFERR);
-    }
-
-  /* Get the length ready, and find the HDF type we'll be
-   * writing. */
-  dims[0] = att->len;
-  if ((retval = nc4_get_hdf_typeid(grp->nc4_info, att->nc_typeid,
-                                   &file_typeid, 0)))
-    BAIL(retval);
-
-  /* Even if the length is zero, HDF5 won't let me write with a
-   * NULL pointer. So if the length of the att is zero, point to
-   * some phoney data (which won't be written anyway.)*/
-  if (!dims[0])
-    data = &phoney_data;
-  else if (att->data)
-    data = att->data;
-  else if (att->stdata)
-    data = att->stdata;
-  else
-    data = att->vldata;
-
-  /* NC_CHAR types require some extra work. The space ID is set to
-   * scalar, and the type is told how long the string is. If it's
-   * really zero length, set the size to 1. (The fact that it's
-   * really zero will be marked by the NULL dataspace, but HDF5
-   * doesn't allow me to set the size of the type to zero.)*/
-  if (att->nc_typeid == NC_CHAR)
-    {
+         BAIL(NC_EHDFERR);
+   }
+
+   /* Get the length ready, and find the HDF type we'll be
+    * writing. */
+   dims[0] = att->len;
+   if ((retval = nc4_get_hdf_typeid(grp->nc4_info, att->nc_typeid,
+                                    &file_typeid, 0)))
+      BAIL(retval);
+
+   /* Even if the length is zero, HDF5 won't let me write with a
+    * NULL pointer. So if the length of the att is zero, point to
+    * some phoney data (which won't be written anyway.)*/
+   if (!dims[0])
+      data = &phoney_data;
+   else if (att->data)
+      data = att->data;
+   else if (att->stdata)
+      data = att->stdata;
+   else
+      data = att->vldata;
+
+   /* NC_CHAR types require some extra work. The space ID is set to
+    * scalar, and the type is told how long the string is. If it's
+    * really zero length, set the size to 1. (The fact that it's
+    * really zero will be marked by the NULL dataspace, but HDF5
+    * doesn't allow me to set the size of the type to zero.)*/
+   if (att->nc_typeid == NC_CHAR)
+   {
       size_t string_size = dims[0];
       if (!string_size)
-        {
-          string_size = 1;
-          if ((spaceid = H5Screate(H5S_NULL)) < 0)
+      {
+         string_size = 1;
+         if ((spaceid = H5Screate(H5S_NULL)) < 0)
             BAIL(NC_EATTMETA);
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-        }
+      }
       else
-        {
-          if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
+      {
+         if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
             BAIL(NC_EATTMETA);
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-        }
+      }
       if (H5Tset_size(file_typeid, string_size) < 0)
-        BAIL(NC_EATTMETA);
+         BAIL(NC_EATTMETA);
       if (H5Tset_strpad(file_typeid, H5T_STR_NULLTERM) < 0)
-        BAIL(NC_EATTMETA);
-    }
-  else
-    {
+         BAIL(NC_EATTMETA);
+   }
+   else
+   {
       if (!att->len)
-        {
-          if ((spaceid = H5Screate(H5S_NULL)) < 0)
+      {
+         if ((spaceid = H5Screate(H5S_NULL)) < 0)
             BAIL(NC_EATTMETA);
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-        }
+      }
       else
-        {
-          if ((spaceid = H5Screate_simple(1, dims, NULL)) < 0)
+      {
+         if ((spaceid = H5Screate_simple(1, dims, NULL)) < 0)
             BAIL(NC_EATTMETA);
-#ifdef EXTRA_TESTS
-          num_spaces++;
-#endif
-        }
-    }
-  if ((attid = H5Acreate(locid, att->name, file_typeid, spaceid,
-                         H5P_DEFAULT)) < 0)
-    BAIL(NC_EATTMETA);
-
-  /* Write the values, (even if length is zero). */
-  if (H5Awrite(attid, file_typeid, data) < 0)
-    BAIL(NC_EATTMETA);
-
- exit:
-  if (file_typeid && H5Tclose(file_typeid))
-    BAIL2(NC_EHDFERR);
-  if (attid > 0 && H5Aclose(attid) < 0)
-    BAIL2(NC_EHDFERR);
-  if (spaceid > 0 && H5Sclose(spaceid) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  return retval;
+      }
+   }
+   if ((attid = H5Acreate(locid, att->name, file_typeid, spaceid,
+                          H5P_DEFAULT)) < 0)
+      BAIL(NC_EATTMETA);
+
+   /* Write the values, (even if length is zero). */
+   if (H5Awrite(attid, file_typeid, data) < 0)
+      BAIL(NC_EATTMETA);
+
+exit:
+   if (file_typeid && H5Tclose(file_typeid))
+      BAIL2(NC_EHDFERR);
+   if (attid > 0 && H5Aclose(attid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (spaceid > 0 && H5Sclose(spaceid) < 0)
+      BAIL2(NC_EHDFERR);
+   return retval;
 }
 
-/* Write all the dirty atts in an attlist. */
+/**
+ * @internal Write all the dirty atts in an attlist. 
+ *
+ * @param attlist Pointer to the list if attributes.
+ * @param varid Variable ID.
+ * @param grp Pointer to group info struct.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 static int
 write_attlist(NC_ATT_INFO_T *attlist, int varid, NC_GRP_INFO_T *grp)
 {
-  NC_ATT_INFO_T *att;
-  int retval;
+   NC_ATT_INFO_T *att;
+   int retval;
 
-  for (att = attlist; att; att = att->l.next)
-    {
+   for (att = attlist; att; att = att->l.next)
+   {
       if (att->dirty)
-        {
-          LOG((4, "%s: writing att %s to varid %d", __func__, att->name, varid));
-          if ((retval = put_att_grpa(grp, varid, att)))
+      {
+         LOG((4, "%s: writing att %s to varid %d", __func__, att->name, varid));
+         if ((retval = put_att_grpa(grp, varid, att)))
             return retval;
-          att->dirty = NC_FALSE;
-          att->created = NC_TRUE;
-        }
-    }
-  return NC_NOERR;
+         att->dirty = NC_FALSE;
+         att->created = NC_TRUE;
+      }
+   }
+   return NC_NOERR;
 }
 
 
-/* This function is a bit of a hack. Turns out that HDF5 dimension
- * scales cannot themselves have scales attached. This leaves
- * multidimensional coordinate variables hosed. So this function
- * writes a special attribute for such a variable, which has the ids
- * of all the dimensions for that coordinate variable. This sucks,
- * really. But that's the way the cookie crumbles. Better luck next
- * time. This function also contains a new way of dealing with HDF5
- * error handling, abandoning the BAIL macros for a more organic and
- * natural approach, made with whole grains, and locally-grown
- * vegetables. */
+/**
+ * @internal This function is a bit of a hack. Turns out that HDF5
+ * dimension scales cannot themselves have scales attached. This
+ * leaves multidimensional coordinate variables hosed. So this
+ * function writes a special attribute for such a variable, which has
+ * the ids of all the dimensions for that coordinate variable. This
+ * sucks, really. But that's the way the cookie crumbles. Better luck
+ * next time. This function also contains a new way of dealing with
+ * HDF5 error handling, abandoning the BAIL macros for a more organic
+ * and natural approach, made with whole grains, and locally-grown
+ * vegetables. 
+ *
+ * @param var Pointer to var info struct.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+ */
 static int
 write_coord_dimids(NC_VAR_INFO_T *var)
 {
-  hsize_t coords_len[1];
-  hid_t c_spaceid = -1, c_attid = -1;
-  int ret = 0;
-
-  /* Write our attribute. */
-  coords_len[0] = var->ndims;
-  if ((c_spaceid = H5Screate_simple(1, coords_len, coords_len)) < 0) ret++;
-#ifdef EXTRA_TESTS
-  num_spaces++;
-#endif
-  if (!ret && (c_attid = H5Acreate(var->hdf_datasetid, COORDINATES, H5T_NATIVE_INT,
-                                   c_spaceid, H5P_DEFAULT)) < 0) ret++;
-  if (!ret && H5Awrite(c_attid, H5T_NATIVE_INT, var->dimids) < 0) ret++;
-
-  /* Close up shop. */
-  if (c_spaceid > 0 && H5Sclose(c_spaceid) < 0) ret++;
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  if (c_attid > 0 && H5Aclose(c_attid) < 0) ret++;
-  return ret ? NC_EHDFERR : 0;
+   hsize_t coords_len[1];
+   hid_t c_spaceid = -1, c_attid = -1;
+   int ret = 0;
+
+   /* Write our attribute. */
+   coords_len[0] = var->ndims;
+   if ((c_spaceid = H5Screate_simple(1, coords_len, coords_len)) < 0) ret++;
+   if (!ret && (c_attid = H5Acreate(var->hdf_datasetid, COORDINATES, H5T_NATIVE_INT,
+                                    c_spaceid, H5P_DEFAULT)) < 0) ret++;
+   if (!ret && H5Awrite(c_attid, H5T_NATIVE_INT, var->dimids) < 0) ret++;
+
+   /* Close up shop. */
+   if (c_spaceid > 0 && H5Sclose(c_spaceid) < 0) ret++;
+   if (c_attid > 0 && H5Aclose(c_attid) < 0) ret++;
+   return ret ? NC_EHDFERR : 0;
 }
 
-/* Write a special attribute for the netCDF-4 dimension ID. */
+/**
+ * @internal Write a special attribute for the netCDF-4 dimension ID. 
+ *
+ * @param datasetid HDF5 datasset ID.
+ * @param dimid NetCDF dimension ID.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 static int
 write_netcdf4_dimid(hid_t datasetid, int dimid)
 {
-  hid_t dimid_spaceid, dimid_attid;
-  htri_t attr_exists;
-
-  /* Create the space. */
-  if ((dimid_spaceid = H5Screate(H5S_SCALAR)) < 0)
-    return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-  num_spaces++;
-#endif
-
-  /* Does the attribute already exist? If so, don't try to create it. */
-  if ((attr_exists = H5Aexists(datasetid, NC_DIMID_ATT_NAME)) < 0)
-    return NC_EHDFERR;
-  if (attr_exists)
-    dimid_attid = H5Aopen_by_name(datasetid, ".", NC_DIMID_ATT_NAME,
-                                  H5P_DEFAULT, H5P_DEFAULT);
-  else
-    /* Create the attribute if needed. */
-    dimid_attid = H5Acreate(datasetid, NC_DIMID_ATT_NAME,
-                            H5T_NATIVE_INT, dimid_spaceid, H5P_DEFAULT);
-  if (dimid_attid  < 0)
-    return NC_EHDFERR;
-
-
-  /* Write it. */
-  LOG((4, "%s: writing secret dimid %d", __func__, dimid));
-  if (H5Awrite(dimid_attid, H5T_NATIVE_INT, &dimid) < 0)
-    return NC_EHDFERR;
-
-  /* Close stuff*/
-  if (H5Sclose(dimid_spaceid) < 0)
-    return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  if (H5Aclose(dimid_attid) < 0)
-    return NC_EHDFERR;
-
-  return NC_NOERR;
+   hid_t dimid_spaceid, dimid_attid;
+   htri_t attr_exists;
+
+   /* Create the space. */
+   if ((dimid_spaceid = H5Screate(H5S_SCALAR)) < 0)
+      return NC_EHDFERR;
+
+   /* Does the attribute already exist? If so, don't try to create it. */
+   if ((attr_exists = H5Aexists(datasetid, NC_DIMID_ATT_NAME)) < 0)
+      return NC_EHDFERR;
+   if (attr_exists)
+      dimid_attid = H5Aopen_by_name(datasetid, ".", NC_DIMID_ATT_NAME,
+                                    H5P_DEFAULT, H5P_DEFAULT);
+   else
+      /* Create the attribute if needed. */
+      dimid_attid = H5Acreate(datasetid, NC_DIMID_ATT_NAME,
+                              H5T_NATIVE_INT, dimid_spaceid, H5P_DEFAULT);
+   if (dimid_attid  < 0)
+      return NC_EHDFERR;
+
+
+   /* Write it. */
+   LOG((4, "%s: writing secret dimid %d", __func__, dimid));
+   if (H5Awrite(dimid_attid, H5T_NATIVE_INT, &dimid) < 0)
+      return NC_EHDFERR;
+
+   /* Close stuff*/
+   if (H5Sclose(dimid_spaceid) < 0)
+      return NC_EHDFERR;
+   if (H5Aclose(dimid_attid) < 0)
+      return NC_EHDFERR;
+
+   return NC_NOERR;
 }
 
-/* This function creates the HDF5 dataset for a variable. */
+/**
+ * @internal This function creates the HDF5 dataset for a variable. 
+ *
+ * @param grp Pointer to group info struct.
+ * @param var Pointer to variable info struct.
+ * @param write_dimid True to write dimid.
+ *
+ * @return ::NC_NOERR
+ * @author Ed Hartnett
+*/
 static int
 var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, nc_bool_t write_dimid)
 {
-  hid_t plistid = 0, access_plistid = 0, typeid = 0, spaceid = 0;
-  hsize_t chunksize[H5S_MAX_RANK], dimsize[H5S_MAX_RANK], maxdimsize[H5S_MAX_RANK];
-  int d;
-  void *fillp = NULL;
-  NC_DIM_INFO_T *dim = NULL;
-  char *name_to_use;
-  int retval = NC_NOERR;
-
-  LOG((3, "%s:: name %s", __func__, var->name));
-
-  /* Scalar or not, we need a creation property list. */
-  if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0)
-    BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_plists++;
-#endif
-  if ((access_plistid = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
-    BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_plists++;
-#endif
+   hid_t plistid = 0, access_plistid = 0, typeid = 0, spaceid = 0;
+   hsize_t chunksize[H5S_MAX_RANK], dimsize[H5S_MAX_RANK], maxdimsize[H5S_MAX_RANK];
+   int d;
+   void *fillp = NULL;
+   NC_DIM_INFO_T *dim = NULL;
+   char *name_to_use;
+   int retval = NC_NOERR;
+
+   LOG((3, "%s:: name %s", __func__, var->name));
+
+   /* Scalar or not, we need a creation property list. */
+   if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0)
+      BAIL(NC_EHDFERR);
+   if ((access_plistid = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
+      BAIL(NC_EHDFERR);
 
-  /* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
-  if (H5Pset_obj_track_times(plistid,0)<0)
-    BAIL(NC_EHDFERR);
+   /* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
+   if (H5Pset_obj_track_times(plistid,0)<0)
+      BAIL(NC_EHDFERR);
 
-  /* Find the HDF5 type of the dataset. */
-  if ((retval = nc4_get_hdf_typeid(grp->nc4_info, var->type_info->nc_typeid, &typeid,
-                                   var->type_info->endianness)))
-    BAIL(retval);
+   /* Find the HDF5 type of the dataset. */
+   if ((retval = nc4_get_hdf_typeid(grp->nc4_info, var->type_info->nc_typeid, &typeid,
+                                    var->type_info->endianness)))
+      BAIL(retval);
 
-  /* Figure out what fill value to set, if any. */
-  if (var->no_fill)
-    {
+   /* Figure out what fill value to set, if any. */
+   if (var->no_fill)
+   {
       /* Required to truly turn HDF5 fill values off */
       if (H5Pset_fill_time(plistid, H5D_FILL_TIME_NEVER) < 0)
-        BAIL(NC_EHDFERR);
-    }
-  else
-    {
+         BAIL(NC_EHDFERR);
+   }
+   else
+   {
       if ((retval = get_fill_value(grp->nc4_info, var, &fillp)))
-        BAIL(retval);
+         BAIL(retval);
 
       /* If there is a fill value, set it. */
       if (fillp)
-        {
-          if (var->type_info->nc_type_class == NC_STRING)
-            {
-              if (H5Pset_fill_value(plistid, typeid, fillp) < 0)
-                BAIL(NC_EHDFERR);
-            }
-          else
+      {
+         if (var->type_info->nc_type_class == NC_STRING)
+         {
+            if (H5Pset_fill_value(plistid, typeid, fillp) < 0)
+               BAIL(NC_EHDFERR);
+         }
+         else
+         {
+            /* The fill value set in HDF5 must always be presented as
+             * a native type, even if the endianness for this dataset
+             * is non-native. HDF5 will translate the fill value to
+             * the target endiannesss. */
+            hid_t fill_typeid = 0;
+
+            if ((retval = nc4_get_hdf_typeid(grp->nc4_info, var->type_info->nc_typeid, &fill_typeid,
+                                             NC_ENDIAN_NATIVE)))
+               BAIL(retval);
+            if (H5Pset_fill_value(plistid, fill_typeid, fillp) < 0)
             {
-              /* The fill value set in HDF5 must always be presented as
-               * a native type, even if the endianness for this dataset
-               * is non-native. HDF5 will translate the fill value to
-               * the target endiannesss. */
-              hid_t fill_typeid = 0;
-
-              if ((retval = nc4_get_hdf_typeid(grp->nc4_info, var->type_info->nc_typeid, &fill_typeid,
-                                               NC_ENDIAN_NATIVE)))
-                BAIL(retval);
-              if (H5Pset_fill_value(plistid, fill_typeid, fillp) < 0)
-                {
-                  if (H5Tclose(fill_typeid) < 0)
-                    BAIL(NC_EHDFERR);
+               if (H5Tclose(fill_typeid) < 0)
                   BAIL(NC_EHDFERR);
-                }
-              if (H5Tclose(fill_typeid) < 0)
-                BAIL(NC_EHDFERR);
+               BAIL(NC_EHDFERR);
             }
-        }
-    }
-
-  /* If the user wants to shuffle the data, set that up now. */
-  if (var->shuffle)
-    if (H5Pset_shuffle(plistid) < 0)
-      BAIL(NC_EHDFERR);
-
-  /* If the user wants to deflate the data, set that up now. */
-  if (var->deflate)
-    if (H5Pset_deflate(plistid, var->deflate_level) < 0)
-      BAIL(NC_EHDFERR);
-
-  /* Szip? NO! We don't want anyone to produce szipped netCDF files! */
-  /* #ifdef USE_SZIP */
-  /*    if (var->options_mask) */
-  /*       if (H5Pset_szip(plistid, var->options_mask, var->bits_per_pixel) < 0) */
-  /*          BAIL(NC_EHDFERR); */
-  /* #endif */
-
-  /* If the user wants to fletcher error correcton, set that up now. */
-  if (var->fletcher32)
-    if (H5Pset_fletcher32(plistid) < 0)
-      BAIL(NC_EHDFERR);
-
-  /* If ndims non-zero, get info for all dimensions. We look up the
-     dimids and get the len of each dimension. We need this to create
-     the space for the dataset. In netCDF a dimension length of zero
-     means an unlimited dimension. */
-  if (var->ndims)
-    {
+            if (H5Tclose(fill_typeid) < 0)
+               BAIL(NC_EHDFERR);
+         }
+      }
+   }
+
+   /* If the user wants to shuffle the data, set that up now. */
+   if (var->shuffle) {
+      if (H5Pset_shuffle(plistid) < 0)
+         BAIL(NC_EHDFERR);
+   }
+
+   /* If the user wants to deflate the data, set that up now. */
+   if (var->deflate) {
+      if (H5Pset_deflate(plistid, var->deflate_level) < 0)
+         BAIL(NC_EHDFERR);
+   } else if(var->filterid) {
+      /* Handle szip case here */
+      if(var->filterid == H5Z_FILTER_SZIP) {
+         int options_mask;
+         int bits_per_pixel;
+         if(var->nparams != 2)
+            BAIL(NC_EFILTER);
+         options_mask = (int)var->params[0];
+         bits_per_pixel = (int)var->params[1];
+         if(H5Pset_szip(plistid, options_mask, bits_per_pixel) < 0)
+            BAIL(NC_EFILTER);
+      } else {
+         herr_t code = H5Pset_filter(plistid, var->filterid, H5Z_FLAG_MANDATORY, var->nparams, var->params);
+         if(code < 0) {
+            BAIL(NC_EFILTER);
+	 }
+      }
+   }
+
+   /* If the user wants to fletcher error correcton, set that up now. */
+   if (var->fletcher32)
+      if (H5Pset_fletcher32(plistid) < 0)
+         BAIL(NC_EHDFERR);
+
+   /* If ndims non-zero, get info for all dimensions. We look up the
+      dimids and get the len of each dimension. We need this to create
+      the space for the dataset. In netCDF a dimension length of zero
+      means an unlimited dimension. */
+   if (var->ndims)
+   {
       int unlimdim = 0;
 
       /* Check to see if any unlimited dimensions are used in this var. */
       for (d = 0; d < var->ndims; d++) {
-	dim = var->dim[d];
-	assert(dim && dim->dimid == var->dimids[d]);
-	if (dim->unlimited)
-	  unlimdim++;
+         dim = var->dim[d];
+         assert(dim && dim->dimid == var->dimids[d]);
+         if (dim->unlimited)
+            unlimdim++;
       }
 
       /* If there are no unlimited dims, and no filters, and the user
        * has not specified chunksizes, use contiguous variable for
        * better performance. */
 
-      if(!var->shuffle && !var->deflate && !var->options_mask &&
+      if(!var->shuffle && !var->deflate &&
          !var->fletcher32 && (var->chunksizes == NULL || !var->chunksizes[0])) {
 #ifdef USE_HDF4
-        NC_HDF5_FILE_INFO_T *h5 = grp->nc4_info;
-        if(h5->hdf4 || !unlimdim)
+         NC_HDF5_FILE_INFO_T *h5 = grp->nc4_info;
+         if(h5->hdf4 || !unlimdim)
 #else
-          if(!unlimdim)
+            if(!unlimdim)
 #endif
-            var->contiguous = NC_TRUE;
+               var->contiguous = NC_TRUE;
       }
 
       /* Gather current & maximum dimension sizes, along with chunk sizes */
       for (d = 0; d < var->ndims; d++)
-        {
-          dim = var->dim[d];
-	  assert(dim && dim->dimid == var->dimids[d]);
-          dimsize[d] = dim->unlimited ? NC_HDF5_UNLIMITED_DIMSIZE : dim->len;
-          maxdimsize[d] = dim->unlimited ? H5S_UNLIMITED : (hsize_t)dim->len;
-          if (!var->contiguous) {
+      {
+         dim = var->dim[d];
+         assert(dim && dim->dimid == var->dimids[d]);
+         dimsize[d] = dim->unlimited ? NC_HDF5_UNLIMITED_DIMSIZE : dim->len;
+         maxdimsize[d] = dim->unlimited ? H5S_UNLIMITED : (hsize_t)dim->len;
+         if (!var->contiguous) {
             if (var->chunksizes[d])
-              chunksize[d] = var->chunksizes[d];
+               chunksize[d] = var->chunksizes[d];
             else
-              {
-                size_t type_size;
-                if (var->type_info->nc_type_class == NC_STRING)
+            {
+               size_t type_size;
+               if (var->type_info->nc_type_class == NC_STRING)
                   type_size = sizeof(char *);
-                else
+               else
                   type_size = var->type_info->size;
 
-                /* Unlimited dim always gets chunksize of 1. */
-                if (dim->unlimited)
+               /* Unlimited dim always gets chunksize of 1. */
+               if (dim->unlimited)
                   chunksize[d] = 1;
-                else
+               else
                   chunksize[d] = pow((double)DEFAULT_CHUNK_SIZE/type_size,
                                      1/(double)(var->ndims - unlimdim));
 
-                /* If the chunksize is greater than the dim
-                 * length, make it the dim length. */
-                if (!dim->unlimited && chunksize[d] > dim->len)
+               /* If the chunksize is greater than the dim
+                * length, make it the dim length. */
+               if (!dim->unlimited && chunksize[d] > dim->len)
                   chunksize[d] = dim->len;
 
-                /* Remember the computed chunksize */
-                var->chunksizes[d] = chunksize[d];
-              }
-          }
-        }
+               /* Remember the computed chunksize */
+               var->chunksizes[d] = chunksize[d];
+            }
+         }
+      }
 
       if (var->contiguous)
-        {
-          if (H5Pset_layout(plistid, H5D_CONTIGUOUS) < 0)
+      {
+         if (H5Pset_layout(plistid, H5D_CONTIGUOUS) < 0)
             BAIL(NC_EHDFERR);
-        }
+      }
       else
-        {
-          if (H5Pset_chunk(plistid, var->ndims, chunksize) < 0)
+      {
+         if (H5Pset_chunk(plistid, var->ndims, chunksize) < 0)
             BAIL(NC_EHDFERR);
-        }
+      }
 
       /* Create the dataspace. */
       if ((spaceid = H5Screate_simple(var->ndims, dimsize, maxdimsize)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces++;
-#endif
-    }
-  else
-    {
+         BAIL(NC_EHDFERR);
+   }
+   else
+   {
       if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces++;
-#endif
-    }
-
-  /* Turn on creation order tracking. */
-  if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED|
-                                 H5P_CRT_ORDER_INDEXED) < 0)
-    BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
+   }
 
-  /* Set per-var chunk cache, for chunked datasets. */
-  if (!var->contiguous && var->chunk_cache_size)
-    if (H5Pset_chunk_cache(access_plistid, var->chunk_cache_nelems,
-                           var->chunk_cache_size, var->chunk_cache_preemption) < 0)
+   /* Turn on creation order tracking. */
+   if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED|
+                                  H5P_CRT_ORDER_INDEXED) < 0)
       BAIL(NC_EHDFERR);
 
-  /* At long last, create the dataset. */
-  name_to_use = var->hdf5_name ? var->hdf5_name : var->name;
-  LOG((4, "%s: about to H5Dcreate2 dataset %s of type 0x%x", __func__,
-       name_to_use, typeid));
-  if ((var->hdf_datasetid = H5Dcreate2(grp->hdf_grpid, name_to_use, typeid,
-                                       spaceid, H5P_DEFAULT, plistid, access_plistid)) < 0)
-    BAIL(NC_EHDFERR);
-  var->created = NC_TRUE;
-  var->is_new_var = NC_FALSE;
-
-  /* If this is a dimscale, mark it as such in the HDF5 file. Also
-   * find the dimension info and store the dataset id of the dimscale
-   * dataset. */
-  if (var->dimscale)
-    {
+   /* Set per-var chunk cache, for chunked datasets. */
+   if (!var->contiguous && var->chunk_cache_size)
+      if (H5Pset_chunk_cache(access_plistid, var->chunk_cache_nelems,
+                             var->chunk_cache_size, var->chunk_cache_preemption) < 0)
+         BAIL(NC_EHDFERR);
+
+   /* At long last, create the dataset. */
+   name_to_use = var->hdf5_name ? var->hdf5_name : var->name;
+   LOG((4, "%s: about to H5Dcreate2 dataset %s of type 0x%x", __func__,
+        name_to_use, typeid));
+   if ((var->hdf_datasetid = H5Dcreate2(grp->hdf_grpid, name_to_use, typeid,
+                                        spaceid, H5P_DEFAULT, plistid, access_plistid)) < 0)
+      BAIL(NC_EHDFERR);
+   var->created = NC_TRUE;
+   var->is_new_var = NC_FALSE;
+
+   /* If this is a dimscale, mark it as such in the HDF5 file. Also
+    * find the dimension info and store the dataset id of the dimscale
+    * dataset. */
+   if (var->dimscale)
+   {
       if (H5DSset_scale(var->hdf_datasetid, var->name) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       /* If this is a multidimensional coordinate variable, write a
        * coordinates attribute. */
       if (var->ndims > 1)
-        if ((retval = write_coord_dimids(var)))
-          BAIL(retval);
+         if ((retval = write_coord_dimids(var)))
+            BAIL(retval);
 
       /* If desired, write the netCDF dimid. */
       if (write_dimid)
-        if ((retval = write_netcdf4_dimid(var->hdf_datasetid, var->dimids[0])))
-          BAIL(retval);
-    }
-
-
-  /* Write attributes for this var. */
-  if ((retval = write_attlist(var->att, var->varid, grp)))
-    BAIL(retval);
-  var->attr_dirty = NC_FALSE;
-
- exit:
-  if (typeid > 0 && H5Tclose(typeid) < 0)
-    BAIL2(NC_EHDFERR);
-  if (plistid > 0 && H5Pclose(plistid) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_plists--;
-#endif
-  if (access_plistid > 0 && H5Pclose(access_plistid) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_plists--;
-#endif
-  if (spaceid > 0 && H5Sclose(spaceid) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  if (fillp)
-    {
+         if ((retval = write_netcdf4_dimid(var->hdf_datasetid, var->dimids[0])))
+            BAIL(retval);
+   }
+
+
+   /* Write attributes for this var. */
+   if ((retval = write_attlist(var->att, var->varid, grp)))
+      BAIL(retval);
+   var->attr_dirty = NC_FALSE;
+
+exit:
+   if (typeid > 0 && H5Tclose(typeid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (plistid > 0 && H5Pclose(plistid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (access_plistid > 0 && H5Pclose(access_plistid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (spaceid > 0 && H5Sclose(spaceid) < 0)
+      BAIL2(NC_EHDFERR);
+   if (fillp)
+   {
       if (var->type_info->nc_type_class == NC_VLEN)
-        nc_free_vlen((nc_vlen_t *)fillp);
+         nc_free_vlen((nc_vlen_t *)fillp);
       else if (var->type_info->nc_type_class == NC_STRING && *(char **)fillp)
-        free(*(char **)fillp);
+         free(*(char **)fillp);
       free(fillp);
-    }
+   }
 
-  return retval;
+   return retval;
 }
 
-/* Adjust the chunk cache of a var for better performance. */
+/**
+ * @internal Adjust the chunk cache of a var for better
+ * performance. 
+ *
+ * @param grp Pointer to group info struct.
+ * @param var Pointer to var info struct.
+ *
+ * @return NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var)
 {
-  size_t chunk_size_bytes = 1;
-  int d;
-  int retval;
+   size_t chunk_size_bytes = 1;
+   int d;
+   int retval;
 
-  /* Nothing to be done. */
-  if (var->contiguous)
-    return NC_NOERR;
+   /* Nothing to be done. */
+   if (var->contiguous)
+      return NC_NOERR;
 #ifdef USE_PARALLEL4
-  return NC_NOERR;
+   return NC_NOERR;
 #endif
 
-  /* How many bytes in the chunk? */
-  for (d = 0; d < var->ndims; d++)
-    chunk_size_bytes *= var->chunksizes[d];
-  if (var->type_info->size)
-    chunk_size_bytes *= var->type_info->size;
-  else
-    chunk_size_bytes *= sizeof(char *);
-
-  /* If the chunk cache is too small, and the user has not changed
-   * the default value of the chunk cache size, then increase the
-   * size of the cache. */
-  if (var->chunk_cache_size == CHUNK_CACHE_SIZE)
-    if (chunk_size_bytes > var->chunk_cache_size)
+   /* How many bytes in the chunk? */
+   for (d = 0; d < var->ndims; d++)
+      chunk_size_bytes *= var->chunksizes[d];
+   if (var->type_info->size)
+      chunk_size_bytes *= var->type_info->size;
+   else
+      chunk_size_bytes *= sizeof(char *);
+
+   /* If the chunk cache is too small, and the user has not changed
+    * the default value of the chunk cache size, then increase the
+    * size of the cache. */
+   if (var->chunk_cache_size == CHUNK_CACHE_SIZE)
+      if (chunk_size_bytes > var->chunk_cache_size)
       {
-        var->chunk_cache_size = chunk_size_bytes * DEFAULT_CHUNKS_IN_CACHE;
-        if (var->chunk_cache_size > MAX_DEFAULT_CACHE_SIZE)
-          var->chunk_cache_size = MAX_DEFAULT_CACHE_SIZE;
-        if ((retval = nc4_reopen_dataset(grp, var)))
-          return retval;
+         var->chunk_cache_size = chunk_size_bytes * DEFAULT_CHUNKS_IN_CACHE;
+         if (var->chunk_cache_size > MAX_DEFAULT_CACHE_SIZE)
+            var->chunk_cache_size = MAX_DEFAULT_CACHE_SIZE;
+         if ((retval = nc4_reopen_dataset(grp, var)))
+            return retval;
       }
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
-/* Create a HDF5 defined type from a NC_TYPE_INFO_T struct, and commit
- * it to the file. */
-static int
-commit_type(NC_GRP_INFO_T *grp, NC_TYPE_INFO_T *type)
+/**
+ * @internal Create a HDF5 defined type from a NC_TYPE_INFO_T struct,
+ * and commit it to the file. 
+ *
+ * @param grp Pointer to group info struct.
+ * @param type Pointer to type info struct.
+ *
+ * @return NC_NOERR No error.
+ * @author Ed Hartnett
+*/
+static int
+commit_type(NC_GRP_INFO_T *grp, NC_TYPE_INFO_T *type)
 {
-  int retval;
+   int retval;
 
-  assert(grp && type);
+   assert(grp && type);
 
-  /* Did we already record this type? */
-  if (type->committed)
-    return NC_NOERR;
+   /* Did we already record this type? */
+   if (type->committed)
+      return NC_NOERR;
 
-  /* Is this a compound type? */
-  if (type->nc_type_class == NC_COMPOUND)
-    {
+   /* Is this a compound type? */
+   if (type->nc_type_class == NC_COMPOUND)
+   {
       NC_FIELD_INFO_T *field;
       hid_t hdf_base_typeid, hdf_typeid;
 
       if ((type->hdf_typeid = H5Tcreate(H5T_COMPOUND, type->size)) < 0)
-        return NC_EHDFERR;
+         return NC_EHDFERR;
       LOG((4, "creating compound type %s hdf_typeid 0x%x", type->name,
            type->hdf_typeid));
 
       for (field = type->u.c.field; field; field = field->l.next)
-        {
-          if ((retval = nc4_get_hdf_typeid(grp->nc4_info, field->nc_typeid,
-                                           &hdf_base_typeid, type->endianness)))
+      {
+         if ((retval = nc4_get_hdf_typeid(grp->nc4_info, field->nc_typeid,
+                                          &hdf_base_typeid, type->endianness)))
             return retval;
 
-          /* If this is an array, create a special array type. */
-          if (field->ndims)
+         /* If this is an array, create a special array type. */
+         if (field->ndims)
+         {
+            int d;
+            hsize_t dims[NC_MAX_VAR_DIMS];
+
+            for (d = 0; d < field->ndims; d++)
+               dims[d] = field->dim_size[d];
+            if ((hdf_typeid = H5Tarray_create(hdf_base_typeid, field->ndims,
+                                              dims, NULL)) < 0)
             {
-              int d;
-              hsize_t dims[NC_MAX_VAR_DIMS];
-
-              for (d = 0; d < field->ndims; d++)
-                dims[d] = field->dim_size[d];
-              if ((hdf_typeid = H5Tarray_create(hdf_base_typeid, field->ndims,
-                                                dims, NULL)) < 0)
-                {
-                  if (H5Tclose(hdf_base_typeid) < 0)
-                    return NC_EHDFERR;
+               if (H5Tclose(hdf_base_typeid) < 0)
                   return NC_EHDFERR;
-                }
-              if (H5Tclose(hdf_base_typeid) < 0)
-                return NC_EHDFERR;
+               return NC_EHDFERR;
             }
-          else
+            if (H5Tclose(hdf_base_typeid) < 0)
+               return NC_EHDFERR;
+         }
+         else
             hdf_typeid = hdf_base_typeid;
-          LOG((4, "inserting field %s offset %d hdf_typeid 0x%x", field->name,
-               field->offset, hdf_typeid));
-          if (H5Tinsert(type->hdf_typeid, field->name, field->offset,
-                        hdf_typeid) < 0)
+         LOG((4, "inserting field %s offset %d hdf_typeid 0x%x", field->name,
+              field->offset, hdf_typeid));
+         if (H5Tinsert(type->hdf_typeid, field->name, field->offset,
+                       hdf_typeid) < 0)
             return NC_EHDFERR;
-          if (H5Tclose(hdf_typeid) < 0)
+         if (H5Tclose(hdf_typeid) < 0)
             return NC_EHDFERR;
-        }
-    }
-  else if (type->nc_type_class == NC_VLEN)
-    {
+      }
+   }
+   else if (type->nc_type_class == NC_VLEN)
+   {
       /* Find the HDF typeid of the base type of this vlen. */
       if ((retval = nc4_get_hdf_typeid(grp->nc4_info, type->u.v.base_nc_typeid,
                                        &type->u.v.base_hdf_typeid, type->endianness)))
-        return retval;
+         return retval;
 
       /* Create a vlen type. */
       if ((type->hdf_typeid = H5Tvlen_create(type->u.v.base_hdf_typeid)) < 0)
-        return NC_EHDFERR;
-    }
-  else if (type->nc_type_class == NC_OPAQUE)
-    {
+         return NC_EHDFERR;
+   }
+   else if (type->nc_type_class == NC_OPAQUE)
+   {
       /* Create the opaque type. */
       if ((type->hdf_typeid = H5Tcreate(H5T_OPAQUE, type->size)) < 0)
-        return NC_EHDFERR;
-    }
-  else if (type->nc_type_class == NC_ENUM)
-    {
+         return NC_EHDFERR;
+   }
+   else if (type->nc_type_class == NC_ENUM)
+   {
       NC_ENUM_MEMBER_INFO_T *enum_m;
 
       if (!type->u.e.enum_member)
-        return NC_EINVAL;
+         return NC_EINVAL;
 
       /* Find the HDF typeid of the base type of this enum. */
       if ((retval = nc4_get_hdf_typeid(grp->nc4_info, type->u.e.base_nc_typeid,
                                        &type->u.e.base_hdf_typeid, type->endianness)))
-        return retval;
+         return retval;
 
       /* Create an enum type. */
       if ((type->hdf_typeid =  H5Tenum_create(type->u.e.base_hdf_typeid)) < 0)
-        return NC_EHDFERR;
+         return NC_EHDFERR;
 
       /* Add all the members to the HDF5 type. */
       for (enum_m = type->u.e.enum_member; enum_m; enum_m = enum_m->l.next)
-        if (H5Tenum_insert(type->hdf_typeid, enum_m->name, enum_m->value) < 0)
-          return NC_EHDFERR;
-    }
-  else
-    {
+         if (H5Tenum_insert(type->hdf_typeid, enum_m->name, enum_m->value) < 0)
+            return NC_EHDFERR;
+   }
+   else
+   {
       LOG((0, "Unknown class: %d", type->nc_type_class));
       return NC_EBADTYPE;
-    }
-
-  /* Commit the type. */
-  if (H5Tcommit(grp->hdf_grpid, type->name, type->hdf_typeid) < 0)
-    return NC_EHDFERR;
-  type->committed = NC_TRUE;
-  LOG((4, "just committed type %s, HDF typeid: 0x%x", type->name,
-       type->hdf_typeid));
-
-  /* Later we will always use the native typeid. In this case, it is
-   * a copy of the same type pointed to by hdf_typeid, but it's
-   * easier to maintain a copy. */
-  if ((type->native_hdf_typeid = H5Tget_native_type(type->hdf_typeid,
-                                                    H5T_DIR_DEFAULT)) < 0)
-    return NC_EHDFERR;
-
-  return NC_NOERR;
+   }
+
+   /* Commit the type. */
+   if (H5Tcommit(grp->hdf_grpid, type->name, type->hdf_typeid) < 0)
+      return NC_EHDFERR;
+   type->committed = NC_TRUE;
+   LOG((4, "just committed type %s, HDF typeid: 0x%x", type->name,
+        type->hdf_typeid));
+
+   /* Later we will always use the native typeid. In this case, it is
+    * a copy of the same type pointed to by hdf_typeid, but it's
+    * easier to maintain a copy. */
+   if ((type->native_hdf_typeid = H5Tget_native_type(type->hdf_typeid,
+                                                     H5T_DIR_DEFAULT)) < 0)
+      return NC_EHDFERR;
+
+   return NC_NOERR;
 }
 
-/* Write an attribute, with value 1, to indicate that strict NC3 rules
- * apply to this file. */
+/**
+ * @internal Write an attribute, with value 1, to indicate that strict
+ * NC3 rules apply to this file. 
+ *
+ * @param hdf_grpid HDF5 group ID.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+ */
 static int
 write_nc3_strict_att(hid_t hdf_grpid)
 {
-  hid_t attid = 0, spaceid = 0;
-  int one = 1;
-  int retval = NC_NOERR;
-  htri_t attr_exists;
-
-  /* If the attribute already exists, call that a success and return
-   * NC_NOERR. */
-  if ((attr_exists = H5Aexists(hdf_grpid, NC3_STRICT_ATT_NAME)) < 0)
-    return NC_EHDFERR;
-  if (attr_exists)
-    return NC_NOERR;
-
-  /* Create the attribute to mark this as a file that needs to obey
-   * strict netcdf-3 rules. */
-  if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
-    BAIL(NC_EFILEMETA);
-#ifdef EXTRA_TESTS
-  num_spaces++;
-#endif
-  if ((attid = H5Acreate(hdf_grpid, NC3_STRICT_ATT_NAME,
-                         H5T_NATIVE_INT, spaceid, H5P_DEFAULT)) < 0)
-    BAIL(NC_EFILEMETA);
-  if (H5Awrite(attid, H5T_NATIVE_INT, &one) < 0)
-    BAIL(NC_EFILEMETA);
-
- exit:
-  if (spaceid > 0 && (H5Sclose(spaceid) < 0))
-    BAIL2(NC_EFILEMETA);
-#ifdef EXTRA_TESTS
-  num_spaces--;
-#endif
-  if (attid > 0 && (H5Aclose(attid) < 0))
-    BAIL2(NC_EFILEMETA);
-  return retval;
+   hid_t attid = 0, spaceid = 0;
+   int one = 1;
+   int retval = NC_NOERR;
+   htri_t attr_exists;
+
+   /* If the attribute already exists, call that a success and return
+    * NC_NOERR. */
+   if ((attr_exists = H5Aexists(hdf_grpid, NC3_STRICT_ATT_NAME)) < 0)
+      return NC_EHDFERR;
+   if (attr_exists)
+      return NC_NOERR;
+
+   /* Create the attribute to mark this as a file that needs to obey
+    * strict netcdf-3 rules. */
+   if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
+      BAIL(NC_EFILEMETA);
+   if ((attid = H5Acreate(hdf_grpid, NC3_STRICT_ATT_NAME,
+                          H5T_NATIVE_INT, spaceid, H5P_DEFAULT)) < 0)
+      BAIL(NC_EFILEMETA);
+   if (H5Awrite(attid, H5T_NATIVE_INT, &one) < 0)
+      BAIL(NC_EFILEMETA);
+
+exit:
+   if (spaceid > 0 && (H5Sclose(spaceid) < 0))
+      BAIL2(NC_EFILEMETA);
+   if (attid > 0 && (H5Aclose(attid) < 0))
+      BAIL2(NC_EFILEMETA);
+   return retval;
 }
 
+/**
+ * @internal Create a HDF5 group.
+ *
+ * @param grp Pointer to group info struct.
+ *
+ * @return NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 create_group(NC_GRP_INFO_T *grp)
 {
-  hid_t gcpl_id = 0;
-  int retval = NC_NOERR;;
+   hid_t gcpl_id = 0;
+   int retval = NC_NOERR;;
 
-  assert(grp);
+   assert(grp);
 
-  /* If this is not the root group, create it in the HDF5 file. */
-  if (grp->parent)
-    {
+   /* If this is not the root group, create it in the HDF5 file. */
+   if (grp->parent)
+   {
       /* Create group, with link_creation_order set in the group
        * creation property list. */
       if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0)
-        return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-      num_plists++;
-#endif
+         return NC_EHDFERR;
 
       /* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
       if (H5Pset_obj_track_times(gcpl_id,0)<0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
       if (H5Pset_attr_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
       if ((grp->hdf_grpid = H5Gcreate2(grp->parent->hdf_grpid, grp->name,
                                        H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
       if (H5Pclose(gcpl_id) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_plists--;
-#endif
-    }
-  else
-    {
+         BAIL(NC_EHDFERR);
+   }
+   else
+   {
       /* Since this is the root group, we have to open it. */
       if ((grp->hdf_grpid = H5Gopen2(grp->nc4_info->hdfid, "/", H5P_DEFAULT)) < 0)
-        BAIL(NC_EFILEMETA);
-    }
-  return NC_NOERR;
-
- exit:
-  if (gcpl_id > 0 && H5Pclose(gcpl_id) < 0)
-    BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-  num_plists--;
-#endif
-  if (grp->hdf_grpid > 0 && H5Gclose(grp->hdf_grpid) < 0)
-    BAIL2(NC_EHDFERR);
-  return retval;
+         BAIL(NC_EFILEMETA);
+   }
+   return NC_NOERR;
+
+exit:
+   if (gcpl_id > 0 && H5Pclose(gcpl_id) < 0)
+      BAIL2(NC_EHDFERR);
+   if (grp->hdf_grpid > 0 && H5Gclose(grp->hdf_grpid) < 0)
+      BAIL2(NC_EHDFERR);
+   return retval;
 }
 
-/* After all the datasets of the file have been read, it's time to
- * sort the wheat from the chaff. Which of the datasets are netCDF
- * dimensions, and which are coordinate variables, and which are
- * non-coordinate variables. */
+/**
+ * @internal After all the datasets of the file have been read, it's
+ * time to sort the wheat from the chaff. Which of the datasets are
+ * netCDF dimensions, and which are coordinate variables, and which
+ * are non-coordinate variables. 
+ *
+ * @param grp Pointer to group info struct. 
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 static int
 attach_dimscales(NC_GRP_INFO_T *grp)
 {
-  NC_VAR_INFO_T *var;
-  NC_DIM_INFO_T *dim1;
-  int d, i;
-  int retval = NC_NOERR;
-
-  /* Attach dimension scales. */
-  for (i=0; i < grp->vars.nelems; i++)
-    {
+   NC_VAR_INFO_T *var;
+   NC_DIM_INFO_T *dim1;
+   int d, i;
+   int retval = NC_NOERR;
+
+   /* Attach dimension scales. */
+   for (i=0; i < grp->vars.nelems; i++)
+   {
       var = grp->vars.value[i];
       if (!var) continue;
       /* Scales themselves do not attach. But I really wish they
        * would. */
       if (var->dimscale)
-        {
-          /* If this is a multidimensional coordinate variable, it will
-           * have a special coords attribute (read earlier) with a list
-           * of the dimensions for this variable. */
-        }
+      {
+         /* If this is a multidimensional coordinate variable, it will
+          * have a special coords attribute (read earlier) with a list
+          * of the dimensions for this variable. */
+      }
       else /* not a dimscale... */
-        {
-          /* Find the scale for each dimension and attach it. */
-          for (d = 0; d < var->ndims; d++)
+      {
+         /* Find the scale for each dimension and attach it. */
+         for (d = 0; d < var->ndims; d++)
+         {
+            /* Is there a dimscale for this dimension? */
+            if (var->dimscale_attached)
             {
-              /* Is there a dimscale for this dimension? */
-              if (var->dimscale_attached)
-                {
-                  if (!var->dimscale_attached[d])
-                    {
-                      hid_t dim_datasetid;  /* Dataset ID for dimension */
-                      dim1 = var->dim[d];
-		      assert(dim1 && dim1->dimid == var->dimids[d]);
-
-                      LOG((2, "%s: attaching scale for dimid %d to var %s",
-                           __func__, var->dimids[d], var->name));
-
-                      /* Find dataset ID for dimension */
-                      if (dim1->coord_var)
-                        dim_datasetid = dim1->coord_var->hdf_datasetid;
-                      else
-                        dim_datasetid = dim1->hdf_dimscaleid;
-                      assert(dim_datasetid > 0);
-                      if (H5DSattach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
-                        BAIL(NC_EHDFERR);
-                      var->dimscale_attached[d] = NC_TRUE;
-                    }
-
-		  /* If we didn't find a dimscale to attach, that's a problem! */
-		  if (!var->dimscale_attached[d])
-		    {
-		      LOG((0, "no dimscale found!"));
-		      return NC_EDIMSCALE;
-		    }
-                }
+               if (!var->dimscale_attached[d])
+               {
+                  hid_t dim_datasetid;  /* Dataset ID for dimension */
+                  dim1 = var->dim[d];
+                  assert(dim1 && dim1->dimid == var->dimids[d]);
+
+                  LOG((2, "%s: attaching scale for dimid %d to var %s",
+                       __func__, var->dimids[d], var->name));
+
+                  /* Find dataset ID for dimension */
+                  if (dim1->coord_var)
+                     dim_datasetid = dim1->coord_var->hdf_datasetid;
+                  else
+                     dim_datasetid = dim1->hdf_dimscaleid;
+                  assert(dim_datasetid > 0);
+                  if (H5DSattach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
+                     BAIL(NC_EHDFERR);
+                  var->dimscale_attached[d] = NC_TRUE;
+               }
+
+               /* If we didn't find a dimscale to attach, that's a problem! */
+               if (!var->dimscale_attached[d])
+               {
+                  LOG((0, "no dimscale found!"));
+                  return NC_EDIMSCALE;
+               }
             }
-        }
-    }
+         }
+      }
+   }
 
- exit:
-  return retval;
+exit:
+   return retval;
 }
 
+/**
+ * @internal Does a variable exist?
+ *
+ * @param grpid HDF5 group ID.
+ * @param name Name of variable.
+ * @param exists Pointer that gets 1 of the variable exists, 0 otherwise.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 var_exists(hid_t grpid, char *name, nc_bool_t *exists)
 {
-  htri_t link_exists;
+   htri_t link_exists;
 
-  /* Reset the boolean */
-  *exists = NC_FALSE;
+   /* Reset the boolean */
+   *exists = NC_FALSE;
 
-  /* Check if the object name exists in the group */
-  if ((link_exists = H5Lexists(grpid, name, H5P_DEFAULT)) < 0)
-    return NC_EHDFERR;
-  if (link_exists)
-    {
+   /* Check if the object name exists in the group */
+   if ((link_exists = H5Lexists(grpid, name, H5P_DEFAULT)) < 0)
+      return NC_EHDFERR;
+   if (link_exists)
+   {
       H5G_stat_t statbuf;
 
       /* Get info about the object */
       if (H5Gget_objinfo(grpid, name, 1, &statbuf) < 0)
-        return NC_EHDFERR;
+         return NC_EHDFERR;
 
       if (H5G_DATASET == statbuf.type)
-        *exists = NC_TRUE;
-    }
+         *exists = NC_TRUE;
+   }
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
-/* This function writes a variable. The principle difficulty comes
- * from the possibility that this is a coordinate variable, and was
- * already written to the file as a dimension-only dimscale. If this
- * occurs, then it must be deleted and recreated. */
+/**
+ * @internal This function writes a variable. The principle difficulty
+ * comes from the possibility that this is a coordinate variable, and
+ * was already written to the file as a dimension-only dimscale. If
+ * this occurs, then it must be deleted and recreated. 
+ *
+ * @param var Pointer to variable info struct.
+ * @param grp Pointer to group info struct.
+ * @param write_dimid
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 static int
 write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
 {
-  nc_bool_t replace_existing_var = NC_FALSE;
-  int retval;
+   nc_bool_t replace_existing_var = NC_FALSE;
+   int retval;
 
-  LOG((4, "%s: writing var %s", __func__, var->name));
+   LOG((4, "%s: writing var %s", __func__, var->name));
 
-  /* If the variable has already been created & the fill value changed,
-   * indicate that the existing variable should be replaced. */
-  if (var->created && var->fill_val_changed)
-    {
+   /* If the variable has already been created & the fill value changed,
+    * indicate that the existing variable should be replaced. */
+   if (var->created && var->fill_val_changed)
+   {
       replace_existing_var = NC_TRUE;
       var->fill_val_changed = NC_FALSE;
       /* If the variable is going to be replaced,
@@ -2183,204 +2326,216 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
          * https://github.com/Unidata/netcdf-c/issues/239 */
 
       flag_atts_dirty(&var->att);
-    }
-
-  /* Is this a coordinate var that has already been created in
-   * the HDF5 file as a dimscale dataset? Check for dims with the
-   * same name in this group. If there is one, check to see if
-   * this object exists in the HDF group. */
-  if (var->became_coord_var)
-    {
+   }
+
+   /* Is this a coordinate var that has already been created in
+    * the HDF5 file as a dimscale dataset? Check for dims with the
+    * same name in this group. If there is one, check to see if
+    * this object exists in the HDF group. */
+   if (var->became_coord_var)
+   {
       NC_DIM_INFO_T *d1;
 
       for (d1 = grp->dim; d1; d1 = d1->l.next)
-        if (!strcmp(d1->name, var->name))
-          {
+         if (!strcmp(d1->name, var->name))
+         {
             nc_bool_t exists;
 
             if ((retval = var_exists(grp->hdf_grpid, var->name, &exists)))
-              return retval;
+               return retval;
             if (exists)
-              {
-                /* Indicate that the variable already exists, and should be replaced */
-                replace_existing_var = NC_TRUE;
-                flag_atts_dirty(&var->att);
-                break;
-              }
-          }
-    }
-
-  /* Check dims if the variable will be replaced, so that the dimensions
-   * will be de-attached and re-attached correctly. */
-  /* (Note: There's a temptation to merge this loop over the dimensions with
-   *        the prior loop over dimensions, but that blurs the line over the
-   *        purpose of them, so they are currently separate.  If performance
-   *        becomes an issue here, it would be possible to merge them. -QAK)
-   */
-  if (replace_existing_var)
-    {
+            {
+               /* Indicate that the variable already exists, and should be replaced */
+               replace_existing_var = NC_TRUE;
+               flag_atts_dirty(&var->att);
+               break;
+            }
+         }
+   }
+
+   /* Check dims if the variable will be replaced, so that the dimensions
+    * will be de-attached and re-attached correctly. */
+   /* (Note: There's a temptation to merge this loop over the dimensions with
+    *        the prior loop over dimensions, but that blurs the line over the
+    *        purpose of them, so they are currently separate.  If performance
+    *        becomes an issue here, it would be possible to merge them. -QAK)
+    */
+   if (replace_existing_var)
+   {
       NC_DIM_INFO_T *d1;
 
       for (d1 = grp->dim; d1; d1 = d1->l.next)
-        if (!strcmp(d1->name, var->name))
-          {
+         if (!strcmp(d1->name, var->name))
+         {
             nc_bool_t exists;
 
             if ((retval = var_exists(grp->hdf_grpid, var->name, &exists)))
-              return retval;
+               return retval;
             if (exists)
-              {
-                hid_t dim_datasetid;  /* Dataset ID for dimension */
+            {
+               hid_t dim_datasetid;  /* Dataset ID for dimension */
 
-                /* Find dataset ID for dimension */
-                if (d1->coord_var)
+               /* Find dataset ID for dimension */
+               if (d1->coord_var)
                   dim_datasetid = d1->coord_var->hdf_datasetid;
-                else
+               else
                   dim_datasetid = d1->hdf_dimscaleid;
-                assert(dim_datasetid > 0);
+               assert(dim_datasetid > 0);
 
-                /* If we're replacing an existing dimscale dataset, go to
-                 * every var in the file and detach this dimension scale,
-                 * because we have to delete it. */
-                if ((retval = rec_detach_scales(grp->nc4_info->root_grp,
-                                                var->dimids[0], dim_datasetid)))
+               /* If we're replacing an existing dimscale dataset, go to
+                * every var in the file and detach this dimension scale,
+                * because we have to delete it. */
+               if ((retval = rec_detach_scales(grp->nc4_info->root_grp,
+                                               var->dimids[0], dim_datasetid)))
                   return retval;
-                break;
-              }
-          }
-    }
-
-  /* If this is not a dimension scale, do this stuff. */
-  if (var->was_coord_var && var->dimscale_attached)
-    {
+               break;
+            }
+         }
+   }
+
+   /* If this is not a dimension scale, do this stuff. */
+   if (var->was_coord_var && var->dimscale_attached)
+   {
       /* If the variable already exists in the file, Remove any dimension scale
        * attributes from it, if they exist. */
       /* (The HDF5 Dimension Scale API should really have an API routine
        * for making a dataset not a scale. -QAK) */
       if (var->created)
-        {
-          htri_t attr_exists;
+      {
+         htri_t attr_exists;
 
-          /* (We could do a better job here and verify that the attributes are
-           * really dimension scale 'CLASS' & 'NAME' attributes, but that would be
-           * poking about in the HDF5 DimScale internal data) */
-          if ((attr_exists = H5Aexists(var->hdf_datasetid, "CLASS")) < 0)
+         /* (We could do a better job here and verify that the attributes are
+          * really dimension scale 'CLASS' & 'NAME' attributes, but that would be
+          * poking about in the HDF5 DimScale internal data) */
+         if ((attr_exists = H5Aexists(var->hdf_datasetid, "CLASS")) < 0)
             BAIL(NC_EHDFERR);
-          if (attr_exists)
-            {
-              if (H5Adelete(var->hdf_datasetid, "CLASS") < 0)
-                BAIL(NC_EHDFERR);
-            }
-          if ((attr_exists = H5Aexists(var->hdf_datasetid, "NAME")) < 0)
+         if (attr_exists)
+         {
+            if (H5Adelete(var->hdf_datasetid, "CLASS") < 0)
+               BAIL(NC_EHDFERR);
+         }
+         if ((attr_exists = H5Aexists(var->hdf_datasetid, "NAME")) < 0)
             BAIL(NC_EHDFERR);
-          if (attr_exists)
-            {
-              if (H5Adelete(var->hdf_datasetid, "NAME") < 0)
-                BAIL(NC_EHDFERR);
-            }
-        }
+         if (attr_exists)
+         {
+            if (H5Adelete(var->hdf_datasetid, "NAME") < 0)
+               BAIL(NC_EHDFERR);
+         }
+      }
 
       if (var->dimscale_attached)
-        {
-          int d;
+      {
+         int d;
 
-          /* If this is a regular var, detach all its dim scales. */
-          for (d = 0; d < var->ndims; d++)
+         /* If this is a regular var, detach all its dim scales. */
+         for (d = 0; d < var->ndims; d++)
             if (var->dimscale_attached[d])
-              {
-                hid_t dim_datasetid;  /* Dataset ID for dimension */
-                NC_DIM_INFO_T *dim1 = var->dim[d];
-		assert(dim1 && dim1->dimid == var->dimids[d]);
+            {
+               hid_t dim_datasetid;  /* Dataset ID for dimension */
+               NC_DIM_INFO_T *dim1 = var->dim[d];
+               assert(dim1 && dim1->dimid == var->dimids[d]);
 
-                /* Find dataset ID for dimension */
-                if (dim1->coord_var)
+               /* Find dataset ID for dimension */
+               if (dim1->coord_var)
                   dim_datasetid = dim1->coord_var->hdf_datasetid;
-                else
+               else
                   dim_datasetid = dim1->hdf_dimscaleid;
-                assert(dim_datasetid > 0);
+               assert(dim_datasetid > 0);
 
-                if (H5DSdetach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
+               if (H5DSdetach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
                   BAIL(NC_EHDFERR);
-                var->dimscale_attached[d] = NC_FALSE;
-              }
-        }
-    }
-
-  /* Delete the HDF5 dataset that is to be replaced. */
-  if (replace_existing_var)
-    {
+               var->dimscale_attached[d] = NC_FALSE;
+            }
+      }
+   }
+
+   /* Delete the HDF5 dataset that is to be replaced. */
+   if (replace_existing_var)
+   {
       /* Free the HDF5 dataset id. */
       if (var->hdf_datasetid && H5Dclose(var->hdf_datasetid) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
       var->hdf_datasetid = 0;
 
       /* Now delete the variable. */
       if (H5Gunlink(grp->hdf_grpid, var->name) < 0)
-        return NC_EDIMMETA;
-    }
+         return NC_EDIMMETA;
+   }
 
-  /* Create the dataset. */
-  if (var->is_new_var || replace_existing_var)
-    {
+   /* Create the dataset. */
+   if (var->is_new_var || replace_existing_var)
+   {
       if ((retval = var_create_dataset(grp, var, write_dimid)))
-        return retval;
-    }
-  else
-    {
+         return retval;
+   }
+   else
+   {
       if (write_dimid && var->ndims)
-        if ((retval = write_netcdf4_dimid(var->hdf_datasetid, var->dimids[0])))
-          BAIL(retval);
-    }
+         if ((retval = write_netcdf4_dimid(var->hdf_datasetid, var->dimids[0])))
+            BAIL(retval);
+   }
 
-  if (replace_existing_var)
-    {
+   if (replace_existing_var)
+   {
       /* If this is a dimension scale, reattach the scale everywhere it
        * is used. (Recall that netCDF dimscales are always 1-D). */
       if(var->dimscale)
-        {
-          if ((retval = rec_reattach_scales(grp->nc4_info->root_grp,
-                                            var->dimids[0], var->hdf_datasetid)))
+      {
+         if ((retval = rec_reattach_scales(grp->nc4_info->root_grp,
+                                           var->dimids[0], var->hdf_datasetid)))
             return retval;
-        }
+      }
       /* If it's not a dimension scale, clear the dimscale attached flags,
        * so the dimensions are re-attached. */
       else
-        {
-          if (var->dimscale_attached)
+      {
+         if (var->dimscale_attached)
             memset(var->dimscale_attached, 0, sizeof(nc_bool_t) * var->ndims);
-        }
-    }
+      }
+   }
 
-  /* Clear coord. var state transition flags */
-  var->was_coord_var = NC_FALSE;
-  var->became_coord_var = NC_FALSE;
+   /* Clear coord. var state transition flags */
+   var->was_coord_var = NC_FALSE;
+   var->became_coord_var = NC_FALSE;
 
-  /* Now check the attributes for this var. */
-  if (var->attr_dirty)
-    {
+   /* Now check the attributes for this var. */
+   if (var->attr_dirty)
+   {
       /* Write attributes for this var. */
       if ((retval = write_attlist(var->att, var->varid, grp)))
-        BAIL(retval);
+         BAIL(retval);
       var->attr_dirty = NC_FALSE;
-    }
+   }
 
-  return NC_NOERR;
- exit:
-  return retval;
+   return NC_NOERR;
+exit:
+   return retval;
 }
 
+/**
+ * @internal Write a dimension.
+ *
+ * @param dim Pointer to dim info struct.
+ * @param grp Pointer to group info struct.
+ * @param write_dimid
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EPERM Read-only file.
+ * @returns ::NC_EHDFERR HDF5 returned error.
+ * @author Ed Hartnett
+ */
 static int
 write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
 {
-  int retval;
-  int i;
-
-  /* If there's no dimscale dataset for this dim, create one,
-   * and mark that it should be hidden from netCDF as a
-   * variable. (That is, it should appear as a dimension
-   * without an associated variable.) */
-  if (0 == dim->hdf_dimscaleid)
-    {
+   int retval;
+   int i;
+
+   /* If there's no dimscale dataset for this dim, create one,
+    * and mark that it should be hidden from netCDF as a
+    * variable. (That is, it should appear as a dimension
+    * without an associated variable.) */
+   if (0 == dim->hdf_dimscaleid)
+   {
       hid_t spaceid, create_propid;
       hsize_t dims[1], max_dims[1], chunk_dims[1] = {1};
       char dimscale_wo_var[NC_MAX_NAME];
@@ -2394,64 +2549,52 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
        * unlimited (i.e. it's an unlimited dimension), then set
        * up chunking, with a chunksize of 1. */
       if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_plists++;
-#endif
+         BAIL(NC_EHDFERR);
 
       /* RJ: this suppose to be FALSE that is defined in H5 private.h as 0 */
       if (H5Pset_obj_track_times(create_propid,0)<0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       dims[0] = dim->len;
       max_dims[0] = dim->len;
       if (dim->unlimited)
-        {
-          max_dims[0] = H5S_UNLIMITED;
-          if (H5Pset_chunk(create_propid, 1, chunk_dims) < 0)
+      {
+         max_dims[0] = H5S_UNLIMITED;
+         if (H5Pset_chunk(create_propid, 1, chunk_dims) < 0)
             BAIL(NC_EHDFERR);
-        }
+      }
 
       /* Set up space. */
       if ((spaceid = H5Screate_simple(1, dims, max_dims)) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces++;
-#endif
+         BAIL(NC_EHDFERR);
 
       if (H5Pset_attr_creation_order(create_propid, H5P_CRT_ORDER_TRACKED|
                                      H5P_CRT_ORDER_INDEXED) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       /* Create the dataset that will be the dimension scale. */
       LOG((4, "%s: about to H5Dcreate1 a dimscale dataset %s", __func__, dim->name));
       if ((dim->hdf_dimscaleid = H5Dcreate1(grp->hdf_grpid, dim->name, H5T_IEEE_F32BE,
                                             spaceid, create_propid)) < 0)
-        BAIL(NC_EHDFERR);
+         BAIL(NC_EHDFERR);
 
       /* Close the spaceid and create_propid. */
       if (H5Sclose(spaceid) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_spaces--;
-#endif
+         BAIL(NC_EHDFERR);
       if (H5Pclose(create_propid) < 0)
-        BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-      num_plists--;
-#endif
+         BAIL(NC_EHDFERR);
 
       /* Indicate that this is a scale. Also indicate that not
        * be shown to the user as a variable. It is hidden. It is
        * a DIM WITHOUT A VARIABLE! */
       sprintf(dimscale_wo_var, "%s%10d", DIM_WITHOUT_VARIABLE, (int)dim->len);
       if (H5DSset_scale(dim->hdf_dimscaleid, dimscale_wo_var) < 0)
-        BAIL(NC_EHDFERR);
-    }
+         BAIL(NC_EHDFERR);
+   }
 
-  /* Did we extend an unlimited dimension? */
-  if (dim->extended)
-    {
+   /* Did we extend an unlimited dimension? */
+   if (dim->extended)
+   {
       NC_VAR_INFO_T *v1 = NULL;
 
       assert(dim->unlimited);
@@ -2460,234 +2603,275 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
        * attribute. */
       for (i=0; i < grp->vars.nelems; i++)
       {
-	if (grp->vars.value[i] && !strcmp(grp->vars.value[i]->name, dim->name))
-	{
-	  v1 = grp->vars.value[i];
-          break;
-	}
+         if (grp->vars.value[i] && !strcmp(grp->vars.value[i]->name, dim->name))
+         {
+            v1 = grp->vars.value[i];
+            break;
+         }
       }
       if (v1)
-        {
-          hsize_t *new_size = NULL;
-          int d1;
+      {
+         hsize_t *new_size = NULL;
+         int d1;
 
-          /* Extend the dimension scale dataset to reflect the new
-           * length of the dimension. */
-          if (!(new_size = malloc(v1->ndims * sizeof(hsize_t))))
+         /* Extend the dimension scale dataset to reflect the new
+          * length of the dimension. */
+         if (!(new_size = malloc(v1->ndims * sizeof(hsize_t))))
             BAIL(NC_ENOMEM);
-          for (d1 = 0; d1 < v1->ndims; d1++)
-            {
-	      assert(v1->dim[d1] && v1->dim[d1]->dimid == v1->dimids[d1]);
-	      new_size[d1] = v1->dim[d1]->len;
-            }
-          if (H5Dset_extent(v1->hdf_datasetid, new_size) < 0) {
+         for (d1 = 0; d1 < v1->ndims; d1++)
+         {
+            assert(v1->dim[d1] && v1->dim[d1]->dimid == v1->dimids[d1]);
+            new_size[d1] = v1->dim[d1]->len;
+         }
+         if (H5Dset_extent(v1->hdf_datasetid, new_size) < 0) {
             free(new_size);
             BAIL(NC_EHDFERR);
-          }
-          free(new_size);
-        }
-    }
-
-  /* If desired, write the secret dimid. This will be used instead of
-   * the dimid that the dimension would otherwise receive based on
-   * creation order. This can be necessary when dims and their
-   * coordinate variables were created in different order. */
-  if (write_dimid && dim->hdf_dimscaleid)
-    if ((retval = write_netcdf4_dimid(dim->hdf_dimscaleid, dim->dimid)))
-      BAIL(retval);
+         }
+         free(new_size);
+      }
+   }
+
+   /* If desired, write the secret dimid. This will be used instead of
+    * the dimid that the dimension would otherwise receive based on
+    * creation order. This can be necessary when dims and their
+    * coordinate variables were created in different order. */
+   if (write_dimid && dim->hdf_dimscaleid)
+      if ((retval = write_netcdf4_dimid(dim->hdf_dimscaleid, dim->dimid)))
+         BAIL(retval);
 
-  return NC_NOERR;
- exit:
+   return NC_NOERR;
+exit:
 
-  return retval;
+   return retval;
 }
 
-/* Recursively determine if there is a mismatch between order of
- * coordinate creation and associated dimensions in this group or any
- * subgroups, to find out if we have to handle that situation.  Also
- * check if there are any multidimensional coordinate variables
- * defined, which require the same treatment to fix a potential bug
- * when such variables occur in subgroups. */
+/**
+ * @internal Recursively determine if there is a mismatch between
+ * order of coordinate creation and associated dimensions in this
+ * group or any subgroups, to find out if we have to handle that
+ * situation.  Also check if there are any multidimensional coordinate
+ * variables defined, which require the same treatment to fix a
+ * potential bug when such variables occur in subgroups. 
+ *
+ * @param grp Pointer to group info struct.
+ * @param bad_coord_orderp Pointer that gets 1 if there is a bad
+ * coordinate order.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 int
 nc4_rec_detect_need_to_preserve_dimids(NC_GRP_INFO_T *grp, nc_bool_t *bad_coord_orderp)
 {
-  NC_VAR_INFO_T *var;
-  NC_GRP_INFO_T *child_grp;
-  int last_dimid = -1;
-  int retval;
-  int i;
-
-  /* Iterate over variables in this group */
-  for (i=0; i < grp->vars.nelems; i++)
-    {
+   NC_VAR_INFO_T *var;
+   NC_GRP_INFO_T *child_grp;
+   int last_dimid = -1;
+   int retval;
+   int i;
+
+   /* Iterate over variables in this group */
+   for (i=0; i < grp->vars.nelems; i++)
+   {
       var = grp->vars.value[i];
       if (!var) continue;
       /* Only matters for dimension scale variables, with non-scalar dimensionality */
       if (var->dimscale && var->ndims)
-        {
-          /* If the user writes coord vars in a different order then he
-           * defined their dimensions, then, when the file is reopened, the
-           * order of the dimids will change to match the order of the coord
-           * vars. Detect if this is about to happen. */
-          if (var->dimids[0] < last_dimid)
-            {
-              LOG((5, "%s: %s is out of order coord var", __func__, var->name));
-              *bad_coord_orderp = NC_TRUE;
-              return NC_NOERR;
-            }
-          last_dimid = var->dimids[0];
-
-          /* If there are multidimensional coordinate variables defined, then
-           * it's also necessary to preserve dimension IDs when the file is
-           * reopened ... */
-          if (var->ndims > 1)
-            {
-              LOG((5, "%s: %s is multidimensional coord var", __func__, var->name));
-              *bad_coord_orderp = NC_TRUE;
-              return NC_NOERR;
-            }
-
-          /* Did the user define a dimension, end define mode, reenter define
-           * mode, and then define a coordinate variable for that dimension?
-           * If so, dimensions will be out of order. */
-          if (var->is_new_var || var->became_coord_var)
-            {
-              LOG((5, "%s: coord var defined after enddef/redef", __func__));
-              *bad_coord_orderp = NC_TRUE;
-              return NC_NOERR;
-            }
-        }
-    }
+      {
+         /* If the user writes coord vars in a different order then he
+          * defined their dimensions, then, when the file is reopened, the
+          * order of the dimids will change to match the order of the coord
+          * vars. Detect if this is about to happen. */
+         if (var->dimids[0] < last_dimid)
+         {
+            LOG((5, "%s: %s is out of order coord var", __func__, var->name));
+            *bad_coord_orderp = NC_TRUE;
+            return NC_NOERR;
+         }
+         last_dimid = var->dimids[0];
+
+         /* If there are multidimensional coordinate variables defined, then
+          * it's also necessary to preserve dimension IDs when the file is
+          * reopened ... */
+         if (var->ndims > 1)
+         {
+            LOG((5, "%s: %s is multidimensional coord var", __func__, var->name));
+            *bad_coord_orderp = NC_TRUE;
+            return NC_NOERR;
+         }
+
+         /* Did the user define a dimension, end define mode, reenter define
+          * mode, and then define a coordinate variable for that dimension?
+          * If so, dimensions will be out of order. */
+         if (var->is_new_var || var->became_coord_var)
+         {
+            LOG((5, "%s: coord var defined after enddef/redef", __func__));
+            *bad_coord_orderp = NC_TRUE;
+            return NC_NOERR;
+         }
+      }
+   }
 
-  /* If there are any child groups, check them also for this condition. */
-  for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
-    if ((retval = nc4_rec_detect_need_to_preserve_dimids(child_grp, bad_coord_orderp)))
-      return retval;
+   /* If there are any child groups, check them also for this condition. */
+   for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
+      if ((retval = nc4_rec_detect_need_to_preserve_dimids(child_grp, bad_coord_orderp)))
+         return retval;
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
-
-/* Recursively write all the metadata in a group. Groups and types
- * have all already been written.  Propagate bad cooordinate order to
- * subgroups, if detected. */
+/**
+ * @internal Recursively write all the metadata in a group. Groups and
+ * types have all already been written. Propagate bad cooordinate
+ * order to subgroups, if detected.
+ *
+ * @param grp Pointer to group info struct.
+ * @param bad_coord_order 1 if there is a bad coordinate order.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 int
 nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
 {
-  NC_DIM_INFO_T *dim = NULL;
-  NC_VAR_INFO_T *var = NULL;
-  NC_GRP_INFO_T *child_grp = NULL;
-  int coord_varid = -1;
-  int var_index = 0;
-
-  int retval;
-  assert(grp && grp->name && grp->hdf_grpid);
-  LOG((3, "%s: grp->name %s, bad_coord_order %d", __func__, grp->name, bad_coord_order));
-
-  /* Write global attributes for this group. */
-  if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
-    return retval;
-  /* Set the pointers to the beginning of the list of dims & vars in this
-   * group. */
-  dim = grp->dim;
-  if (var_index < grp->vars.nelems)
-    var = grp->vars.value[var_index];
-
-  /* Because of HDF5 ordering the dims and vars have to be stored in
-   * this way to ensure that the dims and coordinate vars come out in
-   * the correct order. */
-  while (dim || var)
-    {
+   NC_DIM_INFO_T *dim = NULL;
+   NC_VAR_INFO_T *var = NULL;
+   NC_GRP_INFO_T *child_grp = NULL;
+   int coord_varid = -1;
+   int var_index = 0;
+
+   int retval;
+   assert(grp && grp->name && grp->hdf_grpid);
+   LOG((3, "%s: grp->name %s, bad_coord_order %d", __func__, grp->name, bad_coord_order));
+
+   /* Write global attributes for this group. */
+   if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
+      return retval;
+   /* Set the pointers to the beginning of the list of dims & vars in this
+    * group. */
+   dim = grp->dim;
+   if (var_index < grp->vars.nelems)
+      var = grp->vars.value[var_index];
+
+   /* Because of HDF5 ordering the dims and vars have to be stored in
+    * this way to ensure that the dims and coordinate vars come out in
+    * the correct order. */
+   while (dim || var)
+   {
       nc_bool_t found_coord, wrote_coord;
 
       /* Write non-coord dims in order, stopping at the first one that
        * has an associated coord var. */
       for (found_coord = NC_FALSE; dim && !found_coord; dim = dim->l.next)
-        {
-          if (!dim->coord_var)
-            {
-              if ((retval = write_dim(dim, grp, bad_coord_order)))
-                return retval;
-            }
-          else
-            {
-              coord_varid = dim->coord_var->varid;
-              found_coord = NC_TRUE;
-            }
-        }
+      {
+         if (!dim->coord_var)
+         {
+            if ((retval = write_dim(dim, grp, bad_coord_order)))
+               return retval;
+         }
+         else
+         {
+            coord_varid = dim->coord_var->varid;
+            found_coord = NC_TRUE;
+         }
+      }
 
       /* Write each var. When we get to the coord var we are waiting
        * for (if any), then we break after writing it. */
       for (wrote_coord = NC_FALSE; var && !wrote_coord; )
-        {
-          if ((retval = write_var(var, grp, bad_coord_order)))
+      {
+         if ((retval = write_var(var, grp, bad_coord_order)))
             return retval;
-          if (found_coord && var->varid == coord_varid)
+         if (found_coord && var->varid == coord_varid)
             wrote_coord = NC_TRUE;
-	  if (++var_index < grp->vars.nelems)
-	    var = grp->vars.value[var_index];
-	  else
-	    var = NULL;
-        }
-    } /* end while */
-
-  if ((retval = attach_dimscales(grp)))
-    return retval;
-
-  /* If there are any child groups, write their metadata. */
-  for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
-    if ((retval = nc4_rec_write_metadata(child_grp, bad_coord_order)))
+         if (++var_index < grp->vars.nelems)
+            var = grp->vars.value[var_index];
+         else
+            var = NULL;
+      }
+   } /* end while */
+
+   if ((retval = attach_dimscales(grp)))
       return retval;
 
-  return NC_NOERR;
+   /* If there are any child groups, write their metadata. */
+   for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
+      if ((retval = nc4_rec_write_metadata(child_grp, bad_coord_order)))
+         return retval;
+
+   return NC_NOERR;
 }
 
-/* Recursively write all groups and types. */
+/**
+ * @internal Recursively write all groups and types. 
+ *
+ * @param grp Pointer to group info struct.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 int
 nc4_rec_write_groups_types(NC_GRP_INFO_T *grp)
 {
-  NC_GRP_INFO_T *child_grp;
-  NC_TYPE_INFO_T *type;
-  int retval;
-
-  assert(grp && grp->name);
-  LOG((3, "%s: grp->name %s", __func__, grp->name));
-
-  /* Create the group in the HDF5 file if it doesn't exist. */
-  if (!grp->hdf_grpid)
-    if ((retval = create_group(grp)))
-      return retval;
-
-  /* If this is the root group of a file with strict NC3 rules, write
-   * an attribute. But don't leave the attribute open. */
-  if (!grp->parent && (grp->nc4_info->cmode & NC_CLASSIC_MODEL))
-    if ((retval = write_nc3_strict_att(grp->hdf_grpid)))
-      return retval;
-
-  /* If there are any user-defined types, write them now. */
-  for (type = grp->type; type; type = type->l.next)
-    if ((retval = commit_type(grp, type)))
-      return retval;
-
-  /* If there are any child groups, write their groups and types. */
-  for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
-    if ((retval = nc4_rec_write_groups_types(child_grp)))
-      return retval;
-
-  return NC_NOERR;
+   NC_GRP_INFO_T *child_grp;
+   NC_TYPE_INFO_T *type;
+   int retval;
+
+   assert(grp && grp->name);
+   LOG((3, "%s: grp->name %s", __func__, grp->name));
+
+   /* Create the group in the HDF5 file if it doesn't exist. */
+   if (!grp->hdf_grpid)
+      if ((retval = create_group(grp)))
+         return retval;
+
+   /* If this is the root group of a file with strict NC3 rules, write
+    * an attribute. But don't leave the attribute open. */
+   if (!grp->parent && (grp->nc4_info->cmode & NC_CLASSIC_MODEL))
+      if ((retval = write_nc3_strict_att(grp->hdf_grpid)))
+         return retval;
+
+   /* If there are any user-defined types, write them now. */
+   for (type = grp->type; type; type = type->l.next)
+      if ((retval = commit_type(grp, type)))
+         return retval;
+
+   /* If there are any child groups, write their groups and types. */
+   for (child_grp = grp->children; child_grp; child_grp = child_grp->l.next)
+      if ((retval = nc4_rec_write_groups_types(child_grp)))
+         return retval;
+
+   return NC_NOERR;
 }
 
-/*! Copy data from one buffer to another, performing appropriate data conversion.
-
-  This function will copy data from one buffer to another, in
-  accordance with the types. Range errors will be noted, and the fill
-  value used (or the default fill value if none is supplied) for
-  values that overflow the type.
-
-  I should be able to take this out when HDF5 does the right thing
-  with data type conversion.
-
-  Ed Hartnett, 11/15/3
+/**
+ * @internal Copy data from one buffer to another, performing
+ * appropriate data conversion.
+ *
+ * This function will copy data from one buffer to another, in
+ * accordance with the types. Range errors will be noted, and the fill
+ * value used (or the default fill value if none is supplied) for
+ * values that overflow the type.
+ *
+ * @note I should be able to take this out when HDF5 does the right thing
+ * with data type conversion. Ed Hartnett, 11/15/3
+ *
+ * @param src Pointer to source of data.
+ * @param dest Pointer that gets data.
+ * @param src_type Type ID of source data.
+ * @param dest_type Type ID of destination data.
+ * @param len Number of elements of data to copy.
+ * @param range_error Pointer that gets 1 if there was a range error.
+ * @param fill_value The fill value.
+ * @param strict_nc3 Non-zero if strict model in effect.
+ * @param src_long Is the source NC_LONG?
+ * @param dest_long Is the destination NC_LONG?
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EBADTYPE Type not found.
+ * @author Ed Hartnett
 */
 int
 nc4_convert_type(const void *src, void *dest,
@@ -2696,985 +2880,994 @@ nc4_convert_type(const void *src, void *dest,
                  const void *fill_value, int strict_nc3, int src_long,
                  int dest_long)
 {
-  char *cp, *cp1;
-  float *fp, *fp1;
-  double *dp, *dp1;
-  int *ip, *ip1;
-  signed long *lp, *lp1;
-  short *sp, *sp1;
-  signed char *bp, *bp1;
-  unsigned char *ubp, *ubp1;
-  unsigned short *usp, *usp1;
-  unsigned int *uip, *uip1;
-  long long *lip, *lip1;
-  unsigned long long *ulip, *ulip1;
-  size_t count = 0;
-
-  *range_error = 0;
-  LOG((3, "%s: len %d src_type %d dest_type %d src_long %d dest_long %d",
-       __func__, len, src_type, dest_type, src_long, dest_long));
-
-  /* OK, this is ugly. If you can think of anything better, I'm open
-     to suggestions!
-
-     Note that we don't use a default fill value for type
-     NC_BYTE. This is because Lord Voldemort cast a nofilleramous spell
-     at Harry Potter, but it bounced off his scar and hit the netcdf-4
-     code.
-  */
-  switch (src_type)
-    {
-    case NC_CHAR:
+   char *cp, *cp1;
+   float *fp, *fp1;
+   double *dp, *dp1;
+   int *ip, *ip1;
+   signed long *lp, *lp1;
+   short *sp, *sp1;
+   signed char *bp, *bp1;
+   unsigned char *ubp, *ubp1;
+   unsigned short *usp, *usp1;
+   unsigned int *uip, *uip1;
+   long long *lip, *lip1;
+   unsigned long long *ulip, *ulip1;
+   size_t count = 0;
+
+   *range_error = 0;
+   LOG((3, "%s: len %d src_type %d dest_type %d src_long %d dest_long %d",
+        __func__, len, src_type, dest_type, src_long, dest_long));
+
+   /* OK, this is ugly. If you can think of anything better, I'm open
+      to suggestions!
+
+      Note that we don't use a default fill value for type
+      NC_BYTE. This is because Lord Voldemort cast a nofilleramous spell
+      at Harry Potter, but it bounced off his scar and hit the netcdf-4
+      code.
+   */
+   switch (src_type)
+   {
+   case NC_CHAR:
       switch (dest_type)
-        {
-        case NC_CHAR:
-          for (cp = (char *)src, cp1 = dest; count < len; count++)
+      {
+      case NC_CHAR:
+         for (cp = (char *)src, cp1 = dest; count < len; count++)
             *cp1++ = *cp++;
-          break;
-        default:
-          LOG((0, "%s: Uknown destination type.", __func__));
-        }
+         break;
+      default:
+         LOG((0, "%s: Uknown destination type.", __func__));
+      }
       break;
 
-    case NC_BYTE:
+   case NC_BYTE:
       switch (dest_type)
-        {
-        case NC_BYTE:
-          for (bp = (signed char *)src, bp1 = dest; count < len; count++)
+      {
+      case NC_BYTE:
+         for (bp = (signed char *)src, bp1 = dest; count < len; count++)
             *bp1++ = *bp++;
-          break;
-        case NC_UBYTE:
-          for (bp = (signed char *)src, ubp = dest; count < len; count++)
-            {
-              if (*bp < 0)
-                (*range_error)++;
-              *ubp++ = *bp++;
-            }
-          break;
-        case NC_SHORT:
-          for (bp = (signed char *)src, sp = dest; count < len; count++)
+         break;
+      case NC_UBYTE:
+         for (bp = (signed char *)src, ubp = dest; count < len; count++)
+         {
+            if (*bp < 0)
+               (*range_error)++;
+            *ubp++ = *bp++;
+         }
+         break;
+      case NC_SHORT:
+         for (bp = (signed char *)src, sp = dest; count < len; count++)
             *sp++ = *bp++;
-          break;
-        case NC_USHORT:
-          for (bp = (signed char *)src, usp = dest; count < len; count++)
-            {
-              if (*bp < 0)
-                (*range_error)++;
-              *usp++ = *bp++;
-            }
-          break;
-        case NC_INT:
-          if (dest_long)
-            {
-              for (bp = (signed char *)src, lp = dest; count < len; count++)
-                *lp++ = *bp++;
-              break;
-            }
-          else
-            {
-              for (bp = (signed char *)src, ip = dest; count < len; count++)
-                *ip++ = *bp++;
-              break;
-            }
-        case NC_UINT:
-          for (bp = (signed char *)src, uip = dest; count < len; count++)
-            {
-              if (*bp < 0)
-                (*range_error)++;
-              *uip++ = *bp++;
-            }
-          break;
-        case NC_INT64:
-          for (bp = (signed char *)src, lip = dest; count < len; count++)
+         break;
+      case NC_USHORT:
+         for (bp = (signed char *)src, usp = dest; count < len; count++)
+         {
+            if (*bp < 0)
+               (*range_error)++;
+            *usp++ = *bp++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
+         {
+            for (bp = (signed char *)src, lp = dest; count < len; count++)
+               *lp++ = *bp++;
+            break;
+         }
+         else
+         {
+            for (bp = (signed char *)src, ip = dest; count < len; count++)
+               *ip++ = *bp++;
+            break;
+         }
+      case NC_UINT:
+         for (bp = (signed char *)src, uip = dest; count < len; count++)
+         {
+            if (*bp < 0)
+               (*range_error)++;
+            *uip++ = *bp++;
+         }
+         break;
+      case NC_INT64:
+         for (bp = (signed char *)src, lip = dest; count < len; count++)
             *lip++ = *bp++;
-          break;
-        case NC_UINT64:
-          for (bp = (signed char *)src, ulip = dest; count < len; count++)
-            {
-              if (*bp < 0)
-                (*range_error)++;
-              *ulip++ = *bp++;
-            }
-          break;
-        case NC_FLOAT:
-          for (bp = (signed char *)src, fp = dest; count < len; count++)
+         break;
+      case NC_UINT64:
+         for (bp = (signed char *)src, ulip = dest; count < len; count++)
+         {
+            if (*bp < 0)
+               (*range_error)++;
+            *ulip++ = *bp++;
+         }
+         break;
+      case NC_FLOAT:
+         for (bp = (signed char *)src, fp = dest; count < len; count++)
             *fp++ = *bp++;
-          break;
-        case NC_DOUBLE:
-          for (bp = (signed char *)src, dp = dest; count < len; count++)
+         break;
+      case NC_DOUBLE:
+         for (bp = (signed char *)src, dp = dest; count < len; count++)
             *dp++ = *bp++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    case NC_UBYTE:
+   case NC_UBYTE:
       switch (dest_type)
-        {
-        case NC_BYTE:
-          for (ubp = (unsigned char *)src, bp = dest; count < len; count++)
-            {
-              if (!strict_nc3 && *ubp > X_SCHAR_MAX)
-                (*range_error)++;
-              *bp++ = *ubp++;
-            }
-          break;
-        case NC_SHORT:
-          for (ubp = (unsigned char *)src, sp = dest; count < len; count++)
+      {
+      case NC_BYTE:
+         for (ubp = (unsigned char *)src, bp = dest; count < len; count++)
+         {
+            if (!strict_nc3 && *ubp > X_SCHAR_MAX)
+               (*range_error)++;
+            *bp++ = *ubp++;
+         }
+         break;
+      case NC_SHORT:
+         for (ubp = (unsigned char *)src, sp = dest; count < len; count++)
             *sp++ = *ubp++;
-          break;
-        case NC_UBYTE:
-          for (ubp = (unsigned char *)src, ubp1 = dest; count < len; count++)
+         break;
+      case NC_UBYTE:
+         for (ubp = (unsigned char *)src, ubp1 = dest; count < len; count++)
             *ubp1++ = *ubp++;
-          break;
-        case NC_USHORT:
-          for (ubp = (unsigned char *)src, usp = dest; count < len; count++)
+         break;
+      case NC_USHORT:
+         for (ubp = (unsigned char *)src, usp = dest; count < len; count++)
             *usp++ = *ubp++;
-          break;
-        case NC_INT:
-          if (dest_long)
-            {
-              for (ubp = (unsigned char *)src, lp = dest; count < len; count++)
-                *lp++ = *ubp++;
-              break;
-            }
-          else
-            {
-              for (ubp = (unsigned char *)src, ip = dest; count < len; count++)
-                *ip++ = *ubp++;
-              break;
-            }
-        case NC_UINT:
-          for (ubp = (unsigned char *)src, uip = dest; count < len; count++)
+         break;
+      case NC_INT:
+         if (dest_long)
+         {
+            for (ubp = (unsigned char *)src, lp = dest; count < len; count++)
+               *lp++ = *ubp++;
+            break;
+         }
+         else
+         {
+            for (ubp = (unsigned char *)src, ip = dest; count < len; count++)
+               *ip++ = *ubp++;
+            break;
+         }
+      case NC_UINT:
+         for (ubp = (unsigned char *)src, uip = dest; count < len; count++)
             *uip++ = *ubp++;
-          break;
-        case NC_INT64:
-          for (ubp = (unsigned char *)src, lip = dest; count < len; count++)
+         break;
+      case NC_INT64:
+         for (ubp = (unsigned char *)src, lip = dest; count < len; count++)
             *lip++ = *ubp++;
-          break;
-        case NC_UINT64:
-          for (ubp = (unsigned char *)src, ulip = dest; count < len; count++)
+         break;
+      case NC_UINT64:
+         for (ubp = (unsigned char *)src, ulip = dest; count < len; count++)
             *ulip++ = *ubp++;
-          break;
-        case NC_FLOAT:
-          for (ubp = (unsigned char *)src, fp = dest; count < len; count++)
+         break;
+      case NC_FLOAT:
+         for (ubp = (unsigned char *)src, fp = dest; count < len; count++)
             *fp++ = *ubp++;
-          break;
-        case NC_DOUBLE:
-          for (ubp = (unsigned char *)src, dp = dest; count < len; count++)
+         break;
+      case NC_DOUBLE:
+         for (ubp = (unsigned char *)src, dp = dest; count < len; count++)
             *dp++ = *ubp++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    case NC_SHORT:
+   case NC_SHORT:
       switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (sp = (short *)src, ubp = dest; count < len; count++)
-            {
-              if (*sp > X_UCHAR_MAX || *sp < 0)
-                (*range_error)++;
-              *ubp++ = *sp++;
-            }
-          break;
-        case NC_BYTE:
-          for (sp = (short *)src, bp = dest; count < len; count++)
-            {
-              if (*sp > X_SCHAR_MAX || *sp < X_SCHAR_MIN)
-                (*range_error)++;
-              *bp++ = *sp++;
-            }
-          break;
-        case NC_SHORT:
-          for (sp = (short *)src, sp1 = dest; count < len; count++)
+      {
+      case NC_UBYTE:
+         for (sp = (short *)src, ubp = dest; count < len; count++)
+         {
+            if (*sp > X_UCHAR_MAX || *sp < 0)
+               (*range_error)++;
+            *ubp++ = *sp++;
+         }
+         break;
+      case NC_BYTE:
+         for (sp = (short *)src, bp = dest; count < len; count++)
+         {
+            if (*sp > X_SCHAR_MAX || *sp < X_SCHAR_MIN)
+               (*range_error)++;
+            *bp++ = *sp++;
+         }
+         break;
+      case NC_SHORT:
+         for (sp = (short *)src, sp1 = dest; count < len; count++)
             *sp1++ = *sp++;
-          break;
-        case NC_USHORT:
-          for (sp = (short *)src, usp = dest; count < len; count++)
-            {
-              if (*sp < 0)
-                (*range_error)++;
-              *usp++ = *sp++;
-            }
-          break;
-        case NC_INT:
-          if (dest_long)
+         break;
+      case NC_USHORT:
+         for (sp = (short *)src, usp = dest; count < len; count++)
+         {
+            if (*sp < 0)
+               (*range_error)++;
+            *usp++ = *sp++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
             for (sp = (short *)src, lp = dest; count < len; count++)
-              *lp++ = *sp++;
-          else
+               *lp++ = *sp++;
+         else
             for (sp = (short *)src, ip = dest; count < len; count++)
-              *ip++ = *sp++;
-          break;
-        case NC_UINT:
-          for (sp = (short *)src, uip = dest; count < len; count++)
-            {
-              if (*sp < 0)
-                (*range_error)++;
-              *uip++ = *sp++;
-            }
-          break;
-        case NC_INT64:
-          for (sp = (short *)src, lip = dest; count < len; count++)
+               *ip++ = *sp++;
+         break;
+      case NC_UINT:
+         for (sp = (short *)src, uip = dest; count < len; count++)
+         {
+            if (*sp < 0)
+               (*range_error)++;
+            *uip++ = *sp++;
+         }
+         break;
+      case NC_INT64:
+         for (sp = (short *)src, lip = dest; count < len; count++)
             *lip++ = *sp++;
-          break;
-        case NC_UINT64:
-          for (sp = (short *)src, ulip = dest; count < len; count++)
-            {
-              if (*sp < 0)
-                (*range_error)++;
-              *ulip++ = *sp++;
-            }
-          break;
-        case NC_FLOAT:
-          for (sp = (short *)src, fp = dest; count < len; count++)
+         break;
+      case NC_UINT64:
+         for (sp = (short *)src, ulip = dest; count < len; count++)
+         {
+            if (*sp < 0)
+               (*range_error)++;
+            *ulip++ = *sp++;
+         }
+         break;
+      case NC_FLOAT:
+         for (sp = (short *)src, fp = dest; count < len; count++)
             *fp++ = *sp++;
-          break;
-        case NC_DOUBLE:
-          for (sp = (short *)src, dp = dest; count < len; count++)
+         break;
+      case NC_DOUBLE:
+         for (sp = (short *)src, dp = dest; count < len; count++)
             *dp++ = *sp++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    case NC_USHORT:
+   case NC_USHORT:
       switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (usp = (unsigned short *)src, ubp = dest; count < len; count++)
-            {
-              if (*usp > X_UCHAR_MAX)
-                (*range_error)++;
-              *ubp++ = *usp++;
-            }
-          break;
-        case NC_BYTE:
-          for (usp = (unsigned short *)src, bp = dest; count < len; count++)
-            {
-              if (*usp > X_SCHAR_MAX)
-                (*range_error)++;
-              *bp++ = *usp++;
-            }
-          break;
-        case NC_SHORT:
-          for (usp = (unsigned short *)src, sp = dest; count < len; count++)
-            {
-              if (*usp > X_SHORT_MAX)
-                (*range_error)++;
-              *sp++ = *usp++;
-            }
-          break;
-        case NC_USHORT:
-          for (usp = (unsigned short *)src, usp1 = dest; count < len; count++)
+      {
+      case NC_UBYTE:
+         for (usp = (unsigned short *)src, ubp = dest; count < len; count++)
+         {
+            if (*usp > X_UCHAR_MAX)
+               (*range_error)++;
+            *ubp++ = *usp++;
+         }
+         break;
+      case NC_BYTE:
+         for (usp = (unsigned short *)src, bp = dest; count < len; count++)
+         {
+            if (*usp > X_SCHAR_MAX)
+               (*range_error)++;
+            *bp++ = *usp++;
+         }
+         break;
+      case NC_SHORT:
+         for (usp = (unsigned short *)src, sp = dest; count < len; count++)
+         {
+            if (*usp > X_SHORT_MAX)
+               (*range_error)++;
+            *sp++ = *usp++;
+         }
+         break;
+      case NC_USHORT:
+         for (usp = (unsigned short *)src, usp1 = dest; count < len; count++)
             *usp1++ = *usp++;
-          break;
-        case NC_INT:
-          if (dest_long)
+         break;
+      case NC_INT:
+         if (dest_long)
             for (usp = (unsigned short *)src, lp = dest; count < len; count++)
-              *lp++ = *usp++;
-          else
+               *lp++ = *usp++;
+         else
             for (usp = (unsigned short *)src, ip = dest; count < len; count++)
-              *ip++ = *usp++;
-          break;
-        case NC_UINT:
-          for (usp = (unsigned short *)src, uip = dest; count < len; count++)
+               *ip++ = *usp++;
+         break;
+      case NC_UINT:
+         for (usp = (unsigned short *)src, uip = dest; count < len; count++)
             *uip++ = *usp++;
-          break;
-        case NC_INT64:
-          for (usp = (unsigned short *)src, lip = dest; count < len; count++)
+         break;
+      case NC_INT64:
+         for (usp = (unsigned short *)src, lip = dest; count < len; count++)
             *lip++ = *usp++;
-          break;
-        case NC_UINT64:
-          for (usp = (unsigned short *)src, ulip = dest; count < len; count++)
+         break;
+      case NC_UINT64:
+         for (usp = (unsigned short *)src, ulip = dest; count < len; count++)
             *ulip++ = *usp++;
-          break;
-        case NC_FLOAT:
-          for (usp = (unsigned short *)src, fp = dest; count < len; count++)
+         break;
+      case NC_FLOAT:
+         for (usp = (unsigned short *)src, fp = dest; count < len; count++)
             *fp++ = *usp++;
-          break;
-        case NC_DOUBLE:
-          for (usp = (unsigned short *)src, dp = dest; count < len; count++)
+         break;
+      case NC_DOUBLE:
+         for (usp = (unsigned short *)src, dp = dest; count < len; count++)
             *dp++ = *usp++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    case NC_INT:
+   case NC_INT:
       if (src_long)
-        {
-          switch (dest_type)
+      {
+         switch (dest_type)
+         {
+         case NC_UBYTE:
+            for (lp = (long *)src, ubp = dest; count < len; count++)
             {
-            case NC_UBYTE:
-              for (lp = (long *)src, ubp = dest; count < len; count++)
-                {
-                  if (*lp > X_UCHAR_MAX || *lp < 0)
-                    (*range_error)++;
-                  *ubp++ = *lp++;
-                }
-              break;
-            case NC_BYTE:
-              for (lp = (long *)src, bp = dest; count < len; count++)
-                {
-                  if (*lp > X_SCHAR_MAX || *lp < X_SCHAR_MIN)
-                    (*range_error)++;
-                  *bp++ = *lp++;
-                }
-              break;
-            case NC_SHORT:
-              for (lp = (long *)src, sp = dest; count < len; count++)
-                {
-                  if (*lp > X_SHORT_MAX || *lp < X_SHORT_MIN)
-                    (*range_error)++;
-                  *sp++ = *lp++;
-                }
-              break;
-            case NC_USHORT:
-              for (lp = (long *)src, usp = dest; count < len; count++)
-                {
-                  if (*lp > X_USHORT_MAX || *lp < 0)
-                    (*range_error)++;
-                  *usp++ = *lp++;
-                }
-              break;
-            case NC_INT: /* src is long */
-              if (dest_long)
-                {
-                  for (lp = (long *)src, lp1 = dest; count < len; count++)
-                    {
-                      if (*lp > X_LONG_MAX || *lp < X_LONG_MIN)
-                        (*range_error)++;
-                      *lp1++ = *lp++;
-                    }
-                }
-              else /* dest is int */
-                {
-                  for (lp = (long *)src, ip = dest; count < len; count++)
-                    {
-                      if (*lp > X_INT_MAX || *lp < X_INT_MIN)
-                        (*range_error)++;
-                      *ip++ = *lp++;
-                    }
-                }
-              break;
-            case NC_UINT:
-              for (lp = (long *)src, uip = dest; count < len; count++)
-                {
-                  if (*lp > X_UINT_MAX || *lp < 0)
-                    (*range_error)++;
-                  *uip++ = *lp++;
-                }
-              break;
-            case NC_INT64:
-              for (lp = (long *)src, lip = dest; count < len; count++)
-                *lip++ = *lp++;
-              break;
-            case NC_UINT64:
-              for (lp = (long *)src, ulip = dest; count < len; count++)
-                {
-                  if (*lp < 0)
-                    (*range_error)++;
-                  *ulip++ = *lp++;
-                }
-              break;
-            case NC_FLOAT:
-              for (lp = (long *)src, fp = dest; count < len; count++)
-                *fp++ = *lp++;
-              break;
-            case NC_DOUBLE:
-              for (lp = (long *)src, dp = dest; count < len; count++)
-                *dp++ = *lp++;
-              break;
-            default:
-              LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-                   __func__, src_type, dest_type));
-              return NC_EBADTYPE;
+               if (*lp > X_UCHAR_MAX || *lp < 0)
+                  (*range_error)++;
+               *ubp++ = *lp++;
             }
-        }
-      else
-        {
-          switch (dest_type)
+            break;
+         case NC_BYTE:
+            for (lp = (long *)src, bp = dest; count < len; count++)
             {
-            case NC_UBYTE:
-              for (ip = (int *)src, ubp = dest; count < len; count++)
-                {
-                  if (*ip > X_UCHAR_MAX || *ip < 0)
-                    (*range_error)++;
-                  *ubp++ = *ip++;
-                }
-              break;
-            case NC_BYTE:
-              for (ip = (int *)src, bp = dest; count < len; count++)
-                {
-                  if (*ip > X_SCHAR_MAX || *ip < X_SCHAR_MIN)
-                    (*range_error)++;
-                  *bp++ = *ip++;
-                }
-              break;
-            case NC_SHORT:
-              for (ip = (int *)src, sp = dest; count < len; count++)
-                {
-                  if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
-                    (*range_error)++;
-                  *sp++ = *ip++;
-                }
-              break;
-            case NC_USHORT:
-              for (ip = (int *)src, usp = dest; count < len; count++)
-                {
-                  if (*ip > X_USHORT_MAX || *ip < 0)
-                    (*range_error)++;
-                  *usp++ = *ip++;
-                }
-              break;
-            case NC_INT: /* src is int */
-              if (dest_long)
-                {
-                  for (ip = (int *)src, lp1 = dest; count < len; count++)
-                    {
-                      if (*ip > X_LONG_MAX || *ip < X_LONG_MIN)
-                        (*range_error)++;
-                      *lp1++ = *ip++;
-                    }
-                }
-              else /* dest is int */
-                {
-                  for (ip = (int *)src, ip1 = dest; count < len; count++)
-                    {
-                      if (*ip > X_INT_MAX || *ip < X_INT_MIN)
-                        (*range_error)++;
-                      *ip1++ = *ip++;
-                    }
-                }
-              break;
-            case NC_UINT:
-              for (ip = (int *)src, uip = dest; count < len; count++)
-                {
-                  if (*ip > X_UINT_MAX || *ip < 0)
-                    (*range_error)++;
-                  *uip++ = *ip++;
-                }
-              break;
-            case NC_INT64:
-              for (ip = (int *)src, lip = dest; count < len; count++)
-                *lip++ = *ip++;
-              break;
-            case NC_UINT64:
-              for (ip = (int *)src, ulip = dest; count < len; count++)
-                {
-                  if (*ip < 0)
-                    (*range_error)++;
-                  *ulip++ = *ip++;
-                }
-              break;
-            case NC_FLOAT:
-              for (ip = (int *)src, fp = dest; count < len; count++)
-                *fp++ = *ip++;
-              break;
-            case NC_DOUBLE:
-              for (ip = (int *)src, dp = dest; count < len; count++)
-                *dp++ = *ip++;
-              break;
-            default:
-              LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-                   __func__, src_type, dest_type));
-              return NC_EBADTYPE;
+               if (*lp > X_SCHAR_MAX || *lp < X_SCHAR_MIN)
+                  (*range_error)++;
+               *bp++ = *lp++;
             }
-        }
-      break;
-
-    case NC_UINT:
-      switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (uip = (unsigned int *)src, ubp = dest; count < len; count++)
+            break;
+         case NC_SHORT:
+            for (lp = (long *)src, sp = dest; count < len; count++)
             {
-              if (*uip > X_UCHAR_MAX)
-                (*range_error)++;
-              *ubp++ = *uip++;
+               if (*lp > X_SHORT_MAX || *lp < X_SHORT_MIN)
+                  (*range_error)++;
+               *sp++ = *lp++;
             }
-          break;
-        case NC_BYTE:
-          for (uip = (unsigned int *)src, bp = dest; count < len; count++)
+            break;
+         case NC_USHORT:
+            for (lp = (long *)src, usp = dest; count < len; count++)
             {
-              if (*uip > X_SCHAR_MAX)
-                (*range_error)++;
-              *bp++ = *uip++;
+               if (*lp > X_USHORT_MAX || *lp < 0)
+                  (*range_error)++;
+               *usp++ = *lp++;
             }
-          break;
-        case NC_SHORT:
-          for (uip = (unsigned int *)src, sp = dest; count < len; count++)
+            break;
+         case NC_INT: /* src is long */
+            if (dest_long)
             {
-              if (*uip > X_SHORT_MAX)
-                (*range_error)++;
-              *sp++ = *uip++;
+               for (lp = (long *)src, lp1 = dest; count < len; count++)
+               {
+                  if (*lp > X_LONG_MAX || *lp < X_LONG_MIN)
+                     (*range_error)++;
+                  *lp1++ = *lp++;
+               }
             }
-          break;
-        case NC_USHORT:
-          for (uip = (unsigned int *)src, usp = dest; count < len; count++)
+            else /* dest is int */
             {
-              if (*uip > X_USHORT_MAX)
-                (*range_error)++;
-              *usp++ = *uip++;
+               for (lp = (long *)src, ip = dest; count < len; count++)
+               {
+                  if (*lp > X_INT_MAX || *lp < X_INT_MIN)
+                     (*range_error)++;
+                  *ip++ = *lp++;
+               }
             }
-          break;
-        case NC_INT:
-          if (dest_long)
-            for (uip = (unsigned int *)src, lp = dest; count < len; count++)
-              {
-                if (*uip > X_LONG_MAX)
+            break;
+         case NC_UINT:
+            for (lp = (long *)src, uip = dest; count < len; count++)
+            {
+               if (*lp > X_UINT_MAX || *lp < 0)
                   (*range_error)++;
-                *lp++ = *uip++;
-              }
-          else
-            for (uip = (unsigned int *)src, ip = dest; count < len; count++)
-              {
-                if (*uip > X_INT_MAX)
+               *uip++ = *lp++;
+            }
+            break;
+         case NC_INT64:
+            for (lp = (long *)src, lip = dest; count < len; count++)
+               *lip++ = *lp++;
+            break;
+         case NC_UINT64:
+            for (lp = (long *)src, ulip = dest; count < len; count++)
+            {
+               if (*lp < 0)
                   (*range_error)++;
-                *ip++ = *uip++;
-              }
-          break;
-        case NC_UINT:
-          for (uip = (unsigned int *)src, uip1 = dest; count < len; count++)
+               *ulip++ = *lp++;
+            }
+            break;
+         case NC_FLOAT:
+            for (lp = (long *)src, fp = dest; count < len; count++)
+               *fp++ = *lp++;
+            break;
+         case NC_DOUBLE:
+            for (lp = (long *)src, dp = dest; count < len; count++)
+               *dp++ = *lp++;
+            break;
+         default:
+            LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+                 __func__, src_type, dest_type));
+            return NC_EBADTYPE;
+         }
+      }
+      else
+      {
+         switch (dest_type)
+         {
+         case NC_UBYTE:
+            for (ip = (int *)src, ubp = dest; count < len; count++)
             {
-              if (*uip > X_UINT_MAX)
-                (*range_error)++;
-              *uip1++ = *uip++;
+               if (*ip > X_UCHAR_MAX || *ip < 0)
+                  (*range_error)++;
+               *ubp++ = *ip++;
             }
-          break;
-        case NC_INT64:
-          for (uip = (unsigned int *)src, lip = dest; count < len; count++)
-            *lip++ = *uip++;
-          break;
-        case NC_UINT64:
-          for (uip = (unsigned int *)src, ulip = dest; count < len; count++)
-            *ulip++ = *uip++;
-          break;
-        case NC_FLOAT:
-          for (uip = (unsigned int *)src, fp = dest; count < len; count++)
-            *fp++ = *uip++;
-          break;
-        case NC_DOUBLE:
-          for (uip = (unsigned int *)src, dp = dest; count < len; count++)
-            *dp++ = *uip++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
-      break;
-
-    case NC_INT64:
-      switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (lip = (long long *)src, ubp = dest; count < len; count++)
+            break;
+         case NC_BYTE:
+            for (ip = (int *)src, bp = dest; count < len; count++)
             {
-              if (*lip > X_UCHAR_MAX || *lip < 0)
-                (*range_error)++;
-              *ubp++ = *lip++;
+               if (*ip > X_SCHAR_MAX || *ip < X_SCHAR_MIN)
+                  (*range_error)++;
+               *bp++ = *ip++;
             }
-          break;
-        case NC_BYTE:
-          for (lip = (long long *)src, bp = dest; count < len; count++)
+            break;
+         case NC_SHORT:
+            for (ip = (int *)src, sp = dest; count < len; count++)
             {
-              if (*lip > X_SCHAR_MAX || *lip < X_SCHAR_MIN)
-                (*range_error)++;
-              *bp++ = *lip++;
+               if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
+                  (*range_error)++;
+               *sp++ = *ip++;
             }
-          break;
-        case NC_SHORT:
-          for (lip = (long long *)src, sp = dest; count < len; count++)
+            break;
+         case NC_USHORT:
+            for (ip = (int *)src, usp = dest; count < len; count++)
             {
-              if (*lip > X_SHORT_MAX || *lip < X_SHORT_MIN)
-                (*range_error)++;
-              *sp++ = *lip++;
+               if (*ip > X_USHORT_MAX || *ip < 0)
+                  (*range_error)++;
+               *usp++ = *ip++;
             }
-          break;
-        case NC_USHORT:
-          for (lip = (long long *)src, usp = dest; count < len; count++)
+            break;
+         case NC_INT: /* src is int */
+            if (dest_long)
             {
-              if (*lip > X_USHORT_MAX || *lip < 0)
-                (*range_error)++;
-              *usp++ = *lip++;
+               for (ip = (int *)src, lp1 = dest; count < len; count++)
+               {
+                  if (*ip > X_LONG_MAX || *ip < X_LONG_MIN)
+                     (*range_error)++;
+                  *lp1++ = *ip++;
+               }
             }
-          break;
-        case NC_UINT:
-          for (lip = (long long *)src, uip = dest; count < len; count++)
+            else /* dest is int */
             {
-              if (*lip > X_UINT_MAX || *lip < 0)
-                (*range_error)++;
-              *uip++ = *lip++;
+               for (ip = (int *)src, ip1 = dest; count < len; count++)
+               {
+                  if (*ip > X_INT_MAX || *ip < X_INT_MIN)
+                     (*range_error)++;
+                  *ip1++ = *ip++;
+               }
             }
-          break;
-        case NC_INT:
-          if (dest_long)
-            for (lip = (long long *)src, lp = dest; count < len; count++)
-              {
-                if (*lip > X_LONG_MAX || *lip < X_LONG_MIN)
-                  (*range_error)++;
-                *lp++ = *lip++;
-              }
-          else
-            for (lip = (long long *)src, ip = dest; count < len; count++)
-              {
-                if (*lip > X_INT_MAX || *lip < X_INT_MIN)
+            break;
+         case NC_UINT:
+            for (ip = (int *)src, uip = dest; count < len; count++)
+            {
+               if (*ip > X_UINT_MAX || *ip < 0)
                   (*range_error)++;
-                *ip++ = *lip++;
-              }
-          break;
-        case NC_INT64:
-          for (lip = (long long *)src, lip1 = dest; count < len; count++)
-            *lip1++ = *lip++;
-          break;
-        case NC_UINT64:
-          for (lip = (long long *)src, ulip = dest; count < len; count++)
+               *uip++ = *ip++;
+            }
+            break;
+         case NC_INT64:
+            for (ip = (int *)src, lip = dest; count < len; count++)
+               *lip++ = *ip++;
+            break;
+         case NC_UINT64:
+            for (ip = (int *)src, ulip = dest; count < len; count++)
             {
-              if (*lip < 0)
-                (*range_error)++;
-              *ulip++ = *lip++;
+               if (*ip < 0)
+                  (*range_error)++;
+               *ulip++ = *ip++;
             }
-          break;
-        case NC_FLOAT:
-          for (lip = (long long *)src, fp = dest; count < len; count++)
-            *fp++ = *lip++;
-          break;
-        case NC_DOUBLE:
-          for (lip = (long long *)src, dp = dest; count < len; count++)
-            *dp++ = *lip++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+            break;
+         case NC_FLOAT:
+            for (ip = (int *)src, fp = dest; count < len; count++)
+               *fp++ = *ip++;
+            break;
+         case NC_DOUBLE:
+            for (ip = (int *)src, dp = dest; count < len; count++)
+               *dp++ = *ip++;
+            break;
+         default:
+            LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+                 __func__, src_type, dest_type));
+            return NC_EBADTYPE;
+         }
+      }
       break;
 
-    case NC_UINT64:
+   case NC_UINT:
       switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (ulip = (unsigned long long *)src, ubp = dest; count < len; count++)
-            {
-              if (*ulip > X_UCHAR_MAX)
-                (*range_error)++;
-              *ubp++ = *ulip++;
-            }
-          break;
-        case NC_BYTE:
-          for (ulip = (unsigned long long *)src, bp = dest; count < len; count++)
+      {
+      case NC_UBYTE:
+         for (uip = (unsigned int *)src, ubp = dest; count < len; count++)
+         {
+            if (*uip > X_UCHAR_MAX)
+               (*range_error)++;
+            *ubp++ = *uip++;
+         }
+         break;
+      case NC_BYTE:
+         for (uip = (unsigned int *)src, bp = dest; count < len; count++)
+         {
+            if (*uip > X_SCHAR_MAX)
+               (*range_error)++;
+            *bp++ = *uip++;
+         }
+         break;
+      case NC_SHORT:
+         for (uip = (unsigned int *)src, sp = dest; count < len; count++)
+         {
+            if (*uip > X_SHORT_MAX)
+               (*range_error)++;
+            *sp++ = *uip++;
+         }
+         break;
+      case NC_USHORT:
+         for (uip = (unsigned int *)src, usp = dest; count < len; count++)
+         {
+            if (*uip > X_USHORT_MAX)
+               (*range_error)++;
+            *usp++ = *uip++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
+            for (uip = (unsigned int *)src, lp = dest; count < len; count++)
             {
-              if (*ulip > X_SCHAR_MAX)
-                (*range_error)++;
-              *bp++ = *ulip++;
+               if (*uip > X_LONG_MAX)
+                  (*range_error)++;
+               *lp++ = *uip++;
             }
-          break;
-        case NC_SHORT:
-          for (ulip = (unsigned long long *)src, sp = dest; count < len; count++)
+         else
+            for (uip = (unsigned int *)src, ip = dest; count < len; count++)
             {
-              if (*ulip > X_SHORT_MAX)
-                (*range_error)++;
-              *sp++ = *ulip++;
+               if (*uip > X_INT_MAX)
+                  (*range_error)++;
+               *ip++ = *uip++;
             }
-          break;
-        case NC_USHORT:
-          for (ulip = (unsigned long long *)src, usp = dest; count < len; count++)
+         break;
+      case NC_UINT:
+         for (uip = (unsigned int *)src, uip1 = dest; count < len; count++)
+         {
+            if (*uip > X_UINT_MAX)
+               (*range_error)++;
+            *uip1++ = *uip++;
+         }
+         break;
+      case NC_INT64:
+         for (uip = (unsigned int *)src, lip = dest; count < len; count++)
+            *lip++ = *uip++;
+         break;
+      case NC_UINT64:
+         for (uip = (unsigned int *)src, ulip = dest; count < len; count++)
+            *ulip++ = *uip++;
+         break;
+      case NC_FLOAT:
+         for (uip = (unsigned int *)src, fp = dest; count < len; count++)
+            *fp++ = *uip++;
+         break;
+      case NC_DOUBLE:
+         for (uip = (unsigned int *)src, dp = dest; count < len; count++)
+            *dp++ = *uip++;
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
+      break;
+
+   case NC_INT64:
+      switch (dest_type)
+      {
+      case NC_UBYTE:
+         for (lip = (long long *)src, ubp = dest; count < len; count++)
+         {
+            if (*lip > X_UCHAR_MAX || *lip < 0)
+               (*range_error)++;
+            *ubp++ = *lip++;
+         }
+         break;
+      case NC_BYTE:
+         for (lip = (long long *)src, bp = dest; count < len; count++)
+         {
+            if (*lip > X_SCHAR_MAX || *lip < X_SCHAR_MIN)
+               (*range_error)++;
+            *bp++ = *lip++;
+         }
+         break;
+      case NC_SHORT:
+         for (lip = (long long *)src, sp = dest; count < len; count++)
+         {
+            if (*lip > X_SHORT_MAX || *lip < X_SHORT_MIN)
+               (*range_error)++;
+            *sp++ = *lip++;
+         }
+         break;
+      case NC_USHORT:
+         for (lip = (long long *)src, usp = dest; count < len; count++)
+         {
+            if (*lip > X_USHORT_MAX || *lip < 0)
+               (*range_error)++;
+            *usp++ = *lip++;
+         }
+         break;
+      case NC_UINT:
+         for (lip = (long long *)src, uip = dest; count < len; count++)
+         {
+            if (*lip > X_UINT_MAX || *lip < 0)
+               (*range_error)++;
+            *uip++ = *lip++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
+            for (lip = (long long *)src, lp = dest; count < len; count++)
             {
-              if (*ulip > X_USHORT_MAX)
-                (*range_error)++;
-              *usp++ = *ulip++;
+               if (*lip > X_LONG_MAX || *lip < X_LONG_MIN)
+                  (*range_error)++;
+               *lp++ = *lip++;
             }
-          break;
-        case NC_UINT:
-          for (ulip = (unsigned long long *)src, uip = dest; count < len; count++)
+         else
+            for (lip = (long long *)src, ip = dest; count < len; count++)
             {
-              if (*ulip > X_UINT_MAX)
-                (*range_error)++;
-              *uip++ = *ulip++;
+               if (*lip > X_INT_MAX || *lip < X_INT_MIN)
+                  (*range_error)++;
+               *ip++ = *lip++;
             }
-          break;
-        case NC_INT:
-          if (dest_long)
+         break;
+      case NC_INT64:
+         for (lip = (long long *)src, lip1 = dest; count < len; count++)
+            *lip1++ = *lip++;
+         break;
+      case NC_UINT64:
+         for (lip = (long long *)src, ulip = dest; count < len; count++)
+         {
+            if (*lip < 0)
+               (*range_error)++;
+            *ulip++ = *lip++;
+         }
+         break;
+      case NC_FLOAT:
+         for (lip = (long long *)src, fp = dest; count < len; count++)
+            *fp++ = *lip++;
+         break;
+      case NC_DOUBLE:
+         for (lip = (long long *)src, dp = dest; count < len; count++)
+            *dp++ = *lip++;
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
+      break;
+
+   case NC_UINT64:
+      switch (dest_type)
+      {
+      case NC_UBYTE:
+         for (ulip = (unsigned long long *)src, ubp = dest; count < len; count++)
+         {
+            if (*ulip > X_UCHAR_MAX)
+               (*range_error)++;
+            *ubp++ = *ulip++;
+         }
+         break;
+      case NC_BYTE:
+         for (ulip = (unsigned long long *)src, bp = dest; count < len; count++)
+         {
+            if (*ulip > X_SCHAR_MAX)
+               (*range_error)++;
+            *bp++ = *ulip++;
+         }
+         break;
+      case NC_SHORT:
+         for (ulip = (unsigned long long *)src, sp = dest; count < len; count++)
+         {
+            if (*ulip > X_SHORT_MAX)
+               (*range_error)++;
+            *sp++ = *ulip++;
+         }
+         break;
+      case NC_USHORT:
+         for (ulip = (unsigned long long *)src, usp = dest; count < len; count++)
+         {
+            if (*ulip > X_USHORT_MAX)
+               (*range_error)++;
+            *usp++ = *ulip++;
+         }
+         break;
+      case NC_UINT:
+         for (ulip = (unsigned long long *)src, uip = dest; count < len; count++)
+         {
+            if (*ulip > X_UINT_MAX)
+               (*range_error)++;
+            *uip++ = *ulip++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
             for (ulip = (unsigned long long *)src, lp = dest; count < len; count++)
-              {
-                if (*ulip > X_LONG_MAX)
+            {
+               if (*ulip > X_LONG_MAX)
                   (*range_error)++;
-                *lp++ = *ulip++;
-              }
-          else
+               *lp++ = *ulip++;
+            }
+         else
             for (ulip = (unsigned long long *)src, ip = dest; count < len; count++)
-              {
-                if (*ulip > X_INT_MAX)
-                  (*range_error)++;
-                *ip++ = *ulip++;
-              }
-          break;
-        case NC_INT64:
-          for (ulip = (unsigned long long *)src, lip = dest; count < len; count++)
             {
-              if (*ulip > X_INT64_MAX)
-                (*range_error)++;
-              *lip++ = *ulip++;
+               if (*ulip > X_INT_MAX)
+                  (*range_error)++;
+               *ip++ = *ulip++;
             }
-          break;
-        case NC_UINT64:
-          for (ulip = (unsigned long long *)src, ulip1 = dest; count < len; count++)
+         break;
+      case NC_INT64:
+         for (ulip = (unsigned long long *)src, lip = dest; count < len; count++)
+         {
+            if (*ulip > X_INT64_MAX)
+               (*range_error)++;
+            *lip++ = *ulip++;
+         }
+         break;
+      case NC_UINT64:
+         for (ulip = (unsigned long long *)src, ulip1 = dest; count < len; count++)
             *ulip1++ = *ulip++;
-          break;
-        case NC_FLOAT:
-          for (ulip = (unsigned long long *)src, fp = dest; count < len; count++)
+         break;
+      case NC_FLOAT:
+         for (ulip = (unsigned long long *)src, fp = dest; count < len; count++)
             *fp++ = *ulip++;
-          break;
-        case NC_DOUBLE:
-          for (ulip = (unsigned long long *)src, dp = dest; count < len; count++)
+         break;
+      case NC_DOUBLE:
+         for (ulip = (unsigned long long *)src, dp = dest; count < len; count++)
             *dp++ = *ulip++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    case NC_FLOAT:
+   case NC_FLOAT:
       switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (fp = (float *)src, ubp = dest; count < len; count++)
-            {
-              if (*fp > X_UCHAR_MAX || *fp < 0)
-                (*range_error)++;
-              *ubp++ = *fp++;
-            }
-          break;
-        case NC_BYTE:
-          for (fp = (float *)src, bp = dest; count < len; count++)
-            {
-              if (*fp > (double)X_SCHAR_MAX || *fp < (double)X_SCHAR_MIN)
-                (*range_error)++;
-              *bp++ = *fp++;
-            }
-          break;
-        case NC_SHORT:
-          for (fp = (float *)src, sp = dest; count < len; count++)
-            {
-              if (*fp > (double)X_SHORT_MAX || *fp < (double)X_SHORT_MIN)
-                (*range_error)++;
-              *sp++ = *fp++;
-            }
-          break;
-        case NC_USHORT:
-          for (fp = (float *)src, usp = dest; count < len; count++)
-            {
-              if (*fp > X_USHORT_MAX || *fp < 0)
-                (*range_error)++;
-              *usp++ = *fp++;
-            }
-          break;
-        case NC_UINT:
-          for (fp = (float *)src, uip = dest; count < len; count++)
-            {
-              if (*fp > X_UINT_MAX || *fp < 0)
-                (*range_error)++;
-              *uip++ = *fp++;
-            }
-          break;
-        case NC_INT:
-          if (dest_long)
+      {
+      case NC_UBYTE:
+         for (fp = (float *)src, ubp = dest; count < len; count++)
+         {
+            if (*fp > X_UCHAR_MAX || *fp < 0)
+               (*range_error)++;
+            *ubp++ = *fp++;
+         }
+         break;
+      case NC_BYTE:
+         for (fp = (float *)src, bp = dest; count < len; count++)
+         {
+            if (*fp > (double)X_SCHAR_MAX || *fp < (double)X_SCHAR_MIN)
+               (*range_error)++;
+            *bp++ = *fp++;
+         }
+         break;
+      case NC_SHORT:
+         for (fp = (float *)src, sp = dest; count < len; count++)
+         {
+            if (*fp > (double)X_SHORT_MAX || *fp < (double)X_SHORT_MIN)
+               (*range_error)++;
+            *sp++ = *fp++;
+         }
+         break;
+      case NC_USHORT:
+         for (fp = (float *)src, usp = dest; count < len; count++)
+         {
+            if (*fp > X_USHORT_MAX || *fp < 0)
+               (*range_error)++;
+            *usp++ = *fp++;
+         }
+         break;
+      case NC_UINT:
+         for (fp = (float *)src, uip = dest; count < len; count++)
+         {
+            if (*fp > X_UINT_MAX || *fp < 0)
+               (*range_error)++;
+            *uip++ = *fp++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
             for (fp = (float *)src, lp = dest; count < len; count++)
-              {
-                if (*fp > (double)X_LONG_MAX || *fp < (double)X_LONG_MIN)
-                  (*range_error)++;
-                *lp++ = *fp++;
-              }
-          else
-            for (fp = (float *)src, ip = dest; count < len; count++)
-              {
-                if (*fp > (double)X_INT_MAX || *fp < (double)X_INT_MIN)
-                  (*range_error)++;
-                *ip++ = *fp++;
-              }
-          break;
-        case NC_INT64:
-          for (fp = (float *)src, lip = dest; count < len; count++)
             {
-              if (*fp > X_INT64_MAX || *fp <X_INT64_MIN)
-                (*range_error)++;
-              *lip++ = *fp++;
-            }
-          break;
-        case NC_UINT64:
-          for (fp = (float *)src, lip = dest; count < len; count++)
-            {
-              if (*fp > X_UINT64_MAX || *fp < 0)
-                (*range_error)++;
-              *lip++ = *fp++;
+               if (*fp > (double)X_LONG_MAX || *fp < (double)X_LONG_MIN)
+                  (*range_error)++;
+               *lp++ = *fp++;
             }
-          break;
-        case NC_FLOAT:
-          for (fp = (float *)src, fp1 = dest; count < len; count++)
+         else
+            for (fp = (float *)src, ip = dest; count < len; count++)
             {
-              /*                if (*fp > X_FLOAT_MAX || *fp < X_FLOAT_MIN)
-                                (*range_error)++;*/
-              *fp1++ = *fp++;
+               if (*fp > (double)X_INT_MAX || *fp < (double)X_INT_MIN)
+                  (*range_error)++;
+               *ip++ = *fp++;
             }
-          break;
-        case NC_DOUBLE:
-          for (fp = (float *)src, dp = dest; count < len; count++)
+         break;
+      case NC_INT64:
+         for (fp = (float *)src, lip = dest; count < len; count++)
+         {
+            if (*fp > X_INT64_MAX || *fp <X_INT64_MIN)
+               (*range_error)++;
+            *lip++ = *fp++;
+         }
+         break;
+      case NC_UINT64:
+         for (fp = (float *)src, lip = dest; count < len; count++)
+         {
+            if (*fp > X_UINT64_MAX || *fp < 0)
+               (*range_error)++;
+            *lip++ = *fp++;
+         }
+         break;
+      case NC_FLOAT:
+         for (fp = (float *)src, fp1 = dest; count < len; count++)
+         {
+            /*                if (*fp > X_FLOAT_MAX || *fp < X_FLOAT_MIN)
+                              (*range_error)++;*/
+            *fp1++ = *fp++;
+         }
+         break;
+      case NC_DOUBLE:
+         for (fp = (float *)src, dp = dest; count < len; count++)
             *dp++ = *fp++;
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    case NC_DOUBLE:
+   case NC_DOUBLE:
       switch (dest_type)
-        {
-        case NC_UBYTE:
-          for (dp = (double *)src, ubp = dest; count < len; count++)
-            {
-              if (*dp > X_UCHAR_MAX || *dp < 0)
-                (*range_error)++;
-              *ubp++ = *dp++;
-            }
-          break;
-        case NC_BYTE:
-          for (dp = (double *)src, bp = dest; count < len; count++)
-            {
-              if (*dp > X_SCHAR_MAX || *dp < X_SCHAR_MIN)
-                (*range_error)++;
-              *bp++ = *dp++;
-            }
-          break;
-        case NC_SHORT:
-          for (dp = (double *)src, sp = dest; count < len; count++)
-            {
-              if (*dp > X_SHORT_MAX || *dp < X_SHORT_MIN)
-                (*range_error)++;
-              *sp++ = *dp++;
-            }
-          break;
-        case NC_USHORT:
-          for (dp = (double *)src, usp = dest; count < len; count++)
-            {
-              if (*dp > X_USHORT_MAX || *dp < 0)
-                (*range_error)++;
-              *usp++ = *dp++;
-            }
-          break;
-        case NC_UINT:
-          for (dp = (double *)src, uip = dest; count < len; count++)
-            {
-              if (*dp > X_UINT_MAX || *dp < 0)
-                (*range_error)++;
-              *uip++ = *dp++;
-            }
-          break;
-        case NC_INT:
-          if (dest_long)
+      {
+      case NC_UBYTE:
+         for (dp = (double *)src, ubp = dest; count < len; count++)
+         {
+            if (*dp > X_UCHAR_MAX || *dp < 0)
+               (*range_error)++;
+            *ubp++ = *dp++;
+         }
+         break;
+      case NC_BYTE:
+         for (dp = (double *)src, bp = dest; count < len; count++)
+         {
+            if (*dp > X_SCHAR_MAX || *dp < X_SCHAR_MIN)
+               (*range_error)++;
+            *bp++ = *dp++;
+         }
+         break;
+      case NC_SHORT:
+         for (dp = (double *)src, sp = dest; count < len; count++)
+         {
+            if (*dp > X_SHORT_MAX || *dp < X_SHORT_MIN)
+               (*range_error)++;
+            *sp++ = *dp++;
+         }
+         break;
+      case NC_USHORT:
+         for (dp = (double *)src, usp = dest; count < len; count++)
+         {
+            if (*dp > X_USHORT_MAX || *dp < 0)
+               (*range_error)++;
+            *usp++ = *dp++;
+         }
+         break;
+      case NC_UINT:
+         for (dp = (double *)src, uip = dest; count < len; count++)
+         {
+            if (*dp > X_UINT_MAX || *dp < 0)
+               (*range_error)++;
+            *uip++ = *dp++;
+         }
+         break;
+      case NC_INT:
+         if (dest_long)
             for (dp = (double *)src, lp = dest; count < len; count++)
-              {
-                if (*dp > X_LONG_MAX || *dp < X_LONG_MIN)
-                  (*range_error)++;
-                *lp++ = *dp++;
-              }
-          else
-            for (dp = (double *)src, ip = dest; count < len; count++)
-              {
-                if (*dp > X_INT_MAX || *dp < X_INT_MIN)
-                  (*range_error)++;
-                *ip++ = *dp++;
-              }
-          break;
-        case NC_INT64:
-          for (dp = (double *)src, lip = dest; count < len; count++)
-            {
-              if (*dp > X_INT64_MAX || *dp < X_INT64_MIN)
-                (*range_error)++;
-              *lip++ = *dp++;
-            }
-          break;
-        case NC_UINT64:
-          for (dp = (double *)src, lip = dest; count < len; count++)
-            {
-              if (*dp > X_UINT64_MAX || *dp < 0)
-                (*range_error)++;
-              *lip++ = *dp++;
-            }
-          break;
-        case NC_FLOAT:
-          for (dp = (double *)src, fp = dest; count < len; count++)
             {
-              if (*dp > X_FLOAT_MAX || *dp < X_FLOAT_MIN)
-                (*range_error)++;
-              *fp++ = *dp++;
+               if (*dp > X_LONG_MAX || *dp < X_LONG_MIN)
+                  (*range_error)++;
+               *lp++ = *dp++;
             }
-          break;
-        case NC_DOUBLE:
-          for (dp = (double *)src, dp1 = dest; count < len; count++)
+         else
+            for (dp = (double *)src, ip = dest; count < len; count++)
             {
-              /* if (*dp > X_DOUBLE_MAX || *dp < X_DOUBLE_MIN) */
-              /*    (*range_error)++; */
-              *dp1++ = *dp++;
+               if (*dp > X_INT_MAX || *dp < X_INT_MIN)
+                  (*range_error)++;
+               *ip++ = *dp++;
             }
-          break;
-        default:
-          LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
-               __func__, src_type, dest_type));
-          return NC_EBADTYPE;
-        }
+         break;
+      case NC_INT64:
+         for (dp = (double *)src, lip = dest; count < len; count++)
+         {
+            if (*dp > X_INT64_MAX || *dp < X_INT64_MIN)
+               (*range_error)++;
+            *lip++ = *dp++;
+         }
+         break;
+      case NC_UINT64:
+         for (dp = (double *)src, lip = dest; count < len; count++)
+         {
+            if (*dp > X_UINT64_MAX || *dp < 0)
+               (*range_error)++;
+            *lip++ = *dp++;
+         }
+         break;
+      case NC_FLOAT:
+         for (dp = (double *)src, fp = dest; count < len; count++)
+         {
+            if (*dp > X_FLOAT_MAX || *dp < X_FLOAT_MIN)
+               (*range_error)++;
+            *fp++ = *dp++;
+         }
+         break;
+      case NC_DOUBLE:
+         for (dp = (double *)src, dp1 = dest; count < len; count++)
+         {
+            /* if (*dp > X_DOUBLE_MAX || *dp < X_DOUBLE_MIN) */
+            /*    (*range_error)++; */
+            *dp1++ = *dp++;
+         }
+         break;
+      default:
+         LOG((0, "%s: unexpected dest type. src_type %d, dest_type %d",
+              __func__, src_type, dest_type));
+         return NC_EBADTYPE;
+      }
       break;
 
-    default:
+   default:
       LOG((0, "%s: unexpected src type. src_type %d, dest_type %d",
            __func__, src_type, dest_type));
       return NC_EBADTYPE;
-    }
-  return NC_NOERR;
+   }
+   return NC_NOERR;
 }
 
-/* In our first pass through the data, we may have encountered
- * variables before encountering their dimscales, so go through the
- * vars in this file and make sure we've got a dimid for each. */
+/**
+ * @internal In our first pass through the data, we may have
+ * encountered variables before encountering their dimscales, so go
+ * through the vars in this file and make sure we've got a dimid for
+ * each. 
+ *
+ * @param grp Pointer to group info struct.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned an error.
+ * @author Ed Hartnett
+*/
 int
 nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
 {
-  NC_GRP_INFO_T *g;
-  NC_VAR_INFO_T *var;
-  NC_DIM_INFO_T *dim;
-  int retval = NC_NOERR;
-  int i;
-
-  assert(grp && grp->name);
-  LOG((4, "%s: grp->name %s", __func__, grp->name));
-
-  /* Perform var dimscale match for child groups. */
-  for (g = grp->children; g; g = g->l.next)
-    if ((retval = nc4_rec_match_dimscales(g)))
-      return retval;
-
-  /* Check all the vars in this group. If they have dimscale info,
-   * try and find a dimension for them. */
-  for (i=0; i < grp->vars.nelems; i++)
-    {
+   NC_GRP_INFO_T *g;
+   NC_VAR_INFO_T *var;
+   NC_DIM_INFO_T *dim;
+   int retval = NC_NOERR;
+   int i;
+
+   assert(grp && grp->name);
+   LOG((4, "%s: grp->name %s", __func__, grp->name));
+
+   /* Perform var dimscale match for child groups. */
+   for (g = grp->children; g; g = g->l.next)
+      if ((retval = nc4_rec_match_dimscales(g)))
+         return retval;
+
+   /* Check all the vars in this group. If they have dimscale info,
+    * try and find a dimension for them. */
+   for (i=0; i < grp->vars.nelems; i++)
+   {
       int ndims;
       int d;
       var = grp->vars.value[i];
@@ -3682,485 +3875,566 @@ nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
       /* Check all vars and see if dim[i] != NULL if dimids[i] valid. */
       ndims = var->ndims;
       for (d = 0; d < ndims; d++)
-	{
-	  if (var->dim[d] == NULL) {
-	    nc4_find_dim(grp, var->dimids[d], &var->dim[d], NULL);
-	  }
-	  /*	  assert(var->dim[d] && var->dim[d]->dimid == var->dimids[d]); */
-	}
+      {
+         if (var->dim[d] == NULL) {
+            nc4_find_dim(grp, var->dimids[d], &var->dim[d], NULL);
+         }
+         /*       assert(var->dim[d] && var->dim[d]->dimid == var->dimids[d]); */
+      }
 
       /* Skip dimension scale variables */
       if (!var->dimscale)
-        {
-          int d;
+      {
+         int d;
 
-          /* Are there dimscales for this variable? */
-          if (var->dimscale_hdf5_objids)
+         /* Are there dimscales for this variable? */
+         if (var->dimscale_hdf5_objids)
+         {
+            for (d = 0; d < var->ndims; d++)
+            {
+               nc_bool_t finished = NC_FALSE;
+
+               LOG((5, "%s: var %s has dimscale info...", __func__, var->name));
+               /* Look at all the dims in this group to see if they
+                * match. */
+               for (g = grp; g && !finished; g = g->parent)
+               {
+                  for (dim = g->dim; dim; dim = dim->l.next)
+                  {
+                     if (var->dimscale_hdf5_objids[d].fileno[0] == dim->hdf5_objid.fileno[0] &&
+                         var->dimscale_hdf5_objids[d].objno[0] == dim->hdf5_objid.objno[0] &&
+                         var->dimscale_hdf5_objids[d].fileno[1] == dim->hdf5_objid.fileno[1] &&
+                         var->dimscale_hdf5_objids[d].objno[1] == dim->hdf5_objid.objno[1])
+                     {
+                        LOG((4, "%s: for dimension %d, found dim %s",
+                             __func__, d, dim->name));
+                        var->dimids[d] = dim->dimid;
+                        var->dim[d] = dim;
+                        finished = NC_TRUE;
+                        break;
+                     }
+                  } /* next dim */
+               } /* next grp */
+               LOG((5, "%s: dimid for this dimscale is %d", __func__, var->type_info->nc_typeid));
+            } /* next var->dim */
+         }
+         /* No dimscales for this var! Invent phony dimensions. */
+         else
+         {
+            hid_t spaceid = 0;
+            hsize_t *h5dimlen = NULL, *h5dimlenmax = NULL;
+            int dataset_ndims;
+
+            /* Find the space information for this dimension. */
+            if ((spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
+               return NC_EHDFERR;
+
+            /* Get the len of each dim in the space. */
+            if (var->ndims)
             {
-              for (d = 0; d < var->ndims; d++)
-                {
-                  nc_bool_t finished = NC_FALSE;
-
-                  LOG((5, "%s: var %s has dimscale info...", __func__, var->name));
-                  /* Look at all the dims in this group to see if they
-                   * match. */
-                  for (g = grp; g && !finished; g = g->parent)
-                    {
-                      for (dim = g->dim; dim; dim = dim->l.next)
-                        {
-                          if (var->dimscale_hdf5_objids[d].fileno[0] == dim->hdf5_objid.fileno[0] &&
-                              var->dimscale_hdf5_objids[d].objno[0] == dim->hdf5_objid.objno[0] &&
-                              var->dimscale_hdf5_objids[d].fileno[1] == dim->hdf5_objid.fileno[1] &&
-                              var->dimscale_hdf5_objids[d].objno[1] == dim->hdf5_objid.objno[1])
-                            {
-                              LOG((4, "%s: for dimension %d, found dim %s",
-                                   __func__, d, dim->name));
-                              var->dimids[d] = dim->dimid;
-                              var->dim[d] = dim;
-                              finished = NC_TRUE;
-                              break;
-                            }
-                        } /* next dim */
-                    } /* next grp */
-                  LOG((5, "%s: dimid for this dimscale is %d", __func__, var->type_info->nc_typeid));
-                } /* next var->dim */
+               if (!(h5dimlen = malloc(var->ndims * sizeof(hsize_t))))
+                  return NC_ENOMEM;
+               if (!(h5dimlenmax = malloc(var->ndims * sizeof(hsize_t))))
+               {
+                  free(h5dimlen);
+                  return NC_ENOMEM;
+               }
+               if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid, h5dimlen,
+                                                              h5dimlenmax)) < 0) {
+                  free(h5dimlenmax);
+                  free(h5dimlen);
+                  return NC_EHDFERR;
+               }
+               if (dataset_ndims != var->ndims) {
+                  free(h5dimlenmax);
+                  free(h5dimlen);
+                  return NC_EHDFERR;
+               }
             }
-          /* No dimscales for this var! Invent phony dimensions. */
-          else
+            else
             {
-              hid_t spaceid = 0;
-              hsize_t *h5dimlen = NULL, *h5dimlenmax = NULL;
-              int dataset_ndims;
-
-              /* Find the space information for this dimension. */
-              if ((spaceid = H5Dget_space(var->hdf_datasetid)) < 0)
-                return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-              num_spaces++;
-#endif
+               /* Make sure it's scalar. */
+               if (H5Sget_simple_extent_type(spaceid) != H5S_SCALAR)
+                  return NC_EHDFERR;
+            }
+
+            /* Release the space object. */
+            if (H5Sclose(spaceid) < 0) {
+               free(h5dimlen);
+               free(h5dimlenmax);
+               return NC_EHDFERR;
+            }
 
-              /* Get the len of each dim in the space. */
-              if (var->ndims)
-                {
-                  if (!(h5dimlen = malloc(var->ndims * sizeof(hsize_t))))
-                    return NC_ENOMEM;
-                  if (!(h5dimlenmax = malloc(var->ndims * sizeof(hsize_t))))
-                    {
-                      free(h5dimlen);
-                      return NC_ENOMEM;
-                    }
-                  if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid, h5dimlen,
-                                                                 h5dimlenmax)) < 0) {
-                    free(h5dimlenmax);
-                    free(h5dimlen);
-                    return NC_EHDFERR;
+            /* Create a phony dimension for each dimension in the
+             * dataset, unless there already is one the correct
+             * size. */
+            for (d = 0; d < var->ndims; d++)
+            {
+               /* Is there already a phony dimension of the correct size? */
+               for (dim = grp->dim; dim; dim = dim->l.next)
+                  if ((dim->len == h5dimlen[d]) &&
+                      ((h5dimlenmax[d] == H5S_UNLIMITED && dim->unlimited) ||
+                       (h5dimlenmax[d] != H5S_UNLIMITED && !dim->unlimited)))
+                     break;
+
+               /* Didn't find a phony dim? Then create one. */
+               if (!dim)
+               {
+                  char phony_dim_name[NC_MAX_NAME + 1];
+
+                  LOG((3, "%s: creating phony dim for var %s", __func__, var->name));
+                  if ((retval = nc4_dim_list_add(&grp->dim, &dim))) {
+                     free(h5dimlenmax);
+                     free(h5dimlen);
+                     return retval;
                   }
-                  if (dataset_ndims != var->ndims) {
-                    free(h5dimlenmax);
-                    free(h5dimlen);
-                    return NC_EHDFERR;
+                  dim->dimid = grp->nc4_info->next_dimid++;
+                  sprintf(phony_dim_name, "phony_dim_%d", dim->dimid);
+                  if (!(dim->name = strdup(phony_dim_name))) {
+                     free(h5dimlenmax);
+                     free(h5dimlen);
+                     return NC_ENOMEM;
                   }
-                }
-              else
-                {
-                  /* Make sure it's scalar. */
-                  if (H5Sget_simple_extent_type(spaceid) != H5S_SCALAR)
-                    return NC_EHDFERR;
-                }
-
-              /* Release the space object. */
-              if (H5Sclose(spaceid) < 0) {
-                free(h5dimlen);
-                free(h5dimlenmax);
-                return NC_EHDFERR;
-              }
-#ifdef EXTRA_TESTS
-              num_spaces--;
-#endif
+                  dim->len = h5dimlen[d];
+                  dim->hash = hash_fast(phony_dim_name, strlen(phony_dim_name));
+                  if (h5dimlenmax[d] == H5S_UNLIMITED)
+                     dim->unlimited = NC_TRUE;
+               }
 
-              /* Create a phony dimension for each dimension in the
-               * dataset, unless there already is one the correct
-               * size. */
-              for (d = 0; d < var->ndims; d++)
-                {
-                  /* Is there already a phony dimension of the correct size? */
-                  for (dim = grp->dim; dim; dim = dim->l.next)
-                    if ((dim->len == h5dimlen[d]) &&
-                        ((h5dimlenmax[d] == H5S_UNLIMITED && dim->unlimited) ||
-                         (h5dimlenmax[d] != H5S_UNLIMITED && !dim->unlimited)))
-                      break;
-
-                  /* Didn't find a phony dim? Then create one. */
-                  if (!dim)
-                    {
-                      char phony_dim_name[NC_MAX_NAME + 1];
-
-                      LOG((3, "%s: creating phony dim for var %s", __func__, var->name));
-                      if ((retval = nc4_dim_list_add(&grp->dim, &dim))) {
-                        free(h5dimlenmax);
-                        free(h5dimlen);
-                        return retval;
-                      }
-                      dim->dimid = grp->nc4_info->next_dimid++;
-                      sprintf(phony_dim_name, "phony_dim_%d", dim->dimid);
-                      if (!(dim->name = strdup(phony_dim_name))) {
-                        free(h5dimlenmax);
-                        free(h5dimlen);
-                        return NC_ENOMEM;
-                      }
-                      dim->len = h5dimlen[d];
-                      dim->hash = hash_fast(phony_dim_name, strlen(phony_dim_name));
-                      if (h5dimlenmax[d] == H5S_UNLIMITED)
-                        dim->unlimited = NC_TRUE;
-                    }
-
-                  /* The variable must remember the dimid. */
-                  var->dimids[d] = dim->dimid;
-                  var->dim[d] = dim;
-                } /* next dim */
+               /* The variable must remember the dimid. */
+               var->dimids[d] = dim->dimid;
+               var->dim[d] = dim;
+            } /* next dim */
 
               /* Free the memory we malloced. */
-              free(h5dimlen);
-              free(h5dimlenmax);
-            }
-        }
-    }
+            free(h5dimlen);
+            free(h5dimlenmax);
+         }
+      }
+   }
 
-  return retval;
+   return retval;
 }
 
-/* Get the length, in bytes, of one element of a type in memory. */
+/**
+ * @internal Get the length, in bytes, of one element of a type in
+ * memory. 
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param xtype NetCDF type ID.
+ * @param is_long True only if NC_LONG is the memory type.
+ * @param len Pointer that gets lenght in bytes.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EBADTYPE Type not found
+ * @author Ed Hartnett
+*/
 int
 nc4_get_typelen_mem(NC_HDF5_FILE_INFO_T *h5, nc_type xtype, int is_long,
                     size_t *len)
 {
-  NC_TYPE_INFO_T *type;
-  int retval;
-
-  LOG((4, "%s xtype: %d", __func__, xtype));
-  assert(len);
-
-  /* If this is an atomic type, the answer is easy. */
-  switch (xtype)
-    {
-    case NC_BYTE:
-    case NC_CHAR:
-    case NC_UBYTE:
+   NC_TYPE_INFO_T *type;
+   int retval;
+
+   LOG((4, "%s xtype: %d", __func__, xtype));
+   assert(len);
+
+   /* If this is an atomic type, the answer is easy. */
+   switch (xtype)
+   {
+   case NC_BYTE:
+   case NC_CHAR:
+   case NC_UBYTE:
       *len = sizeof(char);
       return NC_NOERR;
-    case NC_SHORT:
-    case NC_USHORT:
+   case NC_SHORT:
+   case NC_USHORT:
       *len = sizeof(short);
       return NC_NOERR;
-    case NC_INT:
-    case NC_UINT:
+   case NC_INT:
+   case NC_UINT:
       if (is_long)
-        *len = sizeof(long);
+         *len = sizeof(long);
       else
-        *len = sizeof(int);
+         *len = sizeof(int);
       return NC_NOERR;
-    case NC_FLOAT:
+   case NC_FLOAT:
       *len = sizeof(float);
       return NC_NOERR;
-    case NC_DOUBLE:
+   case NC_DOUBLE:
       *len = sizeof(double);
       return NC_NOERR;
-    case NC_INT64:
-    case NC_UINT64:
+   case NC_INT64:
+   case NC_UINT64:
       *len = sizeof(long long);
       return NC_NOERR;
-    case NC_STRING:
+   case NC_STRING:
       *len = sizeof(char *);
       return NC_NOERR;
-    }
+   }
 
-  /* See if var is compound type. */
-  if ((retval = nc4_find_type(h5, xtype, &type)))
-    return retval;
+   /* See if var is compound type. */
+   if ((retval = nc4_find_type(h5, xtype, &type)))
+      return retval;
 
-  if (!type)
-    return NC_EBADTYPE;
+   if (!type)
+      return NC_EBADTYPE;
 
-  *len = type->size;
+   *len = type->size;
 
-  LOG((5, "type->size: %d", type->size));
+   LOG((5, "type->size: %d", type->size));
 
-  return NC_NOERR;
+   return NC_NOERR;
 }
 
-/* Get the class of a type */
+/**
+ * @internal Get the class of a type 
+ *
+ * @param h5 Pointer to the HDF5 file info struct.
+ * @param xtype NetCDF type ID.
+ * @param type_class Pointer that gets class of type, NC_INT,
+ * NC_FLOAT, NC_CHAR, or NC_STRING, NC_ENUM, NC_VLEN, NC_COMPOUND, or
+ * NC_OPAQUE.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 nc4_get_typeclass(const NC_HDF5_FILE_INFO_T *h5, nc_type xtype, int *type_class)
 {
-  int retval = NC_NOERR;
+   int retval = NC_NOERR;
 
-  LOG((4, "%s xtype: %d", __func__, xtype));
-  assert(type_class);
+   LOG((4, "%s xtype: %d", __func__, xtype));
+   assert(type_class);
 
-  /* If this is an atomic type, the answer is easy. */
-  if (xtype <= NC_STRING)
-    {
+   /* If this is an atomic type, the answer is easy. */
+   if (xtype <= NC_STRING)
+   {
       switch (xtype)
-        {
-        case NC_BYTE:
-        case NC_UBYTE:
-        case NC_SHORT:
-        case NC_USHORT:
-        case NC_INT:
-        case NC_UINT:
-        case NC_INT64:
-        case NC_UINT64:
-          /* NC_INT is class used for all integral types */
-          *type_class = NC_INT;
-          break;
-
-        case NC_FLOAT:
-        case NC_DOUBLE:
-          /* NC_FLOAT is class used for all floating-point types */
-          *type_class = NC_FLOAT;
-          break;
-
-        case NC_CHAR:
-          *type_class = NC_CHAR;
-          break;
-
-        case NC_STRING:
-          *type_class = NC_STRING;
-          break;
-
-        default:
-          BAIL(NC_EBADTYPE);
-        }
-    }
-  else
-    {
+      {
+      case NC_BYTE:
+      case NC_UBYTE:
+      case NC_SHORT:
+      case NC_USHORT:
+      case NC_INT:
+      case NC_UINT:
+      case NC_INT64:
+      case NC_UINT64:
+         /* NC_INT is class used for all integral types */
+         *type_class = NC_INT;
+         break;
+
+      case NC_FLOAT:
+      case NC_DOUBLE:
+         /* NC_FLOAT is class used for all floating-point types */
+         *type_class = NC_FLOAT;
+         break;
+
+      case NC_CHAR:
+         *type_class = NC_CHAR;
+         break;
+
+      case NC_STRING:
+         *type_class = NC_STRING;
+         break;
+
+      default:
+         BAIL(NC_EBADTYPE);
+      }
+   }
+   else
+   {
       NC_TYPE_INFO_T *type;
 
       /* See if it's a used-defined type */
       if ((retval = nc4_find_type(h5, xtype, &type)))
-        BAIL(retval);
+         BAIL(retval);
       if (!type)
-        BAIL(NC_EBADTYPE);
+         BAIL(NC_EBADTYPE);
 
       *type_class = type->nc_type_class;
-    }
+   }
 
- exit:
-  return retval;
+exit:
+   return retval;
 }
 
-int
-NC4_test_netcdf4(void)
-{
-    return NC_NOERR;
-}
+/**
+ * @internal
+ *
+ * @param log
+ * @param id HDF5 ID.
+ * @param type
+ *
+ * @return NC_NOERR No error.
+ */
 void
 reportobject(int log, hid_t id, unsigned int type)
 {
-#   define MAXNAME 1024
-    char name[MAXNAME];
-    ssize_t len;
-    const char* typename = NULL;
-
-    len = H5Iget_name(id, name, MAXNAME);
-    if(len < 0) return;
-    name[len] = '\0';
-
-    switch (type) {
-    case H5F_OBJ_FILE: typename = "File"; break;
-    case H5F_OBJ_DATASET: typename = "Dataset"; break;
-    case H5F_OBJ_GROUP: typename = "Group"; break;
-    case H5F_OBJ_DATATYPE: typename = "Datatype"; break;
-    case H5F_OBJ_ATTR:
-	typename = "Attribute";
-	len = H5Aget_name(id, MAXNAME, name);
-        if(len < 0) len = 0;
-	name[len] = '\0';
-	break;
-    default: typename = "<unknown>"; break;
-    }
-    if(log) {
+   char name[MAXNAME];
+   ssize_t len;
+   const char* typename = NULL;
+
+   len = H5Iget_name(id, name, MAXNAME);
+   if(len < 0) return;
+   name[len] = '\0';
+
+   switch (type) {
+   case H5F_OBJ_FILE: typename = "File"; break;
+   case H5F_OBJ_DATASET: typename = "Dataset"; break;
+   case H5F_OBJ_GROUP: typename = "Group"; break;
+   case H5F_OBJ_DATATYPE: typename = "Datatype"; break;
+   case H5F_OBJ_ATTR:
+      typename = "Attribute";
+      len = H5Aget_name(id, MAXNAME, name);
+      if(len < 0) len = 0;
+      name[len] = '\0';
+      break;
+   default: typename = "<unknown>"; break;
+   }
+   if(log) {
 #ifdef LOGGING
-	LOG((0,"Type = %s(%8u) name='%s'",typename,id,name));
+      LOG((0,"Type = %s(%8u) name='%s'",typename,id,name));
 #endif
-    } else {
-	fprintf(stderr,"Type = %s(%8u) name='%s'",typename,id,name);
-    }
+   } else {
+      fprintf(stderr,"Type = %s(%8u) name='%s'",typename,(unsigned int)id,name);
+   }
 }
 
-static unsigned int OTYPES[5] = {H5F_OBJ_FILE, H5F_OBJ_DATASET, H5F_OBJ_GROUP, H5F_OBJ_DATATYPE, H5F_OBJ_ATTR};
-
+/**
+ * @internal
+ *
+ * @param log
+ * @param fid HDF5 ID.
+ * @param ntypes Number of types.
+ * @param otypes Pointer that gets number of open types.
+ *
+ * @return ::NC_NOERR No error.
+ */
 static void
 reportopenobjectsT(int log, hid_t fid, int ntypes, unsigned int* otypes)
 {
-    int t,i;
-    ssize_t ocount;
-    size_t maxobjs = -1;
-    hid_t* idlist = NULL;
+   int t,i;
+   ssize_t ocount;
+   size_t maxobjs = -1;
+   hid_t* idlist = NULL;
 
-    if(log) {
+   if(log) {
 #ifdef LOGGING
-        LOG((0,"\nReport: open objects on %d\n",fid));
+      LOG((0,"\nReport: open objects on %d\n",fid));
 #endif
-    } else {
-        fprintf(stdout,"\nReport: open objects on %d\n",fid);
-    }
-    maxobjs = H5Fget_obj_count(fid,H5F_OBJ_ALL);
-    if(idlist != NULL) free(idlist);
-    idlist = (hid_t*)malloc(sizeof(hid_t)*maxobjs);
-    for(t=0;t<ntypes;t++) {
-	unsigned int ot = otypes[t];
-        ocount = H5Fget_obj_ids(fid,ot,maxobjs,idlist);
-	for(i=0;i<ocount;i++) {
-	    hid_t o = idlist[i];
-	    reportobject(log,o,ot);
-	}
-    }
-    if(idlist != NULL) free(idlist);
+   } else {
+      fprintf(stdout,"\nReport: open objects on %d\n",(int)fid);
+   }
+   maxobjs = H5Fget_obj_count(fid,H5F_OBJ_ALL);
+   if(idlist != NULL) free(idlist);
+   idlist = (hid_t*)malloc(sizeof(hid_t)*maxobjs);
+   for(t=0;t<ntypes;t++) {
+      unsigned int ot = otypes[t];
+      ocount = H5Fget_obj_ids(fid,ot,maxobjs,idlist);
+      for(i=0;i<ocount;i++) {
+         hid_t o = idlist[i];
+         reportobject(log,o,ot);
+      }
+   }
+   if(idlist != NULL) free(idlist);
 }
 
+/**
+ * @internal Report open objects.
+ *
+ * @param log
+ * @param fid HDF5 file ID.
+ *
+ * @return NC_NOERR No error.
+ */
 void
 reportopenobjects(int log, hid_t fid)
 {
-    reportopenobjectsT(log, fid,5,OTYPES);
+   reportopenobjectsT(log, fid,5,OTYPES);
 }
 
-
+/**
+ * @internal Get HDF5 library version.
+ *
+ * @param major Pointer that gets major version number.
+ * @param minor Pointer that gets minor version number.
+ * @param release Pointer that gets release version number.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_hdf5get_libversion(unsigned* major,unsigned* minor,unsigned* release)
 {
-    if(H5get_libversion(major,minor,release) < 0)
-	return NC_EHDFERR;
-    return NC_NOERR;
+   if(H5get_libversion(major,minor,release) < 0)
+      return NC_EHDFERR;
+   return NC_NOERR;
 }
 
+/**
+ * @internal Get HDF5 superblock version.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param idp Pointer that gets superblock version.
+ *
+ * @returns NC_NOERR No error.
+ * @returns NC_EHDFERR HDF5 returned error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_hdf5get_superblock(struct NC_HDF5_FILE_INFO* h5, int* idp)
 {
-    int stat = NC_NOERR;
-    unsigned super;
-    hid_t plist = -1;
-    if((plist = H5Fget_create_plist(h5->hdfid)) < 0)
-	{stat = NC_EHDFERR; goto done;}
-    if(H5Pget_version(plist, &super, NULL, NULL, NULL) < 0)
-	{stat = NC_EHDFERR; goto done;}
-    if(idp) *idp = (int)super;
+   int stat = NC_NOERR;
+   unsigned super;
+   hid_t plist = -1;
+   if((plist = H5Fget_create_plist(h5->hdfid)) < 0)
+   {stat = NC_EHDFERR; goto done;}
+   if(H5Pget_version(plist, &super, NULL, NULL, NULL) < 0)
+   {stat = NC_EHDFERR; goto done;}
+   if(idp) *idp = (int)super;
 done:
-    if(plist >= 0) H5Pclose(plist);
-    return stat;
+   if(plist >= 0) H5Pclose(plist);
+   return stat;
 }
 
-/* We define a file as being from netcdf-4 if any of the following
-are true:
-1. NCPROPS attribute exists in root group
-2. NC3_STRICT_ATT_NAME exists in root group
-3. any of NC_ATT_REFERENCE_LIST, NC_ATT_CLASS,
-   NC_ATT_DIMENSION_LIST, NC_ATT_NAME,
-   NC_ATT_COORDINATES, NC_DIMID_ATT_NAME
-   exist anywhere in the file; note that this
-   requires walking the file.
-WARNINGS:
-1. False negatives are possible for a small subset of netcdf-4
-   created files.
-2. Deliberate falsification in the file can be used to cause
-   a false positive.
-*/
-
 static int NC4_get_strict_att(NC_HDF5_FILE_INFO_T*);
 static int NC4_walk(hid_t, int*);
 
+/**
+ * @internal Determine whether file is netCDF-4.
+ *
+ * We define a file as being from netcdf-4 if any of the following
+ * are true:
+ * 1. NCPROPS attribute exists in root group
+ * 2. NC3_STRICT_ATT_NAME exists in root group
+ * 3. any of NC_ATT_REFERENCE_LIST, NC_ATT_CLASS,
+ * NC_ATT_DIMENSION_LIST, NC_ATT_NAME,
+ * NC_ATT_COORDINATES, NC_DIMID_ATT_NAME
+ * exist anywhere in the file; note that this
+ * requires walking the file.
+
+ * @note WARNINGS:
+ *   1. False negatives are possible for a small subset of netcdf-4
+ *   created files.
+ *   2. Deliberate falsification in the file can be used to cause
+ *   a false positive.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @returns NC_NOERR No error.
+ * @author Dennis Heimbigner.
+*/
 int
 NC4_isnetcdf4(struct NC_HDF5_FILE_INFO* h5)
 {
-    int stat;
-    int isnc4 = 0;
-    int count;
-
-    /* Look for NC3_STRICT_ATT_NAME */
-    isnc4 = NC4_get_strict_att(h5);
-    if(isnc4 > 0)
-	goto done;
-    /* attribute did not exist */
-    /* => last resort: walk the HDF5 file looking for markers */
-    count = 0;
-    stat = NC4_walk(h5->root_grp->hdf_grpid, &count);
-    if(stat != NC_NOERR)
-	isnc4 = 0;
-    else /* Threshold is at least two matches */
-	isnc4 = (count >= 2);
+   int stat;
+   int isnc4 = 0;
+   int count;
+
+   /* Look for NC3_STRICT_ATT_NAME */
+   isnc4 = NC4_get_strict_att(h5);
+   if(isnc4 > 0)
+      goto done;
+   /* attribute did not exist */
+   /* => last resort: walk the HDF5 file looking for markers */
+   count = 0;
+   stat = NC4_walk(h5->root_grp->hdf_grpid, &count);
+   if(stat != NC_NOERR)
+      isnc4 = 0;
+   else /* Threshold is at least two matches */
+      isnc4 = (count >= 2);
 
 done:
-    return isnc4;
+   return isnc4;
 }
 
+/**
+ * @internal Get the NC3 strict attribute.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @returns NC_NOERR No error.
+ * @author Dennis Heimbigner.
+*/
 static int
 NC4_get_strict_att(NC_HDF5_FILE_INFO_T* h5)
 {
-    hid_t grp = -1;
-    hid_t attid = -1;
-
-    /* Get root group */
-    grp = h5->root_grp->hdf_grpid; /* get root group */
-    /* Try to extract the NC3_STRICT_ATT_NAME attribute */
-    attid = H5Aopen_name(grp, NC3_STRICT_ATT_NAME);
-    H5Aclose(attid);
-    return attid;
+   hid_t grp = -1;
+   hid_t attid = -1;
+
+   /* Get root group */
+   grp = h5->root_grp->hdf_grpid; /* get root group */
+   /* Try to extract the NC3_STRICT_ATT_NAME attribute */
+   attid = H5Aopen_name(grp, NC3_STRICT_ATT_NAME);
+   H5Aclose(attid);
+   return attid;
 }
 
+/**
+ * @internal Walk group struct.
+ *
+ * @param gid HDF5 ID of starting group.
+ * @param countp Pointer that gets count.
+ *
+ * @returns NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 static int
 NC4_walk(hid_t gid, int* countp)
 {
-    int ncstat = NC_NOERR;
-    int i,j,na;
-    ssize_t len;
-    hsize_t nobj;
-    herr_t err;
-    int otype;
-    hid_t grpid, dsid;
-    char name[NC_HDF5_MAX_NAME];
-
-    /* walk group members of interest */
-    err = H5Gget_num_objs(gid, &nobj);
-    if(err < 0) return err;
-
-    for(i = 0; i < nobj; i++) {
-        /* Get name & kind of object in the group */
-        len = H5Gget_objname_by_idx(gid,(hsize_t)i,name,(size_t)NC_HDF5_MAX_NAME);
-        if(len < 0) return len;
-
-        otype =  H5Gget_objtype_by_idx(gid,(size_t)i);
-        switch(otype) {
-        case H5G_GROUP:
-            grpid = H5Gopen(gid,name);
-            NC4_walk(grpid,countp);
-            H5Gclose(grpid);
-            break;
-        case H5G_DATASET: /* variables */
-	    /* Check for phony_dim */
-	    if(strcmp(name,"phony_dim")==0)
-		*countp = *countp + 1;
-            dsid = H5Dopen(gid,name);
-            na = H5Aget_num_attrs(dsid);
-            for(j = 0; j < na; j++) {
-                hid_t aid =  H5Aopen_idx(dsid,(unsigned int)    j);
-                if(aid >= 0) {
-                    const char** p;
-                    ssize_t len = H5Aget_name(aid, NC_HDF5_MAX_NAME, name);
-                    if(len < 0) return len;
-                    /* Is this a netcdf-4 marker attribute */
-                        for(p=NC_RESERVED_VARATT_LIST;*p;p++) {
-                            if(strcmp(name,*p) ==     0) {
-                                *countp = *countp + 1;
-                            }
-                        }
-                }
-                H5Aclose(aid);
-            }
-            H5Dclose(dsid);
-            break;
-        default:/* ignore */
-            break;
+   int ncstat = NC_NOERR;
+   int i,j,na;
+   ssize_t len;
+   hsize_t nobj;
+   herr_t err;
+   int otype;
+   hid_t grpid, dsid;
+   char name[NC_HDF5_MAX_NAME];
+
+   /* walk group members of interest */
+   err = H5Gget_num_objs(gid, &nobj);
+   if(err < 0) return err;
+
+   for(i = 0; i < nobj; i++) {
+      /* Get name & kind of object in the group */
+      len = H5Gget_objname_by_idx(gid,(hsize_t)i,name,(size_t)NC_HDF5_MAX_NAME);
+      if(len < 0) return len;
+
+      otype =  H5Gget_objtype_by_idx(gid,(size_t)i);
+      switch(otype) {
+      case H5G_GROUP:
+         grpid = H5Gopen(gid,name);
+         NC4_walk(grpid,countp);
+         H5Gclose(grpid);
+         break;
+      case H5G_DATASET: /* variables */
+         /* Check for phony_dim */
+         if(strcmp(name,"phony_dim")==0)
+            *countp = *countp + 1;
+         dsid = H5Dopen(gid,name);
+         na = H5Aget_num_attrs(dsid);
+         for(j = 0; j < na; j++) {
+            hid_t aid =  H5Aopen_idx(dsid,(unsigned int)    j);
+            if(aid >= 0) {
+               const char** p;
+               ssize_t len = H5Aget_name(aid, NC_HDF5_MAX_NAME, name);
+               if(len < 0) return len;
+               /* Is this a netcdf-4 marker attribute */
+               for(p=NC_RESERVED_VARATT_LIST;*p;p++) {
+                  if(strcmp(name,*p) ==     0) {
+                     *countp = *countp + 1;
+                  }
+               }
             }
-    }
-    return ncstat;
+            H5Aclose(aid);
+         }
+         H5Dclose(dsid);
+         break;
+      default:/* ignore */
+         break;
+      }
+   }
+   return ncstat;
 }
diff --git a/libsrc4/nc4info.c b/libsrc4/nc4info.c
index b6564f1..4fa6585 100644
--- a/libsrc4/nc4info.c
+++ b/libsrc4/nc4info.c
@@ -1,8 +1,11 @@
-/*********************************************************************
-*    Copyright 2010, UCAR/Unidata
-*    See netcdf/COPYRIGHT file for copying and redistribution conditions.
-* ********************************************************************/
-
+/**
+ * @file
+ * @internal Add provenance info for netcdf-4 files.
+ *
+ * Copyright 2010, UCAR/Unidata See netcdf/COPYRIGHT file for copying
+ * and redistribution conditions.
+ * @author Dennis Heimbigner
+ */
 #include "config.h"
 #include <stdlib.h>
 #include <string.h>
@@ -10,16 +13,22 @@
 #include "netcdf.h"
 #include "nc4internal.h"
 
-#define IGNORE 0
-
-#define HDF5_MAX_NAME 1024
+#define HDF5_MAX_NAME 1024 /**< HDF5 max name. */
 
+/** @internal Check NetCDF return code. */
 #define NCHECK(expr) {if((expr)!=NC_NOERR) {goto done;}}
+
+/** @internal Check HDF5 return code. */
 #define HCHECK(expr) {if((expr)<0) {ncstat = NC_EHDFERR; goto done;}}
 
-/* Global */
-struct NCPROPINFO globalpropinfo;
+struct NCPROPINFO globalpropinfo; /**< Global property info. */
 
+/**
+ * @internal Initialize file info.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_fileinfo_init(void)
 {
@@ -41,6 +50,15 @@ done:
     return stat;
 }
 
+/**
+ * @internal Parse file properties.
+ *
+ * @param ncprops Property info.
+ * @param text Text properties.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 static int
 NC4_properties_parse(struct NCPROPINFO* ncprops, const char* text)
 {
@@ -93,6 +111,14 @@ done:
     return ret;
 }
 
+/**
+ * @internal Get properties attribure.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 static int
 NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5)
 {
@@ -104,7 +130,6 @@ NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5)
     hid_t aspace = -1;
     hid_t atype = -1;
     hid_t ntype = -1;
-    herr_t herr = 0;
     char* text = NULL;
 
     /* Get root group */
@@ -112,7 +137,6 @@ NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5)
     /* Try to extract the NCPROPS attribute */
     if(H5Aexists(grp,NCPROPS) > 0) { /* Does exist */
         attid = H5Aopen_name(grp, NCPROPS);
-	herr = -1;
 	aspace = H5Aget_space(attid); /* dimensions of attribute data */
         atype = H5Aget_type(attid);
 	/* Verify that atype and size */
@@ -129,7 +153,6 @@ NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5)
 	text[size] = '\0';
 	/* Try to parse text */
 	ncstat = NC4_properties_parse(&h5->fileinfo->propattr,text);
-	herr = 0;
     }
 done:
     if(attid >= 0) HCHECK((H5Aclose(attid)));
@@ -140,6 +163,14 @@ done:
     return ncstat;
 }
 
+/**
+ * @internal Write the properties attribute to file.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
 {
@@ -148,7 +179,6 @@ NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
     hid_t attid = -1;
     hid_t aspace = -1;
     hid_t atype = -1;
-    herr_t herr = 0;
     char* text = NULL;
 
     /* Get root group */
@@ -159,7 +189,6 @@ NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
       if(text == NULL || ncstat != NC_NOERR) {
         goto done;
       }
-      herr = -1;
       /* Create a datatype to refer to. */
       HCHECK((atype = H5Tcopy(H5T_C_S1)));
       HCHECK((H5Tset_cset(atype, H5T_CSET_ASCII)));
@@ -167,7 +196,6 @@ NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
       HCHECK((aspace = H5Screate(H5S_SCALAR)));
       HCHECK((attid = H5Acreate(grp, NCPROPS, atype, aspace, H5P_DEFAULT)));
       HCHECK((H5Awrite(attid, atype, text)));
-      herr = 0;
     }
  done:
     if(text != NULL) {
@@ -181,6 +209,15 @@ NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
     return ncstat;
 }
 
+/**
+ * @internal
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param init Initialization.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_get_fileinfo(NC_HDF5_FILE_INFO_T* h5, struct NCPROPINFO* init)
 {
@@ -203,6 +240,15 @@ done:
     return ncstat;
 }
 
+/**
+ * @internal Build properties attribute.
+ *
+ * @param info Properties info.
+ * @param propdatap Pointer that gets properties data.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_buildpropinfo(struct NCPROPINFO* info,char** propdatap)
 {
diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c
index 89526d8..c865de5 100644
--- a/libsrc4/nc4internal.c
+++ b/libsrc4/nc4internal.c
@@ -1,17 +1,19 @@
-/** \file \internal
-Internal netcdf-4 functions.
-
-This file contains functions internal to the netcdf4 library. None of
-the functions in this file are exposed in the exetnal API. These
-functions all relate to the manipulation of netcdf-4's in-memory
-buffer of metadata information, i.e. the linked list of NC
-structs.
-
-Copyright 2003-2011, University Corporation for Atmospheric
-Research. See the COPYRIGHT file for copying and redistribution
-conditions.
-
-*/
+/**
+ * @file
+ * @internal
+ * Internal netcdf-4 functions.
+ *
+ * This file contains functions internal to the netcdf4 library. None of
+ * the functions in this file are exposed in the exetnal API. These
+ * functions all relate to the manipulation of netcdf-4's in-memory
+ * buffer of metadata information, i.e. the linked list of NC
+ * structs.
+ *
+ * Copyright 2003-2011, University Corporation for Atmospheric
+ * Research. See the COPYRIGHT file for copying and redistribution
+ * conditions.
+ * @author Ed Hartnett
+ */
 #include "config.h"
 #include "nc4internal.h"
 #include "nc.h" /* from libsrc */
@@ -19,33 +21,30 @@ conditions.
 #include "ncutf8.h"
 #include "H5DSpublic.h"
 
-#define MEGABYTE 1048576
-
 #undef DEBUGH5
 
 #ifdef DEBUGH5
-/* Provide a catchable error reporting function */
+/**
+ * @internal Provide a catchable error reporting function
+ *
+ * @param ignored Ignored.
+ *
+ * @return 0 for success.
+ */
 static herr_t
 h5catch(void* ignored)
 {
-    H5Eprint(NULL);
-    return 0;
+   H5Eprint(NULL);
+   return 0;
 }
 #endif
 
-
 /* These are the default chunk cache sizes for HDF5 files created or
  * opened with netCDF-4. */
 extern size_t nc4_chunk_cache_size;
 extern size_t nc4_chunk_cache_nelems;
 extern float nc4_chunk_cache_preemption;
 
-/* This is to track opened HDF5 objects to make sure they are
- * closed. */
-#ifdef EXTRA_TESTS
-extern int num_spaces;
-#endif /* EXTRA_TESTS */
-
 #ifdef LOGGING
 /* This is the severity level of messages which will be logged. Use
    severity 0 for errors, 1 for important log messages, 2 for less
@@ -54,39 +53,64 @@ int nc_log_level = NC_TURN_OFF_LOGGING;
 
 #endif /* LOGGING */
 
-int nc4_hdf5_initialized = 0;
+int nc4_hdf5_initialized = 0; /**< True if initialization has happened. */
 
-/* Provide a wrapper for H5Eset_auto */
+/**
+ * @internal Provide a wrapper for H5Eset_auto
+ * @param func Pointer to func.
+ * @param client_data Client data.
+ *
+ * @return 0 for success
+ */
 static herr_t
 set_auto(void* func, void *client_data)
 {
 #ifdef DEBUGH5
-    return H5Eset_auto2(H5E_DEFAULT,(H5E_auto2_t)h5catch,client_data);
+   return H5Eset_auto2(H5E_DEFAULT,(H5E_auto2_t)h5catch,client_data);
 #else
-    return H5Eset_auto2(H5E_DEFAULT,(H5E_auto2_t)func,client_data);
+   return H5Eset_auto2(H5E_DEFAULT,(H5E_auto2_t)func,client_data);
 #endif
 }
 
-/*
-Provide a function to do any necessary initialization
-of the HDF5 library.
-*/
-
+/**
+ * @internal Provide a function to do any necessary initialization of
+ * the HDF5 library.
+ */
 void
 nc4_hdf5_initialize(void)
 {
-    if (set_auto(NULL, NULL) < 0)
-	LOG((0, "Couldn't turn off HDF5 error messages!"));
-    LOG((1, "HDF5 error messages have been turned off."));
-    nc4_hdf5_initialized = 1;
+   if (set_auto(NULL, NULL) < 0)
+      LOG((0, "Couldn't turn off HDF5 error messages!"));
+   LOG((1, "HDF5 error messages have been turned off."));
+   nc4_hdf5_initialized = 1;
 }
 
-/* Check and normalize and name. */
+/**
+ * @internal Check and normalize and name.
+ *
+ * @param name Name to normalize.
+ * @param norm_name The normalized name.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EMAXNAME Name too long.
+ * @return ::NC_EINVAL NULL given for name.
+ * @author Dennis Heimbigner
+ */
 int
 nc4_check_name(const char *name, char *norm_name)
 {
    char *temp;
    int retval;
+   
+   /* Check for NULL. */
+   if (!name)
+      return NC_EINVAL;
+
+   assert(norm_name);
+   
+   /* Check for NULL. */
+   if (!name)
+      return NC_EINVAL;
 
    /* Check the length. */
    if (strlen(name) > NC_MAX_NAME)
@@ -104,8 +128,8 @@ nc4_check_name(const char *name, char *norm_name)
       return retval;
 
    if(strlen(temp) > NC_MAX_NAME) {
-     free(temp);
-     return NC_EMAXNAME;
+      free(temp);
+      return NC_EMAXNAME;
    }
 
    strcpy(norm_name, temp);
@@ -114,8 +138,18 @@ nc4_check_name(const char *name, char *norm_name)
    return NC_NOERR;
 }
 
-/* Given a varid, return the maximum length of a dimension using dimid */
-
+/**
+ * @internal Given a varid, return the maximum length of a dimension
+ * using dimid.
+ *
+ * @param grp Pointer to group info struct.
+ * @param varid Variable ID.
+ * @param dimid Dimension ID.
+ * @param maxlen Pointer that gets the max length.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid, size_t *maxlen)
 {
@@ -129,7 +163,7 @@ find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid, size_t *maxlen
 
    /* Find this var. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
    if (!var) return NC_ENOTVAR;
    assert(var->varid == varid);
@@ -137,61 +171,65 @@ find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid, size_t *maxlen
    /* If the var hasn't been created yet, its size is 0. */
    if (!var->created)
    {
-     *maxlen = 0;
+      *maxlen = 0;
    }
    else
    {
-     /* Get the number of records in the dataset. */
-     if ((retval = nc4_open_var_grp2(grp, var->varid, &datasetid)))
-       BAIL(retval);
-     if ((spaceid = H5Dget_space(datasetid)) < 0)
-       BAIL(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-     num_spaces++;
-#endif
-     /* If it's a scalar dataset, it has length one. */
-     if (H5Sget_simple_extent_type(spaceid) == H5S_SCALAR)
-     {
-       *maxlen = (var->dimids && var->dimids[0] == dimid) ? 1 : 0;
-     }
-     else
-     {
-       /* Check to make sure ndims is right, then get the len of each
-	  dim in the space. */
-       if ((dataset_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0)
-	 BAIL(NC_EHDFERR);
-       if (dataset_ndims != var->ndims)
-	 BAIL(NC_EHDFERR);
-       if (!(h5dimlen = malloc(dataset_ndims * sizeof(hsize_t))))
-	 BAIL(NC_ENOMEM);
-       if (!(h5dimlenmax = malloc(dataset_ndims * sizeof(hsize_t))))
-	 BAIL(NC_ENOMEM);
-       if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid,
-						      h5dimlen, h5dimlenmax)) < 0)
-	 BAIL(NC_EHDFERR);
-       LOG((5, "find_var_dim_max_length: varid %d len %d max: %d",
-	    varid, (int)h5dimlen[0], (int)h5dimlenmax[0]));
-       for (d=0; d<dataset_ndims; d++) {
-	 if (var->dimids[d] == dimid) {
-	   *maxlen = *maxlen > h5dimlen[d] ? *maxlen : h5dimlen[d];
-	 }
-       }
-     }
+      /* Get the number of records in the dataset. */
+      if ((retval = nc4_open_var_grp2(grp, var->varid, &datasetid)))
+         BAIL(retval);
+      if ((spaceid = H5Dget_space(datasetid)) < 0)
+         BAIL(NC_EHDFERR);
+
+      /* If it's a scalar dataset, it has length one. */
+      if (H5Sget_simple_extent_type(spaceid) == H5S_SCALAR)
+      {
+         *maxlen = (var->dimids && var->dimids[0] == dimid) ? 1 : 0;
+      }
+      else
+      {
+         /* Check to make sure ndims is right, then get the len of each
+            dim in the space. */
+         if ((dataset_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0)
+            BAIL(NC_EHDFERR);
+         if (dataset_ndims != var->ndims)
+            BAIL(NC_EHDFERR);
+         if (!(h5dimlen = malloc(dataset_ndims * sizeof(hsize_t))))
+            BAIL(NC_ENOMEM);
+         if (!(h5dimlenmax = malloc(dataset_ndims * sizeof(hsize_t))))
+            BAIL(NC_ENOMEM);
+         if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid,
+                                                        h5dimlen, h5dimlenmax)) < 0)
+            BAIL(NC_EHDFERR);
+         LOG((5, "find_var_dim_max_length: varid %d len %d max: %d",
+              varid, (int)h5dimlen[0], (int)h5dimlenmax[0]));
+         for (d=0; d<dataset_ndims; d++) {
+            if (var->dimids[d] == dimid) {
+               *maxlen = *maxlen > h5dimlen[d] ? *maxlen : h5dimlen[d];
+            }
+         }
+      }
    }
 
-  exit:
+exit:
    if (spaceid > 0 && H5Sclose(spaceid) < 0)
       BAIL2(NC_EHDFERR);
-#ifdef EXTRA_TESTS
-   num_spaces--;
-#endif
    if (h5dimlen) free(h5dimlen);
    if (h5dimlenmax) free(h5dimlenmax);
    return retval;
 }
 
-/* Given an NC pointer, add the necessary stuff for a
- * netcdf-4 file. */
+/**
+ * @internal Given an NC pointer, add the necessary stuff for a
+ * netcdf-4 file.
+ *
+ * @param nc Pointer to file's NC struct.
+ * @param path The file name of the new file.
+ * @param mode The mode flag.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_nc4f_list_add(NC *nc, const char *path, int mode)
 {
@@ -217,12 +255,22 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode)
     * group. Allocate space for one group's worth of information. Set
     * its hdf id, name, and a pointer to it's file structure. */
    return nc4_grp_list_add(&(h5->root_grp), h5->next_nc_grpid++,
-			   NULL, nc, NC_GROUP_NAME, NULL);
+                           NULL, nc, NC_GROUP_NAME, NULL);
 }
 
-/* Given an ncid, find the relevant group and return a pointer to it,
- * return an error of this is not a netcdf-4 file (or if strict nc3 is
- * turned on for this file.) */
+/**
+ * @internal Given an ncid, find the relevant group and return a
+ * pointer to it, return an error of this is not a netcdf-4 file (or
+ * if strict nc3 is turned on for this file.)
+ *
+ * @param ncid File and group ID.
+ * @param grp Pointer that gets pointer to group info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @return ::NC_ESTRICTNC3 Not allowed for classic model.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp)
 {
@@ -244,61 +292,91 @@ nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp)
    return NC_NOERR;
 }
 
-/* Given an ncid, find the relevant group and return a pointer to it,
- * also set a pointer to the nc4_info struct of the related file. For
- * netcdf-3 files, *h5 will be set to NULL. */
+/**
+ * @internal Given an ncid, find the relevant group and return a
+ * pointer to it, also set a pointer to the nc4_info struct of the
+ * related file. For netcdf-3 files, *h5 will be set to NULL.
+ *
+ * @param ncid File and group ID.
+ * @param grpp Pointer that gets pointer to group info struct.
+ * @param h5p Pointer to HDF5 file struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grpp, NC_HDF5_FILE_INFO_T **h5p)
 {
-    NC_HDF5_FILE_INFO_T *h5;
-    NC_GRP_INFO_T *grp;
-    NC *f = nc4_find_nc_file(ncid,&h5);
-    if(f == NULL) return NC_EBADID;
-    if (h5) {
-        assert(h5->root_grp);
-        /* If we can't find it, the grp id part of ncid is bad. */
-	if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
-  	    return NC_EBADID;
-	h5 = (grp)->nc4_info;
-	assert(h5);
-    } else {
-	h5 = NULL;
-	grp = NULL;
-    }
-    if(h5p) *h5p = h5;
-    if(grpp) *grpp = grp;
-    return NC_NOERR;
+   NC_HDF5_FILE_INFO_T *h5;
+   NC_GRP_INFO_T *grp;
+   NC *f = nc4_find_nc_file(ncid,&h5);
+   if(f == NULL) return NC_EBADID;
+   if (h5) {
+      assert(h5->root_grp);
+      /* If we can't find it, the grp id part of ncid is bad. */
+      if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
+         return NC_EBADID;
+      h5 = (grp)->nc4_info;
+      assert(h5);
+   } else {
+      h5 = NULL;
+      grp = NULL;
+   }
+   if(h5p) *h5p = h5;
+   if(grpp) *grpp = grp;
+   return NC_NOERR;
 }
 
+/**
+ * @internal Find info for this file and group, and set pointer to each.
+ *
+ * @param ncid File and group ID.
+ * @param nc Pointer that gets a pointer to the file's NC struct.
+ * @param grpp Pointer that gets a pointer to the group struct.
+ * @param h5p Pointer that gets HDF5 file struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_nc_grp_h5(int ncid, NC **nc, NC_GRP_INFO_T **grpp,
-		   NC_HDF5_FILE_INFO_T **h5p)
+                   NC_HDF5_FILE_INFO_T **h5p)
 {
-    NC_GRP_INFO_T *grp;
-    NC_HDF5_FILE_INFO_T* h5;
-    NC *f = nc4_find_nc_file(ncid,&h5);
-
-    if(f == NULL) return NC_EBADID;
-    *nc = f;
-
-    if (h5) {
-	assert(h5->root_grp);
-	/* If we can't find it, the grp id part of ncid is bad. */
-	if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
-	       return NC_EBADID;
-
-	h5 = (grp)->nc4_info;
-	assert(h5);
-    } else {
-	h5 = NULL;
-	grp = NULL;
-    }
-    if(h5p) *h5p = h5;
-    if(grpp) *grpp = grp;
-    return NC_NOERR;
+   NC_GRP_INFO_T *grp;
+   NC_HDF5_FILE_INFO_T* h5;
+   NC *f = nc4_find_nc_file(ncid,&h5);
+
+   if(f == NULL) return NC_EBADID;
+   *nc = f;
+
+   if (h5) {
+      assert(h5->root_grp);
+      /* If we can't find it, the grp id part of ncid is bad. */
+      if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
+         return NC_EBADID;
+
+      h5 = (grp)->nc4_info;
+      assert(h5);
+   } else {
+      h5 = NULL;
+      grp = NULL;
+   }
+   if(h5p) *h5p = h5;
+   if(grpp) *grpp = grp;
+   return NC_NOERR;
 }
 
-/* Recursively hunt for a group id. */
+/**
+ * @internal Recursively hunt for a group id.
+ *
+ * @param start_grp Pointer to group where search should be started.
+ * @param target_nc_grpid Group ID to be found.
+ *
+ * @return Pointer to group info struct, or NULL if not found.
+ * @author Ed Hartnett
+ */
 NC_GRP_INFO_T *
 nc4_rec_find_grp(NC_GRP_INFO_T *start_grp, int target_nc_grpid)
 {
@@ -313,18 +391,28 @@ nc4_rec_find_grp(NC_GRP_INFO_T *start_grp, int target_nc_grpid)
    /* Shake down the kids. */
    if (start_grp->children)
       for (g = start_grp->children; g; g = g->l.next)
-	 if ((res = nc4_rec_find_grp(g, target_nc_grpid)))
-	    return res;
+         if ((res = nc4_rec_find_grp(g, target_nc_grpid)))
+            return res;
 
    /* Can't find it. Fate, why do you mock me? */
    return NULL;
 }
 
-/* Given an ncid and varid, get pointers to the group and var
- * metadata. */
+/**
+ * @internal Given an ncid and varid, get pointers to the group and var
+ * metadata.
+ *
+ * @param nc Pointer to file's NC struct.
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param grp Pointer that gets pointer to group info.
+ * @param var Pointer that gets pointer to var info.
+ *
+ * @return ::NC_NOERR No error.
+ */
 int
 nc4_find_g_var_nc(NC *nc, int ncid, int varid,
-		  NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var)
+                  NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var)
 {
    NC_HDF5_FILE_INFO_T* h5 = NC4_DATA(nc);
 
@@ -335,20 +423,31 @@ nc4_find_g_var_nc(NC *nc, int ncid, int varid,
    /* It is possible for *grp to be NULL. If it is,
       return an error. */
    if(*grp == NULL)
-     return NC_ENOTVAR;
+      return NC_EBADID;
 
    /* Find the var info. */
    if (varid < 0 || varid >= (*grp)->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    (*var) = (*grp)->vars.value[varid];
 
    return NC_NOERR;
 }
 
-/* Find a dim in a grp (or parents). */
+/**
+ * @internal Find a dim in a grp (or its parents).
+ *
+ * @param grp Pointer to group info struct.
+ * @param dimid Dimension ID to find.
+ * @param dim Pointer that gets pointer to dim info if found.
+ * @param dim_grp Pointer that gets pointer to group info of group that contians dimension.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADDIM Dimension not found.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
-	     NC_GRP_INFO_T **dim_grp)
+             NC_GRP_INFO_T **dim_grp)
 {
    NC_GRP_INFO_T *g, *dg = NULL;
    int finished = 0;
@@ -358,16 +457,16 @@ nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
    /* Find the dim info. */
    for (g = grp; g && !finished; g = g->parent)
       for ((*dim) = g->dim; (*dim); (*dim) = (*dim)->l.next)
-	 if ((*dim)->dimid == dimid)
-	 {
-	    dg = g;
-	    finished++;
-	    break;
-	 }
+         if ((*dim)->dimid == dimid)
+         {
+            dg = g;
+            finished++;
+            break;
+         }
 
    /* If we didn't find it, return an error. */
    if (!(*dim))
-     return NC_EBADDIM;
+      return NC_EBADDIM;
 
    /* Give the caller the group the dimension is in. */
    if (dim_grp)
@@ -376,27 +475,44 @@ nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
    return NC_NOERR;
 }
 
-/* Find a var (by name) in a grp. */
+/**
+ * @internal Find a var (by name) in a grp.
+ *
+ * @param grp Pointer to group info.
+ * @param name Name of var to find.
+ * @param var Pointer that gets pointer to var info struct, if found.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_var(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var)
 {
-  int i;
+   int i;
    assert(grp && var && name);
 
    /* Find the var info. */
    *var = NULL;
    for (i=0; i < grp->vars.nelems; i++)
    {
-     if (0 == strcmp(name, grp->vars.value[i]->name))
-     {
-       *var = grp->vars.value[i];
-       break;
-     }
+      if (0 == strcmp(name, grp->vars.value[i]->name))
+      {
+         *var = grp->vars.value[i];
+         break;
+      }
    }
    return NC_NOERR;
 }
 
-/* Recursively hunt for a HDF type id. */
+/**
+ * @internal Recursively hunt for a HDF type id.
+ *
+ * @param start_grp Pointer to starting group info.
+ * @param target_hdf_typeid HDF5 type ID to find.
+ *
+ * @return Pointer to type info struct, or NULL if not found.
+ * @author Ed Hartnett
+ */
 NC_TYPE_INFO_T *
 nc4_rec_find_hdf_type(NC_GRP_INFO_T *start_grp, hid_t target_hdf_typeid)
 {
@@ -410,22 +526,30 @@ nc4_rec_find_hdf_type(NC_GRP_INFO_T *start_grp, hid_t target_hdf_typeid)
    for (type = start_grp->type; type; type = type->l.next)
    {
       if ((equal = H5Tequal(type->native_hdf_typeid ? type->native_hdf_typeid : type->hdf_typeid, target_hdf_typeid)) < 0)
-	 return NULL;
+         return NULL;
       if (equal)
-	 return type;
+         return type;
    }
 
    /* Shake down the kids. */
    if (start_grp->children)
       for (g = start_grp->children; g; g = g->l.next)
-	 if ((res = nc4_rec_find_hdf_type(g, target_hdf_typeid)))
-	    return res;
+         if ((res = nc4_rec_find_hdf_type(g, target_hdf_typeid)))
+            return res;
 
    /* Can't find it. Fate, why do you mock me? */
    return NULL;
 }
 
-/* Recursively hunt for a netCDF type by name. */
+/**
+ * @internal Recursively hunt for a netCDF type by name.
+ *
+ * @param start_grp Pointer to starting group info.
+ * @param name Name of type to find.
+ *
+ * @return Pointer to type info, or NULL if not found.
+ * @author Ed Hartnett
+ */
 NC_TYPE_INFO_T *
 nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name)
 {
@@ -437,19 +561,27 @@ nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name)
    /* Does this group have the type we are searching for? */
    for (type = start_grp->type; type; type = type->l.next)
       if (!strcmp(type->name, name))
-	 return type;
+         return type;
 
    /* Search subgroups. */
    if (start_grp->children)
       for (g = start_grp->children; g; g = g->l.next)
-	 if ((res = nc4_rec_find_named_type(g, name)))
-	    return res;
+         if ((res = nc4_rec_find_named_type(g, name)))
+            return res;
 
    /* Can't find it. Oh, woe is me! */
    return NULL;
 }
 
-/* Recursively hunt for a netCDF type id. */
+/**
+ * @internal Recursively hunt for a netCDF type id. 
+ *
+ * @param start_grp Pointer to starting group info.
+ * @param target_nc_typeid NetCDF type ID to find.
+ *
+ * @return Pointer to type info, or NULL if not found.
+ * @author Ed Hartnett
+ */
 NC_TYPE_INFO_T *
 nc4_rec_find_nc_type(const NC_GRP_INFO_T *start_grp, nc_type target_nc_typeid)
 {
@@ -460,7 +592,7 @@ nc4_rec_find_nc_type(const NC_GRP_INFO_T *start_grp, nc_type target_nc_typeid)
    /* Does this group have the type we are searching for? */
    for (type = start_grp->type; type; type = type->l.next)
       if (type->nc_typeid == target_nc_typeid)
-	 return type;
+         return type;
 
    /* Shake down the kids. */
    if (start_grp->children)
@@ -471,8 +603,8 @@ nc4_rec_find_nc_type(const NC_GRP_INFO_T *start_grp, nc_type target_nc_typeid)
       {
          NC_TYPE_INFO_T *res;
 
-	 if ((res = nc4_rec_find_nc_type(g, target_nc_typeid)))
-	    return res;
+         if ((res = nc4_rec_find_nc_type(g, target_nc_typeid)))
+            return res;
       }
    }
 
@@ -480,7 +612,17 @@ nc4_rec_find_nc_type(const NC_GRP_INFO_T *start_grp, nc_type target_nc_typeid)
    return NULL;
 }
 
-/* Use a netCDF typeid to find a type in a type_list. */
+/**
+ * @internal Use a netCDF typeid to find a type in a type_list.
+ *
+ * @param h5 Pointer to HDF5 file info struct.
+ * @param typeid The netCDF type ID.
+ * @param type Pointer to pointer to the list of type info structs.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EINVAL Invalid input.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_type(const NC_HDF5_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type)
 {
@@ -500,9 +642,18 @@ nc4_find_type(const NC_HDF5_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **ty
    return NC_NOERR;
 }
 
-/* Find the actual length of a dim by checking the length of that dim
- * in all variables that use it, in grp or children. **len must be
- * initialized to zero before this function is called. */
+/**
+ * @internal Find the actual length of a dim by checking the length of
+ * that dim in all variables that use it, in grp or children. **len
+ * must be initialized to zero before this function is called.
+ *
+ * @param grp Pointer to group info struct.
+ * @param dimid Dimension ID.
+ * @param len Pointer to pointer that gets length.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len)
 {
@@ -518,37 +669,51 @@ nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len)
     * them. */
    for (g = grp->children; g; g = g->l.next)
       if ((retval = nc4_find_dim_len(g, dimid, len)))
-	 return retval;
+         return retval;
 
    /* For all variables in this group, find the ones that use this
     * dimension, and remember the max length. */
    for (i=0; i < grp->vars.nelems; i++)
    {
-     size_t mylen;
-     var = grp->vars.value[i];
-     if (!var) continue;
+      size_t mylen;
+      var = grp->vars.value[i];
+      if (!var) continue;
 
-     /* Find max length of dim in this variable... */
-     if ((retval = find_var_dim_max_length(grp, var->varid, dimid, &mylen)))
-       return retval;
+      /* Find max length of dim in this variable... */
+      if ((retval = find_var_dim_max_length(grp, var->varid, dimid, &mylen)))
+         return retval;
 
-     **len = **len > mylen ? **len : mylen;
+      **len = **len > mylen ? **len : mylen;
    }
 
    return NC_NOERR;
 }
 
 /* Given a group, find an att. */
+/**
+ * @internal
+ *
+ * @param grp Pointer to group info struct.
+ * @param varid Variable ID.
+ * @param name Name to of attribute.
+ * @param attnum Number of attribute.
+ * @param att Pointer to pointer that gets attribute info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOTVAR Variable not found.
+ * @return ::NC_ENOTATT Attribute not found.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
-		 NC_ATT_INFO_T **att)
+                 NC_ATT_INFO_T **att)
 {
    NC_VAR_INFO_T *var;
    NC_ATT_INFO_T *attlist = NULL;
 
    assert(grp && grp->name);
    LOG((4, "nc4_find_grp_att: grp->name %s varid %d name %s attnum %d",
-	grp->name, varid, name, attnum));
+        grp->name, varid, name, attnum));
 
    /* Get either the global or a variable attribute list. */
    if (varid == NC_GLOBAL)
@@ -556,7 +721,7 @@ nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
    else
    {
       if (varid < 0 || varid >= grp->vars.nelems)
-	return NC_ENOTVAR;
+         return NC_ENOTVAR;
       var = grp->vars.value[varid];
       if (!var) return NC_ENOTVAR;
       attlist = var->att;
@@ -566,22 +731,35 @@ nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
    /* Now find the attribute by name or number. If a name is provided,
     * ignore the attnum. */
    if(attlist)
-       for (*att = attlist; *att; *att = (*att)->l.next) {
-           if (name && (*att)->name && !strcmp((*att)->name, name))
-	       return NC_NOERR;
-           if (!name && (*att)->attnum == attnum)
-	       return NC_NOERR;
-       }
+      for (*att = attlist; *att; *att = (*att)->l.next) {
+         if (name && (*att)->name && !strcmp((*att)->name, name))
+            return NC_NOERR;
+         if (!name && (*att)->attnum == attnum)
+            return NC_NOERR;
+      }
 
    /* If we get here, we couldn't find the attribute. */
    return NC_ENOTATT;
 }
 
-/* Given an ncid, varid, and name or attnum, find and return pointer
-   to NC_ATT_INFO_T metadata. */
+/**
+ * @internal Given an ncid, varid, and name or attnum, find and return
+ * pointer to NC_ATT_INFO_T metadata.
+ *
+ * @param ncid File and group ID.
+ * @param varid Variable ID.
+ * @param name Name to of attribute.
+ * @param attnum Number of attribute.
+ * @param att Pointer to pointer that gets attribute info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOTVAR Variable not found.
+ * @return ::NC_ENOTATT Attribute not found.
+ * @author Ed Hartnett
+ */
 int
 nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
-	    NC_ATT_INFO_T **att)
+                NC_ATT_INFO_T **att)
 {
    NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
@@ -590,7 +768,7 @@ nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
    int retval;
 
    LOG((4, "nc4_find_nc_att: ncid 0x%x varid %d name %s attnum %d",
-	ncid, varid, name, attnum));
+        ncid, varid, name, attnum));
 
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
@@ -603,7 +781,7 @@ nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
    else
    {
       if (varid < 0 || varid >= grp->vars.nelems)
-	return NC_ENOTVAR;
+         return NC_ENOTVAR;
       var = grp->vars.value[varid];
       if (!var) return NC_ENOTVAR;
       attlist = var->att;
@@ -613,16 +791,23 @@ nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
    /* Now find the attribute by name or number. If a name is provided, ignore the attnum. */
    for (*att = attlist; *att; *att = (*att)->l.next)
       if ((name && !strcmp((*att)->name, name)) ||
-	  (!name && (*att)->attnum == attnum))
-	 return NC_NOERR;
+          (!name && (*att)->attnum == attnum))
+         return NC_NOERR;
 
    /* If we get here, we couldn't find the attribute. */
    return NC_ENOTATT;
 }
 
 
-/* Given an id, walk the list and find the appropriate
-   NC. */
+/**
+ * @internal Given an id, walk the list and find the appropriate NC.
+ *
+ * @param ext_ncid File/group ID to find.
+ * @param h5p Pointer to pointer that gets the HDF5 file info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 NC*
 nc4_find_nc_file(int ext_ncid, NC_HDF5_FILE_INFO_T** h5p)
 {
@@ -631,15 +816,23 @@ nc4_find_nc_file(int ext_ncid, NC_HDF5_FILE_INFO_T** h5p)
 
    stat = NC_check_id(ext_ncid,&nc);
    if(stat != NC_NOERR)
-	nc = NULL;
+      nc = NULL;
 
    if(nc)
-     if(h5p) *h5p = (NC_HDF5_FILE_INFO_T*)nc->dispatchdata;
+      if(h5p) *h5p = (NC_HDF5_FILE_INFO_T*)nc->dispatchdata;
 
    return nc;
 }
 
-/* Add object to the end of a list. */
+/**
+ * @internal Add object to the end of a list.
+ *
+ * @param list List
+ * @param obj Pointer to object to add.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static void
 obj_list_add(NC_LIST_NODE_T **list, NC_LIST_NODE_T *obj)
 {
@@ -650,8 +843,8 @@ obj_list_add(NC_LIST_NODE_T **list, NC_LIST_NODE_T *obj)
       NC_LIST_NODE_T *o;
 
       for (o = *list; o; o = o->next)
-	 if (!o->next)
-	    break;
+         if (!o->next)
+            break;
       o->next = obj;
       obj->prev = o;
    }
@@ -659,7 +852,15 @@ obj_list_add(NC_LIST_NODE_T **list, NC_LIST_NODE_T *obj)
       *list = obj;
 }
 
-/* Remove object from a list. */
+/**
+ * @internal Remove object from a list.
+ *
+ * @param list List
+ * @param obj Pointer to object to delete.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static void
 obj_list_del(NC_LIST_NODE_T **list, NC_LIST_NODE_T *obj)
 {
@@ -673,7 +874,15 @@ obj_list_del(NC_LIST_NODE_T **list, NC_LIST_NODE_T *obj)
       ((NC_LIST_NODE_T *)obj->next)->prev = obj->prev;
 }
 
-/* Return a pointer to the new var. */
+/**
+ * @internal Return a pointer to the new var.
+ *
+ * @param var Pointer to pointer that gets variable info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+ */
 int
 nc4_var_add(NC_VAR_INFO_T **var)
 {
@@ -692,12 +901,20 @@ nc4_var_add(NC_VAR_INFO_T **var)
    if (var)
       *var = new_var;
    else
-     free(new_var);
+      free(new_var);
 
    return NC_NOERR;
 }
 
-/* Add to the beginning of a dim list. */
+/**
+ * @internal Add to the beginning of a dim list.
+ *
+ * @param list List of dimension info structs.
+ * @param dim Pointer to pointer that gets the new dim info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_dim_list_add(NC_DIM_INFO_T **list, NC_DIM_INFO_T **dim)
 {
@@ -716,7 +933,15 @@ nc4_dim_list_add(NC_DIM_INFO_T **list, NC_DIM_INFO_T **dim)
    return NC_NOERR;
 }
 
-/* Add to the end of an att list. */
+/**
+ * @internal Add to the end of an att list.
+ *
+ * @param list List of att info structs.
+ * @param att Pointer to pointer that gets the new att info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_att_list_add(NC_ATT_INFO_T **list, NC_ATT_INFO_T **att)
 {
@@ -735,12 +960,24 @@ nc4_att_list_add(NC_ATT_INFO_T **list, NC_ATT_INFO_T **att)
    return NC_NOERR;
 }
 
-/* Add to the end of a group list. Can't use 0 as a new_nc_grpid -
- * it's reserverd for the root group. */
+/**
+ * @internal Add to the end of a group list. Can't use 0 as a
+ * new_nc_grpid - it's reserverd for the root group.
+ *
+ * @param list List
+ * @param new_nc_grpid New group ID.
+ * @param parent_grp The parent group.
+ * @param nc Pointer to the file's NC struct.
+ * @param name Name of the group.
+ * @param grp Pointer to pointer that gets new group info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_grp_list_add(NC_GRP_INFO_T **list, int new_nc_grpid,
-		 NC_GRP_INFO_T *parent_grp, NC *nc,
-		 char *name, NC_GRP_INFO_T **grp)
+                 NC_GRP_INFO_T *parent_grp, NC *nc,
+                 char *name, NC_GRP_INFO_T **grp)
 {
    NC_GRP_INFO_T *new_grp;
 
@@ -765,15 +1002,24 @@ nc4_grp_list_add(NC_GRP_INFO_T **list, int new_nc_grpid,
 
    /* Set the group pointer, if one was given */
    if (grp)
-       *grp = new_grp;
+      *grp = new_grp;
 
    return NC_NOERR;
 }
 
-/* Names for groups, variables, and types must not be the same. This
- * function checks that a proposed name is not already in
+/**
+ * @internal Names for groups, variables, and types must not be the
+ * same. This function checks that a proposed name is not already in
  * use. Normalzation of UTF8 strings should happen before this
- * function is called. */
+ * function is called.
+ *
+ * @param grp Pointer to group info struct.
+ * @param name Name to check.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENAMEINUSE Name is in use.
+ * @author Ed Hartnett
+ */
 int
 nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name)
 {
@@ -786,12 +1032,12 @@ nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name)
    /* Any types of this name? */
    for (type = grp->type; type; type = type->l.next)
       if (!strcmp(type->name, name))
-	 return NC_ENAMEINUSE;
+         return NC_ENAMEINUSE;
 
    /* Any child groups of this name? */
    for (g = grp->children; g; g = g->l.next)
       if (!strcmp(g->name, name))
-	 return NC_ENAMEINUSE;
+         return NC_ENAMEINUSE;
 
    /* Any variables of this name? */
    hash =  hash_fast(name, strlen(name));
@@ -800,12 +1046,24 @@ nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name)
       var = grp->vars.value[i];
       if (!var) continue;
       if (var->hash == hash && !strcmp(var->name, name))
-	 return NC_ENAMEINUSE;
+         return NC_ENAMEINUSE;
    }
    return NC_NOERR;
 }
 
-/* Add to the end of a type list. */
+/**
+ * @internal Add to the end of a type list.
+ *
+ * @param grp Pointer to group info struct.
+ * @param size Size of type in bytes.
+ * @param name Name of type.
+ * @param type Pointer that gets pointer to new type info
+ * struct. Ignored if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+ */
 int
 nc4_type_list_add(NC_GRP_INFO_T *grp, size_t size, const char *name,
                   NC_TYPE_INFO_T **type)
@@ -835,11 +1093,26 @@ nc4_type_list_add(NC_GRP_INFO_T *grp, size_t size, const char *name,
    return NC_NOERR;
 }
 
-/* Add to the end of a compound field list. */
+/**
+ * @internal Add to the end of a compound field list.
+ *
+ * @param list Pointer to pointer of list of field info structs.
+ * @param fieldid The ID of this field.
+ * @param name Name of the field.
+ * @param offset Offset in bytes.
+ * @param field_hdf_typeid The HDF5 type ID of the field.
+ * @param native_typeid The HDF5 native type ID of the field.
+ * @param xtype The netCDF type of the field.
+ * @param ndims The number of dimensions of the field.
+ * @param dim_sizesp An array of dim sizes for the field.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_field_list_add(NC_FIELD_INFO_T **list, int fieldid, const char *name,
-		   size_t offset, hid_t field_hdf_typeid, hid_t native_typeid,
-		   nc_type xtype, int ndims, const int *dim_sizesp)
+                   size_t offset, hid_t field_hdf_typeid, hid_t native_typeid,
+                   nc_type xtype, int ndims, const int *dim_sizesp)
 {
    NC_FIELD_INFO_T *field;
 
@@ -871,10 +1144,10 @@ nc4_field_list_add(NC_FIELD_INFO_T **list, int fieldid, const char *name,
       {
          free(field->name);
          free(field);
-	 return NC_ENOMEM;
+         return NC_ENOMEM;
       }
       for (i = 0; i < ndims; i++)
-	 field->dim_size[i] = dim_sizesp[i];
+         field->dim_size[i] = dim_sizesp[i];
    }
 
    /* Add object to list */
@@ -883,10 +1156,21 @@ nc4_field_list_add(NC_FIELD_INFO_T **list, int fieldid, const char *name,
    return NC_NOERR;
 }
 
-/* Add a member to an enum type. */
+/**
+ * @internal Add a member to an enum type.
+ *
+ * @param list Pointer to pointer of list of enum member info structs.
+ * @param size Size in bytes of new member.
+ * @param name Name of the member.
+ * @param value Value to associate with member.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+ */
 int
 nc4_enum_member_add(NC_ENUM_MEMBER_INFO_T **list, size_t size,
-		    const char *name, const void *value)
+                    const char *name, const void *value)
 {
    NC_ENUM_MEMBER_INFO_T *member;
 
@@ -916,7 +1200,15 @@ nc4_enum_member_add(NC_ENUM_MEMBER_INFO_T **list, size_t size,
    return NC_NOERR;
 }
 
-/* Delete a field from a field list, and nc_free the memory. */
+/**
+ * @internal Delete a field from a field list, and nc_free the memory.
+ *
+ * @param list Pointer to pointer of list of field info structs.
+ * @param field Pointer to field info of field to delete.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static void
 field_list_del(NC_FIELD_INFO_T **list, NC_FIELD_INFO_T *field)
 {
@@ -933,7 +1225,14 @@ field_list_del(NC_FIELD_INFO_T **list, NC_FIELD_INFO_T *field)
    free(field);
 }
 
-/* Free allocated space for type information. */
+/**
+ * @internal Free allocated space for type information.
+ *
+ * @param type Pointer to type info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_type_free(NC_TYPE_INFO_T *type)
 {
@@ -957,50 +1256,50 @@ nc4_type_free(NC_TYPE_INFO_T *type)
       /* Class-specific cleanup */
       switch (type->nc_type_class)
       {
-         case NC_COMPOUND:
-            {
-               NC_FIELD_INFO_T *field;
+      case NC_COMPOUND:
+      {
+         NC_FIELD_INFO_T *field;
 
-               /* Delete all the fields in this type (there will be some if its a
-               * compound). */
-               field = type->u.c.field;
-               while (field)
-               {
-                  NC_FIELD_INFO_T *f = field->l.next;
+         /* Delete all the fields in this type (there will be some if its a
+          * compound). */
+         field = type->u.c.field;
+         while (field)
+         {
+            NC_FIELD_INFO_T *f = field->l.next;
 
-                  field_list_del(&type->u.c.field, field);
-                  field = f;
-               }
-            }
-            break;
+            field_list_del(&type->u.c.field, field);
+            field = f;
+         }
+      }
+      break;
 
-         case NC_ENUM:
-            {
-               NC_ENUM_MEMBER_INFO_T *enum_member;
+      case NC_ENUM:
+      {
+         NC_ENUM_MEMBER_INFO_T *enum_member;
 
-               /* Delete all the enum_members, if any. */
-               enum_member = type->u.e.enum_member;
-               while (enum_member)
-               {
-                  NC_ENUM_MEMBER_INFO_T *em = enum_member->l.next;
+         /* Delete all the enum_members, if any. */
+         enum_member = type->u.e.enum_member;
+         while (enum_member)
+         {
+            NC_ENUM_MEMBER_INFO_T *em = enum_member->l.next;
 
-                  free(enum_member->value);
-                  free(enum_member->name);
-                  free(enum_member);
-                  enum_member = em;
-               }
+            free(enum_member->value);
+            free(enum_member->name);
+            free(enum_member);
+            enum_member = em;
+         }
 
-               if (H5Tclose(type->u.e.base_hdf_typeid) < 0)
-                  return NC_EHDFERR;
-            }
-            break;
+         if (H5Tclose(type->u.e.base_hdf_typeid) < 0)
+            return NC_EHDFERR;
+      }
+      break;
 
-         case NC_VLEN:
-            if (H5Tclose(type->u.v.base_hdf_typeid) < 0)
-               return NC_EHDFERR;
+      case NC_VLEN:
+         if (H5Tclose(type->u.v.base_hdf_typeid) < 0)
+            return NC_EHDFERR;
 
-         default:
-            break;
+      default:
+         break;
       }
 
       /* Release the memory. */
@@ -1010,7 +1309,14 @@ nc4_type_free(NC_TYPE_INFO_T *type)
    return NC_NOERR;
 }
 
-/* Delete a var, and free the memory. */
+/**
+ * @internal  Delete a var, and free the memory.
+ *
+ * @param var Pointer to the var info struct of var to delete.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_var_del(NC_VAR_INFO_T *var)
 {
@@ -1018,7 +1324,7 @@ nc4_var_del(NC_VAR_INFO_T *var)
    int ret;
 
    if(var == NULL)
-     return NC_NOERR;
+      return NC_NOERR;
 
    /* First delete all the attributes attached to this var. */
    att = var->att;
@@ -1026,25 +1332,25 @@ nc4_var_del(NC_VAR_INFO_T *var)
    {
       a = att->l.next;
       if ((ret = nc4_att_list_del(&var->att, att)))
-	 return ret;
+         return ret;
       att = a;
    }
 
    /* Free some things that may be allocated. */
    if (var->chunksizes)
-     {free(var->chunksizes);var->chunksizes = NULL;}
+   {free(var->chunksizes);var->chunksizes = NULL;}
 
    if (var->hdf5_name)
-     {free(var->hdf5_name); var->hdf5_name = NULL;}
+   {free(var->hdf5_name); var->hdf5_name = NULL;}
 
    if (var->name)
-     {free(var->name); var->name = NULL;}
+   {free(var->name); var->name = NULL;}
 
    if (var->dimids)
-     {free(var->dimids); var->dimids = NULL;}
+   {free(var->dimids); var->dimids = NULL;}
 
    if (var->dim)
-     {free(var->dim); var->dim = NULL;}
+   {free(var->dim); var->dim = NULL;}
 
    /* Delete any fill value allocation. This must be done before the
     * type_info is freed. */
@@ -1070,7 +1376,7 @@ nc4_var_del(NC_VAR_INFO_T *var)
       int retval;
 
       if ((retval = nc4_type_free(var->type_info)))
-          return retval;
+         return retval;
       var->type_info = NULL;
    }
 
@@ -1082,13 +1388,25 @@ nc4_var_del(NC_VAR_INFO_T *var)
    if (var->dimscale_attached)
       free(var->dimscale_attached);
 
+   /* Release parameter information. */
+   if (var->params)
+      free(var->params);
+
    /* Delete the var. */
    free(var);
 
    return NC_NOERR;
 }
 
-/* Delete a type from a type list, and nc_free the memory. */
+/**
+ * @internal Delete a type from a type list, and nc_free the memory.
+ *
+ * @param list Pointer to pointer of list of types.
+ * @param type Pointer to type info struct of type to delete.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 type_list_del(NC_TYPE_INFO_T **list, NC_TYPE_INFO_T *type)
 {
@@ -1099,7 +1417,15 @@ type_list_del(NC_TYPE_INFO_T **list, NC_TYPE_INFO_T *type)
    return nc4_type_free(type);
 }
 
-/* Delete a del from a var list, and nc_free the memory. */
+/**
+ * @internal Delete a del from a var list, and nc_free the memory.
+ *
+ * @param list Pointer to pointer of list of dims.
+ * @param dim Pointer to dim info struct of type to delete.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim)
 {
@@ -1114,8 +1440,16 @@ nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim)
    return NC_NOERR;
 }
 
-/* Remove a NC_GRP_INFO_T from the linked list. This will nc_free the
-   memory too. */
+/**
+ * @internal Remove a NC_GRP_INFO_T from the linked list. This will
+ * nc_free the memory too.
+ *
+ * @param list Pointer to pointer of list of group info structs.
+ * @param grp Pointer to group info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static void
 grp_list_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
 {
@@ -1125,8 +1459,16 @@ grp_list_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
    free(grp);
 }
 
-/* Recursively delete the data for a group (and everything it
- * contains) in our internal metadata store. */
+/**
+ * @internal Recursively delete the data for a group (and everything
+ * it contains) in our internal metadata store.
+ *
+ * @param list Pointer to pointer of list.
+ * @param grp Pointer to group info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
 {
@@ -1148,7 +1490,7 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
    {
       c = g->l.next;
       if ((retval = nc4_rec_grp_del(&(grp->children), g)))
-	 return retval;
+         return retval;
       g = c;
    }
 
@@ -1160,7 +1502,7 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
       LOG((4, "%s: deleting att %s", __func__, att->name));
       a = att->l.next;
       if ((retval = nc4_att_list_del(&grp->att, att)))
-	 return retval;
+         return retval;
       att = a;
    }
 
@@ -1174,9 +1516,9 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
       /* Close HDF5 dataset associated with this var, unless it's a
        * scale. */
       if (var->hdf_datasetid && H5Dclose(var->hdf_datasetid) < 0)
-	 return NC_EHDFERR;
+         return NC_EHDFERR;
       if ((retval = nc4_var_del(var)))
-	 return retval;
+         return retval;
       grp->vars.value[i] = NULL;
    }
 
@@ -1184,10 +1526,10 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
       then need to iterate value and free vars from it.
    */
    if (grp->vars.nalloc != 0) {
-     assert(grp->vars.value != NULL);
-     free(grp->vars.value);
-     grp->vars.value = NULL;
-     grp->vars.nalloc = 0;
+      assert(grp->vars.value != NULL);
+      free(grp->vars.value);
+      grp->vars.value = NULL;
+      grp->vars.nalloc = 0;
    }
 
    /* Delete all dims. */
@@ -1195,12 +1537,14 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
    while (dim)
    {
       LOG((4, "%s: deleting dim %s", __func__, dim->name));
-      /* Close HDF5 dataset associated with this dim. */
+      /* If this is a dim without a coordinate variable, then close
+       * the HDF5 DIM_WITHOUT_VARIABLE dataset associated with this
+       * dim. */
       if (dim->hdf_dimscaleid && H5Dclose(dim->hdf_dimscaleid) < 0)
-	 return NC_EHDFERR;
+         return NC_EHDFERR;
       d = dim->l.next;
       if ((retval = nc4_dim_list_del(&grp->dim, dim)))
-	 return retval;
+         return retval;
       dim = d;
    }
 
@@ -1211,7 +1555,7 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
       LOG((4, "%s: deleting type %s", __func__, type->name));
       t = type->l.next;
       if ((retval = type_list_del(&grp->type, type)))
-	 return retval;
+         return retval;
       type = t;
    }
 
@@ -1230,9 +1574,16 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
    return NC_NOERR;
 }
 
-/* Remove a NC_ATT_INFO_T from the linked list. This will nc_free the
-   memory too.
-*/
+/**
+ * @internal Remove a NC_ATT_INFO_T from the linked list. This will
+ * nc_free the memory too.
+ *
+ * @param list Pointer to pointer of list.
+ * @param att Pointer to attribute info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att)
 {
@@ -1264,7 +1615,7 @@ nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att)
    {
       for (i = 0; i < att->len; i++)
          if(att->stdata[i])
-	    free(att->stdata[i]);
+            free(att->stdata[i]);
       free(att->stdata);
    }
 
@@ -1272,7 +1623,7 @@ nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att)
    if (att->vldata)
    {
       for (i = 0; i < att->len; i++)
-	 nc_free_vlen(&att->vldata[i]);
+         nc_free_vlen(&att->vldata[i]);
       free(att->vldata);
    }
 
@@ -1280,17 +1631,34 @@ nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att)
    return NC_NOERR;
 }
 
-/* Break a coordinate variable to separate the dimension and the variable */
+/**
+ * @internal Break a coordinate variable to separate the dimension and
+ * the variable. 
+ *
+ * This is called from nc_rename_dim() and nc_rename_var(). In some
+ * renames, the coord variable must stay, but it is no longer a coord
+ * variable. This function changes a coord var into an ordinary
+ * variable.
+ *
+ * @param grp Pointer to group info struct.
+ * @param coord_var Pointer to variable info struct.
+ * @param dim Pointer to dimension info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @author Quincey Koziol, Ed Hartnett
+ */
 int
 nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T *dim)
 {
    int retval = NC_NOERR;
 
    /* Sanity checks */
-   assert(dim->coord_var == coord_var);
-   assert(coord_var->dim[0] == dim);
-   assert(coord_var->dimids[0] == dim->dimid);
-   assert(0 == dim->hdf_dimscaleid);
+   assert(grp && coord_var && dim && dim->coord_var == coord_var &&
+          coord_var->dim[0] == dim && coord_var->dimids[0] == dim->dimid &&
+          !dim->hdf_dimscaleid);
+   LOG((3, "%s dim %s was associated with var %s, but now has different name",
+        __func__, dim->name, coord_var->name));
 
    /* If we're replacing an existing dimscale dataset, go to
     * every var in the file and detach this dimension scale. */
@@ -1298,17 +1666,23 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
                                    dim->dimid, coord_var->hdf_datasetid)))
       return retval;
 
-   /* Allow attached dimscales to be tracked on the [former] coordinate variable */
+   /* Allow attached dimscales to be tracked on the [former]
+    * coordinate variable */
    if (coord_var->ndims)
    {
-      /* Coordinate variables shouldn't have dimscales attached */
-      assert(NULL == coord_var->dimscale_attached);
+      /* Coordinate variables shouldn't have dimscales attached. */
+      assert(!coord_var->dimscale_attached);
 
       /* Allocate space for tracking them */
-      if (NULL == (coord_var->dimscale_attached = calloc(coord_var->ndims, sizeof(nc_bool_t))))
+      if (!(coord_var->dimscale_attached = calloc(coord_var->ndims,
+                                                  sizeof(nc_bool_t))))
          return NC_ENOMEM;
    }
 
+   /* Remove the atts that go with being a coordinate var. */
+   /* if ((retval = remove_coord_atts(coord_var->hdf_datasetid))) */
+   /*    return retval; */
+   
    /* Detach dimension from variable */
    coord_var->dimscale = NC_FALSE;
    dim->coord_var = NULL;
@@ -1320,12 +1694,71 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
    return NC_NOERR;
 }
 
-/* Reform a coordinate variable from a dimension and a variable */
+/**
+ * @internal Delete an existing dimscale-only dataset.
+ *
+ * A dimscale-only HDF5 dataset is created when a dim is defined
+ * without an accompanying coordinate variable.
+ *
+ * Sometimes, during renames, or late creation of variables, an
+ * existing, dimscale-only dataset must be removed. This means
+ * detatching all variables that use the dataset, then closing and
+ * unlinking it.
+ *
+ * @param grp The grp of the dimscale-only dataset to be deleted, or a
+ * higher group in the heirarchy (ex. root group).
+ * @param dim Pointer to the dim with the dimscale-only dataset to be
+ * deleted.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EHDFERR HDF5 error.
+ * @author Ed Hartnett
+ */
+int
+delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim)
+{
+   int retval;
+
+   assert(grp && dim);
+   LOG((2, "%s: deleting dimscale dataset %s dimid %d", __func__, dim->name,
+        dimid));
+   
+   /* Detach dimscale from any variables using it */
+   if ((retval = rec_detach_scales(grp, dimid, dim->hdf_dimscaleid)) < 0)
+      return retval;
+      
+   /* Close the HDF5 dataset */
+   if (H5Dclose(dim->hdf_dimscaleid) < 0) 
+      return NC_EHDFERR;
+   dim->hdf_dimscaleid = 0;
+            
+   /* Now delete the dataset. */
+   if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
+      return NC_EHDFERR;
+   
+   return NC_NOERR;
+}
+
+/**
+ * @internal Reform a coordinate variable from a dimension and a
+ * variable.
+ *
+ * @param grp Pointer to group info struct.
+ * @param var Pointer to variable info struct.
+ * @param dim Pointer to dimension info struct.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Quincey Koziol
+ */
 int
 nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
 {
+   int need_to_reattach_scales = 0;
    int retval = NC_NOERR;
 
+   assert(grp && var && dim);
+   LOG((3, "%s: dim->name %s var->name %s", __func__, dim->name, var->name));
+   
    /* Detach dimscales from the [new] coordinate variable */
    if(var->dimscale_attached)
    {
@@ -1335,6 +1768,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
 
       /* Loop over all dimensions for variable */
       for (d = 0; d < var->ndims && !finished; d++)
+      {
          /* Is there a dimscale attached to this axis? */
          if(var->dimscale_attached[d])
          {
@@ -1345,33 +1779,46 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
                NC_DIM_INFO_T *dim1;
 
                for (dim1 = g->dim; dim1 && !finished; dim1 = dim1->l.next)
+               {
                   if (var->dimids[d] == dim1->dimid)
                   {
                      hid_t dim_datasetid;  /* Dataset ID for dimension */
 
                      /* Find dataset ID for dimension */
                      if (dim1->coord_var)
-                         dim_datasetid = dim1->coord_var->hdf_datasetid;
+                        dim_datasetid = dim1->coord_var->hdf_datasetid;
                      else
-                         dim_datasetid = dim1->hdf_dimscaleid;
-                     assert(dim_datasetid > 0);
-                     if (H5DSdetach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
-                        BAIL(NC_EHDFERR);
+                        dim_datasetid = dim1->hdf_dimscaleid;
+
+                     /* dim_datasetid may be 0 in some cases when
+                      * renames of dims and vars are happening. In
+                      * this case, the scale has already been
+                      * detached. */
+                     if (dim_datasetid > 0)
+                     {
+                        LOG((3, "detaching scale from %s", var->name));
+                        if (H5DSdetach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
+                           BAIL(NC_EHDFERR);
+                     }
                      var->dimscale_attached[d] = NC_FALSE;
                      if (dims_detached++ == var->ndims)
                         finished++;
                   }
+               }
             }
          }
+      } /* next variable dimension */
 
       /* Release & reset the array tracking attached dimscales */
       free(var->dimscale_attached);
       var->dimscale_attached = NULL;
+      need_to_reattach_scales++;
    }
 
-   /* Use variable's dataset ID for the dimscale ID */
+   /* Use variable's dataset ID for the dimscale ID. */
    if (dim->hdf_dimscaleid && grp != NULL)
    {
+      LOG((3, "closing and unlinking dimscale dataset %s", dim->name));
       if (H5Dclose(dim->hdf_dimscaleid) < 0)
          BAIL(NC_EHDFERR);
       dim->hdf_dimscaleid = 0;
@@ -1379,7 +1826,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
       /* Now delete the dimscale's dataset
          (it will be recreated later, if necessary) */
       if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
-        return NC_EDIMMETA;
+         return NC_EDIMMETA;
    }
 
    /* Attach variable to dimension */
@@ -1387,7 +1834,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
    dim->coord_var = var;
 
    /* Check if this variable used to be a coord. var */
-   if (var->was_coord_var && grp != NULL)
+   if (need_to_reattach_scales || (var->was_coord_var && grp != NULL))
    {
       /* Reattach the scale everywhere it is used. */
       /* (Recall that netCDF dimscales are always 1-D) */
@@ -1402,14 +1849,23 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
       /* Set state transition indicator */
       var->became_coord_var = NC_TRUE;
 
-  exit:
+exit:
    return retval;
 }
 
-/* Normalize a UTF8 name. Put the result in norm_name, which can be
- * NC_MAX_NAME + 1 in size. This function makes sure the free() gets
- * called on the return from utf8proc_NFC, and also ensures that the
- * name is not too long. */
+/**
+ * @internal Normalize a UTF8 name. Put the result in norm_name, which
+ * can be NC_MAX_NAME + 1 in size. This function makes sure the free()
+ * gets called on the return from utf8proc_NFC, and also ensures that
+ * the name is not too long.
+ *
+ * @param name Name to normalize.
+ * @param norm_name The normalized name.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EMAXNAME Name too long.
+ * @author Dennis Heimbigner
+ */
 int
 nc4_normalize_name(const char *name, char *norm_name)
 {
@@ -1430,14 +1886,21 @@ nc4_normalize_name(const char *name, char *norm_name)
 /* Print out a bunch of info to stderr about the metadata for
    debugging purposes. */
 #ifdef LOGGING
-/* Use this to set the global log level. Set it to NC_TURN_OFF_LOGGING
-   (-1) to turn off all logging. Set it to 0 to show only errors, and
-   to higher numbers to show more and more logging details. */
+/**
+ * Use this to set the global log level. Set it to NC_TURN_OFF_LOGGING
+ * (-1) to turn off all logging. Set it to 0 to show only errors, and
+ * to higher numbers to show more and more logging details.
+ *
+ * @param new_level The new logging level.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 nc_set_log_level(int new_level)
 {
    if(!nc4_hdf5_initialized)
-	nc4_hdf5_initialize();
+      nc4_hdf5_initialize();
 
    /* If the user wants to completely turn off logging, turn off HDF5
       logging too. Now I truely can't think of what to do if this
@@ -1453,7 +1916,7 @@ nc_set_log_level(int new_level)
        nc_log_level <= NC_TURN_OFF_LOGGING)
    {
       if (set_auto((H5E_auto_t)&H5Eprint, stderr) < 0)
-	 LOG((0, "H5Eset_auto failed!"));
+         LOG((0, "H5Eset_auto failed!"));
       LOG((1, "HDF5 error messages turned on."));
    }
 
@@ -1463,8 +1926,16 @@ nc_set_log_level(int new_level)
    return 0;
 }
 
-/* Recursively print the metadata of a group. */
 #define MAX_NESTS 10
+/**
+ * @internal Recursively print the metadata of a group.
+ *
+ * @param grp Pointer to group info struct.
+ * @param tab_count Number of tabs.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 static int
 rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
 {
@@ -1474,25 +1945,26 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
    NC_DIM_INFO_T *dim;
    NC_TYPE_INFO_T *type;
    NC_FIELD_INFO_T *field;
-   char tabs[MAX_NESTS] = "";
+   char tabs[MAX_NESTS+1] = "";
    char *dims_string = NULL;
    char temp_string[10];
    int t, retval, d, i;
 
    /* Come up with a number of tabs relative to the group. */
    for (t = 0; t < tab_count && t < MAX_NESTS; t++)
-      strcat(tabs, "\t");
+      tabs[t] = '\t';
+   tabs[t] = '\0';
 
    LOG((2, "%s GROUP - %s nc_grpid: %d nvars: %d natts: %d",
-	tabs, grp->name, grp->nc_grpid, grp->nvars, grp->natts));
+        tabs, grp->name, grp->nc_grpid, grp->nvars, grp->natts));
 
    for(att = grp->att; att; att = att->l.next)
       LOG((2, "%s GROUP ATTRIBUTE - attnum: %d name: %s type: %d len: %d",
-	   tabs, att->attnum, att->name, att->nc_typeid, att->len));
+           tabs, att->attnum, att->name, att->nc_typeid, att->len));
 
    for(dim = grp->dim; dim; dim = dim->l.next)
       LOG((2, "%s DIMENSION - dimid: %d name: %s len: %d unlimited: %d",
-	   tabs, dim->dimid, dim->name, dim->len, dim->unlimited));
+           tabs, dim->dimid, dim->name, dim->len, dim->unlimited));
 
    for (i=0; i < grp->vars.nelems; i++)
    {
@@ -1503,17 +1975,17 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
          dims_string = (char*)malloc(sizeof(char)*(var->ndims*4));
          strcpy(dims_string, "");
          for (d = 0; d < var->ndims; d++)
-           {
-             sprintf(temp_string, " %d", var->dimids[d]);
-             strcat(dims_string, temp_string);
-           }
+         {
+            sprintf(temp_string, " %d", var->dimids[d]);
+            strcat(dims_string, temp_string);
+         }
       }
       LOG((2, "%s VARIABLE - varid: %d name: %s type: %d ndims: %d dimscale: %d dimids:%s endianness: %d, hdf_typeid: %d",
-	   tabs, var->varid, var->name, var->type_info->nc_typeid, var->ndims, (int)var->dimscale,
-       (dims_string ? dims_string : " -"),var->type_info->endianness, var->type_info->native_hdf_typeid));
+           tabs, var->varid, var->name, var->type_info->nc_typeid, var->ndims, (int)var->dimscale,
+           (dims_string ? dims_string : " -"),var->type_info->endianness, var->type_info->native_hdf_typeid));
       for(att = var->att; att; att = att->l.next)
-	 LOG((2, "%s VAR ATTRIBUTE - attnum: %d name: %s type: %d len: %d",
-	      tabs, att->attnum, att->name, att->nc_typeid, att->len));
+         LOG((2, "%s VAR ATTRIBUTE - attnum: %d name: %s type: %d len: %d",
+              tabs, att->attnum, att->name, att->nc_typeid, att->len));
       if(dims_string)
       {
          free(dims_string);
@@ -1524,33 +1996,33 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
    for (type = grp->type; type; type = type->l.next)
    {
       LOG((2, "%s TYPE - nc_typeid: %d hdf_typeid: 0x%x size: %d committed: %d "
-	   "name: %s num_fields: %d", tabs, type->nc_typeid,
-	   type->hdf_typeid, type->size, (int)type->committed, type->name,
-	   type->u.c.num_fields));
+           "name: %s num_fields: %d", tabs, type->nc_typeid,
+           type->hdf_typeid, type->size, (int)type->committed, type->name,
+           type->u.c.num_fields));
       /* Is this a compound type? */
       if (type->nc_type_class == NC_COMPOUND)
       {
-	 LOG((3, "compound type"));
-	 for (field = type->u.c.field; field; field = field->l.next)
-	    LOG((4, "field %s offset %d nctype %d ndims %d", field->name,
-		 field->offset, field->nc_typeid, field->ndims));
+         LOG((3, "compound type"));
+         for (field = type->u.c.field; field; field = field->l.next)
+            LOG((4, "field %s offset %d nctype %d ndims %d", field->name,
+                 field->offset, field->nc_typeid, field->ndims));
       }
       else if (type->nc_type_class == NC_VLEN)
       {
-	 LOG((3, "VLEN type"));
+         LOG((3, "VLEN type"));
          LOG((4, "base_nc_type: %d", type->u.v.base_nc_typeid));
       }
       else if (type->nc_type_class == NC_OPAQUE)
-	 LOG((3, "Opaque type"));
+         LOG((3, "Opaque type"));
       else if (type->nc_type_class == NC_ENUM)
       {
-	 LOG((3, "Enum type"));
+         LOG((3, "Enum type"));
          LOG((4, "base_nc_type: %d", type->u.e.base_nc_typeid));
       }
       else
       {
-	 LOG((0, "Unknown class: %d", type->nc_type_class));
-	 return NC_EBADTYPE;
+         LOG((0, "Unknown class: %d", type->nc_type_class));
+         return NC_EBADTYPE;
       }
    }
 
@@ -1558,38 +2030,50 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
    if (grp->children)
    {
       for (g = grp->children; g; g = g->l.next)
-	 if ((retval = rec_print_metadata(g, tab_count + 1)))
-	    return retval;
+         if ((retval = rec_print_metadata(g, tab_count + 1)))
+            return retval;
    }
 
    return NC_NOERR;
 }
 
-/* Print out the internal metadata for a file. This is useful to check
- * that netCDF is working! Nonetheless, this function will print
- * nothing if logging is not set to at least two. */
+/**
+ * @internal Print out the internal metadata for a file. This is
+ * useful to check that netCDF is working! Nonetheless, this function
+ * will print nothing if logging is not set to at least two.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 log_metadata_nc(NC *nc)
 {
    NC_HDF5_FILE_INFO_T *h5 = NC4_DATA(nc);
 
    LOG((2, "*** NetCDF-4 Internal Metadata: int_ncid 0x%x ext_ncid 0x%x",
-	nc->int_ncid, nc->ext_ncid));
+        nc->int_ncid, nc->ext_ncid));
    if (!h5)
    {
       LOG((2, "This is a netCDF-3 file."));
       return NC_NOERR;
    }
    LOG((2, "FILE - hdfid: 0x%x path: %s cmode: 0x%x parallel: %d redef: %d "
-	"fill_mode: %d no_write: %d next_nc_grpid: %d",	h5->hdfid, nc->path,
-	h5->cmode, (int)h5->parallel, (int)h5->redef, h5->fill_mode, (int)h5->no_write,
-	h5->next_nc_grpid));
+        "fill_mode: %d no_write: %d next_nc_grpid: %d", h5->hdfid, nc->path,
+        h5->cmode, (int)h5->parallel, (int)h5->redef, h5->fill_mode, (int)h5->no_write,
+        h5->next_nc_grpid));
    return rec_print_metadata(h5->root_grp, 0);
 }
 
 #endif /*LOGGING */
 
-/* Show the in-memory metadata for a netcdf file. */
+/**
+ * @internal Show the in-memory metadata for a netcdf file.
+ *
+ * @param ncid File and group ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+ */
 int
 NC4_show_metadata(int ncid)
 {
diff --git a/libsrc4/nc4type.c b/libsrc4/nc4type.c
index 57eb28f..43dc524 100644
--- a/libsrc4/nc4type.c
+++ b/libsrc4/nc4type.c
@@ -1,27 +1,56 @@
-/*
-
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-HDF5 backend for netCDF, depending on your point of view.
-
-This file handles the nc4 user-defined type functions (i.e. compound
-and opaque types).
-
-Copyright 2005, University Corporation for Atmospheric Research. See
-the COPYRIGHT file for copying and redistribution conditions.
-
-$Id: nc4type.c,v 1.73 2010/05/25 17:54:24 dmh Exp $
-*/
-
+/**
+ * @file
+ *
+ * @internal This file is part of netcdf-4, a netCDF-like interface
+ * for HDF5, or a HDF5 backend for netCDF, depending on your point of
+ * view.
+ *
+ * This file handles the nc4 user-defined type functions
+ * (i.e. compound and opaque types).
+ *
+ * Copyright 2005, University Corporation for Atmospheric Research. See
+ * the COPYRIGHT file for copying and redistribution conditions.
+ *
+ * @author Ed Hartnett
+ */
 #include "nc4internal.h"
 #include "nc4dispatch.h"
 
-#define NUM_ATOMIC_TYPES 13
+#define NUM_ATOMIC_TYPES 13 /**< Number of netCDF atomic types. */
+
+/** @internal Names of atomic types. */
 char atomic_name[NUM_ATOMIC_TYPES][NC_MAX_NAME + 1] = {"none", "byte", "char", 
 						       "short", "int", "float", 
 						       "double", "ubyte",
 						       "ushort", "uint",
 						       "int64", "uint64", "string"};
 
+/* The sizes of types may vary from platform to platform, but within
+ * netCDF files, type sizes are fixed. */
+#define NC_CHAR_LEN sizeof(char)      /**< @internal Size of char. */
+#define NC_STRING_LEN sizeof(char *)  /**< @internal Size of char *. */
+#define NC_BYTE_LEN 1     /**< @internal Size of byte. */
+#define NC_SHORT_LEN 2    /**< @internal Size of short. */
+#define NC_INT_LEN 4      /**< @internal Size of int. */
+#define NC_FLOAT_LEN 4    /**< @internal Size of float. */
+#define NC_DOUBLE_LEN 8   /**< @internal Size of double. */
+#define NC_INT64_LEN 8    /**< @internal Size of int64. */
+
+/**
+ * @internal Determine if two types are equal.
+ *
+ * @param ncid1 First file/group ID.
+ * @param typeid1 First type ID.
+ * @param ncid2 Second file/group ID.
+ * @param typeid2 Second type ID.
+ * @param equalp Pointer that will get 1 if the two types are equal.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @return ::NC_EINVAL Invalid type.
+ * @author Ed Hartnett
+ */
 extern int
 NC4_inq_type_equal(int ncid1, nc_type typeid1, int ncid2, 
 		  nc_type typeid2, int *equalp)
@@ -75,12 +104,29 @@ NC4_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
 
    /* Are the two types equal? */
    if (equalp)
-      *equalp = (int)H5Tequal(type1->native_hdf_typeid, type2->native_hdf_typeid);
+   {
+      if ((retval = H5Tequal(type1->native_hdf_typeid, type2->native_hdf_typeid)) < 0)
+         return NC_EHDFERR;
+      *equalp = 1 ? retval : 0;
+   }
    
    return NC_NOERR;
 }
 
-/* Get the id of a type from the name. */
+/**
+ * @internal Get the id of a type from the name. 
+ *
+ * @param ncid File and group ID.
+ * @param name Name of type.
+ * @param typeidp Pointer that will get the type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_ENOMEM Out of memory.
+ * @return ::NC_EINVAL Bad size.
+ * @return ::NC_ENOTNC4 User types in netCDF-4 files only.
+ * @return ::NC_EBADTYPE Type not found.
+ * @author Ed Hartnett
+ */
 extern int
 NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
 {
@@ -91,6 +137,7 @@ NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
    char *norm_name;
    int i, retval;
 
+   /* Handle atomic types. */
    for (i = 0; i < NUM_ATOMIC_TYPES; i++)
       if (!strcmp(name, atomic_name[i]))
       {
@@ -102,10 +149,7 @@ NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
-
-   /* Must be a netCDF-4 file. */
-   if (!h5)
-      return NC_ENOTNC4;
+   assert(h5 && grp);
 
    /* If the first char is a /, this is a fully-qualified
     * name. Otherwise, this had better be a local name (i.e. no / in
@@ -146,8 +190,19 @@ NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
    return NC_NOERR;
 }
 
-/* Find all user-defined types for a location. This finds all
- * user-defined types in a group. */
+/**
+ * @internal Find all user-defined types for a location. This finds
+ * all user-defined types in a group.
+ *
+ * @param ncid File and group ID.
+ * @param ntypes Pointer that gets the number of user-defined
+ * types. Ignored if NULL
+ * @param typeids Array that gets the typeids. Ignored if NULL.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int 
 NC4_inq_typeids(int ncid, int *ntypes, int *typeids)
 {
@@ -162,9 +217,10 @@ NC4_inq_typeids(int ncid, int *ntypes, int *typeids)
    /* Find info for this file and group, and set pointer to each. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
+   assert(h5 && grp);
 
-   /* If this is a netCDF-4 file, count types. */
-   if (h5 && grp->type)
+   /* Count types. */
+   if (grp->type)
       for (type = grp->type; type; type = type->l.next)
       {
 	 if (typeids)
@@ -179,9 +235,25 @@ NC4_inq_typeids(int ncid, int *ntypes, int *typeids)
    return NC_NOERR;
 }
 
-
-/* This internal function adds a new user defined type to the metadata
- * of a group of an open file. */
+/**
+ * @internal This internal function adds a new user defined type to
+ * the metadata of a group of an open file.
+ *
+ * @param ncid File and group ID.
+ * @param size Size in bytes of new type.
+ * @param name Name of new type.
+ * @param base_typeid Base type ID.
+ * @param type_class NC_VLEN, NC_ENUM, or NC_STRING
+ * @param typeidp Pointer that gets new type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ENOTNC4 User types in netCDF-4 files only.
+ * @return ::NC_EINVAL Bad size.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 static int
 add_user_type(int ncid, size_t size, const char *name, nc_type base_typeid,
 	      nc_type type_class, nc_type *typeidp)
@@ -202,10 +274,7 @@ add_user_type(int ncid, size_t size, const char *name, nc_type base_typeid,
    /* Find group metadata. */
    if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
       return retval;
-
-   /* Only netcdf-4 files! */
-   if (!h5)
-      return NC_ENOTNC4;
+   assert(h5 && grp);
 
    /* Turn on define mode if it is not on. */
    if (!(h5->cmode & NC_INDEF))
@@ -244,20 +313,20 @@ add_user_type(int ncid, size_t size, const char *name, nc_type base_typeid,
    return NC_NOERR;
 }
 
-
-/* The sizes of types may vary from platform to platform, but within
- * netCDF files, type sizes are fixed. */
-#define NC_CHAR_LEN sizeof(char)
-#define NC_STRING_LEN sizeof(char *)
-#define NC_BYTE_LEN 1
-#define NC_SHORT_LEN 2
-#define NC_INT_LEN 4
-#define NC_FLOAT_LEN 4
-#define NC_DOUBLE_LEN 8
-#define NC_INT64_LEN 8
-
-/* Get the name and size of a type. For strings, 1 is returned. For
- * VLEN the base type len is returned. */
+/**
+ * @internal Get the name and size of a type. For strings, 1 is
+ * returned. For VLEN the base type len is returned.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param name Gets the name of the type.
+ * @param size Gets the size of one element of the type in bytes.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_type(int ncid, nc_type typeid1, char *name, size_t *size)
 {
@@ -306,14 +375,41 @@ NC4_inq_type(int ncid, nc_type typeid1, char *name, size_t *size)
    return NC_NOERR;
 }
 
-/* Create a compound type. */
+/**
+ * @internal Create a compound type.
+ *
+ * @param ncid File and group ID.
+ * @param size Gets size in bytes of one element of type.
+ * @param name Name of the type.
+ * @param typeidp Gets the type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 int
 NC4_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp)
 {
    return add_user_type(ncid, size, name, 0, NC_COMPOUND, typeidp);
 }
 
-/* Insert a named field into a compound type. */
+/**
+ * @internal Insert a named field into a compound type.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param name Name of the type.
+ * @param offset Offset of field.
+ * @param field_typeid Field type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 int
 NC4_insert_compound(int ncid, nc_type typeid1, const char *name, size_t offset, 
 		   nc_type field_typeid)
@@ -322,7 +418,23 @@ NC4_insert_compound(int ncid, nc_type typeid1, const char *name, size_t offset,
 				   field_typeid, 0, NULL);
 }
 
-/* Insert a named array into a compound type. */
+/**
+ * @internal Insert a named array into a compound type.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param name Name of the array field.
+ * @param offset Offset in bytes.
+ * @param field_typeid Type of field.
+ * @param ndims Number of dims for field.
+ * @param dim_sizesp Array of dim sizes.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 extern int
 NC4_insert_array_compound(int ncid, int typeid1, const char *name, 
 			 size_t offset, nc_type field_typeid,
@@ -368,7 +480,22 @@ NC4_insert_array_compound(int ncid, int typeid1, const char *name,
    return NC_NOERR;
 }
 
-/* Find info about any user defined type. */
+/**
+ * @internal Find info about any user defined type.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param name Gets name of the type.
+ * @param size Gets size in bytes of one element of type.
+ * @param base_nc_typep Gets the base nc_type.
+ * @param nfieldsp Gets the number of fields.
+ * @param classp Gets the type class (NC_COMPOUND, NC_ENUM, NC_VLEN).
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_user_type(int ncid, nc_type typeid1, char *name, size_t *size, 
 		 nc_type *base_nc_typep, size_t *nfieldsp, int *classp)
@@ -431,7 +558,23 @@ NC4_inq_user_type(int ncid, nc_type typeid1, char *name, size_t *size,
    return NC_NOERR;
 }
 
-/* Given the ncid, typeid and fieldid, get info about the field. */
+/**
+ * @internal Given the ncid, typeid and fieldid, get info about the
+ * field.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param fieldid Field ID.
+ * @param name Gets name of field.
+ * @param offsetp Gets offset of field.
+ * @param field_typeidp Gets field type ID.
+ * @param ndimsp Gets number of dims for this field.
+ * @param dim_sizesp Gets the dim sizes for this field.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name, 
 		      size_t *offsetp, nc_type *field_typeidp, int *ndimsp, 
@@ -471,16 +614,27 @@ NC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name,
    return NC_EBADFIELD;
 }
 
-/* Find a netcdf-4 file. THis will return an error if it finds a
- * netcdf-3 file, or a netcdf-4 file with strict nc3 rules. */
+/**
+ * @internal Find a netcdf-4 file. THis will return an error if it
+ * finds a netcdf-3 file, or a netcdf-4 file with strict nc3 rules.
+ *
+ * @param ncid File and group ID.
+ * @param nc Pointer to pointer that gets NC struct for file.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_ESTRICTNC3 File uses classic model.
+ * @author Ed Hartnett
+*/
 static int
 find_nc4_file(int ncid, NC **nc)
 {
    NC_HDF5_FILE_INFO_T* h5;
    
    /* Find file metadata. */
-   if (!((*nc) = nc4_find_nc_file(ncid,&h5)))
+   if (!((*nc) = nc4_find_nc_file(ncid, &h5)))
       return NC_EBADID;
+   assert(h5);
       
    if (h5->cmode & NC_CLASSIC_MODEL)
       return NC_ESTRICTNC3;
@@ -488,7 +642,20 @@ find_nc4_file(int ncid, NC **nc)
    return NC_NOERR;
 }
 
-/* Given the typeid and the name, get the fieldid. */
+/**
+ * @internal Given the typeid and the name, get the fieldid.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param name Name of field.
+ * @param fieldidp Pointer that gets new field ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @return ::NC_EBADFIELD Field not found.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
 {
@@ -533,7 +700,20 @@ NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fi
 
 /* Opaque type. */
 
-/* Create an opaque type. Provide a size and a name. */
+/**
+ * @internal Create an opaque type. Provide a size and a name.
+ *
+ * @param ncid File and group ID.
+ * @param datum_size Size in bytes of a datum.
+ * @param name Name of new vlen type.
+ * @param typeidp Pointer that gets new type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 int
 NC4_def_opaque(int ncid, size_t datum_size, const char *name, 
 	      nc_type *typeidp)
@@ -542,7 +722,20 @@ NC4_def_opaque(int ncid, size_t datum_size, const char *name,
 }
 
 
-/* Define a variable length type. */
+/**
+ * @internal Define a variable length type.
+ *
+ * @param ncid File and group ID.
+ * @param name Name of new vlen type.
+ * @param base_typeid Base type of vlen.
+ * @param typeidp Pointer that gets new type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 int
 NC4_def_vlen(int ncid, const char *name, nc_type base_typeid, 
 	    nc_type *typeidp)
@@ -550,8 +743,20 @@ NC4_def_vlen(int ncid, const char *name, nc_type base_typeid,
    return add_user_type(ncid, 0, name, base_typeid, NC_VLEN, typeidp);
 }
 
-/* Create an enum type. Provide a base type and a name. At the moment
- * only ints are accepted as base types. */
+/**
+ * @internal Create an enum type. Provide a base type and a name. At
+ * the moment only ints are accepted as base types.
+ *
+ * @param ncid File and group ID.
+ * @param base_typeid Base type of vlen.
+ * @param name Name of new vlen type.
+ * @param typeidp Pointer that gets new type ID.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EMAXNAME Name is too long.
+ * @return ::NC_EBADNAME Name breaks netCDF name rules.
+ * @author Ed Hartnett
+*/
 int
 NC4_def_enum(int ncid, nc_type base_typeid, const char *name, 
 	    nc_type *typeidp)
@@ -560,7 +765,21 @@ NC4_def_enum(int ncid, nc_type base_typeid, const char *name,
 }
 
 
-/* Get enum name from enum value. Name size will be <= NC_MAX_NAME. */
+/**
+ * @internal Get enum name from enum value. Name size will be <=
+ * NC_MAX_NAME.
+ *
+ * @param ncid File and group ID.
+ * @param xtype Type ID.
+ * @param value Value of enum.
+ * @param identifier Gets the identifier for this enum value.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @return ::NC_EINVAL Invalid type data.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
 {
@@ -634,8 +853,22 @@ NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
    return NC_NOERR;
 }
 
-/* Get information about an enum member: an identifier and
- * value. Identifier size will be <= NC_MAX_NAME. */
+/**
+ * @internal Get information about an enum member: an identifier and
+ * value. Identifier size will be <= NC_MAX_NAME.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param idx Enum member index.
+ * @param identifier Gets the identifier.
+ * @param value Gets the enum value.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @return ::NC_EINVAL Bad idx.
+ * @author Ed Hartnett
+*/
 int
 NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier, 
 		   void *value)
@@ -678,8 +911,22 @@ NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier,
    return NC_NOERR;
 }
 
-/* Insert a identifierd value into an enum type. The value must fit within
- * the size of the enum type, the identifier size must be <= NC_MAX_NAME. */
+/**
+ * @internal Insert a identifier value into an enum type. The value
+ * must fit within the size of the enum type, the identifier size must
+ * be <= NC_MAX_NAME.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param identifier Name of this enum value.
+ * @param value Value of enum.
+ *
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @return ::NC_EBADTYPE Type not found.
+ * @return ::NC_ETYPDEFINED Type already defined.
+ * @author Ed Hartnett
+*/
 int
 NC4_insert_enum(int ncid, nc_type typeid1, const char *identifier, 
 	       const void *value)
@@ -722,7 +969,19 @@ NC4_insert_enum(int ncid, nc_type typeid1, const char *identifier,
    return NC_NOERR;
 }
 
-/* Insert one element into an already allocated vlen array element. */
+/**
+ * @internal Insert one element into an already allocated vlen array
+ * element.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param vlen_element The VLEN element to insert.
+ * @param len Length of element in bytes.
+ * @param data Element data.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_put_vlen_element(int ncid, int typeid1, void *vlen_element, 
 		    size_t len, const void *data)
@@ -733,7 +992,19 @@ NC4_put_vlen_element(int ncid, int typeid1, void *vlen_element,
    return NC_NOERR;
 }
 
-/* Insert one element into an already allocated vlen array element. */
+/**
+ * @internal Insert one element into an already allocated vlen array
+ * element.
+ *
+ * @param ncid File and group ID.
+ * @param typeid1 Type ID.
+ * @param vlen_element The VLEN element to insert.
+ * @param len Length of element in bytes.
+ * @param data Element data.
+ *
+ * @return ::NC_NOERR No error.
+ * @author Ed Hartnett
+*/
 int
 NC4_get_vlen_element(int ncid, int typeid1, const void *vlen_element, 
 		    size_t *len, void *data)
diff --git a/libsrc4/nc4var.c b/libsrc4/nc4var.c
index 0e9c8b8..0e1f4f9 100644
--- a/libsrc4/nc4var.c
+++ b/libsrc4/nc4var.c
@@ -1,41 +1,43 @@
-/*
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-HDF5 backend for netCDF, depending on your point of view.
+/**
+ * @file
+ * This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
+ * HDF5 backend for netCDF, depending on your point of view.
 
-This file handles the nc4 variable functions.
+ * This file handles the NetCDF-4 variable functions.
 
-Copyright 2003-2006, University Corporation for Atmospheric
-Research. See COPYRIGHT file for copying and redistribution
-conditions.
-*/
+ * Copyright 2003-2006, University Corporation for Atmospheric
+ * Research. See COPYRIGHT file for copying and redistribution
+ * conditions.
+ */
 
 #include <nc4internal.h>
 #include "nc4dispatch.h"
 #include <math.h>
 
-/* Min and max deflate levels tolerated by HDF5. */
-#define MIN_DEFLATE_LEVEL 0
-#define MAX_DEFLATE_LEVEL 9
-
-/* This is to track opened HDF5 objects to make sure they are
- * closed. */
-#ifdef EXTRA_TESTS
-extern int num_plists;
-#endif /* EXTRA_TESTS */
-
-/* One meg is the minimum buffer size. */
-#define ONE_MEG 1048576
-
 /* Szip options. */
-#define NC_SZIP_EC_OPTION_MASK 4
-#define NC_SZIP_NN_OPTION_MASK 32
-#define NC_SZIP_MAX_PIXELS_PER_BLOCK 32
-
-extern int nc4_get_default_fill_value(const NC_TYPE_INFO_T *type_info, void *fill_value);
-
-
-/* If the HDF5 dataset for this variable is open, then close it and
- * reopen it, with the perhaps new settings for chunk caching. */
+#define NC_SZIP_EC_OPTION_MASK 4  /**< @internal SZIP EC option mask. */
+#define NC_SZIP_NN_OPTION_MASK 32 /**< @internal SZIP NN option mask. */
+#define NC_SZIP_MAX_PIXELS_PER_BLOCK 32 /**< @internal SZIP max pixels per block. */
+
+/** @internal Default size for unlimited dim chunksize */
+#define DEFAULT_1D_UNLIM_SIZE (4096)
+
+#define NC_ARRAY_GROWBY 4 /**< @internal Amount to grow array. */
+
+extern int nc4_get_default_fill_value(const NC_TYPE_INFO_T *type_info,
+                                      void *fill_value);
+
+/**
+ * @internal If the HDF5 dataset for this variable is open, then close
+ * it and reopen it, with the perhaps new settings for chunk caching.
+ *
+ * @param grp Pointer to the group info.
+ * @param var Pointer to the var info.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EHDFERR HDF5 error.
+ * @author Ed Hartnett
+ */
 int
 nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 {
@@ -44,33 +46,44 @@ nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    if (var->hdf_datasetid)
    {
       if ((access_pid = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
-	 return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-      num_plists++;
-#endif
+         return NC_EHDFERR;
       if (H5Pset_chunk_cache(access_pid, var->chunk_cache_nelems,
-			     var->chunk_cache_size,
-			     var->chunk_cache_preemption) < 0)
-	 return NC_EHDFERR;
+                             var->chunk_cache_size,
+                             var->chunk_cache_preemption) < 0)
+         return NC_EHDFERR;
       if (H5Dclose(var->hdf_datasetid) < 0)
-	 return NC_EHDFERR;
+         return NC_EHDFERR;
       if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name,
-					 access_pid)) < 0)
-	 return NC_EHDFERR;
+                                         access_pid)) < 0)
+         return NC_EHDFERR;
       if (H5Pclose(access_pid) < 0)
-	 return NC_EHDFERR;
-#ifdef EXTRA_TESTS
-      num_plists--;
-#endif
+         return NC_EHDFERR;
    }
 
    return NC_NOERR;
 }
 
-/* Set chunk cache size for a variable. */
+/**
+ * @internal Set chunk cache size for a variable. This is the internal
+ * function called by nc_set_var_chunk_cache().
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param size Size in bytes to set cache.
+ * @param nelems Number of elements in cache.
+ * @param preemption Controls cache swapping.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+ * @returns ::NC_EINVAL Invalid input.
+ * @returns ::NC_EHDFERR HDF5 error.
+ * @author Ed Hartnett
+ */
 int
 NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
-			float preemption)
+                        float preemption)
 {
    NC *nc;
    NC_GRP_INFO_T *grp;
@@ -85,20 +98,13 @@ NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
    /* 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;
-
-   /* An attempt to do any of these things on a netCDF-3 file is
-    * ignored with no error. */
-   if (!h5)
-      return NC_NOERR;
-
    assert(nc && grp && h5);
 
    /* Find the var. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
-   if (!var) return NC_ENOTVAR;
-   assert(var->varid == varid);
+   assert(var && var->varid == varid);
 
    /* Set the values. */
    var->chunk_cache_size = size;
@@ -111,18 +117,29 @@ NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
    return NC_NOERR;
 }
 
-/* Need this version for fortran. Accept negative numbers to leave
- * settings as they are. */
+/**
+ * @internal A wrapper for NC4_set_var_chunk_cache(), we need this
+ * version for fortran. Negative values leave settings as they are.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param size Size in bytes to set cache.
+ * @param nelems Number of elements in cache.
+ * @param preemption Controls cache swapping.
+ *
+ * @returns ::NC_NOERR for success
+ * @author Ed Hartnett
+ */
 int
 nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems,
-			    int preemption)
+                            int preemption)
 {
    size_t real_size = H5D_CHUNK_CACHE_NBYTES_DEFAULT;
    size_t real_nelems = H5D_CHUNK_CACHE_NSLOTS_DEFAULT;
-   float real_preemption = H5D_CHUNK_CACHE_W0_DEFAULT;
+   float real_preemption = CHUNK_CACHE_PREEMPTION;
 
    if (size >= 0)
-       real_size = ((size_t) size) * MEGABYTE;
+      real_size = ((size_t) size) * MEGABYTE;
 
    if (nelems >= 0)
       real_nelems = nelems;
@@ -131,13 +148,28 @@ nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems,
       real_preemption = preemption / 100.;
 
    return NC4_set_var_chunk_cache(ncid, varid, real_size, real_nelems,
-				 real_preemption);
+                                  real_preemption);
 }
 
-/* Get chunk cache size for a variable. */
+/**
+ * @internal This is called by nc_get_var_chunk_cache(). Get chunk
+ * cache size for a variable.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param sizep Gets size in bytes of cache.
+ * @param nelemsp Gets number of element slots in cache.
+ * @param preemptionp Gets cache swapping setting.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @author Ed Hartnett
+ */
 int
 NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep,
-			size_t *nelemsp, float *preemptionp)
+                        size_t *nelemsp, float *preemptionp)
 {
    NC *nc;
    NC_GRP_INFO_T *grp;
@@ -148,20 +180,13 @@ NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep,
    /* 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;
-
-   /* Attempting to do any of these things on a netCDF-3 file produces
-    * an error. */
-   if (!h5)
-      return NC_ENOTNC4;
-
    assert(nc && grp && h5);
 
    /* Find the var. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
-   if (!var) return NC_ENOTVAR;
-   assert(var->varid == varid);
+   assert(var && var->varid == varid);
 
    /* Give the user what they want. */
    if (sizep)
@@ -174,17 +199,32 @@ NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep,
    return NC_NOERR;
 }
 
-/* Get chunk cache size for a variable. */
+/**
+ * @internal A wrapper for NC4_get_var_chunk_cache(), we need this
+ * version for fortran.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param sizep Gets size in bytes of cache.
+ * @param nelemsp Gets number of element slots in cache.
+ * @param preemptionp Gets cache swapping setting.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Not a netCDF-4 file.
+ * @author Ed Hartnett
+ */
 int
 nc_get_var_chunk_cache_ints(int ncid, int varid, int *sizep,
-			    int *nelemsp, int *preemptionp)
+                            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,
-				     &real_nelems, &real_preemption)))
+                                      &real_nelems, &real_preemption)))
       return ret;
 
    if (sizep)
@@ -197,7 +237,19 @@ nc_get_var_chunk_cache_ints(int ncid, int varid, int *sizep,
    return NC_NOERR;
 }
 
-/* Check a set of chunksizes to see if they specify a chunk that is too big. */
+/**
+ * @internal Check a set of chunksizes to see if they specify a chunk
+ * that is too big.
+ *
+ * @param grp Pointer to the group info.
+ * @param var Pointer to the var info.
+ * @param chunksizes Array of chunksizes to check.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_EBADCHUNK Bad chunksize.
+ */
 static int
 check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksizes)
 {
@@ -209,13 +261,13 @@ check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksize
    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)
-       dprod = (double)sizeof(hvl_t);
+      dprod = (double)sizeof(hvl_t);
    else
-       dprod = (double)type_len;
+      dprod = (double)type_len;
    for (d = 0; d < var->ndims; d++)
    {
       if (chunksizes[d] < 1)
-	 return NC_EINVAL;
+         return NC_EINVAL;
       dprod *= (double) chunksizes[d];
    }
 
@@ -225,8 +277,17 @@ check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksize
    return NC_NOERR;
 }
 
-/* Find the default chunk nelems (i.e. length of chunk along each
- * dimension). */
+/**
+ * @internal Determine some default chunksizes for a variable.
+ *
+ * @param grp Pointer to the group info.
+ * @param var Pointer to the var info.
+ *
+ * @returns ::NC_NOERR for success
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @author Ed Hartnett
+ */
 static int
 nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 {
@@ -256,35 +317,34 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    {
       assert(var->dim[d]);
       if (! var->dim[d]->unlimited)
-	 num_values *= (float)var->dim[d]->len;
+         num_values *= (float)var->dim[d]->len;
       else {
-	  num_unlim++;
-	  var->chunksizes[d] = 1; /* overwritten below, if all dims are unlimited */
+         num_unlim++;
+         var->chunksizes[d] = 1; /* overwritten below, if all dims are unlimited */
       }
    }
    /* Special case to avoid 1D vars with unlim dim taking huge amount
       of space (DEFAULT_CHUNK_SIZE bytes). Instead we limit to about
       4KB */
-#define DEFAULT_1D_UNLIM_SIZE (4096) /* TODO: make build-time parameter? */
    if (var->ndims == 1 && num_unlim == 1) {
-       if (DEFAULT_CHUNK_SIZE / type_size <= 0)
-	 suggested_size = 1;
-       else if (DEFAULT_CHUNK_SIZE / type_size > DEFAULT_1D_UNLIM_SIZE)
-	 suggested_size = DEFAULT_1D_UNLIM_SIZE;
-       else
-	 suggested_size = DEFAULT_CHUNK_SIZE / type_size;
-       var->chunksizes[0] = suggested_size / type_size;
-       LOG((4, "%s: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d "
-	    "chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[0]));
+      if (DEFAULT_CHUNK_SIZE / type_size <= 0)
+         suggested_size = 1;
+      else if (DEFAULT_CHUNK_SIZE / type_size > DEFAULT_1D_UNLIM_SIZE)
+         suggested_size = DEFAULT_1D_UNLIM_SIZE;
+      else
+         suggested_size = DEFAULT_CHUNK_SIZE / type_size;
+      var->chunksizes[0] = suggested_size / type_size;
+      LOG((4, "%s: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d "
+           "chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[0]));
    }
    if (var->ndims > 1 && var->ndims == num_unlim) { /* all dims unlimited */
-       suggested_size = pow((double)DEFAULT_CHUNK_SIZE/type_size, 1.0/(double)(var->ndims));
-       for (d = 0; d < var->ndims; d++)
-       {
-	   var->chunksizes[d] = suggested_size ? suggested_size : 1;
-	   LOG((4, "%s: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d "
-		"chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[d]));
-       }
+      suggested_size = pow((double)DEFAULT_CHUNK_SIZE/type_size, 1.0/(double)(var->ndims));
+      for (d = 0; d < var->ndims; d++)
+      {
+         var->chunksizes[d] = suggested_size ? suggested_size : 1;
+         LOG((4, "%s: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d "
+              "chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[d]));
+      }
    }
 
    /* Pick a chunk length for each dimension, if one has not already
@@ -292,19 +352,19 @@ 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),
-			       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;
-	 var->chunksizes[d] = suggested_size ? suggested_size : 1;
-	 LOG((4, "%s: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d "
-	      "chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[d]));
+         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;
+         var->chunksizes[d] = suggested_size ? suggested_size : 1;
+         LOG((4, "%s: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d "
+              "chunksize %ld", __func__, var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[d]));
       }
 
 #ifdef LOGGING
    /* Find total chunk size. */
    for (d = 0; d < var->ndims; d++)
-       total_chunk_size *= (double) var->chunksizes[d];
+      total_chunk_size *= (double) var->chunksizes[d];
    LOG((4, "total_chunk_size %f", total_chunk_size));
 #endif
 
@@ -314,12 +374,12 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
    {
       /* Other error? */
       if (retval != NC_EBADCHUNK)
-	 return retval;
+         return retval;
 
       /* Chunk is too big! Reduce each dimension by half and try again. */
       for ( ; retval == NC_EBADCHUNK; retval = check_chunksizes(grp, var, var->chunksizes))
-    	 for (d = 0; d < var->ndims; d++)
-	    var->chunksizes[d] = var->chunksizes[d]/2 ? var->chunksizes[d]/2 : 1;
+         for (d = 0; d < var->ndims; d++)
+            var->chunksizes[d] = var->chunksizes[d]/2 ? var->chunksizes[d]/2 : 1;
    }
 
    /* Do we have any big data overhangs? They can be dangerous to
@@ -327,55 +387,92 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
     * beer. */
    for (d = 0; d < var->ndims; d++)
    {
-       size_t num_chunks;
-       size_t overhang;
-       assert(var->chunksizes[d] > 0);
-       num_chunks = (var->dim[d]->len + var->chunksizes[d] - 1) / var->chunksizes[d];
-       if(num_chunks > 0) {
-	   overhang = (num_chunks * var->chunksizes[d]) - var->dim[d]->len;
-	   var->chunksizes[d] -= overhang / num_chunks;
-       }
+      size_t num_chunks;
+      size_t overhang;
+      assert(var->chunksizes[d] > 0);
+      num_chunks = (var->dim[d]->len + var->chunksizes[d] - 1) / var->chunksizes[d];
+      if(num_chunks > 0) {
+         overhang = (num_chunks * var->chunksizes[d]) - var->dim[d]->len;
+         var->chunksizes[d] -= overhang / num_chunks;
+      }
    }
 
    return NC_NOERR;
 }
 
-#define NC_ARRAY_GROWBY 4
-int nc4_vararray_add(NC_GRP_INFO_T *grp,
-		     NC_VAR_INFO_T *var)
+/**
+ * @internal Grow the variable array.
+ *
+ * @param grp Pointer to the group info.
+ * @param var Pointer to the var info.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @author Dennis Heimbigner
+ */
+int nc4_vararray_add(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 {
-  NC_VAR_INFO_T **vp = NULL;
+   NC_VAR_INFO_T **vp = NULL;
+
+   if (grp->vars.nalloc == 0) {
+      assert(grp->vars.nelems == 0);
+      vp = (NC_VAR_INFO_T **) malloc(NC_ARRAY_GROWBY * sizeof(NC_VAR_INFO_T *));
+      if(vp == NULL)
+         return NC_ENOMEM;
+      grp->vars.value = vp;
+      grp->vars.nalloc = NC_ARRAY_GROWBY;
+   }
+   else if(grp->vars.nelems +1 > grp->vars.nalloc) {
+      vp = (NC_VAR_INFO_T **) realloc(grp->vars.value,
+                                      (grp->vars.nalloc + NC_ARRAY_GROWBY) * sizeof(NC_VAR_INFO_T *));
+      if(vp == NULL)
+         return NC_ENOMEM;
+      grp->vars.value = vp;
+      grp->vars.nalloc += NC_ARRAY_GROWBY;
+   }
 
-  if (grp->vars.nalloc == 0) {
-    assert(grp->vars.nelems == 0);
-    vp = (NC_VAR_INFO_T **) malloc(NC_ARRAY_GROWBY * sizeof(NC_VAR_INFO_T *));
-    if(vp == NULL)
-      return NC_ENOMEM;
-    grp->vars.value = vp;
-    grp->vars.nalloc = NC_ARRAY_GROWBY;
-  }
-  else if(grp->vars.nelems +1 > grp->vars.nalloc) {
-    vp = (NC_VAR_INFO_T **) realloc(grp->vars.value,
-			     (grp->vars.nalloc + NC_ARRAY_GROWBY) * sizeof(NC_VAR_INFO_T *));
-    if(vp == NULL)
-      return NC_ENOMEM;
-    grp->vars.value = vp;
-    grp->vars.nalloc += NC_ARRAY_GROWBY;
-  }
-
-  if(var != NULL) {
-    assert(var->varid == grp->vars.nelems);
-    grp->vars.value[grp->vars.nelems] = var;
-    grp->vars.nelems++;
-  }
-  return NC_NOERR;
+   if(var != NULL) {
+      assert(var->varid == grp->vars.nelems);
+      grp->vars.value[grp->vars.nelems] = var;
+      grp->vars.nelems++;
+   }
+   return NC_NOERR;
 }
 
-/* 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,
-               int ndims, const int *dimidsp, int *varidp)
+/**
+ * @internal This is called when a new netCDF-4 variable is defined
+ * with nc_def_var().
+ *
+ * @param ncid File ID.
+ * @param name Name.
+ * @param xtype Type.
+ * @param ndims Number of dims.
+ * @param dimidsp Array of dim IDs.
+ * @param varidp Gets the var ID.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ * netcdf-4 file.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EPERM File is read only.
+ * @returns ::NC_EMAXDIMS Classic model file exceeds ::NC_MAX_VAR_DIMS.
+ * @returns ::NC_ESTRICTNC3 Attempting to create netCDF-4 type var in
+ * classic model file
+ * @returns ::NC_EBADNAME Bad name.
+ * @returns ::NC_EBADTYPE Bad type.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @returns ::NC_EHDFERR Error returned by HDF5 layer.
+ * @returns ::NC_EINVAL Invalid input
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
+int
+NC4_def_var(int ncid, const char *name, nc_type xtype,
+            int ndims, const int *dimidsp, int *varidp)
 {
    NC_GRP_INFO_T *grp;
    NC_VAR_INFO_T *var;
@@ -392,7 +489,8 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    assert(grp && h5);
 
    /* If it's not in define mode, strict nc3 files error out,
-    * otherwise switch to define mode. */
+    * otherwise switch to define mode. This will also check that the
+    * file is writable. */
    if (!(h5->flags & NC_INDEF))
    {
       if (h5->cmode & NC_CLASSIC_MODEL)
@@ -400,6 +498,7 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
       if ((retval = NC4_redef(ncid)))
          BAIL(retval);
    }
+   assert(!h5->no_write);
 
    /* Check and normalize the name. */
    if ((retval = nc4_check_name(name, norm_name)))
@@ -413,6 +512,10 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    if (h5->cmode & NC_CLASSIC_MODEL && xtype > NC_DOUBLE)
       BAIL(NC_ESTRICTNC3);
 
+   /* For classic files */
+   if (h5->cmode & NC_CLASSIC_MODEL && ndims > NC_MAX_VAR_DIMS)
+      BAIL(NC_EMAXDIMS);
+
    /* cast needed for braindead systems with signed size_t */
    if((unsigned long) ndims > X_INT_MAX) /* Backward compat */
       BAIL(NC_EINVAL);
@@ -421,9 +524,9 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    if ((retval = nc4_check_dup_name(grp, norm_name)))
       BAIL(retval);
 
-   /* If the file is read-only, return an error. */
-   if (h5->no_write)
-     BAIL(NC_EPERM);
+   /* If there for non-scalar vars, dim IDs must be provided. */
+   if (ndims && !dimidsp)
+      BAIL(NC_EINVAL);      
 
    /* Check all the dimids to make sure they exist. */
    for (d = 0; d < ndims; d++)
@@ -431,7 +534,7 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
          BAIL(retval);
 
    /* These degrubbing messages sure are handy! */
-   LOG((3, "%s: name %s type %d ndims %d", __func__, norm_name, xtype, ndims));
+   LOG((2, "%s: name %s type %d ndims %d", __func__, norm_name, xtype, ndims));
 #ifdef LOGGING
    {
       int dd;
@@ -440,39 +543,24 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    }
 #endif
 
-   /* Add a new var. */
-   if ((retval = nc4_var_add(&var)))
-      BAIL(retval);
-
-   /* Now fill in the values in the var info structure. */
-   if (!(var->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
-      BAIL(NC_ENOMEM);
-   strcpy(var->name, norm_name);
-   var->hash = hash_fast(norm_name, strlen(norm_name));
-   var->varid = grp->nvars++;
-   var->ndims = ndims;
-   var->is_new_var = NC_TRUE;
-
-   nc4_vararray_add(grp, var);
-
    /* 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. */
    if (xtype <= NC_STRING)
    {
       if (!(type_info = calloc(1, sizeof(NC_TYPE_INFO_T))))
-	 BAIL(NC_ENOMEM);
+         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,
-				       type_info->endianness)))
-	 BAIL(retval);
+                                       type_info->endianness)))
+         BAIL(retval);
       if ((type_info->native_hdf_typeid = H5Tget_native_type(type_info->hdf_typeid,
-							      H5T_DIR_DEFAULT)) < 0)
+                                                             H5T_DIR_DEFAULT)) < 0)
          BAIL(NC_EHDFERR);
       if ((retval = nc4_get_typelen_mem(h5, type_info->nc_typeid, 0,
-					&type_info->size)))
-	 BAIL(retval);
+                                        &type_info->size)))
+         BAIL(retval);
 
       /* Set the "class" of the type */
       if (xtype == NC_CHAR)
@@ -485,20 +573,20 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
             BAIL(NC_EHDFERR);
          switch(class)
          {
-            case H5T_STRING:
-               type_info->nc_type_class = NC_STRING;
-               break;
+         case H5T_STRING:
+            type_info->nc_type_class = NC_STRING;
+            break;
 
-            case H5T_INTEGER:
-               type_info->nc_type_class = NC_INT;
-               break;
+         case H5T_INTEGER:
+            type_info->nc_type_class = NC_INT;
+            break;
 
-            case H5T_FLOAT:
-               type_info->nc_type_class = NC_FLOAT;
-               break;
+         case H5T_FLOAT:
+            type_info->nc_type_class = NC_FLOAT;
+            break;
 
-            default:
-               BAIL(NC_EBADTYPID);
+         default:
+            BAIL(NC_EBADTYPID);
          }
       }
    }
@@ -509,18 +597,35 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
          BAIL(NC_EBADTYPE);
    }
 
-  /* Point to the type, and increment its ref. count */
-  var->type_info = type_info;
-  var->type_info->rc++;
-  type_info = NULL;
+   /* Create a new var and fill in some HDF5 cache setting values. */
+   if ((retval = nc4_var_add(&var)))
+      BAIL(retval);
+
+   /* Now fill in the values in the var info structure. */
+   if (!(var->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
+      BAIL(NC_ENOMEM);
+   strcpy(var->name, norm_name);
+   var->hash = hash_fast(norm_name, strlen(norm_name));
+   var->varid = grp->nvars++;
+   var->ndims = ndims;
+   var->is_new_var = NC_TRUE;
+
+   /* Add a var to the variable array, growing it as needed. */
+   if ((retval = nc4_vararray_add(grp, var)))
+      BAIL(retval);
+
+   /* Point to the type, and increment its ref. count */
+   var->type_info = type_info;
+   var->type_info->rc++;
+   type_info = NULL;
 
    /* Allocate space for dimension information. */
    if (ndims)
    {
       if (!(var->dim = calloc(ndims, sizeof(NC_DIM_INFO_T *))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
       if (!(var->dimids = calloc(ndims, sizeof(int))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
    }
 
    /* Set variables no_fill to match the database default
@@ -550,32 +655,31 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
       {
          var->dimscale = NC_TRUE;
          dim->coord_var = var;
-
-         /* Use variable's dataset ID for the dimscale ID */
+         
+         /* Use variable's dataset ID for the dimscale ID. So delete
+          * the HDF5 DIM_WITHOUT_VARIABLE dataset that was created for
+          * this dim. */
          if (dim->hdf_dimscaleid)
          {
             /* Detach dimscale from any variables using it */
             if ((retval = rec_detach_scales(grp, dimidsp[d], dim->hdf_dimscaleid)) < 0)
                BAIL(retval);
-
+            
+            /* Close the HDF5 DIM_WITHOUT_VARIABLE dataset. */
             if (H5Dclose(dim->hdf_dimscaleid) < 0)
-                BAIL(NC_EHDFERR);
+               BAIL(NC_EHDFERR);
             dim->hdf_dimscaleid = 0;
-
-            /* Now delete the dataset (it will be recreated later, if necessary) */
+            
+            /* Now delete the DIM_WITHOUT_VARIABLE dataset (it will be
+             * recreated later, if necessary). */
             if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
                BAIL(NC_EDIMMETA);
          }
       }
 
-      /* Check for unlimited dimension and turn off contiguous storage */
-      /* (unless HDF4 file) */
-#ifdef USE_HDF4
-      if (dim->unlimited && !h5->hdf4)
-#else
+      /* Check for unlimited dimension and turn off contiguous storage. */
       if (dim->unlimited)
-#endif
-	 var->contiguous = NC_FALSE;
+         var->contiguous = NC_FALSE;
 
       /* Track dimensions for variable */
       var->dimids[d] = dimidsp[d];
@@ -583,12 +687,12 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
    }
 
    /* Determine default chunksizes for this variable. (Even for
-    * variables which may be contiguous. */
+    * variables which may be contiguous.) */
    LOG((4, "allocating array of %d size_t to hold chunksizes for var %s",
-	var->ndims, var->name));
+        var->ndims, var->name));
    if (var->ndims)
       if (!(var->chunksizes = calloc(var->ndims, sizeof(size_t))))
-	 BAIL(NC_ENOMEM);
+         BAIL(NC_ENOMEM);
 
    if ((retval = nc4_find_default_chunksizes2(grp, var)))
       BAIL(retval);
@@ -605,17 +709,17 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
     * and this var has the same name. */
    for (dim = grp->dim; dim; dim = dim->l.next)
       if (dim->hash == var->hash && !strcmp(dim->name, norm_name) &&
-	  (!var->ndims || dimidsp[0] != dim->dimid))
+          (!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) +
-					strlen(norm_name) + 1) * sizeof(char))))
-	    BAIL(NC_ENOMEM);
-
-	 sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, norm_name);
+         /* 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) +
+                                        strlen(norm_name) + 1) * sizeof(char))))
+            BAIL(NC_ENOMEM);
+
+         sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, norm_name);
       }
 
    /* If this is a coordinate var, it is marked as a HDF5 dimension
@@ -639,40 +743,51 @@ exit:
    return retval;
 }
 
-/* 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,
-           const int *dimidsp, int *varidp)
-{
-   NC *nc;
-   NC_HDF5_FILE_INFO_T *h5;
-
-   LOG((2, "%s: ncid 0x%x name %s xtype %d ndims %d",
-        __func__, ncid, name, xtype, ndims));
-
-   /* If there are dimensions, I need their ids. */
-   if (ndims && !dimidsp)
-      return NC_EINVAL;
-
-   /* Find metadata for this file. */
-   if (!(nc = nc4_find_nc_file(ncid,&h5)))
-      return NC_EBADID;
-
-   /* Handle netcdf-4 cases. */
-   return nc_def_var_nc4(ncid, name, xtype, ndims, dimidsp, varidp);
-}
-
-/* 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. */
+/**
+ * @internal Get all the information about a variable. Pass NULL for
+ * whatever you don't care about. This is the internal function called
+ * by nc_inq_var(), nc_inq_var_deflate(), nc_inq_var_fletcher32(),
+ * nc_inq_var_chunking(), nc_inq_var_chunking_ints(),
+ * nc_inq_var_fill(), nc_inq_var_endian(), nc_inq_var_filter(), and
+ * nc_inq_var_szip().
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param name Gets name.
+ * @param xtypep Gets type.
+ * @param ndimsp Gets number of dims.
+ * @param dimidsp Gets array of dim IDs.
+ * @param nattsp Gets number of attributes.
+ * @param shufflep Gets shuffle setting.
+ * @param deflatep Gets deflate setting.
+ * @param deflate_levelp Gets deflate level.
+ * @param fletcher32p Gets fletcher32 setting.
+ * @param contiguousp Gets contiguous setting.
+ * @param chunksizesp Gets chunksizes.
+ * @param no_fill Gets fill mode.
+ * @param fill_valuep Gets fill value.
+ * @param endiannessp Gets one of ::NC_ENDIAN_BIG ::NC_ENDIAN_LITTLE
+ * ::NC_ENDIAN_NATIVE
+ * @param idp Pointer to memory to store filter id.
+ * @param nparamsp Pointer to memory to store filter parameter count.
+ * @param params Pointer to vector of unsigned integers into which
+ * to store filter parameters.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Bad varid.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @returns ::NC_EINVAL Invalid input.
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 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 *options_maskp, int *pixels_per_blockp)
+                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,
+                unsigned int* idp, size_t* nparamsp, unsigned int* params
+   )
 {
    NC *nc;
    NC_GRP_INFO_T *grp;
@@ -708,10 +823,9 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
 
    /* Find the var. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
-   if (!var) return NC_ENOTVAR;
-   assert(var->varid == varid);
+   assert(var && var->varid == varid);
 
    /* Copy the data to the user's data buffers. */
    if (name)
@@ -750,13 +864,13 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
       *shufflep = (int)var->shuffle;
    if (fletcher32p)
       *fletcher32p = (int)var->fletcher32;
-   /* NOTE: No interface for returning szip flag currently (but it should never
-    *   be set).
-    */
-   if (options_maskp)
-      *options_maskp = var->options_mask;
-   if (pixels_per_blockp)
-      *pixels_per_blockp = var->pixels_per_block;
+
+   if (idp)
+      *idp = var->filterid;
+   if (nparamsp)
+      *nparamsp = (var->params == NULL ? 0 : var->nparams);
+   if (params && var->params != NULL)
+      memcpy(params,var->params,var->nparams*sizeof(unsigned int));
 
    /* Fill value stuff. */
    if (no_fill)
@@ -767,25 +881,25 @@ 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 (*(char **)var->fill_value) {
+         {
+            if (*(char **)var->fill_value) {
 
                if (!(fill_valuep = calloc(1, sizeof(char *))))
-                 return NC_ENOMEM;
+                  return NC_ENOMEM;
 
                if (!(*(char **)fill_valuep = strdup(*(char **)var->fill_value)))
-                 {
-                   free(fill_valuep);
-                   return NC_ENOMEM;
-                 }
-             }
-           }
+               {
+                  free(fill_valuep);
+                  return NC_ENOMEM;
+               }
+            }
+         }
          else {
-             assert(var->type_info->size);
-             memcpy(fill_valuep, var->fill_value, var->type_info->size);
+            assert(var->type_info->size);
+            memcpy(fill_valuep, var->fill_value, var->type_info->size);
          }
       }
       else
@@ -800,8 +914,8 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                free(fill_valuep);
                return retval;
             } else {
-	      free(fill_valuep);
-	    }
+               free(fill_valuep);
+            }
          }
          else
          {
@@ -818,59 +932,75 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
    return NC_NOERR;
 }
 
-/* This functions sets extra stuff about a netCDF-4 variable which
-   must be set before the enddef but after the def_var. This is an
-   internal function, deliberately hidden from the user so that we can
-   change the prototype of this functions without changing the API. */
+/**
+ * @internal This functions sets extra stuff about a netCDF-4 variable which
+ * must be set before the enddef but after the def_var.
+ *
+ * @note All pointer parameters may be NULL, in which case they are ignored.
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param shuffle Pointer to shuffle setting. 
+ * @param deflate Pointer to deflate setting.
+ * @param deflate_level Pointer to deflate level.
+ * @param fletcher32 Pointer to fletcher32 setting.
+ * @param contiguous Pointer to contiguous setting.
+ * @param chunksizes Array of chunksizes.
+ * @param no_fill Pointer to no_fill setting.
+ * @param fill_value Pointer to fill value.
+ * @param endianness Pointer to endianness setting.
+ *
+ * @returns ::NC_NOERR for success
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ * netcdf-4 file.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EPERM File is read only.
+ * @returns ::NC_EINVAL Invalid input
+ * @returns ::NC_EBADCHUNK Bad chunksize.
+ * @author Ed Hartnett
+ */
 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,
+                 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_HDF5_FILE_INFO_T *h5;
    NC_VAR_INFO_T *var;
-   NC_DIM_INFO_T *dim;
    int d;
    int retval;
-   nc_bool_t ishdf4 = NC_FALSE; /* Use this to avoid so many ifdefs */
+
+   /* All or none of these will be provided. */
+   assert((deflate && deflate_level && shuffle) ||
+          (!deflate && !deflate_level && !shuffle));
 
    LOG((2, "%s: ncid 0x%x varid %d", __func__, ncid, varid));
 
    /* 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;
-
-#ifdef USE_HDF4
-   ishdf4 = h5->hdf4;
-#endif
-
-   /* Attempting to do any of these things on a netCDF-3 file produces
-    * an error. */
-   if (!h5)
-      return NC_ENOTNC4;
-
    assert(nc && grp && h5);
 
+   /* Trying to write to a read-only file? No way, Jose! */
+   if (h5->no_write)
+      return NC_EPERM;
+
    /* Find the var. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
-   if (!var) return NC_ENOTVAR;
-   assert(var->varid == varid);
-
-   /* Can't turn on contiguous and deflate/fletcher32/szip. */
-   if (contiguous)
-      if ((*contiguous != NC_CHUNKED && deflate) ||
-	  (*contiguous != NC_CHUNKED && fletcher32))
-	 return NC_EINVAL;
+   assert(var && var->varid == varid);
 
    /* Can't turn on parallel and deflate/fletcher32/szip/shuffle. */
    if (nc->mode & (NC_MPIIO | NC_MPIPOSIX)) {
       if (deflate || fletcher32 || shuffle)
-	 return NC_EINVAL;
+         return NC_EINVAL;
    }
 
    /* If the HDF5 dataset has already been created, then it is too
@@ -886,13 +1016,13 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
    if (deflate && deflate_level)
    {
       if (*deflate)
-         if (*deflate_level < MIN_DEFLATE_LEVEL ||
-             *deflate_level > MAX_DEFLATE_LEVEL)
+         if (*deflate_level < NC_MIN_DEFLATE_LEVEL ||
+             *deflate_level > NC_MAX_DEFLATE_LEVEL)
             return NC_EINVAL;
 
       /* For scalars, just ignore attempt to deflate. */
       if (!var->ndims)
-            return NC_NOERR;
+         return NC_NOERR;
 
       /* Well, if we couldn't find any errors, I guess we have to take
        * the users settings. Darn! */
@@ -923,21 +1053,16 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
    if (contiguous && *contiguous)
    {
       if (var->deflate || var->fletcher32 || var->shuffle)
-	 return NC_EINVAL;
+         return NC_EINVAL;
 
-     if (!ishdf4) {
       for (d = 0; d < var->ndims; d++)
-      {
-	 dim = var->dim[d];
-	 if (dim->unlimited)
-	    return NC_EINVAL;
-      }
+         if (var->dim[d]->unlimited)
+            return NC_EINVAL;
       var->contiguous = NC_TRUE;
-    }
    }
 
    /* Chunksizes anyone? */
-   if (!ishdf4 && contiguous && *contiguous == NC_CHUNKED)
+   if (contiguous && *contiguous == NC_CHUNKED)
    {
       var->contiguous = NC_FALSE;
 
@@ -946,31 +1071,33 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
       if (chunksizes)
       {
 
-	 if ((retval = check_chunksizes(grp, var, chunksizes)))
-	    return retval;
-	 for (d = 0; d < var->ndims; d++) {
-	    if(var->dim[d]->len > 0 && chunksizes[d] > var->dim[d]->len)
-	       return NC_EBADCHUNK;
-	 }
+         if ((retval = check_chunksizes(grp, var, chunksizes)))
+            return retval;
 
-	 /* Set the chunksizes for this variable. */
-	 for (d = 0; d < var->ndims; d++)
-	    var->chunksizes[d] = chunksizes[d];
+         /* Ensure chunksize is smaller than dimension size */
+         for (d = 0; d < var->ndims; d++)
+            if(!var->dim[d]->unlimited && var->dim[d]->len > 0 && chunksizes[d] > var->dim[d]->len)
+               return NC_EBADCHUNK;
+
+         /* Set the chunksizes for this variable. */
+         for (d = 0; d < var->ndims; d++)
+            var->chunksizes[d] = chunksizes[d];
       }
    }
 
    /* Is this a variable with a chunksize greater than the current
     * cache size? */
-   if (!var->contiguous && (chunksizes || deflate || contiguous))
+   if (!var->contiguous && (deflate || contiguous))
    {
-      /* Determine default chunksizes for this variable. */
-      if (!var->chunksizes[0])
-	 if ((retval = nc4_find_default_chunksizes2(grp, var)))
-	    return retval;
+      /* Determine default chunksizes for this variable (do nothing
+       * for scalar vars). */
+      if (var->chunksizes && !var->chunksizes[0])
+         if ((retval = nc4_find_default_chunksizes2(grp, var)))
+            return retval;
 
       /* Adjust the cache. */
       if ((retval = nc4_adjust_var_cache(grp, var)))
-	 return retval;
+         return retval;
    }
 
    /* Are we setting a fill modes? */
@@ -1006,19 +1133,53 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
    return NC_NOERR;
 }
 
-/* Set the deflate level for a var, lower is faster, higher is
- * better. Must be called after nc_def_var and before nc_enddef or any
- * functions which writes data to the file. */
+/**
+ * @internal Set compression settings on a variable. This is called by
+ * nc_def_var_deflate().
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param shuffle True to turn on the shuffle filter.
+ * @param deflate True to turn on deflation.
+ * @param deflate_level A number between 0 (no compression) and 9
+ * (maximum compression).
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EINVAL Invalid input
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 int
 NC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
-                   int deflate_level)
+                    int deflate_level)
 {
    return nc_def_var_extra(ncid, varid, &shuffle, &deflate,
                            &deflate_level, NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
-/* Set checksum for a var. This must be called after the nc_def_var
- * but before the nc_enddef. */
+/**
+ * @internal Set checksum on a variable. This is called by
+ * nc_def_var_fletcher32().
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param fletcher32 Pointer to fletcher32 setting.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EINVAL Invalid input
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 int
 NC4_def_var_fletcher32(int ncid, int varid, int fletcher32)
 {
@@ -1026,15 +1187,28 @@ NC4_def_var_fletcher32(int ncid, int varid, int fletcher32)
                            NULL, NULL, NULL, NULL, NULL);
 }
 
-/* Define chunking stuff for a var. This must be done after nc_def_var
-   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.
-*/
+/**
+ * @internal Define chunking stuff for a var. This is called by
+ * nc_def_var_chunking(). Chunking is required in any dataset with one
+ * or more unlimited dimensions in HDF5, or any dataset using a
+ * filter.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param contiguous Pointer to contiguous setting.
+ * @param chunksizesp Array of chunksizes.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EINVAL Invalid input
+ * @returns ::NC_EBADCHUNK Bad chunksize.
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 int
 NC4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp)
 {
@@ -1042,9 +1216,22 @@ NC4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksiz
                            &contiguous, chunksizesp, NULL, NULL, NULL);
 }
 
-/* Inquire about chunking stuff for a var. This is a private,
- * undocumented function, used by the f77 API to avoid size_t
- * problems. */
+/**
+ * @internal Inquire about chunking settings for a var. This is used
+ * by the fortran API.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param contiguousp Gets contiguous setting.
+ * @param chunksizesp Gets chunksizes.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_EINVAL Invalid input
+ * @returns ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+ */
 int
 nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp)
 {
@@ -1068,19 +1255,19 @@ nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp
    /* 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;
+         return NC_ENOMEM;
 
    retval = NC4_inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, contiguousp, cs, NULL,
-                           NULL, NULL, NULL, NULL);
+                            NULL, NULL, NULL, NULL, contiguousp, cs, NULL,
+                            NULL, NULL, NULL, NULL, NULL);
 
    /* Copy from size_t array. */
-   if (*contiguousp == NC_CHUNKED)
+   if (chunksizesp && var->contiguous == NC_CHUNKED)
       for (i = 0; i < var->ndims; i++)
       {
-	 chunksizesp[i] = (int)cs[i];
-	 if (cs[i] > NC_MAX_INT)
-	    retval = NC_ERANGE;
+         chunksizesp[i] = (int)cs[i];
+         if (cs[i] > NC_MAX_INT)
+            retval = NC_ERANGE;
       }
 
    if (var->ndims)
@@ -1088,10 +1275,26 @@ nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp
    return retval;
 }
 
-/* This function defines the chunking with ints, which works better
- * with F77 portability. It is a secret function, which has been
- * rendered unmappable, and it is impossible to apparate anywhere in
- * this function. */
+/**
+ * @internal Define chunking stuff for a var. This is called by
+ * the fortran API.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param contiguous Pointer to contiguous setting.
+ * @param chunksizesp Array of chunksizes.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EINVAL Invalid input
+ * @returns ::NC_EBADCHUNK Bad chunksize.
+ * @author Ed Hartnett
+ */
 int
 nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
 {
@@ -1109,7 +1312,7 @@ nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
 
 #ifdef USE_HDF4
    if(h5->hdf4)
-	return NC_NOERR;
+      return NC_NOERR;
 #endif
 
    /* Find var cause I need the number of dims. */
@@ -1119,7 +1322,7 @@ nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
    /* 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;
+         return NC_ENOMEM;
 
    /* Copy to size_t array. */
    for (i = 0; i < var->ndims; i++)
@@ -1133,8 +1336,29 @@ nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
    return retval;
 }
 
-/* Define fill value behavior for a variable. This must be done after
-   nc_def_var and before nc_enddef. */
+/**
+ * @internal This functions sets fill value and no_fill mode for a
+ * netCDF-4 variable. It is called by nc_def_var_fill().
+ *
+ * @note All pointer parameters may be NULL, in which case they are ignored.
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param no_fill No_fill setting.
+ * @param fill_value Pointer to fill value.
+ *
+ * @returns ::NC_NOERR for success
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ * netcdf-4 file.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EPERM File is read only.
+ * @returns ::NC_EINVAL Invalid input
+ * @author Ed Hartnett
+ */
 int
 NC4_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
 {
@@ -1142,8 +1366,28 @@ NC4_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
                            NULL, &no_fill, fill_value, NULL);
 }
 
-
-/* Define the endianness of a variable. */
+/**
+ * @internal This functions sets endianness for a netCDF-4
+ * variable. Called by nc_def_var_endian().
+ *
+ * @note All pointer parameters may be NULL, in which case they are ignored.
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param endianness Endianness setting.
+ *
+ * @returns ::NC_NOERR for success
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3
+ * netcdf-4 file.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_ENOTINDEFINE Not in define mode.
+ * @returns ::NC_EPERM File is read only.
+ * @returns ::NC_EINVAL Invalid input
+ * @author Ed Hartnett
+ */
 int
 NC4_def_var_endian(int ncid, int varid, int endianness)
 {
@@ -1151,7 +1395,105 @@ NC4_def_var_endian(int ncid, int varid, int endianness)
                            NULL, NULL, NULL, &endianness);
 }
 
-/* Get var id from name. */
+/**
+ * @internal Define filter settings. Called by nc_def_var_filter().
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param id Filter ID
+ * @param nparams Number of parameters for filter.
+ * @param parms Filter parameters.
+ *
+ * @returns ::NC_NOERR for success
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
+ * not netCDF-4/HDF5.
+ * @returns ::NC_ELATEDEF Too late to change settings for this variable.
+ * @returns ::NC_EFILTER Filter error.
+ * @returns ::NC_EINVAL Invalid input
+ * @author Dennis Heimbigner
+ */
+int
+NC4_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams,
+                   const unsigned int* parms)
+{
+   int retval = NC_NOERR;
+   NC *nc;
+   NC_GRP_INFO_T *grp;
+   NC_HDF5_FILE_INFO_T *h5;
+   NC_VAR_INFO_T *var;
+
+   LOG((2, "%s: ncid 0x%x varid %d", __func__, ncid, varid));
+
+   /* 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(nc && grp && h5);
+
+   /* Find the var. */
+   if (varid < 0 || varid >= grp->vars.nelems)
+      return NC_ENOTVAR;
+   var = grp->vars.value[varid];
+   if (!var) return NC_ENOTVAR;
+   assert(var->varid == varid);
+
+   /* Can't turn on parallel and filters */
+   if (nc->mode & (NC_MPIIO | NC_MPIPOSIX)) {
+      return NC_EINVAL;
+   }
+
+   /* If the HDF5 dataset has already been created, then it is too
+    * late to set all the extra stuff. */
+   if (var->created)
+      return NC_ELATEDEF;
+
+#ifdef HAVE_H5Z_SZIP
+   if(id == H5Z_FILTER_SZIP) {
+      if(nparams != 2)
+         return NC_EFILTER; /* incorrect no. of parameters */
+   }
+#else /*!HAVE_H5Z_SZIP*/
+   if(id == H5Z_FILTER_SZIP)
+      return NC_EFILTER; /* Not allowed */
+#endif
+
+#if 0
+   {
+      unsigned int fcfg = 0;
+      herr_t herr = H5Zget_filter_info(id,&fcfg);
+      if(herr < 0)
+         return NC_EFILTER;
+      if((H5Z_FILTER_CONFIG_ENCODE_ENABLED & fcfg) == 0
+         || (H5Z_FILTER_CONFIG_DECODE_ENABLED & fcfg) == 0)
+         return NC_EFILTER;
+   }
+#endif /*0*/
+
+   var->filterid = id;
+   var->nparams = nparams;
+   var->params = NULL;
+   if(parms != NULL) {
+      var->params = (unsigned int*)calloc(nparams,sizeof(unsigned int));
+      if(var->params == NULL) return NC_ENOMEM;
+      memcpy(var->params,parms,sizeof(unsigned int)*var->nparams);
+   }
+   return NC_NOERR;
+}
+
+/**
+ * @internal Find the ID of a variable, from the name. This function
+ * is called by nc_inq_varid().
+ *
+ * @param ncid File ID.
+ * @param name Name of the variable.
+ * @param varidp Gets variable ID.
+
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Bad variable ID.
+ */
 int
 NC4_inq_varid(int ncid, const char *name, int *varidp)
 {
@@ -1162,7 +1504,7 @@ NC4_inq_varid(int ncid, const char *name, int *varidp)
    int retval;
    uint32_t nn_hash;
    int i;
-   
+
    if (!name)
       return NC_EINVAL;
    if (!varidp)
@@ -1182,22 +1524,35 @@ NC4_inq_varid(int ncid, const char *name, int *varidp)
 
    /* Find var of this name. */
    for (i=0; i < grp->vars.nelems; i++)
+   {
+      var = grp->vars.value[i];
+      if (!var) continue;
+      if (nn_hash == var->hash && !(strcmp(var->name, norm_name)))
       {
-	var = grp->vars.value[i];
-	if (!var) continue;
-        if (nn_hash == var->hash && !(strcmp(var->name, norm_name)))
-          {
-             *varidp = var->varid;
-             return NC_NOERR;
-          }
+         *varidp = var->varid;
+         return NC_NOERR;
       }
+   }
    return NC_ENOTVAR;
 }
 
-/* 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.  */
+/**
+ * @internal Rename a var to "bubba," for example. This is called by
+ * nc_rename_var() for netCDF-4 files.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID
+ * @param name New name of the variable.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Bad ncid.
+ * @returns ::NC_ENOTVAR Invalid variable ID.
+ * @returns ::NC_EBADNAME Bad name.
+ * @returns ::NC_EMAXNAME Name is too long.
+ * @returns ::NC_ENAMEINUSE Name in use.
+ * @returns ::NC_ENOMEM Out of memory.
+ * @author Ed Hartnett
+*/
 int
 NC4_rename_var(int ncid, int varid, const char *name)
 {
@@ -1209,14 +1564,16 @@ NC4_rename_var(int ncid, int varid, const char *name)
    int retval = NC_NOERR;
    int i;
 
-   LOG((2, "%s: ncid 0x%x varid %d name %s",
-        __func__, ncid, varid, name));
+   if (!name)
+      return NC_EINVAL;
+
+   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);
+   assert(h5 && grp && h5);
 
    /* Is the new name too long? */
    if (strlen(name) > NC_MAX_NAME)
@@ -1254,9 +1611,19 @@ NC4_rename_var(int ncid, int varid, const char *name)
       return NC_ENOTINDEFINE;
 
    /* Change the HDF5 file, if this var has already been created
-      there. */
+      there. Should we check here to ensure there is not already a
+      dimscale dataset of name name??? */
    if (var->created)
    {
+      /* Is there an existing dimscale-only dataset of this name? If
+       * so, it must be deleted. */
+      if (var->ndims && var->dim[0]->hdf_dimscaleid)
+      {
+         if ((retval = delete_existing_dimscale_dataset(grp, var->dim[0]->dimid, var->dim[0])))
+            return retval;
+      }
+      
+      LOG((3, "Moving dataset %s to %s", var->name, name));
       if (H5Gmove(grp->hdf_grpid, var->name, name) < 0)
          BAIL(NC_EHDFERR);
    }
@@ -1267,6 +1634,7 @@ NC4_rename_var(int ncid, int varid, const char *name)
       return NC_ENOMEM;
    strcpy(var->name, name);
    var->hash = nn_hash;
+   LOG((3, "var is now %s", var->name));
 
    /* Check if this was a coordinate variable previously, but names are different now */
    if (var->dimscale && strcmp(var->name, var->dim[0]->name))
@@ -1285,26 +1653,43 @@ NC4_rename_var(int ncid, int varid, const char *name)
          NC_GRP_INFO_T *dim_grp;
          NC_DIM_INFO_T *dim;
 
-          /* Check to see if this is became a coordinate variable.  If so, it
-           * will have the same name as dimension index 0. If it is a
-           * coordinate var, is it a coordinate var in the same group as the dim?
-           */
+         /* Check to see if this is became a coordinate variable.  If so, it
+          * will have the same name as dimension index 0. If it is a
+          * coordinate var, is it a coordinate var in the same group as the dim?
+          */
          if ((retval = nc4_find_dim(grp, var->dimids[0], &dim, &dim_grp)))
             return retval;
          if (strcmp(dim->name, name) == 0 && dim_grp == grp)
          {
-             /* Reform the coordinate variable */
-             if ((retval = nc4_reform_coord_var(grp, var, dim)))
-                return retval;
+            /* Reform the coordinate variable */
+            if ((retval = nc4_reform_coord_var(grp, var, dim)))
+               return retval;
          }
       }
    }
 
-  exit:
+exit:
    return retval;
 }
 
-
+/**
+ * @internal
+ *
+ * This function will change the parallel access of a variable from
+ * independent to collective.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param par_access NC_COLLECTIVE or NC_INDEPENDENT.
+ *
+ * @returns ::NC_NOERR No error.
+ * @returns ::NC_EBADID Invalid ncid passed.
+ * @returns ::NC_ENOTVAR Invalid varid passed.
+ * @returns ::NC_ENOPAR LFile was not opened with nc_open_par/nc_create_var.
+ * @returns ::NC_EINVAL Invalid par_access specified.
+ * @returns ::NC_NOERR for success
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 int
 NC4_var_par_access(int ncid, int varid, int par_access)
 {
@@ -1333,7 +1718,7 @@ NC4_var_par_access(int ncid, int varid, int par_access)
 
    /* Find the var, and set its preference. */
    if (varid < 0 || varid >= grp->vars.nelems)
-     return NC_ENOTVAR;
+      return NC_ENOTVAR;
    var = grp->vars.value[varid];
    if (!var) return NC_ENOTVAR;
    assert(var->varid == varid);
@@ -1346,26 +1731,23 @@ NC4_var_par_access(int ncid, int varid, int par_access)
 #endif /* USE_PARALLEL4 */
 }
 
-static int
-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;
-
-   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)))
-      return NC_EBADID;
-
-   return nc4_put_vara(nc, ncid, varid, startp, countp, mem_type,
-                       mem_type_is_long, (void *)op);
-}
-
 #ifdef USE_HDF4
+/**
+ * @internal Get data from an HDF4 SD dataset.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param startp Array of start indicies.
+ * @param countp Array of counts.
+ * @param mem_nc_type The type of these data after it is read into memory.
+ * @param is_long Ignored for HDF4.
+ * @param data pointer that gets the data.
+ * @returns ::NC_NOERR for success
+ * @author Ed Hartnett
+ */
 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)
+                  const size_t *countp, nc_type mem_nc_type, int is_long, void *data)
 {
    NC_GRP_INFO_T *grp;
    NC_HDF5_FILE_INFO_T *h5;
@@ -1393,58 +1775,69 @@ nc4_get_hdf4_vara(NC *nc, int ncid, int varid, const size_t *startp,
 }
 #endif /* USE_HDF4 */
 
-/* Get an array. */
-static int
-nc4_get_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long,
-                const size_t *startp, const size_t *countp, void *ip)
+/**
+ * @internal Write an array of data to a variable. This is called by
+ * nc_put_vara() and other nc_put_vara_* functions, for netCDF-4
+ * files.
+ * 
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param startp Array of start indicies.
+ * @param countp Array of counts.
+ * @param op pointer that gets the data.
+ * @param memtype The type of these data in memory.
+ *
+ * @returns ::NC_NOERR for success
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
+int
+NC4_put_vara(int ncid, int varid, const size_t *startp,
+             const size_t *countp, const void *op, int memtype)
 {
    NC *nc;
-   NC_HDF5_FILE_INFO_T* h5;
 
-   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)))
+   if (!(nc = nc4_find_nc_file(ncid, NULL)))
       return NC_EBADID;
 
-#ifdef USE_HDF4
-   /* Handle HDF4 cases. */
-   if (h5->hdf4)
-      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,
-                       mem_type_is_long, (void *)ip);
+   return nc4_put_vara(nc, ncid, varid, startp, countp, memtype, 0, (void *)op);
 }
 
+/**
+ * Read an array of values. This is called by nc_get_vara() for
+ * netCDF-4 files, as well as all the other nc_get_vara_*
+ * functions. HDF4 files are handled as a special case.
+ *
+ * @param ncid File ID.
+ * @param varid Variable ID.
+ * @param startp Array of start indicies.
+ * @param countp Array of counts.
+ * @param ip pointer that gets the data.
+ * @param memtype The type of these data after it is read into memory.
+
+ * @returns ::NC_NOERR for success
+ * @author Ed Hartnett, Dennis Heimbigner
+ */
 int
-NC4_put_vara(int ncid, int varid, const size_t *startp,
-            const size_t *countp, const void *op, int memtype)
+NC4_get_vara(int ncid, int varid, const size_t *startp,
+             const size_t *countp, void *ip, int memtype)
 {
-   return nc4_put_vara_tc(ncid, varid, memtype, 0, startp, countp, op);
-}
+   NC *nc;
+   NC_HDF5_FILE_INFO_T* h5;
 
+   LOG((2, "%s: ncid 0x%x varid %d memtype %d", __func__, ncid, varid,
+        memtype));
 
-/* Read an array of values. */
-int
-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);
-}
+   if (!(nc = nc4_find_nc_file(ncid, &h5)))
+      return NC_EBADID;
 
-void
-nc4verify(int ncid, char* name)
-{
-   NC_GRP_INFO_T *grp;
-   NC_HDF5_FILE_INFO_T *h5;
-   int retval;
+#ifdef USE_HDF4
+   /* Handle HDF4 cases. */
+   if (h5->hdf4)
+      return nc4_get_hdf4_vara(nc, ncid, varid, startp, countp, memtype,
+                               0, (void *)ip);
+#endif /* USE_HDF4 */
 
-   /* Find info for this file and group, and set pointer to each. */
-   retval = nc4_find_grp_h5(ncid, &grp, &h5);
-   assert(grp && h5);
-   retval = nc4_check_dup_name(grp, name);
-   return;
+   /* Handle HDF5 cases. */
+   return nc4_get_vara(nc, ncid, varid, startp, countp, memtype,
+                       0, (void *)ip);
 }
diff --git a/libsrc4/ncfunc.c b/libsrc4/ncfunc.c
index c73840f..9e3b050 100644
--- a/libsrc4/ncfunc.c
+++ b/libsrc4/ncfunc.c
@@ -1,40 +1,64 @@
-/*
-
-This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
-HDF5 backend for netCDF, depending on your point of view.
-
-This file handles the nc_ calls, calling the appropriate nc3 or nc4
-function, depending on ncid.
-
-Copyright 2003, University Corporation for Atmospheric Research. See
-netcdf-4/docs/COPYRIGHT file for copying and redistribution
-conditions.
+/**
+ * @internal
+ *
+ * Copyright 2003, University Corporation for Atmospheric
+ * Research. See netcdf-4/docs/COPYRIGHT file for copying and
+ * redistribution conditions.
+ *
+ * This file is part of netcdf-4, a netCDF-like interface for HDF5, or a
+ * HDF5 backend for netCDF, depending on your point of view.
+ *
+ * This file handles the (useless) *_base_pe() functions, and the
+ * inq_format functions.
+ *
+ * @author Ed Hartnett, Dennis Heimbigner
 */
 
 #include "nc4internal.h"
 #include "nc4dispatch.h"
 
-/* This will return the length of a netcdf data type in bytes. Since
-   we haven't added any new types, I just call the v3 function.
-   Ed Hartnett 10/43/03
-*/
-
-/* This function only does anything for netcdf-3 files. */
+/**
+ * @internal This function only does anything for netcdf-3 files.
+ *
+ * @param ncid File ID (ignored).
+ * @param pe Processor element (ignored).
+ *
+ * @return ::NC_ENOTNC3 Not a netCDF classic format file.
+ * @author Ed Hartnett
+ */
 int
 NC4_set_base_pe(int ncid, int pe)
 {
-      return NC_ENOTNC3;
+   return NC_ENOTNC3;
 }
 
-/* This function only does anything for netcdf-3 files. */
+/**
+ * @internal This function only does anything for netcdf-3 files.
+ *
+ * @param ncid File ID (ignored).
+ * @param pe Pointer to processor element. Ignored if NULL. Gets a 0
+ * if present.
+ *
+ * @return ::NC_ENOTNC3 Not a netCDF classic format file.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_base_pe(int ncid, int *pe)
 {
    return NC_ENOTNC3;
 }
 
-/* Get the format (i.e. classic, 64-bit-offset, or netcdf-4) of an
- * open file. */
+/**
+ * @internal Get the format (i.e. NC_FORMAT_NETCDF4 pr
+ * NC_FORMAT_NETCDF4_CLASSIC) of an open netCDF-4 file.
+ *
+ * @param ncid File ID (ignored).
+ * @param formatp Pointer that gets the constant indicating format.
+
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Ed Hartnett
+ */
 int
 NC4_inq_format(int ncid, int *formatp)
 {
@@ -60,7 +84,23 @@ NC4_inq_format(int ncid, int *formatp)
    return NC_NOERR;
 }
 
-/* Get the extended format of an open file. */
+/**
+ * @internal Return the extended format (i.e. the dispatch model),
+ * plus the mode associated with an open file.
+ *
+ * @param ncid File ID (ignored).
+ * @param formatp a pointer that gets the extended format. Note that
+ * this is not the same as the format provided by nc_inq_format(). The
+ * extended foramt indicates the dispatch layer model. NetCDF-4 files
+ * will always get NC_FORMATX_NC4 for netCDF files, NC_FORMATX_HDF4
+ * for HDF4 files.
+ * @param modep a pointer that gets the open/create mode associated with
+ * this file. Ignored if NULL.
+
+ * @return ::NC_NOERR No error.
+ * @return ::NC_EBADID Bad ncid.
+ * @author Dennis Heimbigner
+ */
 int
 NC4_inq_format_extended(int ncid, int *formatp, int *modep)
 {
@@ -77,10 +117,10 @@ NC4_inq_format_extended(int ncid, int *formatp, int *modep)
 
    if(formatp) {
 #ifdef USE_HDF4
-	/* Distinguish HDF5 from HDF4 */
-	*formatp = (h5->hdf4 ? NC_FORMATX_NC_HDF4 : NC_FORMATX_NC_HDF5);
+      /* Distinguish HDF5 from HDF4 */
+      *formatp = (h5->hdf4 ? NC_FORMATX_NC_HDF4 : NC_FORMATX_NC_HDF5);
 #else /* USE_HDF4 */
-	*formatp = NC_FORMATX_NC_HDF5;
+      *formatp = NC_FORMATX_NC_HDF5;
 #endif /* USE_HDF4 */
    }
    return NC_NOERR;
diff --git a/libsrcp/Makefile.am b/libsrcp/Makefile.am
index 9e59f0c..291a51c 100644
--- a/libsrcp/Makefile.am
+++ b/libsrcp/Makefile.am
@@ -11,11 +11,6 @@ libnetcdfp_la_CPPFLAGS = ${AM_CPPFLAGS}
 # This is the code for a dispatch table for pnetcdf
 # (which has CDF5 as its magic number)
 
-# Turn on a pre-processor flag when building a DLL for windows.
-if BUILD_DLL
-libnetcdfp_la_CPPFLAGS += -DDLL_EXPORT
-endif # BUILD_DLL
-
 # These files comprise the pnetcdf dispatch library code.
 libnetcdfp_la_SOURCES = ncpdispatch.c
 
diff --git a/libsrcp/Makefile.in b/libsrcp/Makefile.in
index 77814f1..38f979a 100644
--- a/libsrcp/Makefile.in
+++ b/libsrcp/Makefile.in
@@ -103,15 +103,6 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
-# This is the code for a dispatch table for pnetcdf
-# (which has CDF5 as its magic number)
-
-# Turn on a pre-processor flag when building a DLL for windows.
- at BUILD_DLL_TRUE@am__append_3 = -DDLL_EXPORT
 subdir = libsrcp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -200,11 +191,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -227,12 +217,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -258,6 +250,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -272,6 +265,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -375,8 +369,11 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
-libnetcdfp_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_3)
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
+libnetcdfp_la_CPPFLAGS = ${AM_CPPFLAGS}
+
+# This is the code for a dispatch table for pnetcdf
+# (which has CDF5 as its magic number)
 
 # These files comprise the pnetcdf dispatch library code.
 libnetcdfp_la_SOURCES = ncpdispatch.c
diff --git a/libsrcp/ncpdispatch.c b/libsrcp/ncpdispatch.c
index 04f5ec8..5d4d14c 100644
--- a/libsrcp/ncpdispatch.c
+++ b/libsrcp/ncpdispatch.c
@@ -1157,7 +1157,7 @@ NCP_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
                int *shufflep, int *deflatep, int *deflate_levelp,
                int *fletcher32p, int *contiguousp, size_t *chunksizesp,
                int *no_fill, void *fill_valuep, int *endiannessp,
-	       int *options_maskp, int *pixels_per_blockp)
+	       unsigned int* idp, size_t* nparamsp, unsigned int* params)
 {
     int status;
     NC* nc;
@@ -1173,7 +1173,9 @@ NCP_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
     if(contiguousp) *contiguousp = NC_CONTIGUOUS;
     if(no_fill) *no_fill = 1;
     if(endiannessp) return NC_ENOTNC4;
-    if(options_maskp) return NC_ENOTNC4;
+    if(idp) return NC_ENOTNC4;
+    if(nparamsp) return NC_ENOTNC4;
+    if(params) return NC_ENOTNC4;
     return NC_NOERR;
 }
 
@@ -1502,6 +1504,12 @@ NCP_def_var_endian(int ncid, int varid, int endianness)
     return NC_ENOTNC4;
 }
 
+static int
+NCP_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms)
+{
+    return NC_ENOTNC4;
+}
+
 #endif /*USE_NETCDF4*/
 
 /**************************************************/
@@ -1593,6 +1601,7 @@ NCP_def_var_fletcher32,
 NCP_def_var_chunking,
 NCP_def_var_fill,
 NCP_def_var_endian,
+NCP_def_var_filter,
 NCP_set_var_chunk_cache,
 NCP_get_var_chunk_cache,
 #endif /*USE_NETCDF4*/
diff --git a/nc_test/CMakeLists.txt b/nc_test/CMakeLists.txt
index a081aa3..09f0261 100644
--- a/nc_test/CMakeLists.txt
+++ b/nc_test/CMakeLists.txt
@@ -83,6 +83,7 @@ IF(BUILD_UTILITIES)
     add_sh_test(nc_test run_diskless)
     IF(BUILD_MMAP)
       add_sh_test(nc_test run_mmap)
+      SET_TESTS_PROPERTIES(nc_test_run_mmap PROPERTIES RUN_SERIAL TRUE)
     ENDIF(BUILD_MMAP)
     IF(LARGE_FILE_TESTS)
       add_sh_test(nc_test run_diskless2)
diff --git a/nc_test/Make0 b/nc_test/Make0
index 9875dbc..a94996a 100644
--- a/nc_test/Make0
+++ b/nc_test/Make0
@@ -1,11 +1,14 @@
 # Test c output
-T=tst_utf8_normalize2
+T=tst_addvar
+
+ARGS=test_pnetcdf.nc
+
 #CMD=valgrind --leak-check=full
 CMD=gdb --args
 
-#PAR=1
+PAR=1
 
-CFLAGS=-Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I.. -I../include
+CFLAGS=-Wall -Wno-unused-variable -Wno-unused-function -g -O -I.. -I../include
 
 ifdef PAR
 CC=mpicc
@@ -23,7 +26,7 @@ LLP=/usr/local/lib:${LD_LIBRARY_PATH}
 
 all:: cmp
 	export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
-	${CMD} ./t
+	${CMD} ./t ${ARGS}
 
 cmp::
 	export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
diff --git a/nc_test/Makefile.am b/nc_test/Makefile.am
index 87d074e..b8fbf16 100644
--- a/nc_test/Makefile.am
+++ b/nc_test/Makefile.am
@@ -9,23 +9,18 @@ include $(top_srcdir)/lib_flags.am
 AM_CPPFLAGS += -I$(top_srcdir)/libsrc
 AM_CPPFLAGS += -DTOPSRCDIR=${abs_top_srcdir}
 AM_CPPFLAGS += -DTOPBINDIR=${abs_top_bindir}
+LDADD = ${top_builddir}/liblib/libnetcdf.la
+AM_CPPFLAGS += -I$(top_builddir)/liblib -I$(top_builddir)/include -I$(top_srcdir)/libsrc
 
-# These files are created by the tests.
-CLEANFILES = nc_test_classic.nc nc_test_64bit.nc nc_test_netcdf4.nc	\
-tst_*.nc t_nc.nc large_files.nc quick_large_files.nc \
-tst_diskless.nc tst_diskless2.nc \
-tst_diskless3.nc tst_diskless3_file.cdl tst_diskless3_memory.cdl \
-tst_diskless4.cdl tst_diskless4.nc tst_formatx.nc nc_test_cdf5.nc \
-unlim.nc tst_inq_type.nc tst_elatefill.nc tst_global_fillval.nc \
-tst_large_cdf5.nc
 
-check_PROGRAMS =
+# Note which tests depend on other tests. necessary for make -j check
+TEST_EXTENSIONS = .sh
 
 # These are the tests which are always run.
-TESTPROGRAMS = t_nc tst_small nc_test tst_misc tst_norm \
-	tst_names tst_nofill tst_nofill2 tst_nofill3 tst_atts3 \
-	tst_meta tst_inq_type tst_utf8_validate tst_utf8_phrases \
-	tst_global_fillval
+TESTPROGRAMS = t_nc tst_small nc_test tst_misc tst_norm tst_names       \
+tst_nofill tst_nofill2 tst_nofill3 tst_atts3 tst_meta tst_inq_type      \
+tst_utf8_validate tst_utf8_phrases tst_global_fillval                   \
+tst_max_var_dims tst_formats
 
 if USE_NETCDF4
 TESTPROGRAMS += tst_atts tst_put_vars tst_elatefill
@@ -35,13 +30,18 @@ if USE_PNETCDF
 TESTPROGRAMS += tst_parallel2 tst_pnetcdf tst_addvar tst_formatx_pnetcdf
 endif
 
+if TEST_PARALLEL4
+if USE_PNETCDF
+if USE_CDF5
+TESTPROGRAMS += tst_cdf5format
+endif
+endif
+endif
+
 # These are the source files for the main workhorse test program,
 # nc_test. If you pass nc_test, you are doing well.
-nc_test_SOURCES = nc_test.c error.c test_get.c test_put.c \
-test_read.c test_write.c util.c error.h tests.h
-
-LDADD = ${top_builddir}/liblib/libnetcdf.la
-AM_CPPFLAGS += -I$(top_builddir)/liblib -I$(top_builddir)/include -I$(top_srcdir)/libsrc
+nc_test_SOURCES = nc_test.c error.c test_get.c test_put.c test_read.c	\
+test_write.c util.c error.h tests.h
 
 # If the user asked for large file tests, then add them.
 if LARGE_FILE_TESTS
@@ -52,11 +52,10 @@ endif # LARGE_FILE_TESTS
 if BUILD_BENCHMARKS
 TESTPROGRAMS += testnc3perf
 testnc3perf_SOURCES = testnc3perf.c
-CLEANFILES += benchmark.nc
 endif
 
 # Set up the tests.
-check_PROGRAMS += $(TESTPROGRAMS)
+check_PROGRAMS = $(TESTPROGRAMS)
 
 # Build Diskless test helpers
 if BUILD_DISKLESS
@@ -73,6 +72,7 @@ if BUILD_DISKLESS
 TESTS += run_diskless.sh run_diskless5.sh
 if BUILD_MMAP
 TESTS += run_mmap.sh
+run_mmap.log: run_diskless.log
 endif
 if LARGE_FILE_TESTS
 TESTS += run_diskless2.sh
@@ -97,23 +97,24 @@ endif # USE_VALGRIND_TESTS
 
 # Distribute the .c files so that m4 isn't required on the users
 # machine.
-EXTRA_DIST = test_get.m4 test_put.m4 run_valgrind_tests.sh \
-run_diskless.sh run_diskless2.sh run_diskless5.sh \
-run_mmap.sh run_pnetcdf_test.sh \
-test_read.m4 test_write.m4
+EXTRA_DIST = test_get.m4 test_put.m4 run_valgrind_tests.sh		\
+run_diskless.sh run_diskless2.sh run_diskless5.sh run_mmap.sh		\
+run_pnetcdf_test.sh test_read.m4 test_write.m4 ref_tst_diskless2.cdl	\
+tst_diskless5.cdl CMakeLists.txt
 
-# ref_tst_diskless2.cdl is for diff comparison and to produce tst_diskless2.c
-EXTRA_DIST += ref_tst_diskless2.cdl tst_diskless5.cdl CMakeLists.txt
+# These files are created by the tests.
+CLEANFILES = nc_test_classic.nc nc_test_64bit.nc nc_test_netcdf4.nc     \
+tst_*.nc t_nc.nc large_files.nc quick_large_files.nc tst_diskless.nc    \
+tst_diskless2.nc tst_diskless3.nc tst_diskless3_file.cdl                \
+tst_diskless3_memory.cdl tst_diskless4.cdl tst_diskless4.nc             \
+tst_formatx.nc nc_test_cdf5.nc unlim.nc tst_inq_type.nc                 \
+tst_elatefill.nc tst_global_fillval.nc tst_large_cdf5.nc                \
+tst_max_var_dims.nc benchmark.nc
 
 # Only clean these on maintainer-clean, because they require m4 to
 # regenerate.
 #MAINTAINERCLEANFILES = test_get.c test_put.c
 
-all:
-	cp $(top_srcdir)/libsrc/ncx.c .
-
-CLEANFILES += ncx.c
-
 # This rule tells make how to turn our .m4 files into .c files.
 .m4.c:
 	m4 $(AM_M4FLAGS) $(M4FLAGS) $< >$@
diff --git a/nc_test/Makefile.in b/nc_test/Makefile.in
index b7afcee..db392b1 100644
--- a/nc_test/Makefile.in
+++ b/nc_test/Makefile.in
@@ -102,30 +102,27 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7)
- at USE_NETCDF4_TRUE@am__append_3 = tst_atts tst_put_vars tst_elatefill
- at USE_PNETCDF_TRUE@am__append_4 = tst_parallel2 tst_pnetcdf tst_addvar tst_formatx_pnetcdf
+ at USE_NETCDF4_TRUE@am__append_2 = tst_atts tst_put_vars tst_elatefill
+ at USE_PNETCDF_TRUE@am__append_3 = tst_parallel2 tst_pnetcdf tst_addvar tst_formatx_pnetcdf
+ at TEST_PARALLEL4_TRUE@@USE_CDF5_TRUE@@USE_PNETCDF_TRUE at am__append_4 = tst_cdf5format
 
 # If the user asked for large file tests, then add them.
 @LARGE_FILE_TESTS_TRUE at am__append_5 = quick_large_files tst_big_var6 tst_big_var2	\
 @LARGE_FILE_TESTS_TRUE at tst_big_rvar tst_big_var tst_large large_files tst_large_cdf5
 
 @BUILD_BENCHMARKS_TRUE at am__append_6 = testnc3perf
- at BUILD_BENCHMARKS_TRUE@am__append_7 = benchmark.nc
+check_PROGRAMS = $(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8)
 
 # Build Diskless test helpers
- at BUILD_DISKLESS_TRUE@am__append_8 = tst_diskless tst_diskless3 tst_diskless4 tst_diskless5
- at BUILD_DISKLESS_TRUE@@USE_NETCDF4_TRUE at am__append_9 = tst_diskless2
-TESTS = $(am__EXEEXT_5) $(am__append_10) $(am__append_11) \
-	$(am__append_12) $(am__append_13) $(am__append_14)
- at BUILD_DISKLESS_TRUE@@BUILD_UTILITIES_TRUE at am__append_10 = run_diskless.sh run_diskless5.sh
- at BUILD_DISKLESS_TRUE@@BUILD_MMAP_TRUE@@BUILD_UTILITIES_TRUE at am__append_11 = run_mmap.sh
- at BUILD_DISKLESS_TRUE@@BUILD_UTILITIES_TRUE@@LARGE_FILE_TESTS_TRUE at am__append_12 = run_diskless2.sh
- at USE_PNETCDF_TRUE@am__append_13 = run_pnetcdf_test.sh
- at USE_VALGRIND_TESTS_TRUE@am__append_14 = run_valgrind_tests.sh
+ at BUILD_DISKLESS_TRUE@am__append_7 = tst_diskless tst_diskless3 tst_diskless4 tst_diskless5
+ at BUILD_DISKLESS_TRUE@@USE_NETCDF4_TRUE at am__append_8 = tst_diskless2
+TESTS = $(am__EXEEXT_6) $(am__append_9) $(am__append_10) \
+	$(am__append_11) $(am__append_12) $(am__append_13)
+ at BUILD_DISKLESS_TRUE@@BUILD_UTILITIES_TRUE at am__append_9 = run_diskless.sh run_diskless5.sh
+ at BUILD_DISKLESS_TRUE@@BUILD_MMAP_TRUE@@BUILD_UTILITIES_TRUE at am__append_10 = run_mmap.sh
+ at BUILD_DISKLESS_TRUE@@BUILD_UTILITIES_TRUE@@LARGE_FILE_TESTS_TRUE at am__append_11 = run_diskless2.sh
+ at USE_PNETCDF_TRUE@am__append_12 = run_pnetcdf_test.sh
+ at USE_VALGRIND_TESTS_TRUE@am__append_13 = run_valgrind_tests.sh
 subdir = nc_test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -144,26 +141,28 @@ CONFIG_CLEAN_VPATH_FILES =
 @USE_PNETCDF_TRUE at am__EXEEXT_2 = tst_parallel2$(EXEEXT) \
 @USE_PNETCDF_TRUE@	tst_pnetcdf$(EXEEXT) tst_addvar$(EXEEXT) \
 @USE_PNETCDF_TRUE@	tst_formatx_pnetcdf$(EXEEXT)
- at LARGE_FILE_TESTS_TRUE@am__EXEEXT_3 = quick_large_files$(EXEEXT) \
+ at TEST_PARALLEL4_TRUE@@USE_CDF5_TRUE@@USE_PNETCDF_TRUE at am__EXEEXT_3 = tst_cdf5format$(EXEEXT)
+ at LARGE_FILE_TESTS_TRUE@am__EXEEXT_4 = quick_large_files$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	tst_big_var6$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	tst_big_var2$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	tst_big_rvar$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	tst_big_var$(EXEEXT) tst_large$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	large_files$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	tst_large_cdf5$(EXEEXT)
- at BUILD_BENCHMARKS_TRUE@am__EXEEXT_4 = testnc3perf$(EXEEXT)
-am__EXEEXT_5 = t_nc$(EXEEXT) tst_small$(EXEEXT) nc_test$(EXEEXT) \
+ at BUILD_BENCHMARKS_TRUE@am__EXEEXT_5 = testnc3perf$(EXEEXT)
+am__EXEEXT_6 = t_nc$(EXEEXT) tst_small$(EXEEXT) nc_test$(EXEEXT) \
 	tst_misc$(EXEEXT) tst_norm$(EXEEXT) tst_names$(EXEEXT) \
 	tst_nofill$(EXEEXT) tst_nofill2$(EXEEXT) tst_nofill3$(EXEEXT) \
 	tst_atts3$(EXEEXT) tst_meta$(EXEEXT) tst_inq_type$(EXEEXT) \
 	tst_utf8_validate$(EXEEXT) tst_utf8_phrases$(EXEEXT) \
-	tst_global_fillval$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
-	$(am__EXEEXT_3) $(am__EXEEXT_4)
- at BUILD_DISKLESS_TRUE@am__EXEEXT_6 = tst_diskless$(EXEEXT) \
+	tst_global_fillval$(EXEEXT) tst_max_var_dims$(EXEEXT) \
+	tst_formats$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
+	$(am__EXEEXT_3) $(am__EXEEXT_4) $(am__EXEEXT_5)
+ at BUILD_DISKLESS_TRUE@am__EXEEXT_7 = tst_diskless$(EXEEXT) \
 @BUILD_DISKLESS_TRUE@	tst_diskless3$(EXEEXT) \
 @BUILD_DISKLESS_TRUE@	tst_diskless4$(EXEEXT) \
 @BUILD_DISKLESS_TRUE@	tst_diskless5$(EXEEXT)
- at BUILD_DISKLESS_TRUE@@USE_NETCDF4_TRUE at am__EXEEXT_7 =  \
+ at BUILD_DISKLESS_TRUE@@USE_NETCDF4_TRUE at am__EXEEXT_8 =  \
 @BUILD_DISKLESS_TRUE@@USE_NETCDF4_TRUE@	tst_diskless2$(EXEEXT)
 large_files_SOURCES = large_files.c
 large_files_OBJECTS = large_files.$(OBJEXT)
@@ -220,6 +219,10 @@ tst_big_var6_SOURCES = tst_big_var6.c
 tst_big_var6_OBJECTS = tst_big_var6.$(OBJEXT)
 tst_big_var6_LDADD = $(LDADD)
 tst_big_var6_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
+tst_cdf5format_SOURCES = tst_cdf5format.c
+tst_cdf5format_OBJECTS = tst_cdf5format.$(OBJEXT)
+tst_cdf5format_LDADD = $(LDADD)
+tst_cdf5format_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_diskless_SOURCES = tst_diskless.c
 tst_diskless_OBJECTS = tst_diskless.$(OBJEXT)
 tst_diskless_LDADD = $(LDADD)
@@ -244,6 +247,10 @@ tst_elatefill_SOURCES = tst_elatefill.c
 tst_elatefill_OBJECTS = tst_elatefill.$(OBJEXT)
 tst_elatefill_LDADD = $(LDADD)
 tst_elatefill_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
+tst_formats_SOURCES = tst_formats.c
+tst_formats_OBJECTS = tst_formats.$(OBJEXT)
+tst_formats_LDADD = $(LDADD)
+tst_formats_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_formatx_pnetcdf_SOURCES = tst_formatx_pnetcdf.c
 tst_formatx_pnetcdf_OBJECTS = tst_formatx_pnetcdf.$(OBJEXT)
 tst_formatx_pnetcdf_LDADD = $(LDADD)
@@ -265,6 +272,10 @@ tst_large_cdf5_SOURCES = tst_large_cdf5.c
 tst_large_cdf5_OBJECTS = tst_large_cdf5.$(OBJEXT)
 tst_large_cdf5_LDADD = $(LDADD)
 tst_large_cdf5_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
+tst_max_var_dims_SOURCES = tst_max_var_dims.c
+tst_max_var_dims_OBJECTS = tst_max_var_dims.$(OBJEXT)
+tst_max_var_dims_LDADD = $(LDADD)
+tst_max_var_dims_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_meta_SOURCES = tst_meta.c
 tst_meta_OBJECTS = tst_meta.$(OBJEXT)
 tst_meta_LDADD = $(LDADD)
@@ -354,23 +365,25 @@ am__v_CCLD_1 =
 SOURCES = large_files.c $(nc_test_SOURCES) quick_large_files.c t_nc.c \
 	$(testnc3perf_SOURCES) tst_addvar.c tst_atts.c tst_atts3.c \
 	tst_big_rvar.c tst_big_var.c tst_big_var2.c tst_big_var6.c \
-	tst_diskless.c tst_diskless2.c tst_diskless3.c tst_diskless4.c \
-	tst_diskless5.c tst_elatefill.c tst_formatx_pnetcdf.c \
+	tst_cdf5format.c tst_diskless.c tst_diskless2.c \
+	tst_diskless3.c tst_diskless4.c tst_diskless5.c \
+	tst_elatefill.c tst_formats.c tst_formatx_pnetcdf.c \
 	tst_global_fillval.c tst_inq_type.c tst_large.c \
-	tst_large_cdf5.c tst_meta.c tst_misc.c tst_names.c \
-	tst_nofill.c tst_nofill2.c tst_nofill3.c tst_norm.c \
-	tst_parallel2.c tst_pnetcdf.c tst_put_vars.c tst_small.c \
-	tst_utf8_phrases.c tst_utf8_validate.c
+	tst_large_cdf5.c tst_max_var_dims.c tst_meta.c tst_misc.c \
+	tst_names.c tst_nofill.c tst_nofill2.c tst_nofill3.c \
+	tst_norm.c tst_parallel2.c tst_pnetcdf.c tst_put_vars.c \
+	tst_small.c tst_utf8_phrases.c tst_utf8_validate.c
 DIST_SOURCES = large_files.c $(nc_test_SOURCES) quick_large_files.c \
 	t_nc.c $(am__testnc3perf_SOURCES_DIST) tst_addvar.c tst_atts.c \
 	tst_atts3.c tst_big_rvar.c tst_big_var.c tst_big_var2.c \
-	tst_big_var6.c tst_diskless.c tst_diskless2.c tst_diskless3.c \
-	tst_diskless4.c tst_diskless5.c tst_elatefill.c \
-	tst_formatx_pnetcdf.c tst_global_fillval.c tst_inq_type.c \
-	tst_large.c tst_large_cdf5.c tst_meta.c tst_misc.c tst_names.c \
-	tst_nofill.c tst_nofill2.c tst_nofill3.c tst_norm.c \
-	tst_parallel2.c tst_pnetcdf.c tst_put_vars.c tst_small.c \
-	tst_utf8_phrases.c tst_utf8_validate.c
+	tst_big_var6.c tst_cdf5format.c tst_diskless.c tst_diskless2.c \
+	tst_diskless3.c tst_diskless4.c tst_diskless5.c \
+	tst_elatefill.c tst_formats.c tst_formatx_pnetcdf.c \
+	tst_global_fillval.c tst_inq_type.c tst_large.c \
+	tst_large_cdf5.c tst_max_var_dims.c tst_meta.c tst_misc.c \
+	tst_names.c tst_nofill.c tst_nofill2.c tst_nofill3.c \
+	tst_norm.c tst_parallel2.c tst_pnetcdf.c tst_put_vars.c \
+	tst_small.c tst_utf8_phrases.c tst_utf8_validate.c
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -580,7 +593,6 @@ am__set_TESTS_bases = \
 RECHECK_LOGS = $(TEST_LOGS)
 AM_RECURSIVE_TARGETS = check recheck
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
 am__set_b = \
@@ -595,10 +607,9 @@ am__set_b = \
   esac
 am__test_logs1 = $(TESTS:=.log)
 am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
 	$(top_srcdir)/lib_flags.am $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -608,14 +619,13 @@ AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) \
 	-I$(top_srcdir)/libsrc -DTOPSRCDIR=${abs_top_srcdir} \
 	-DTOPBINDIR=${abs_top_bindir} -I$(top_builddir)/liblib \
 	-I$(top_builddir)/include -I$(top_srcdir)/libsrc
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -638,12 +648,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -669,6 +681,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -683,6 +696,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -786,30 +800,25 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
+LDADD = ${top_builddir}/liblib/libnetcdf.la
 
-# These files are created by the tests.
-CLEANFILES = nc_test_classic.nc nc_test_64bit.nc nc_test_netcdf4.nc \
-	tst_*.nc t_nc.nc large_files.nc quick_large_files.nc \
-	tst_diskless.nc tst_diskless2.nc tst_diskless3.nc \
-	tst_diskless3_file.cdl tst_diskless3_memory.cdl \
-	tst_diskless4.cdl tst_diskless4.nc tst_formatx.nc \
-	nc_test_cdf5.nc unlim.nc tst_inq_type.nc tst_elatefill.nc \
-	tst_global_fillval.nc tst_large_cdf5.nc $(am__append_7) ncx.c
+# Note which tests depend on other tests. necessary for make -j check
+TEST_EXTENSIONS = .sh
 
 # These are the tests which are always run.
 TESTPROGRAMS = t_nc tst_small nc_test tst_misc tst_norm tst_names \
 	tst_nofill tst_nofill2 tst_nofill3 tst_atts3 tst_meta \
 	tst_inq_type tst_utf8_validate tst_utf8_phrases \
-	tst_global_fillval $(am__append_3) $(am__append_4) \
+	tst_global_fillval tst_max_var_dims tst_formats \
+	$(am__append_2) $(am__append_3) $(am__append_4) \
 	$(am__append_5) $(am__append_6)
 
 # These are the source files for the main workhorse test program,
 # nc_test. If you pass nc_test, you are doing well.
-nc_test_SOURCES = nc_test.c error.c test_get.c test_put.c \
-test_read.c test_write.c util.c error.h tests.h
+nc_test_SOURCES = nc_test.c error.c test_get.c test_put.c test_read.c	\
+test_write.c util.c error.h tests.h
 
-LDADD = ${top_builddir}/liblib/libnetcdf.la
 @BUILD_BENCHMARKS_TRUE at testnc3perf_SOURCES = testnc3perf.c
 @USE_NETCDF4_FALSE@@USE_VALGRIND_TESTS_TRUE at TESTS_ENVIRONMENT = USE_NETCDF4=0
 
@@ -819,16 +828,25 @@ LDADD = ${top_builddir}/liblib/libnetcdf.la
 
 # Distribute the .c files so that m4 isn't required on the users
 # machine.
+EXTRA_DIST = test_get.m4 test_put.m4 run_valgrind_tests.sh		\
+run_diskless.sh run_diskless2.sh run_diskless5.sh run_mmap.sh		\
+run_pnetcdf_test.sh test_read.m4 test_write.m4 ref_tst_diskless2.cdl	\
+tst_diskless5.cdl CMakeLists.txt
+
+
+# These files are created by the tests.
+CLEANFILES = nc_test_classic.nc nc_test_64bit.nc nc_test_netcdf4.nc     \
+tst_*.nc t_nc.nc large_files.nc quick_large_files.nc tst_diskless.nc    \
+tst_diskless2.nc tst_diskless3.nc tst_diskless3_file.cdl                \
+tst_diskless3_memory.cdl tst_diskless4.cdl tst_diskless4.nc             \
+tst_formatx.nc nc_test_cdf5.nc unlim.nc tst_inq_type.nc                 \
+tst_elatefill.nc tst_global_fillval.nc tst_large_cdf5.nc                \
+tst_max_var_dims.nc benchmark.nc
 
-# ref_tst_diskless2.cdl is for diff comparison and to produce tst_diskless2.c
-EXTRA_DIST = test_get.m4 test_put.m4 run_valgrind_tests.sh \
-	run_diskless.sh run_diskless2.sh run_diskless5.sh run_mmap.sh \
-	run_pnetcdf_test.sh test_read.m4 test_write.m4 \
-	ref_tst_diskless2.cdl tst_diskless5.cdl CMakeLists.txt
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .log .m4 .o .obj .test .test$(EXEEXT) .trs
+.SUFFIXES: .c .lo .log .m4 .o .obj .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -917,6 +935,10 @@ tst_big_var6$(EXEEXT): $(tst_big_var6_OBJECTS) $(tst_big_var6_DEPENDENCIES) $(EX
 	@rm -f tst_big_var6$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_big_var6_OBJECTS) $(tst_big_var6_LDADD) $(LIBS)
 
+tst_cdf5format$(EXEEXT): $(tst_cdf5format_OBJECTS) $(tst_cdf5format_DEPENDENCIES) $(EXTRA_tst_cdf5format_DEPENDENCIES) 
+	@rm -f tst_cdf5format$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_cdf5format_OBJECTS) $(tst_cdf5format_LDADD) $(LIBS)
+
 tst_diskless$(EXEEXT): $(tst_diskless_OBJECTS) $(tst_diskless_DEPENDENCIES) $(EXTRA_tst_diskless_DEPENDENCIES) 
 	@rm -f tst_diskless$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_diskless_OBJECTS) $(tst_diskless_LDADD) $(LIBS)
@@ -941,6 +963,10 @@ tst_elatefill$(EXEEXT): $(tst_elatefill_OBJECTS) $(tst_elatefill_DEPENDENCIES) $
 	@rm -f tst_elatefill$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_elatefill_OBJECTS) $(tst_elatefill_LDADD) $(LIBS)
 
+tst_formats$(EXEEXT): $(tst_formats_OBJECTS) $(tst_formats_DEPENDENCIES) $(EXTRA_tst_formats_DEPENDENCIES) 
+	@rm -f tst_formats$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_formats_OBJECTS) $(tst_formats_LDADD) $(LIBS)
+
 tst_formatx_pnetcdf$(EXEEXT): $(tst_formatx_pnetcdf_OBJECTS) $(tst_formatx_pnetcdf_DEPENDENCIES) $(EXTRA_tst_formatx_pnetcdf_DEPENDENCIES) 
 	@rm -f tst_formatx_pnetcdf$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_formatx_pnetcdf_OBJECTS) $(tst_formatx_pnetcdf_LDADD) $(LIBS)
@@ -961,6 +987,10 @@ tst_large_cdf5$(EXEEXT): $(tst_large_cdf5_OBJECTS) $(tst_large_cdf5_DEPENDENCIES
 	@rm -f tst_large_cdf5$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_large_cdf5_OBJECTS) $(tst_large_cdf5_LDADD) $(LIBS)
 
+tst_max_var_dims$(EXEEXT): $(tst_max_var_dims_OBJECTS) $(tst_max_var_dims_DEPENDENCIES) $(EXTRA_tst_max_var_dims_DEPENDENCIES) 
+	@rm -f tst_max_var_dims$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_max_var_dims_OBJECTS) $(tst_max_var_dims_LDADD) $(LIBS)
+
 tst_meta$(EXEEXT): $(tst_meta_OBJECTS) $(tst_meta_DEPENDENCIES) $(EXTRA_tst_meta_DEPENDENCIES) 
 	@rm -f tst_meta$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_meta_OBJECTS) $(tst_meta_LDADD) $(LIBS)
@@ -1036,17 +1066,20 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_big_var.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_big_var2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_big_var6.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_cdf5format.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_diskless.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_diskless2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_diskless3.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_diskless4.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_diskless5.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_elatefill.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_formats.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_formatx_pnetcdf.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_global_fillval.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_inq_type.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_large.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_large_cdf5.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_max_var_dims.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_meta.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_misc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_names.Po at am__quote@
@@ -1390,6 +1423,20 @@ tst_global_fillval.log: tst_global_fillval$(EXEEXT)
 	--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_max_var_dims.log: tst_max_var_dims$(EXEEXT)
+	@p='tst_max_var_dims$(EXEEXT)'; \
+	b='tst_max_var_dims'; \
+	$(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_formats.log: tst_formats$(EXEEXT)
+	@p='tst_formats$(EXEEXT)'; \
+	b='tst_formats'; \
+	$(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_atts.log: tst_atts$(EXEEXT)
 	@p='tst_atts$(EXEEXT)'; \
 	b='tst_atts'; \
@@ -1439,6 +1486,13 @@ tst_formatx_pnetcdf.log: tst_formatx_pnetcdf$(EXEEXT)
 	--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_cdf5format.log: tst_cdf5format$(EXEEXT)
+	@p='tst_cdf5format$(EXEEXT)'; \
+	b='tst_cdf5format'; \
+	$(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)
 quick_large_files.log: quick_large_files$(EXEEXT)
 	@p='quick_large_files$(EXEEXT)'; \
 	b='quick_large_files'; \
@@ -1502,61 +1556,19 @@ testnc3perf.log: testnc3perf$(EXEEXT)
 	--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_diskless.sh.log: run_diskless.sh
-	@p='run_diskless.sh'; \
-	b='run_diskless.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_diskless5.sh.log: run_diskless5.sh
-	@p='run_diskless5.sh'; \
-	b='run_diskless5.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_mmap.sh.log: run_mmap.sh
-	@p='run_mmap.sh'; \
-	b='run_mmap.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_diskless2.sh.log: run_diskless2.sh
-	@p='run_diskless2.sh'; \
-	b='run_diskless2.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_pnetcdf_test.sh.log: run_pnetcdf_test.sh
-	@p='run_pnetcdf_test.sh'; \
-	b='run_pnetcdf_test.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_valgrind_tests.sh.log: run_valgrind_tests.sh
-	@p='run_valgrind_tests.sh'; \
-	b='run_valgrind_tests.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
@@ -1718,14 +1730,12 @@ uninstall-am:
 
 .PRECIOUS: Makefile
 
+ at BUILD_DISKLESS_TRUE@@BUILD_MMAP_TRUE@@BUILD_UTILITIES_TRUE at run_mmap.log: run_diskless.log
 
 # Only clean these on maintainer-clean, because they require m4 to
 # regenerate.
 #MAINTAINERCLEANFILES = test_get.c test_put.c
 
-all:
-	cp $(top_srcdir)/libsrc/ncx.c .
-
 # This rule tells make how to turn our .m4 files into .c files.
 .m4.c:
 	m4 $(AM_M4FLAGS) $(M4FLAGS) $< >$@
diff --git a/nc_test/large_files.c b/nc_test/large_files.c
index f92d785..a723c81 100644
--- a/nc_test/large_files.c
+++ b/nc_test/large_files.c
@@ -11,7 +11,7 @@
   This program is an add-on test to check very large 64-bit offset
   files (8 GB, so make sure you have the disk space!).
 
-  $Id: large_files.c,v 1.4 2008/03/10 17:02:41 ed Exp $
+  Ed Hartnett, Ward Fisher
 */
 
 #include <config.h>
@@ -21,6 +21,11 @@
 #include <netcdf.h>
 
 #define FILE_NAME "large_files.nc"
+#define NUMRECS 2
+#define I_LEN 4106
+#define J_LEN 1023
+#define K_LEN 1023
+#define N_LEN 2
 
 static void
 check_err(const int stat, const int line, const char *file) {
@@ -36,7 +41,7 @@ main(int argc, char **argv) {
    int  stat;			/* return status */
    char file_name[NC_MAX_NAME + 1];
    int  ncid;			/* netCDF id */
-   int rec, i, j, k;
+   int rec, i, j;
    int x[] = {42, 21};
 
    /* dimension ids */
@@ -46,17 +51,6 @@ main(int argc, char **argv) {
    int k_dim;
    int n_dim;
 
-#define NUMRECS 2
-#define I_LEN 4106
-   //#define I_LEN 5
-   //#if 0
-   //#define J_LEN 214700000
-   //#endif
-   //#define J_LEN   500000000
-#define J_LEN 1023
-#define K_LEN 1023
-#define N_LEN 2
-
    /* dimension lengths */
    size_t rec_len = NC_UNLIMITED;
    size_t i_len = I_LEN;
diff --git a/nc_test/nc_enddef.c b/nc_test/nc_enddef.c
deleted file mode 100644
index 2f10657..0000000
--- a/nc_test/nc_enddef.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <netcdf.h>
-
-void
-check_err(const int stat, const int line, const char *file) {
-    if (stat != NC_NOERR) {
-	   (void) fprintf(stderr, "line %d of %s: %s\n", line, file, nc_strerror(stat));
-        exit(1);
-    }
-}
-
-int
-main() {			/* create nc_enddef.nc */
-
-   int  ncid;			/* netCDF id */
-
-   /* dimension ids */
-   int dim_dim;
-
-   /* dimension lengths */
-   size_t dim_len = 1;
-
-   /* variable ids */
-   int var_id;
-
-   /* rank (number of dimensions) for each variable */
-#  define RANK_var 1
-
-   /* variable shapes */
-   int var_dims[RANK_var];
-
-   /* enter define mode */
-   int stat = nc_create("nc_enddef.nc", NC_CLOBBER, &ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define dimensions */
-   stat = nc_def_dim(ncid, "dim", dim_len, &dim_dim);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define variables */
-
-   var_dims[0] = dim_dim;
-   stat = nc_def_var(ncid, "var", NC_DOUBLE, RANK_var, var_dims, &var_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* leave define mode */
-   stat = nc_enddef (ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   {			/* store var */
-    static double var[] = {1.};
-    stat = nc_put_var_double(ncid, var_id, var);
-    check_err(stat,__LINE__,__FILE__);
-   }
-   stat = nc_sync(ncid);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_close(ncid);
-   check_err(stat,__LINE__,__FILE__);
-   return 0;
-}
diff --git a/nc_test/nc_sync.c b/nc_test/nc_sync.c
deleted file mode 100644
index e24bd05..0000000
--- a/nc_test/nc_sync.c
+++ /dev/null
@@ -1,557 +0,0 @@
-#define _XOPEN_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <netcdf.h>
-#include "nc_sync.h"
-
-int
-nc_sync_sub(int ncid)
-{
-    int		everythingOK = 1;
-    FILE*	pipe;		/* IPC pipe to child process */
-
-    setbuf(stdout, NULL);	/* unbuffer stdout */
-
-    /*
-     * Execute the child process.
-     */
-    pipe = popen("nc_sync_child", "w");
-
-    if (pipe == NULL)
-    {
-	perror("popen() error");
-	everythingOK = 0;
-    }
-    else
-    {
-	double	var[DIM2][DIM1][DIM0];
-
-	setbuf(pipe, NULL);	/* unbuffer IPC pipe */
-
-	/*
-	 * Initialize the variable array.
-	 */
-	{
-	    int		i = 0;
-	    int		n = DIM0*DIM1*DIM2;
-	    double	*dp = (double*)var;
-	    for (i = 0; i < n; i++)
-		*dp++ = i;
-	}
-
-	/*
-	 * Write the variable array.
-	 */
-	{
-	    int		i3;
-	    int		ncerr;
-	    size_t	start[NDIM] = {0, 0, 0, 0};
-	    size_t	count[NDIM] = {1, DIM2, DIM1, DIM0};
-
-	    /*
-	     * Loop over the unlimited dimension.
-	     */
-	    for (i3 = 0; everythingOK && i3 < DIM3; ++i3)
-	    {
-		int	ivar;
-
-		start[0] = i3;
-		printf("PARENT: Writing %d\n", i3);
-		fflush(stdout);
-
-		/*
-		 * Loop over the variables.
-		 */
-		for (ivar = 0; everythingOK && ivar < NVAR; ++ivar)
-		{
-		    ncerr =
-			nc_put_vara_double(
-			    ncid, ivar, start, count, (double*)var);
-		    if (ncerr != NC_NOERR)
-		    {
-			fprintf(
-			    stderr, "nc_put_vara_double() error: %s\n",
-			    nc_strerror(ncerr));
-			everythingOK = 0;
-		    }
-		}
-		if (everythingOK)
-		{
-		    /*
-		     * Synchronize the netCDF file.
-		     */
-		    puts("PARENT: Calling nc_sync()");
-		    fflush(stdout);
-		    ncerr = nc_sync(ncid);
-		    if (ncerr != NC_NOERR)
-		    {
-			fprintf(
-			    stderr, "nc_sync() error: %s\n",
-			    nc_strerror(ncerr));
-			everythingOK = 0;
-		    }
-		    else
-		    {
-			/*
-			 * Notify the child process.
-			 */
-			puts("PARENT: Notifying child");
-			fflush(stdout);
-			if (fwrite(&i3, sizeof(i3), 1, pipe) != 1)
-			{
-			    perror("fwrite() error");
-			    everythingOK = 0;
-			}
-		    }
-		}		/* variables written */
-	    }			/* unlimited dimension loop */
-	}			/* write block */
-
-	fclose(pipe);
-
-	{
-	    int   status;
-	    pid_t pid;
-
-	    pid = wait(&status);
-	}
-    }				/* successful popen() */
-
-    return everythingOK ? 0 : 1;
-}
-
-void
-check_err(const int stat, const int line, const char *file)
-{
-    if (stat != NC_NOERR) {
-       (void) fprintf(stderr, "line %d of %s: %s\n", line, file, 
-	   nc_strerror(stat));
-        exit(1);
-    }
-}
-
-int
-main() {			/* create nc_sync.nc */
-
-   int  ncid;			/* netCDF id */
-
-   /* dimension ids */
-   int dim0_dim;
-   int dim1_dim;
-   int dim2_dim;
-   int dim3_dim;
-
-   /* dimension lengths */
-   size_t dim0_len = 53;
-   size_t dim1_len = 67;
-   size_t dim2_len = 30;
-   size_t dim3_len = NC_UNLIMITED;
-
-   /* variable ids */
-   int var0_id;
-   int var1_id;
-   int var2_id;
-   int var3_id;
-   int var4_id;
-   int var5_id;
-   int var6_id;
-   int var7_id;
-   int var8_id;
-   int var9_id;
-   int var10_id;
-   int var11_id;
-   int var12_id;
-   int var13_id;
-   int var14_id;
-   int var15_id;
-   int var16_id;
-   int var17_id;
-   int var18_id;
-   int var19_id;
-   int var20_id;
-   int var21_id;
-   int var22_id;
-   int var23_id;
-   int var24_id;
-   int var25_id;
-   int var26_id;
-   int var27_id;
-   int var28_id;
-   int var29_id;
-   int var30_id;
-   int var31_id;
-   int var32_id;
-   int var33_id;
-   int var34_id;
-   int var35_id;
-   int var36_id;
-
-   /* rank (number of dimensions) for each variable */
-#  define RANK_var0 4
-#  define RANK_var1 4
-#  define RANK_var2 4
-#  define RANK_var3 4
-#  define RANK_var4 4
-#  define RANK_var5 4
-#  define RANK_var6 4
-#  define RANK_var7 4
-#  define RANK_var8 4
-#  define RANK_var9 4
-#  define RANK_var10 4
-#  define RANK_var11 4
-#  define RANK_var12 4
-#  define RANK_var13 4
-#  define RANK_var14 4
-#  define RANK_var15 4
-#  define RANK_var16 4
-#  define RANK_var17 4
-#  define RANK_var18 4
-#  define RANK_var19 4
-#  define RANK_var20 4
-#  define RANK_var21 4
-#  define RANK_var22 4
-#  define RANK_var23 4
-#  define RANK_var24 4
-#  define RANK_var25 4
-#  define RANK_var26 4
-#  define RANK_var27 4
-#  define RANK_var28 4
-#  define RANK_var29 4
-#  define RANK_var30 4
-#  define RANK_var31 4
-#  define RANK_var32 4
-#  define RANK_var33 4
-#  define RANK_var34 4
-#  define RANK_var35 4
-#  define RANK_var36 4
-
-   /* variable shapes */
-   int var0_dims[RANK_var0];
-   int var1_dims[RANK_var1];
-   int var2_dims[RANK_var2];
-   int var3_dims[RANK_var3];
-   int var4_dims[RANK_var4];
-   int var5_dims[RANK_var5];
-   int var6_dims[RANK_var6];
-   int var7_dims[RANK_var7];
-   int var8_dims[RANK_var8];
-   int var9_dims[RANK_var9];
-   int var10_dims[RANK_var10];
-   int var11_dims[RANK_var11];
-   int var12_dims[RANK_var12];
-   int var13_dims[RANK_var13];
-   int var14_dims[RANK_var14];
-   int var15_dims[RANK_var15];
-   int var16_dims[RANK_var16];
-   int var17_dims[RANK_var17];
-   int var18_dims[RANK_var18];
-   int var19_dims[RANK_var19];
-   int var20_dims[RANK_var20];
-   int var21_dims[RANK_var21];
-   int var22_dims[RANK_var22];
-   int var23_dims[RANK_var23];
-   int var24_dims[RANK_var24];
-   int var25_dims[RANK_var25];
-   int var26_dims[RANK_var26];
-   int var27_dims[RANK_var27];
-   int var28_dims[RANK_var28];
-   int var29_dims[RANK_var29];
-   int var30_dims[RANK_var30];
-   int var31_dims[RANK_var31];
-   int var32_dims[RANK_var32];
-   int var33_dims[RANK_var33];
-   int var34_dims[RANK_var34];
-   int var35_dims[RANK_var35];
-   int var36_dims[RANK_var36];
-
-   /* enter define mode */
-   int stat = nc_create("nc_sync.nc", NC_CLOBBER, &ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define dimensions */
-   stat = nc_def_dim(ncid, "dim0", dim0_len, &dim0_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim1", dim1_len, &dim1_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim2", dim2_len, &dim2_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim3", dim3_len, &dim3_dim);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define variables */
-
-   var0_dims[0] = dim3_dim;
-   var0_dims[1] = dim2_dim;
-   var0_dims[2] = dim1_dim;
-   var0_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var0", NC_DOUBLE, RANK_var0, var0_dims, &var0_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var1_dims[0] = dim3_dim;
-   var1_dims[1] = dim2_dim;
-   var1_dims[2] = dim1_dim;
-   var1_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var1", NC_DOUBLE, RANK_var1, var1_dims, &var1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var2_dims[0] = dim3_dim;
-   var2_dims[1] = dim2_dim;
-   var2_dims[2] = dim1_dim;
-   var2_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var2", NC_DOUBLE, RANK_var2, var2_dims, &var2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var3_dims[0] = dim3_dim;
-   var3_dims[1] = dim2_dim;
-   var3_dims[2] = dim1_dim;
-   var3_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var3", NC_DOUBLE, RANK_var3, var3_dims, &var3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var4_dims[0] = dim3_dim;
-   var4_dims[1] = dim2_dim;
-   var4_dims[2] = dim1_dim;
-   var4_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var4", NC_DOUBLE, RANK_var4, var4_dims, &var4_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var5_dims[0] = dim3_dim;
-   var5_dims[1] = dim2_dim;
-   var5_dims[2] = dim1_dim;
-   var5_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var5", NC_DOUBLE, RANK_var5, var5_dims, &var5_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var6_dims[0] = dim3_dim;
-   var6_dims[1] = dim2_dim;
-   var6_dims[2] = dim1_dim;
-   var6_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var6", NC_DOUBLE, RANK_var6, var6_dims, &var6_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var7_dims[0] = dim3_dim;
-   var7_dims[1] = dim2_dim;
-   var7_dims[2] = dim1_dim;
-   var7_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var7", NC_DOUBLE, RANK_var7, var7_dims, &var7_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var8_dims[0] = dim3_dim;
-   var8_dims[1] = dim2_dim;
-   var8_dims[2] = dim1_dim;
-   var8_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var8", NC_DOUBLE, RANK_var8, var8_dims, &var8_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var9_dims[0] = dim3_dim;
-   var9_dims[1] = dim2_dim;
-   var9_dims[2] = dim1_dim;
-   var9_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var9", NC_DOUBLE, RANK_var9, var9_dims, &var9_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var10_dims[0] = dim3_dim;
-   var10_dims[1] = dim2_dim;
-   var10_dims[2] = dim1_dim;
-   var10_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var10", NC_DOUBLE, RANK_var10, var10_dims, &var10_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var11_dims[0] = dim3_dim;
-   var11_dims[1] = dim2_dim;
-   var11_dims[2] = dim1_dim;
-   var11_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var11", NC_DOUBLE, RANK_var11, var11_dims, &var11_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var12_dims[0] = dim3_dim;
-   var12_dims[1] = dim2_dim;
-   var12_dims[2] = dim1_dim;
-   var12_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var12", NC_DOUBLE, RANK_var12, var12_dims, &var12_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var13_dims[0] = dim3_dim;
-   var13_dims[1] = dim2_dim;
-   var13_dims[2] = dim1_dim;
-   var13_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var13", NC_DOUBLE, RANK_var13, var13_dims, &var13_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var14_dims[0] = dim3_dim;
-   var14_dims[1] = dim2_dim;
-   var14_dims[2] = dim1_dim;
-   var14_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var14", NC_DOUBLE, RANK_var14, var14_dims, &var14_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var15_dims[0] = dim3_dim;
-   var15_dims[1] = dim2_dim;
-   var15_dims[2] = dim1_dim;
-   var15_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var15", NC_DOUBLE, RANK_var15, var15_dims, &var15_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var16_dims[0] = dim3_dim;
-   var16_dims[1] = dim2_dim;
-   var16_dims[2] = dim1_dim;
-   var16_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var16", NC_DOUBLE, RANK_var16, var16_dims, &var16_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var17_dims[0] = dim3_dim;
-   var17_dims[1] = dim2_dim;
-   var17_dims[2] = dim1_dim;
-   var17_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var17", NC_DOUBLE, RANK_var17, var17_dims, &var17_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var18_dims[0] = dim3_dim;
-   var18_dims[1] = dim2_dim;
-   var18_dims[2] = dim1_dim;
-   var18_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var18", NC_DOUBLE, RANK_var18, var18_dims, &var18_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var19_dims[0] = dim3_dim;
-   var19_dims[1] = dim2_dim;
-   var19_dims[2] = dim1_dim;
-   var19_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var19", NC_DOUBLE, RANK_var19, var19_dims, &var19_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var20_dims[0] = dim3_dim;
-   var20_dims[1] = dim2_dim;
-   var20_dims[2] = dim1_dim;
-   var20_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var20", NC_DOUBLE, RANK_var20, var20_dims, &var20_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var21_dims[0] = dim3_dim;
-   var21_dims[1] = dim2_dim;
-   var21_dims[2] = dim1_dim;
-   var21_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var21", NC_DOUBLE, RANK_var21, var21_dims, &var21_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var22_dims[0] = dim3_dim;
-   var22_dims[1] = dim2_dim;
-   var22_dims[2] = dim1_dim;
-   var22_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var22", NC_DOUBLE, RANK_var22, var22_dims, &var22_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var23_dims[0] = dim3_dim;
-   var23_dims[1] = dim2_dim;
-   var23_dims[2] = dim1_dim;
-   var23_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var23", NC_DOUBLE, RANK_var23, var23_dims, &var23_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var24_dims[0] = dim3_dim;
-   var24_dims[1] = dim2_dim;
-   var24_dims[2] = dim1_dim;
-   var24_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var24", NC_DOUBLE, RANK_var24, var24_dims, &var24_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var25_dims[0] = dim3_dim;
-   var25_dims[1] = dim2_dim;
-   var25_dims[2] = dim1_dim;
-   var25_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var25", NC_DOUBLE, RANK_var25, var25_dims, &var25_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var26_dims[0] = dim3_dim;
-   var26_dims[1] = dim2_dim;
-   var26_dims[2] = dim1_dim;
-   var26_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var26", NC_DOUBLE, RANK_var26, var26_dims, &var26_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var27_dims[0] = dim3_dim;
-   var27_dims[1] = dim2_dim;
-   var27_dims[2] = dim1_dim;
-   var27_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var27", NC_DOUBLE, RANK_var27, var27_dims, &var27_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var28_dims[0] = dim3_dim;
-   var28_dims[1] = dim2_dim;
-   var28_dims[2] = dim1_dim;
-   var28_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var28", NC_DOUBLE, RANK_var28, var28_dims, &var28_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var29_dims[0] = dim3_dim;
-   var29_dims[1] = dim2_dim;
-   var29_dims[2] = dim1_dim;
-   var29_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var29", NC_DOUBLE, RANK_var29, var29_dims, &var29_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var30_dims[0] = dim3_dim;
-   var30_dims[1] = dim2_dim;
-   var30_dims[2] = dim1_dim;
-   var30_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var30", NC_DOUBLE, RANK_var30, var30_dims, &var30_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var31_dims[0] = dim3_dim;
-   var31_dims[1] = dim2_dim;
-   var31_dims[2] = dim1_dim;
-   var31_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var31", NC_DOUBLE, RANK_var31, var31_dims, &var31_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var32_dims[0] = dim3_dim;
-   var32_dims[1] = dim2_dim;
-   var32_dims[2] = dim1_dim;
-   var32_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var32", NC_DOUBLE, RANK_var32, var32_dims, &var32_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var33_dims[0] = dim3_dim;
-   var33_dims[1] = dim2_dim;
-   var33_dims[2] = dim1_dim;
-   var33_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var33", NC_DOUBLE, RANK_var33, var33_dims, &var33_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var34_dims[0] = dim3_dim;
-   var34_dims[1] = dim2_dim;
-   var34_dims[2] = dim1_dim;
-   var34_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var34", NC_DOUBLE, RANK_var34, var34_dims, &var34_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var35_dims[0] = dim3_dim;
-   var35_dims[1] = dim2_dim;
-   var35_dims[2] = dim1_dim;
-   var35_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var35", NC_DOUBLE, RANK_var35, var35_dims, &var35_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   var36_dims[0] = dim3_dim;
-   var36_dims[1] = dim2_dim;
-   var36_dims[2] = dim1_dim;
-   var36_dims[3] = dim0_dim;
-   stat = nc_def_var(ncid, "var36", NC_DOUBLE, RANK_var36, var36_dims, &var36_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* leave define mode */
-   stat = nc_enddef (ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   nc_sync_sub(ncid);
-
-   stat = nc_close(ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   return 0;
-}
diff --git a/nc_test/nc_sync.h b/nc_test/nc_sync.h
deleted file mode 100644
index 8336fbb..0000000
--- a/nc_test/nc_sync.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#define DIM0	53
-#define DIM1	67
-#define DIM2	30
-#define DIM3	4
-#define NVAR	37
-#define NDIM	4
diff --git a/nc_test/nc_sync_child.c b/nc_test/nc_sync_child.c
deleted file mode 100644
index 106616c..0000000
--- a/nc_test/nc_sync_child.c
+++ /dev/null
@@ -1,100 +0,0 @@
-#include <stdio.h>
-#include <netcdf.h>
-#include "nc_sync.h"
-
-int
-main()
-{
-    int	ncid;
-    int	ncerr;
-    int	everythingOK = 1;
-
-    setbuf(stdout, NULL);	/* unbuffer stdout */
-
-    /*
-     * Open the netCDF file.
-     */
-    ncerr = nc_open("nc_sync.nc", 0, &ncid);
-    if (ncerr != NC_NOERR)
-    {
-	fprintf(stderr, "nc_open() error: %s\n", nc_strerror(ncerr));
-	everythingOK = 0;
-    }
-    else
-    {
-	double	var[DIM2][DIM1][DIM0];
-	size_t	start[NDIM] = {0, 0, 0, 0};
-	size_t	count[NDIM] = {1, DIM2, DIM1, DIM0};
-	int	eofRead = 0;
-
-	/*
-	 * Loop over the unlimited dimension.
-	 */
-	while (everythingOK && !eofRead)
-	{
-	    int	i3;
-	    int	ivar;
-	    int	nitem;
-
-	    /*
-	     * Read the unlimited dimension index.
-	     */
-	    puts("CHILD: Getting notification");
-	    fflush(stdout);
-	    nitem = fread(&i3, sizeof(i3), 1, stdin);
-	    if (nitem == 0)
-	    {
-		puts("CHILD: Read EOF");
-		fflush(stdout);
-		eofRead = 1;
-	    }
-	    else if (nitem != 1)
-	    {
-		perror("fread() error");
-		everythingOK = 0;
-	    }
-	    else
-	    {
-		start[0] = i3;
-
-		/*
-		 * Synchronize the netCDF file.
-		 */
-		puts("CHILD: Calling nc_sync()");
-		fflush(stdout);
-		ncerr = nc_sync(ncid);
-		if (ncerr != NC_NOERR)
-		{
-		    fprintf(
-			stderr, "nc_sync() error: %s\n", nc_strerror(ncerr));
-		    everythingOK = 0;
-		}
-		else
-		{
-		    printf("CHILD: Reading %d\n", i3);
-		    fflush(stdout);
-
-		    /*
-		     * Loop over the variables.
-		     */
-		    for (ivar = 0; everythingOK && ivar < NVAR; ++ivar)
-		    {
-			ncerr =
-			    nc_get_vara_double(
-				ncid, ivar, start, count, (double*)var);
-			if (ncerr != NC_NOERR)
-			{
-			    fprintf(
-				stderr,
-			    "nc_get_vara_double() error: %s: i3=%d, ivar=%d\n",
-				nc_strerror(ncerr), i3, ivar);
-			    everythingOK = 0;
-			}
-		    }
-		}			/* netCDF file synchronized */
-	    }				/* unlimited dimension index read */
-	}				/* unlimited dimension loop */
-    }					/* input netCDF file opened */
-
-    return everythingOK ? 0 : 1;
-}
diff --git a/nc_test/nc_test.c b/nc_test/nc_test.c
index dbb03b0..5800c33 100644
--- a/nc_test/nc_test.c
+++ b/nc_test/nc_test.c
@@ -145,8 +145,14 @@ main(int argc, char *argv[])
 #else
          continue;
 #endif
-	  case NC_FORMAT_NETCDF4_CLASSIC:
-	  case NC_FORMAT_NETCDF4: /* actually it's _CLASSIC. */
+
+         /* Repeated test. See https://github.com/Unidata/netcdf-c/issues/556 for more
+            information re: the immediate 'continue' */
+       case NC_FORMAT_NETCDF4: /* actually it's _CLASSIC. */
+         continue; /* loop i */
+
+
+       case NC_FORMAT_NETCDF4_CLASSIC:
 #ifdef USE_NETCDF4
 	     nc_set_default_format(NC_FORMAT_NETCDF4_CLASSIC, NULL);
 	     strcpy(testfile, "nc_test_netcdf4.nc");
diff --git a/nc_test/quick_large_files.c b/nc_test/quick_large_files.c
index a1209e5..913916c 100644
--- a/nc_test/quick_large_files.c
+++ b/nc_test/quick_large_files.c
@@ -1,12 +1,12 @@
 /*
- Copyright 2004-2006, UCAR/Unidata
- See COPYRIGHT file for copying and redistribution conditions.
+  Copyright 2004-2006, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
 
- This program (quickly, but not thoroughly) tests the large file
- features. It turns off fill mode to quickly create an 8 gb file, and
- write one value is written, nothing is read.
+  This program (quickly, but not thoroughly) tests the large file
+  features. It turns off fill mode to quickly create an 8 gb file, and
+  write one value is written, nothing is read.
 
- $Id: quick_large_files.c,v 1.18 2008/06/05 15:10:16 ed Exp $
+  Ed Hartnett
 */
 #include <config.h>
 #include <nc_tests.h>
@@ -35,539 +35,539 @@
 int
 main(int argc, char **argv)
 {
-    int ncid, spockid, kirkid, dimids[NUMDIMS], recdimid, scottyid;
-    int int_val_in, int_val_out = 99;
-    double double_val_in, double_val_out = 1.79769313486230e+308; /* from ncx.h */
-    size_t index[2] = {QTR_CLASSIC_MAX-1, 0};
-    char file_name[NC_MAX_NAME + 1];
-
-    /* These are for the revolutionary generals tests. */
-    int cromwellid, collinsid, washingtonid;
-    int napoleanid, dimids_gen[4], dimids_gen1[4];
-
-    /* All create modes will be anded to this. All tests will be run
-       twice, with and without NC_SHARE.*/
-    int cmode_run;
-    int cflag = NC_CLOBBER;
-
-    int res;
-
-    printf("\n*** Testing large files, quickly.\n");
-
-    for (cmode_run=0; cmode_run<2; cmode_run++)
-    {
-	size_t big_index = (size_t)MAX_CLASSIC_BYTES + 10;
- 	/* On second pass, try using NC_SHARE. */
-	if (cmode_run == 1)
-	{
-	    cflag |= NC_SHARE;
-	    printf("*** Turned on NC_SHARE for subsequent tests.\n");
-	}
-
-	/* Create a netCDF 64-bit offset format file. Write a value. */
-	sprintf(file_name, "%s/%s", TEMP_LARGE, FILE_NAME);
-	printf("*** Creating %s for 64-bit offset large file test...", file_name);
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "longdim", QTR_CLASSIC_MAX, dimids)))
-	    ERR;
-	/* test bug fix writing record beyond 2**31 */
-	if ((res = nc_def_dim(ncid, "longerdim", NC_UNLIMITED, &recdimid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "spock", NC_DOUBLE, NUMDIMS,
-			      dimids, &spockid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "kirk", NC_DOUBLE, NUMDIMS,
-			      dimids, &kirkid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "scotty", NC_BYTE, 1,
-			      &recdimid, &scottyid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	if ((res = nc_put_var1_double(ncid, kirkid, index, &double_val_out)))
-	    ERR;
-	if ((res = nc_put_var1_int(ncid, scottyid, &big_index, &int_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_int(ncid, scottyid, &big_index, &int_val_in)))
-	    ERR;
-	if (int_val_in != int_val_out)
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* How about a meteorological data file about the weather
-	   experience by various generals of revolutionary armies?
-
-	   This has 3 dims, 4 vars. The dimensions are such that this will
-	   (just barely) not fit in a classic format file. The first three
-	   vars are cromwell, 536870911 bytes, washington, 2*536870911
-	   bytes, and napolean, 536870911 bytes. That's a grand total of
-	   2147483644 bytes. Recall our magic limit for the combined size
-	   of all fixed vars: 2 GiB - 4 bytes, or 2147483644. So you would
-	   think these would exactly fit, unless you realized that
-	   everything is rounded to a 4 byte boundary, so you need to add
-	   some bytes for that (how many?), and that pushes us over the
-	   limit.
-
-	   We will create this file twice, once to ensure it succeeds (with
-	   64-bit offset format), and once to make sure it fails (with
-	   classic format). Then some variations to check record var
-	   boundaries.
-	*/
-	printf("*** Now a 64-bit offset, large file, fixed var test...");
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      QTR_CLASSIC_MAX, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      QTR_CLASSIC_MAX, &dimids_gen[1])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 1, &dimids_gen[0],
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, &dimids_gen[1],
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 1, &dimids_gen[0],
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* Write a value or two just for fun. */
-	/*index[0] = QTR_CLASSIC_MAX - 296;
-	if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in)))
-	    ERR;
-	if (int_val_in != int_val_out)
-	BAIL2;*/
-	printf("*** Now writing some values...");
-	index[0] = QTR_CLASSIC_MAX - 295;
-	if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in)))
-	    ERR;
-	if (int_val_in != int_val_out)
-	   ERR;
-
-	index[0] = QTR_CLASSIC_MAX - 1;
-	if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in)))
-	    ERR;
-	if (int_val_in != int_val_out)
-	    ERR;
-
-	index[0] = QTR_CLASSIC_MAX - 1;
-	if ((res = nc_put_var1_int(ncid, washingtonid, index, &int_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_int(ncid, washingtonid, index, &int_val_in)))
-	    ERR;
-	if (int_val_in != int_val_out)
-	    ERR;
-
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* This time it should fail, because we're trying to cram this into
-	   a classic format file. nc_enddef will detect our violations and
-	   give an error. We've*/
-	printf("*** Now a classic file which will fail...");
-	if ((res = nc_create(file_name, cflag, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      QTR_CLASSIC_MAX, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      QTR_CLASSIC_MAX, &dimids_gen[1])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 1, &dimids_gen[0],
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, &dimids_gen[1],
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 1, &dimids_gen[0],
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
-	    ERR;
-	if ((res = nc_close(ncid)) != NC_EVARSIZE)
-	    ERR;
-	printf("ok\n");
-
-	/* This will create some max sized 64-bit offset format fixed vars. */
-	printf("*** Now a 64-bit offset, simple fixed var create test...");
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_SHORT, 1, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_SHORT, 1, dimids_gen,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, dimids_gen,
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* This will exceed the 64-bit offset format limits for one of the
-	   fixed vars. */
-	printf("*** Now a 64-bit offset, over-sized file that will fail...");
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	/* max dim size is MAX_CLASSIC_BYTES. */
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, dimids_gen)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 1, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, dimids_gen,
-			      &washingtonid)))
-	    if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
-		ERR;
-	if ((res = nc_close(ncid)) != NC_EVARSIZE)
-	    ERR;
-	printf("ok\n");
-
-	/* Now let's see about record vars. First create a 64-bit offset
-	   file with three rec variables, each with the same numbers as
-	   defined above for the fixed var tests. This should all work. */
-	printf("*** Now a 64-bit offset, record var file...");
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      QTR_CLASSIC_MAX, &dimids_gen[1])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      QTR_CLASSIC_MAX, &dimids_gen[2])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[3])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen,
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* Now try this record file in classic format. It should fail and
-	   the enddef. Too many bytes in the first record.*/
-	printf("*** Now a classic file that's too big and will fail...");
-	if ((res = nc_create(file_name, cflag, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      QTR_CLASSIC_MAX, &dimids_gen[1])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      QTR_CLASSIC_MAX, &dimids_gen[2])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[3])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen,
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
-	    ERR;
-	if ((res = nc_close(ncid)) != NC_EVARSIZE)
-	    ERR;
-	printf("ok\n");
-
-	/* Now try this record file in classic format. It just barely
-	   passes at the enddef. Almost, but not quite, too many bytes in
-	   the first record. Since I'm adding a fixed variable (Collins),
-	   I don't get the last record size exemption. */
-	printf("*** Now a classic file with recs and one fixed will fail...");
-	if ((res = nc_create(file_name, cflag, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[1])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* Try a classic file with several records, and the last record var
-	   with a record size greater than our magic number of 2 GiB - 4
-	   bytes. We'll start with just one oversized record var. This
-	   should work. Cromwell has been changed to NC_DOUBLE, and that
-	   increases his size to 2147483644 (the max dimension size) times
-	   8, or about 16 GB per record. Zowie! (Mind you, Cromwell
-	   certainly had a great deal of revolutionary fervor.)
-	*/
-	printf("*** Now a classic file with one large rec var...");
-	if ((res = nc_create(file_name, cflag, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[1])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	index[0] = 0;
-	index[1] = MAX_CLASSIC_BYTES - 1;
-	if ((res = nc_put_var1_double(ncid, cromwellid, index, &double_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_double(ncid, cromwellid, index, &double_val_in)))
-	    ERR;
-	if (double_val_in != double_val_out)
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* This is a classic format file with an extra-large last record
-	   var. */
-	printf("*** Now a classic file with extra-large last record var...") ;
-	if ((res = nc_create(file_name, cflag, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[1])))
-	    ERR;
-	dimids_gen1[0] = dimids_gen[0];
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      5368, &dimids_gen1[1])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	index[0] = 0;
-	index[1] = MAX_CLASSIC_BYTES - 1;
-	if ((res = nc_put_var1_double(ncid, cromwellid, index, &double_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_double(ncid, cromwellid, index, &double_val_in)))
-	    ERR;
-	if (double_val_in != double_val_out)
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-
-	/* This is a classic format file with an extra-large second to last
-	   record var. But this time it won't work, because the size
-	   exemption only applies to the last record var. Note that one
-	   dimension is small (5000). */
-	printf("*** Now a classic file xtra-large 2nd to last var that will fail...");
-	if ((res = nc_create(file_name, cflag, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[1])))
-	    ERR;
-	dimids_gen1[0] = dimids_gen[0];
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      5000, &dimids_gen1[1])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
-	    ERR;
-	if ((res = nc_close(ncid)) != NC_EVARSIZE)
-	    ERR;
-	printf("ok\n");
-
-	/* Now try an extra large second to last ver with 64-bit
-	   offset. This won't work either, because the cromwell var is so
-	   large. It exceeds the 4GiB - 4 byte per record limit for record
-	   vars. */
-	printf("*** Now a 64-bit offset file with too-large rec var that will fail...");
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[1])))
-	    ERR;
-	dimids_gen1[0] = dimids_gen[0];
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      5368, &dimids_gen1[1])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
-	    ERR;
-	if ((res = nc_close(ncid)) != NC_EVARSIZE)
-	    ERR;
-	printf("ok\n");
-
-	/* A 64-bit offset record file that just fits... */
-	printf("*** Now a 64 bit-offset file that just fits...");
-	if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
-	    ERR;
-	if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "political_trouble",
-			      NC_UNLIMITED, &dimids_gen[0])))
-	    ERR;
-	if ((res = nc_def_dim(ncid, "revolutionary_fervor",
-			      MAX_CLASSIC_BYTES, &dimids_gen[1])))
-	    ERR;
-	dimids_gen1[0] = dimids_gen[0];
-	if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
-			      MAX_CLASSIC_BYTES, &dimids_gen1[1])))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
-			      &washingtonid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Napolean", NC_SHORT, 2, dimids_gen1,
-			      &napoleanid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Cromwell", NC_SHORT, 2, dimids_gen,
-			      &cromwellid)))
-	    ERR;
-	if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
-			      &collinsid)))
-	    ERR;
-	if ((res = nc_enddef(ncid)))
-	    ERR;
-	index[0] = 0;
-	index[1] = MAX_CLASSIC_BYTES - 1;
-	if ((res = nc_put_var1_int(ncid, cromwellid, index, &int_val_out)))
-	    ERR;
-	if ((res = nc_get_var1_int(ncid, cromwellid, index, &int_val_in)))
-	    ERR;
-	if (int_val_in != int_val_out)
-	    ERR;
-	if ((res = nc_close(ncid)))
-	    ERR;
-	printf("ok\n");
-    } /* end of cmode run */
-
-    /* Wow! Everything worked! */
-    printf("*** Tests successful!\n");
-
-    /* Delete the huge data file we created. */
-    (void) remove(file_name);
-
-    return 0;
+   int ncid, spockid, kirkid, dimids[NUMDIMS], recdimid, scottyid;
+   int int_val_in, int_val_out = 99;
+   double double_val_in, double_val_out = 1.79769313486230e+308; /* from ncx.h */
+   size_t index[2] = {QTR_CLASSIC_MAX-1, 0};
+   char file_name[NC_MAX_NAME + 1];
+
+   /* These are for the revolutionary generals tests. */
+   int cromwellid, collinsid, washingtonid;
+   int napoleanid, dimids_gen[4], dimids_gen1[4];
+
+   /* All create modes will be anded to this. All tests will be run
+      twice, with and without NC_SHARE.*/
+   int cmode_run;
+   int cflag = NC_CLOBBER;
+
+   int res;
+
+   printf("\n*** Testing large files, quickly.\n");
+
+   for (cmode_run=0; cmode_run<2; cmode_run++)
+   {
+      size_t big_index = (size_t)MAX_CLASSIC_BYTES + 10;
+      /* On second pass, try using NC_SHARE. */
+      if (cmode_run == 1)
+      {
+         cflag |= NC_SHARE;
+         printf("*** Turned on NC_SHARE for subsequent tests.\n");
+      }
+
+      /* Create a netCDF 64-bit offset format file. Write a value. */
+      sprintf(file_name, "%s/%s", TEMP_LARGE, FILE_NAME);
+      printf("*** Creating %s for 64-bit offset large file test...", file_name);
+      {
+         if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+            ERR;
+
+         if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+            ERR;
+         if ((res = nc_def_dim(ncid, "longdim", QTR_CLASSIC_MAX, dimids)))
+            ERR;
+         /* test bug fix writing record beyond 2**31 */
+         if ((res = nc_def_dim(ncid, "longerdim", NC_UNLIMITED, &recdimid)))
+            ERR;
+         if ((res = nc_def_var(ncid, "spock", NC_DOUBLE, NUMDIMS,
+                               dimids, &spockid)))
+            ERR;
+         if ((res = nc_def_var(ncid, "kirk", NC_DOUBLE, NUMDIMS,
+                               dimids, &kirkid)))
+            ERR;
+         if ((res = nc_def_var(ncid, "scotty", NC_BYTE, 1,
+                               &recdimid, &scottyid)))
+            ERR;
+         if ((res = nc_enddef(ncid)))
+            ERR;
+         if ((res = nc_put_var1_double(ncid, kirkid, index, &double_val_out)))
+            ERR;
+         if ((res = nc_put_var1_int(ncid, scottyid, &big_index, &int_val_out)))
+            ERR;
+         if ((res = nc_get_var1_int(ncid, scottyid, &big_index, &int_val_in)))
+            ERR;
+         if (int_val_in != int_val_out)
+            ERR;
+         if ((res = nc_close(ncid)))
+            ERR;
+      }
+      SUMMARIZE_ERR;
+
+      /* How about a meteorological data file about the weather
+         experience by various generals of revolutionary armies?
+
+         This has 3 dims, 4 vars. The dimensions are such that this will
+         (just barely) not fit in a classic format file. The first three
+         vars are cromwell, 536870911 bytes, washington, 2*536870911
+         bytes, and napolean, 536870911 bytes. That's a grand total of
+         2147483644 bytes. Recall our magic limit for the combined size
+         of all fixed vars: 2 GiB - 4 bytes, or 2147483644. So you would
+         think these would exactly fit, unless you realized that
+         everything is rounded to a 4 byte boundary, so you need to add
+         some bytes for that (how many?), and that pushes us over the
+         limit.
+
+         We will create this file twice, once to ensure it succeeds (with
+         64-bit offset format), and once to make sure it fails (with
+         classic format). Then some variations to check record var
+         boundaries.
+      */
+      printf("*** Now a 64-bit offset, large file, fixed var test...");
+      if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            QTR_CLASSIC_MAX, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            QTR_CLASSIC_MAX, &dimids_gen[1])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 1, &dimids_gen[0],
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, &dimids_gen[1],
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 1, &dimids_gen[0],
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* Write a value or two just for fun. */
+      /*index[0] = QTR_CLASSIC_MAX - 296;
+        if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out)))
+        ERR;
+        if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in)))
+        ERR;
+        if (int_val_in != int_val_out)
+        BAIL2;*/
+      printf("*** Now writing some values...");
+      index[0] = QTR_CLASSIC_MAX - 295;
+      if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out)))
+         ERR;
+      if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in)))
+         ERR;
+      if (int_val_in != int_val_out)
+         ERR;
+
+      index[0] = QTR_CLASSIC_MAX - 1;
+      if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out)))
+         ERR;
+      if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in)))
+         ERR;
+      if (int_val_in != int_val_out)
+         ERR;
+
+      index[0] = QTR_CLASSIC_MAX - 1;
+      if ((res = nc_put_var1_int(ncid, washingtonid, index, &int_val_out)))
+         ERR;
+      if ((res = nc_get_var1_int(ncid, washingtonid, index, &int_val_in)))
+         ERR;
+      if (int_val_in != int_val_out)
+         ERR;
+
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* This time it should fail, because we're trying to cram this into
+         a classic format file. nc_enddef will detect our violations and
+         give an error. We've*/
+      printf("*** Now a classic file which will fail...");
+      if ((res = nc_create(file_name, cflag, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            QTR_CLASSIC_MAX, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            QTR_CLASSIC_MAX, &dimids_gen[1])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 1, &dimids_gen[0],
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, &dimids_gen[1],
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 1, &dimids_gen[0],
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
+         ERR;
+      if ((res = nc_close(ncid)) != NC_EVARSIZE)
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* This will create some max sized 64-bit offset format fixed vars. */
+      printf("*** Now a 64-bit offset, simple fixed var create test...");
+      if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_SHORT, 1, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_SHORT, 1, dimids_gen,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, dimids_gen,
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* This will exceed the 64-bit offset format limits for one of the
+         fixed vars. */
+      printf("*** Now a 64-bit offset, over-sized file that will fail...");
+      if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      /* max dim size is MAX_CLASSIC_BYTES. */
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, dimids_gen)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 1, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, dimids_gen,
+                            &washingtonid)))
+         if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
+            ERR;
+      if ((res = nc_close(ncid)) != NC_EVARSIZE)
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* Now let's see about record vars. First create a 64-bit offset
+         file with three rec variables, each with the same numbers as
+         defined above for the fixed var tests. This should all work. */
+      printf("*** Now a 64-bit offset, record var file...");
+      if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            QTR_CLASSIC_MAX, &dimids_gen[1])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            QTR_CLASSIC_MAX, &dimids_gen[2])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[3])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen,
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* Now try this record file in classic format. It should fail and
+         the enddef. Too many bytes in the first record.*/
+      printf("*** Now a classic file that's too big and will fail...");
+      if ((res = nc_create(file_name, cflag, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            QTR_CLASSIC_MAX, &dimids_gen[1])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            QTR_CLASSIC_MAX, &dimids_gen[2])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[3])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen,
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
+         ERR;
+      if ((res = nc_close(ncid)) != NC_EVARSIZE)
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* Now try this record file in classic format. It just barely
+         passes at the enddef. Almost, but not quite, too many bytes in
+         the first record. Since I'm adding a fixed variable (Collins),
+         I don't get the last record size exemption. */
+      printf("*** Now a classic file with recs and one fixed will fail...");
+      if ((res = nc_create(file_name, cflag, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[1])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2],
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* Try a classic file with several records, and the last record var
+         with a record size greater than our magic number of 2 GiB - 4
+         bytes. We'll start with just one oversized record var. This
+         should work. Cromwell has been changed to NC_DOUBLE, and that
+         increases his size to 2147483644 (the max dimension size) times
+         8, or about 16 GB per record. Zowie! (Mind you, Cromwell
+         certainly had a great deal of revolutionary fervor.)
+      */
+      printf("*** Now a classic file with one large rec var...");
+      if ((res = nc_create(file_name, cflag, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[1])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      index[0] = 0;
+      index[1] = MAX_CLASSIC_BYTES - 1;
+      if ((res = nc_put_var1_double(ncid, cromwellid, index, &double_val_out)))
+         ERR;
+      if ((res = nc_get_var1_double(ncid, cromwellid, index, &double_val_in)))
+         ERR;
+      if (double_val_in != double_val_out)
+         ERR;
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* This is a classic format file with an extra-large last record
+         var. */
+      printf("*** Now a classic file with extra-large last record var...") ;
+      if ((res = nc_create(file_name, cflag, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[1])))
+         ERR;
+      dimids_gen1[0] = dimids_gen[0];
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            5368, &dimids_gen1[1])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
+                            &collinsid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      index[0] = 0;
+      index[1] = MAX_CLASSIC_BYTES - 1;
+      if ((res = nc_put_var1_double(ncid, cromwellid, index, &double_val_out)))
+         ERR;
+      if ((res = nc_get_var1_double(ncid, cromwellid, index, &double_val_in)))
+         ERR;
+      if (double_val_in != double_val_out)
+         ERR;
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* This is a classic format file with an extra-large second to last
+         record var. But this time it won't work, because the size
+         exemption only applies to the last record var. Note that one
+         dimension is small (5000). */
+      printf("*** Now a classic file xtra-large 2nd to last var that will fail...");
+      if ((res = nc_create(file_name, cflag, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[1])))
+         ERR;
+      dimids_gen1[0] = dimids_gen[0];
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            5000, &dimids_gen1[1])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
+         ERR;
+      if ((res = nc_close(ncid)) != NC_EVARSIZE)
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* Now try an extra large second to last ver with 64-bit
+         offset. This won't work either, because the cromwell var is so
+         large. It exceeds the 4GiB - 4 byte per record limit for record
+         vars. */
+      printf("*** Now a 64-bit offset file with too-large rec var that will fail...");
+      if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[1])))
+         ERR;
+      dimids_gen1[0] = dimids_gen[0];
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            5368, &dimids_gen1[1])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)) != NC_EVARSIZE)
+         ERR;
+      if ((res = nc_close(ncid)) != NC_EVARSIZE)
+         ERR;
+      SUMMARIZE_ERR;
+
+      /* A 64-bit offset record file that just fits... */
+      printf("*** Now a 64 bit-offset file that just fits...");
+      if ((res = nc_create(file_name, cflag|NC_64BIT_OFFSET, &ncid)))
+         ERR;
+      if ((res = nc_set_fill(ncid, NC_NOFILL, NULL)))
+         ERR;
+      if ((res = nc_def_dim(ncid, "political_trouble",
+                            NC_UNLIMITED, &dimids_gen[0])))
+         ERR;
+      if ((res = nc_def_dim(ncid, "revolutionary_fervor",
+                            MAX_CLASSIC_BYTES, &dimids_gen[1])))
+         ERR;
+      dimids_gen1[0] = dimids_gen[0];
+      if ((res = nc_def_dim(ncid, "post_revoultionary_hangover",
+                            MAX_CLASSIC_BYTES, &dimids_gen1[1])))
+         ERR;
+      if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1,
+                            &washingtonid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Napolean", NC_SHORT, 2, dimids_gen1,
+                            &napoleanid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Cromwell", NC_SHORT, 2, dimids_gen,
+                            &cromwellid)))
+         ERR;
+      if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1,
+                            &collinsid)))
+         ERR;
+      if ((res = nc_enddef(ncid)))
+         ERR;
+      index[0] = 0;
+      index[1] = MAX_CLASSIC_BYTES - 1;
+      if ((res = nc_put_var1_int(ncid, cromwellid, index, &int_val_out)))
+         ERR;
+      if ((res = nc_get_var1_int(ncid, cromwellid, index, &int_val_in)))
+         ERR;
+      if (int_val_in != int_val_out)
+         ERR;
+      if ((res = nc_close(ncid)))
+         ERR;
+      SUMMARIZE_ERR;
+   } /* end of cmode run */
+
+   /* Delete the huge data file we created. */
+   (void) remove(file_name);
+
+   FINAL_RESULTS;
+   return 0;
 }
diff --git a/nc_test/run_diskless.sh b/nc_test/run_diskless.sh
index a14e150..3f66e07 100755
--- a/nc_test/run_diskless.sh
+++ b/nc_test/run_diskless.sh
@@ -117,4 +117,4 @@ diff tst_diskless3_file.cdl tst_diskless3_memory.cdl
 # cleanup
 rm -f $FILE3 tst_diskless3_file.cdl tst_diskless3_memory.cdl
 
-exit
+exit 0
diff --git a/nc_test/run_diskless2.sh b/nc_test/run_diskless2.sh
index 65cec62..3c1a67f 100755
--- a/nc_test/run_diskless2.sh
+++ b/nc_test/run_diskless2.sh
@@ -5,6 +5,9 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 
 set -e
 
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../test_common.sh
+
 # Get the target OS and CPU
 CPU=`uname -p`
 OS=`uname`
diff --git a/nc_test/test_put.c b/nc_test/test_put.c
index 24a0c89..703feed 100644
--- a/nc_test/test_put.c
+++ b/nc_test/test_put.c
@@ -12677,6 +12677,7 @@ int
 test_nc_put_att_text(void)
 {
     int i, j, err, ncid, nok=0;
+    double dtmp;
     size_t k, ndx[1];
     text value[MAX_NELS];
 
@@ -12721,7 +12722,7 @@ test_nc_put_att_text(void)
 
                 for (k = 0; k < ATT_LEN(i,j); k++) {
                     ndx[0] = k;
-                    double dtmp = hash(ATT_TYPE(i,j), -1, ndx);
+                    dtmp = hash(ATT_TYPE(i,j), -1, ndx);
                     value[k] = (text)dtmp;
                 }
                 err = nc_put_att_text(ncid, i, ATT_NAME(i,j), ATT_LEN(i,j), value);
diff --git a/nc_test/test_put.m4 b/nc_test/test_put.m4
index d586b91..0d6705e 100644
--- a/nc_test/test_put.m4
+++ b/nc_test/test_put.m4
@@ -1382,6 +1382,7 @@ int
 TestFunc(att)_text(AttVarArgs)
 {
     int i, j, err, ncid, nok=0;
+    double dtmp;
     IntType k, ndx[1];
     text value[MAX_NELS];
 
@@ -1426,7 +1427,7 @@ TestFunc(att)_text(AttVarArgs)
 
                 for (k = 0; k < ATT_LEN(i,j); k++) {
                     ndx[0] = k;
-                    double dtmp = hash(ATT_TYPE(i,j), -1, ndx);
+                    dtmp = hash(ATT_TYPE(i,j), -1, ndx);
                     value[k] = (text)dtmp;
                 }
                 err = PutAtt(text)(ncid, i, ATT_NAME(i,j), ATT_LEN(i,j), value);
diff --git a/nc_test/test_read.c b/nc_test/test_read.c
index 9df36fb..2028380 100644
--- a/nc_test/test_read.c
+++ b/nc_test/test_read.c
@@ -52,14 +52,14 @@ test_nc_strerror(void)
         {NC_ENOTINDEFINE, "NetCDF: Operation not allowed in data mode"},
         {NC_EINDEFINE, "NetCDF: Operation not allowed in define mode"},
         {NC_EINVALCOORDS, "NetCDF: Index exceeds dimension bound"},
-        {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"},
+        {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"},  /* not enforced after 4.5.0 */
         {NC_ENAMEINUSE, "NetCDF: String match to name in use"},
         {NC_ENOTATT, "NetCDF: Attribute not found"},
-        {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"},
+        {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"}, /* not enforced after 4.5.0 */
         {NC_EBADTYPE, "NetCDF: Not a valid data type or _FillValue type mismatch"},
         {NC_EBADDIM, "NetCDF: Invalid dimension ID or name"},
         {NC_EUNLIMPOS, "NetCDF: NC_UNLIMITED in the wrong index"},
-        {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"},
+        {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"}, /* not enforced after 4.5.0 */
         {NC_ENOTVAR, "NetCDF: Variable not found"},
         {NC_EGLOBAL, "NetCDF: Action prohibited on NC_GLOBAL varid"},
         {NC_ENOTNC, "NetCDF: Unknown file format"},
diff --git a/nc_test/test_read.m4 b/nc_test/test_read.m4
index a091b3f..4434d6d 100644
--- a/nc_test/test_read.m4
+++ b/nc_test/test_read.m4
@@ -81,14 +81,14 @@ TestFunc(strerror)(void)
         {NC_ENOTINDEFINE, "NetCDF: Operation not allowed in data mode"},
         {NC_EINDEFINE, "NetCDF: Operation not allowed in define mode"},
         {NC_EINVALCOORDS, "NetCDF: Index exceeds dimension bound"},
-        {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"},
+        {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"},  /* not enforced after 4.5.0 */
         {NC_ENAMEINUSE, "NetCDF: String match to name in use"},
         {NC_ENOTATT, "NetCDF: Attribute not found"},
-        {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"},
+        {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"}, /* not enforced after 4.5.0 */
         {NC_EBADTYPE, "NetCDF: Not a valid data type or _FillValue type mismatch"},
         {NC_EBADDIM, "NetCDF: Invalid dimension ID or name"},
         {NC_EUNLIMPOS, "NetCDF: NC_UNLIMITED in the wrong index"},
-        {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"},
+        {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"}, /* not enforced after 4.5.0 */
         {NC_ENOTVAR, "NetCDF: Variable not found"},
         {NC_EGLOBAL, "NetCDF: Action prohibited on NC_GLOBAL varid"},
         {NC_ENOTNC, "NetCDF: Unknown file format"},
diff --git a/nc_test/test_write.c b/nc_test/test_write.c
index 8cf116a..70e6cfc 100644
--- a/nc_test/test_write.c
+++ b/nc_test/test_write.c
@@ -2363,7 +2363,7 @@ test_nc_set_default_format(void)
 int
 test_nc_delete(void)
 {
-    int err, nok=0;;
+    int err, nok=0;
     int ncid;
 
     err = file_create(scratch, NC_CLOBBER, &ncid);
diff --git a/nc_test/test_write.m4 b/nc_test/test_write.m4
index 034d558..936d99b 100644
--- a/nc_test/test_write.m4
+++ b/nc_test/test_write.m4
@@ -2504,7 +2504,7 @@ TestFunc(set_default_format)(void)
 int
 TestFunc(delete)(void)
 {
-    int err, nok=0;;
+    int err, nok=0;
     int ncid;
 
     err = FileCreate(scratch, NC_CLOBBER, &ncid);
diff --git a/nc_test/tst_atts3.c b/nc_test/tst_atts3.c
index e5ffc25..d405c42 100644
--- a/nc_test/tst_atts3.c
+++ b/nc_test/tst_atts3.c
@@ -140,14 +140,6 @@ main(int argc, char **argv)
     float float_in[ATT_LEN], float_out[ATT_LEN] = {-0.5, 0.25, 0.125};
     double double_in[ATT_LEN], double_out[ATT_LEN] = {-0.25, .5, 0.125};
     long long longlong_in[ATT_LEN] = {-1LL, -1LL, -1LL};
-#ifdef USE_NETCDF4
-    long long_in[ATT_LEN];
-    unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT};
-    unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT};
-    long long longlong_out[ATT_LEN] = {-3123456789LL, 128LL, 3123456789LL};
-    unsigned long long ulonglong_in[ATT_LEN] = {NC_MAX_UINT64, NC_MAX_UINT64, NC_MAX_UINT64};
-    unsigned long long ulonglong_out[ATT_LEN] = {0LL, 128LL, 3123456789LL};
-#endif
 
 #ifdef TEST_PNETCDF
    MPI_Init(&argc, &argv);
diff --git a/nc_test/tst_big_rvar.c b/nc_test/tst_big_rvar.c
index 800d054..8a59547 100644
--- a/nc_test/tst_big_rvar.c
+++ b/nc_test/tst_big_rvar.c
@@ -41,9 +41,6 @@ static int
 test_big_var(const char *testfile)
 {
     int ncid, varid, dimids[NUMDIMS];
-    size_t index[NUMDIMS];
-    int nval = 99;
-    int nval_in;
     size_t start[NUMDIMS] = {0, 0, 0, 0};
     size_t count[NUMDIMS] = {1, 1, DIM2, DIM3};
     signed char data[DIM2][DIM3];
@@ -84,7 +81,7 @@ test_big_var(const char *testfile)
 	{
 	    if (data[i][j] != (signed char)((i + j) % 16))
 	    {
-		printf("error on start[0]: %d i: %d j: %d expected %d got %d\n",
+		printf("error on start[0]: %ld i: %d j: %d expected %d got %d\n",
 		       start[0], i, j, (i + j) % 16, data[i][j]);
 		ERR;
 		if(nerrs++ > 2)
@@ -98,7 +95,7 @@ test_big_var(const char *testfile)
 	{
 	    if (data[i][j] != (signed char)((i + j) % 16))
 	    {
-		printf("error on start[0]: %d i: %d j: %d expected %d got %d\n",
+		printf("error on start[0]: %ld i: %d j: %d expected %d got %d\n",
 		       start[0], i, j, (i + j) % 16, data[i][j]);
 		ERR;
 		if(nerrs++ > 2)
diff --git a/nc_test/tst_big_var2.c b/nc_test/tst_big_var2.c
index 6ca5c9c..4f722ca 100644
--- a/nc_test/tst_big_var2.c
+++ b/nc_test/tst_big_var2.c
@@ -45,9 +45,6 @@ static int
 test_big_var(const char *testfile)
 {
     int ncid, varid, dimids[NUMDIMS];
-    size_t index[NUMDIMS];
-    int nval = 99;
-    int nval_in;
     size_t start[NUMDIMS] = {0, 0, 0};
     size_t count[NUMDIMS] = {1, DIM1, DIM2};
     signed char data[DIM1][DIM2];
@@ -92,7 +89,7 @@ test_big_var(const char *testfile)
 	{
 	    if (data[i][j] != 42 )
 	    {
-		printf("error on start[0]: %d i: %d j: %d expected %d got %d\n",
+		printf("error on start[0]: %ld i: %d j: %d expected %d got %d\n",
 		       start[0], i, j, 42, data[i][j]);
 		ERR;
 		if(nerrs++ > 1)
@@ -106,7 +103,7 @@ test_big_var(const char *testfile)
 	{
 	    if (data[i][j] != 19 )
 	    {
-	      printf("error on start[0]: %d i: %d j: %d expected %d got %d\n",
+	      printf("error on start[0]: %ld i: %d j: %d expected %d got %d\n",
 		     start[0], i, j, 19, data[i][j]);
 	      ERR;
 		if(nerrs++ > 1)
diff --git a/nc_test/tst_big_var6.c b/nc_test/tst_big_var6.c
index 054e5d2..5f4fad7 100644
--- a/nc_test/tst_big_var6.c
+++ b/nc_test/tst_big_var6.c
@@ -7,7 +7,7 @@
   more than 1 dimension and more than 2**32 values, where the write
   starts after the first 2**32 elements.
 
-  $Id: tst_big_var6.c,v 1.1 2010/05/22 19:56:53 russ Exp $
+  Russ Rew
 */
 
 #include <nc_tests.h>
@@ -49,7 +49,7 @@ test_big_var(const char *testfile)
     size_t start[NUMDIMS] = {0, 0, 0, 0};
     size_t count[NUMDIMS] = {1, 1, 1, DIM3};
     short data[DIM3];
-    int i, j, k;
+    int j;
     int nerrs = 0;
 
     /* Create a file with one big 4D variable. */
@@ -85,7 +85,7 @@ test_big_var(const char *testfile)
     if (nc_get_vara_short(ncid, varid, start, count, &data[0])) ERR;
     for (j = 0; j < DIM3; j++) {
 	if (data[j] != FIRST_VAL ) {
-	    printf("error on start[0..2]: %d,%d,%d  j: %d, expected %d got %d\n",
+	    printf("error on start[0..2]: %ld,%ld,%ld  j: %d, expected %d got %d\n",
 		   start[0], start[1], start[2], j, FIRST_VAL, data[j]);
 	    ERR;
 	    if(nerrs++ > 1)
diff --git a/nc_test/tst_cdf5format.c b/nc_test/tst_cdf5format.c
index 91a65c5..6e183c1 100644
--- a/nc_test/tst_cdf5format.c
+++ b/nc_test/tst_cdf5format.c
@@ -5,224 +5,178 @@
    Test fix of bug involving creation of a file with pnetcdf APIs,
    then opening and modifying the file with netcdf.
 
-   Author: Wei-keng Liao.
+   Author: Wei-keng Liao, Ed Hartnett
 */
-
-/*
-Goal is to verify that cdf-5 code is writing data that can
-be read by pnetcdf and vice-versa.
-*/
-
-/*
-    Compile:
-        mpicc -g -o tst_cdf5format tst_cdf5format.c -lnetcdf -lcurl -lhdf5_hl -lhdf5 -lpnetcdf -lz -lm
-    Run:
-        nc_pnc
-*/
-
+#include <config.h>
 #include <nc_tests.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mpi.h>
-#include <netcdf.h>
-#include <netcdf_par.h>
-#include <assert.h>
+#include <err_macros.h>
 
 #define NVARS 6
-#define NX    5
-#define FILENAME "tst_pnetcdf.nc"
-
-static void 
-report(int stat, char* file, int line)
-{
-    fflush(stdout); /* Make sure our stdout is synced with stderr.*/
-    if(stat != 0) {
-        fprintf(stderr, "Sorry! Unexpected result, %s, line: %d: status=%d\n", \
-	        __FILE__, __LINE__,stat);
-    }
-}
-
-#define Error(stat) report(stat,__FILE__,__LINE__)
-
-/*
-Given ncid,
-write meta-data and data
-*/
+#define NX 5
+#define NDIM2 2
+#define FILENAME "tst_cdf5format.nc"
 
+/* Write a file with 2 dims and 6 vars, including some sample data. */
 int
-write(int ncid, int parallel)
+write2(int ncid, int parallel)
 {
-    int i, j, rank, nprocs, cmode, varid[NVARS], dimid[2], *buf;
-    int err = 0;
-    char str[32];
-    size_t start[2], count[2];
-    int stat = NC_NOERR;
-
-    /* define dimension */
-    if (stat=nc_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0])) Error(stat);;
-    if (stat=nc_def_dim(ncid, "X", NX,           &dimid[1])) Error(stat);;
-
-    /* Odd numbers are fixed variables, even numbers are record variables */
-    for (i=0; i<NVARS; i++) {
-        if (i%2) {
-            sprintf(str,"fixed_var_%d",i);
-            if (nc_def_var(ncid, str, NC_INT, 1, dimid+1, &varid[i])) Error(stat);;
-        }
-        else {
-            sprintf(str,"record_var_%d",i);
-            if (stat=nc_def_var(ncid, str, NC_INT, 2, dimid, &varid[i])) Error(stat);;
-        }
-    }
-    if (stat=nc_enddef(ncid)) Error(stat);;
-<<<<<<< HEAD
-=======
-
->>>>>>> 896fe992ff193edcd1a7f2ad592d144a91de3de5
-    for (i=0; i<NVARS; i++) {
-	if(parallel) {
-            /* Note NC_INDEPENDENT is the default */
-            if (stat=nc_var_par_access(ncid, varid[i], NC_INDEPENDENT)) Error(stat);;
-	}
-    }
-
-    /* write all variables */
-    buf = (int*) malloc(NX * sizeof(int));
-    for (i=0; i<NVARS; i++) {
-        for (j=0; j<NX; j++) buf[j] = i*10 + j;
-        if (i%2) {
-            start[0] = 0; count[0] = NX;
-            if (stat=nc_put_vara_int(ncid, varid[i], start, count, buf)) Error(stat);;
-        }
-        else {
-            start[0] = 0; start[1] = 0;
-            count[0] = 1; count[1] = NX;
-            if (stat=nc_put_vara_int(ncid, varid[i], start, count, buf)) Error(stat);;
-        }
-    }
-    return NC_NOERR;
+   int dimid[NDIM2];
+   char str[NC_MAX_NAME + 1];
+   int varid[NVARS];
+   
+   /* define dimension */
+   if (nc_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0])) ERR;
+   if (nc_def_dim(ncid, "X", NX, &dimid[1])) ERR;
+
+   /* Define vars. */
+   for (int i = 0; i < NVARS; i++)
+   {
+      if (i % 2)
+      {
+	 sprintf(str, "fixed_var_%d",i);
+	 if (nc_def_var(ncid, str, NC_INT, 1, &dimid[1], &varid[i])) ERR;
+      }
+      else
+      {
+	 sprintf(str, "record_var_%d",i);
+	 if (nc_def_var(ncid, str, NC_INT, 2, dimid, &varid[i])) ERR;
+      }
+   }
+   
+   if (nc_enddef(ncid)) ERR;
+   
+   /* write all variables */
+   for (int i = 0; i < NVARS; i++)
+   {
+      size_t start[NDIM2] = {0, 0};
+      size_t count[NDIM2];
+      int buf[NX];
+      
+      /* Initialize some data. */
+      for (int j = 0; j < NX; j++)
+	 buf[j] = i * 10 + j;
+
+      /* Write the data. */
+      if (i % 2)
+      {
+	 count[0] = NX;
+	 if (nc_put_vara_int(ncid, varid[i], start, count, buf)) ERR;
+      }
+      else
+      {
+	 count[0] = 1;
+	 count[1] = NX;
+	 if (nc_put_vara_int(ncid, varid[i], start, count, buf)) ERR;
+      }
+   }
+   return 0;
 }
 
+/* Add some attributes to the vars of an open file. */
 int
 extend(int ncid)
 {
-    int i, j, rank, nprocs, cmode, varid[NVARS], dimid[2], *buf;
-    int err = 0;
-    char str[32];
-    size_t start[2], count[2];
-    int stat = NC_NOERR;
-
-    if (stat=nc_redef(ncid)) Error(stat);;
-    /* add attributes to make header grow */
-    for (i=0; i<NVARS; i++) {
-        sprintf(str, "annotation_for_var_%d",i);
-        if (stat=nc_put_att_text(ncid, varid[i], "text_attr", strlen(str), str)) Error(stat);;
-    }
-    if (stat=nc_enddef(ncid)) Error(stat);;
-    return NC_NOERR;
+   int i;
+   char str[32];
+
+   if (nc_redef(ncid)) ERR;
+   
+   /* add attributes to make header grow */
+   for (i = 0; i < NVARS; i++)
+   {
+      sprintf(str, "annotation_for_var_%d", i);
+      if (nc_put_att_text(ncid, i, "text_attr", strlen(str), str)) ERR;
+   }
+   if (nc_enddef(ncid)) ERR;
+   return NC_NOERR;
 }
 
+/* Read the file and check the data. */
 int
-read(int ncid)
+read2(int ncid)
 {
-    int i, j, rank, nprocs, cmode, varid[NVARS], dimid[2], *buf;
-    int err = 0;
-    char str[32];
-    size_t start[2], count[2];
-    int stat = NC_NOERR;
-<<<<<<< HEAD
-=======
-
->>>>>>> 896fe992ff193edcd1a7f2ad592d144a91de3de5
-    /* read variables and check their contents */
-    for (i=0; i<NVARS; i++) {
-        for (j=0; j<NX; j++) buf[j] = -1;
-        if (i%2) {
-            start[0] = 0; count[0] = NX;
-            if (stat=nc_get_var_int(ncid, varid[i], buf)) Error(stat);
-            for (j=0; j<NX; j++)
-                if (buf[j] != i*10 + j)
-                    printf("unexpected read value var i=%d buf[j=%d]=%d should be %d\n",i,j,buf[j],i*10+j);
-        }
-        else {
-            start[0] = 0; start[1] = 0;
-            count[0] = 1; count[1] = NX;
-            if (stat=nc_get_vara_int(ncid, varid[i], start, count, buf)) Error(stat);
-            for (j=0; j<NX; j++)
-                if (buf[j] != i*10+j)
-                    printf("unexpected read value var i=%d buf[j=%d]=%d should be %d\n",i,j,buf[j],i*10+j);
-        }
-    }
-    return NC_NOERR;
+   for (int i = 0; i < NVARS; i++)
+   {
+      int buf[NX];
+      size_t start[2] = {0, 0}, count[2];      
+
+      if (i % 2)
+      {
+	 count[0] = NX;
+      }
+      else
+      {
+	 count[0] = 1;
+	 count[1] = NX;
+      }
+      if (nc_get_vara_int(ncid, i, start, count, buf)) ERR;	 
+      for (int j = 0; j < NX; j++)
+      {
+	 if (buf[j] != i * 10 + j)
+	 {
+	    printf("unexpected read value var i=%d buf[j=%d]=%d should be %d\n",
+		   i, j, buf[j], i * 10 + j);
+	    ERR;
+	 }
+      }
+   }
+   return 0;
 }
 
-
 int main(int argc, char* argv[])
 {
-    int rank, nprocs, ncid, cmode, stat;
-/*
-    int i, j, rank, nprocs, ncid, cmode, varid[NVARS], dimid[2], *buf;
-    int err = 0;
-    char str[32];
-    size_t start[2], count[2];
-*/
-    MPI_Comm comm=MPI_COMM_SELF;
-    MPI_Info info=MPI_INFO_NULL;
-
-    MPI_Init(&argc,&argv);
-    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
-    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-    if (nprocs > 1 && rank == 0)
-        printf("This test program is intended to run on ONE process\n");
-    if (rank > 0) goto fn_exit;
-
-
-#ifdef DISABLE_PNETCDF_ALIGNMENT
-    MPI_Info_create(&info);
-    MPI_Info_set(info, "nc_header_align_size", "1");
-    MPI_Info_set(info, "nc_var_align_size",    "1");
-#endif
-
-    /* pnetcdf->cdf5 */
-    printf("\nWrite using PNETCDF; Read using CDF5\n");
-    
-    cmode = NC_PNETCDF | NC_CLOBBER;
-    if (stat=nc_create_par(FILENAME, cmode, comm, info, &ncid)) Error(stat);
-    if (stat=write(ncid,1)) Error(stat);
-    if (stat=nc_close(ncid)) Error(stat);
-    /* re-open the file with netCDF (parallel) and enter define mode */
-    if (stat=nc_open_par(FILENAME, NC_WRITE|NC_PNETCDF, comm, info, &ncid)) Error(stat);
-    if(stat=extend(ncid)) Error(stat);
-    if (stat=nc_close(ncid)) Error(stat);
-
-    cmode = NC_CDF5 | NC_NOCLOBBER;
-    if (stat=nc_open(FILENAME, cmode, &ncid)) ERR_RET;
-    if (stat=read(ncid)) Error(stat);
-    if (stat=nc_close(ncid)) Error(stat);
-
-    unlink(FILENAME);
-
-    /* cdf5->pnetcdf */
-    printf("\nWrite using CDF-5; Read using PNETCDF\n");
-    cmode = NC_CDF5 | NC_CLOBBER;
-    if (stat=nc_create(FILENAME, cmode, &ncid)) ERR_RET;
-    if (stat=write(ncid,0)) Error(stat);
-    if (stat=nc_close(ncid)) Error(stat);
-    /* re-open the file with netCDF (parallel) and enter define mode */
-    if (stat=nc_open(FILENAME, NC_WRITE|NC_CDF5, &ncid)) ERR_RET;
-    if (stat=extend(ncid)) Error(stat);
-    if (stat=nc_close(ncid)) Error(stat);
-
-    cmode = NC_PNETCDF | NC_NOCLOBBER;
-    if (stat=nc_open_par(FILENAME, cmode, comm, info, &ncid)) ERR_RET;
-    if (stat=read(ncid)) Error(stat);
-    if (stat=nc_close(ncid)) Error(stat);
-
-    if (info != MPI_INFO_NULL) MPI_Info_free(&info);
-
-fn_exit:
-    MPI_Finalize();
-    SUMMARIZE_ERR;
-    FINAL_RESULTS;
-    return 0;
+   int rank, nprocs, ncid, cmode;
+   MPI_Comm comm = MPI_COMM_SELF;
+   MPI_Info info = MPI_INFO_NULL;
+
+   MPI_Init(&argc, &argv);
+   MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+   if (rank > 0)
+      return 2;
+
+   printf("\nWrite using PNETCDF; Read using classic netCDF...");
+   {
+      /* Create a netCDF classic file with pnetcdf. */
+      cmode = NC_PNETCDF | NC_CLOBBER;
+      if (nc_create_par(FILENAME, cmode, comm, info, &ncid)) ERR;
+      if (write2(ncid, 1)) ERR;
+      if (nc_close(ncid)) ERR;
+      
+      /* Re-open the file with pnetCDF (parallel) and add var attributes. */
+      if (nc_open_par(FILENAME, NC_WRITE|NC_PNETCDF, comm, info, &ncid)) ERR;
+      if (extend(ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      
+      /* Open with classic and check. */
+      if (nc_open(FILENAME, 0, &ncid)) ERR;
+      if (read2(ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
+
+   printf("\nWrite using CDF-5; Read using PNETCDF...");
+   {
+      /* Create a file with CDF5. */
+      cmode = NC_CDF5 | NC_CLOBBER;
+      if (nc_create(FILENAME, cmode, &ncid)) ERR;
+      if (write2(ncid, 0)) ERR;
+      if (nc_close(ncid)) ERR;
+      
+      /* Re-open the file with CDF5 and add some atts. */
+      if (nc_open(FILENAME, NC_WRITE, &ncid)) ERR;
+      if (extend(ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+
+      /* Re-open with pnetcdf and check. */
+      cmode = NC_PNETCDF | NC_NOCLOBBER;
+      if (nc_open_par(FILENAME, cmode, comm, info, &ncid)) ERR;
+      if (read2(ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
+
+   MPI_Finalize();
+   FINAL_RESULTS;
+   return 0;
 }
diff --git a/nc_test/tst_diskless.c b/nc_test/tst_diskless.c
index c0ec039..5e5a91a 100644
--- a/nc_test/tst_diskless.c
+++ b/nc_test/tst_diskless.c
@@ -197,7 +197,7 @@ printf("*** testing diskless file with scalar vars...");
 
     /* Create some atts. They will help document my data forever. */
     if (nc_put_att_text(ncid, NC_GLOBAL, ATT0_NAME,
-    sizeof(ATT0_TEXT) + 1, ATT0_TEXT)) ERR;
+			sizeof(ATT0_TEXT), ATT0_TEXT)) ERR;
 
     /* Create dimensions: money is limited, but fun is not! */
     if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid[0])) ERR;
@@ -222,6 +222,7 @@ printf("*** testing diskless file with scalar vars...");
     /* Check attributes - they will be needed by future generations
     * of scientists to understand my data. */
     if (nc_get_att_text(ncid, NC_GLOBAL, ATT0_NAME, att0_in)) ERR;
+    att0_in[sizeof(ATT0_TEXT)] = '\0';
     if (strcmp(att0_in, ATT0_TEXT)) ERR;
 
     /* Check dimensions. */
diff --git a/nc_test/tst_elatefill.c b/nc_test/tst_elatefill.c
index 0b9ca6a..99dece2 100644
--- a/nc_test/tst_elatefill.c
+++ b/nc_test/tst_elatefill.c
@@ -14,7 +14,6 @@
 
 #include "config.h"
 #include <nc_tests.h>
-#include "err_macros.h"
 #include <stdio.h>
 #include <netcdf.h>
 
@@ -26,7 +25,7 @@ int
 main(int argc, char **argv)
 {
     int ncid, dimid, varid, err;
-    int no_fill, fillv, buf[10];
+    int fillv;
 
     err = nc_create(FILE_NAME, NC_NETCDF4, &ncid); ERR_CHK;
     err = nc_def_dim(ncid, "dim", 10, &dimid); ERR_CHK;
diff --git a/nc_test/tst_formats.c b/nc_test/tst_formats.c
new file mode 100644
index 0000000..c77ccce
--- /dev/null
+++ b/nc_test/tst_formats.c
@@ -0,0 +1,159 @@
+/* This is part of the netCDF package. Copyright 2005-2007 University
+   Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
+   for conditions of use.
+
+   Test handling of formats.
+
+   Ed Hartnett, 11/22/17
+*/
+
+#include "config.h"
+#include <nc_tests.h>
+#include "err_macros.h"
+
+#define FILE_NAME_BASE "tst_formats"
+#define HDF4_FILE "ref_contiguous.hdf4"
+
+/* Determine how many formats are available, and what they are. */
+void
+determine_test_formats(int *num_formats, int *format)
+{
+   int ind = 0;
+   int num;
+
+   /* Check inputs. */
+   assert(num_formats && format);
+
+   /* We always have classic and 64-bit offset */
+   num = 2;
+   format[ind++] = NC_FORMAT_CLASSIC;
+   format[ind++] = NC_FORMAT_64BIT_OFFSET;
+
+   /* Do we have netCDF-4 and netCDF-4 classic? */
+#ifdef USE_NETCDF4
+   num += 2;
+   format[ind++] = NC_FORMAT_NETCDF4;
+   format[ind++] = NC_FORMAT_NETCDF4_CLASSIC;
+#endif /* USE_NETCDF4 */
+
+   /* Do we have CDF5? */
+#ifdef ENABLE_CDF5
+   num++;
+   format[ind++] = NC_FORMAT_CDF5;
+#endif /* ENABLE_CDF5 */
+
+   *num_formats = num;
+}
+
+/* Function to test nc_inq_format(). */
+int
+check_inq_format(int ncid, int expected_format, int expected_extended_format, int expected_mode)
+{
+   int format;
+   int extended_format;
+   int mode;
+   
+   if (nc_inq_format(ncid + 66000, NULL) != NC_EBADID) ERR;
+   if (nc_inq_format(ncid, NULL)) ERR;
+   if (nc_inq_format(ncid, &format)) ERR;
+   if (format != expected_format) {
+      printf("format %d expected_format %d\n", format, expected_format);      
+      ERR;
+   }
+   if (nc_inq_format_extended(ncid + 66000, &extended_format, &mode) != NC_EBADID) ERR;
+   {
+      int mode;
+      if (nc_inq_format_extended(ncid, NULL, &mode)) ERR;
+      if (mode != expected_mode) {
+         printf("expected_mode %x mode %x\n", expected_mode, mode);
+         //ERR;
+      }
+   }
+   {
+      int extended_format;
+      if (nc_inq_format_extended(ncid, &extended_format, NULL)) ERR;
+      if (extended_format != expected_extended_format) ERR;
+   }
+
+   if (nc_inq_format_extended(ncid, &extended_format, &mode)) ERR;
+   if (mode != expected_mode) ERR;
+   if (extended_format != expected_extended_format) ERR;
+
+   /* Nothing to do with inq_format, but let's check the base_pe
+    * functions. */
+   if (expected_format == NC_FORMAT_CLASSIC || expected_format == NC_FORMAT_64BIT_OFFSET ||
+       expected_format == NC_FORMAT_CDF5) {
+      if (nc_set_base_pe(ncid, 0)) ERR;
+      if (nc_inq_base_pe(ncid, NULL)) ERR;
+   } else {
+      if (nc_set_base_pe(ncid, 0) != NC_ENOTNC3) ERR;
+      if (nc_inq_base_pe(ncid, NULL) != NC_ENOTNC3) ERR;
+   }
+
+   return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+   printf("\n*** Testing netcdf format functions.\n");
+   {
+      int ncid;
+      int expected_mode;
+      int expected_extended_format;
+      char file_name[NC_MAX_NAME + 1];
+      int f;
+      int format[MAX_NUM_FORMATS];
+      int num_formats;
+
+      /* How many formats to be tested? */
+      determine_test_formats(&num_formats, format);
+
+      for (f = 0; f < num_formats; f++)
+      {
+         printf("*** testing nc_inq_format() and nc_inq_format_extended() with format %d...", format[f]);
+         sprintf(file_name, "%s_%d.nc", FILE_NAME_BASE, format[f]);
+
+         /* Set up test. */
+         switch (format[f]) {
+         case NC_FORMAT_CLASSIC:
+            expected_extended_format = NC_FORMATX_NC3;
+            expected_mode = 0;
+            break;
+         case NC_FORMAT_64BIT_OFFSET:
+            expected_extended_format = NC_FORMATX_NC3;
+            expected_mode = NC_64BIT_OFFSET;            
+            break;
+         case NC_FORMAT_CDF5:
+            expected_extended_format = NC_FORMATX_NC3;
+            expected_mode = NC_CDF5;            
+            break;
+         case NC_FORMAT_NETCDF4:
+            expected_extended_format = NC_FORMATX_NC4;
+            expected_mode = NC_NETCDF4;            
+            break;
+         case NC_FORMAT_NETCDF4_CLASSIC:
+            expected_extended_format = NC_FORMATX_NC4;
+            expected_mode = NC_NETCDF4|NC_CLASSIC_MODEL;            
+            break;
+         }
+         if (nc_set_default_format(format[f], NULL)) ERR;
+
+         /* Create a file. */
+         if (nc_create(file_name, 0, &ncid)) ERR;
+         if (check_inq_format(ncid, format[f], expected_extended_format, expected_mode)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         /* Re-open the file and check it again. */
+         if (nc_open(file_name, 0, &ncid)) ERR;
+         /* Classic flag is not set on mode in nc_open(). Not sure if
+          * this is a bug or not. */
+         if (format[f] == NC_FORMAT_NETCDF4_CLASSIC)
+            expected_mode = NC_NETCDF4;
+         if (check_inq_format(ncid, format[f], expected_extended_format, expected_mode)) ERR;
+         if (nc_close(ncid)) ERR;
+         SUMMARIZE_ERR;
+      } /* next format */
+   }
+   FINAL_RESULTS;
+}
diff --git a/nc_test/tst_global_fillval.c b/nc_test/tst_global_fillval.c
index b2bd997..5058eb7 100644
--- a/nc_test/tst_global_fillval.c
+++ b/nc_test/tst_global_fillval.c
@@ -9,55 +9,64 @@
 
    * https://github.com/Unidata/netcdf-c/issues/388
    * https://github.com/Unidata/netcdf-c/pull/389
-*/
+
+   Modified by Ed Hartnett, Ward Fisher, see:
+   https://github.com/Unidata/netcdf-c/issues/392
+   */
 
 #include "config.h"
 #include <nc_tests.h>
-#include <stdio.h>
-#include <netcdf.h>
-
-#ifdef USE_CDF5
-#define NUMFORMATS 5
-#else
-#define NUMFORMATS 4
-#endif
+#include "err_macros.h"
 
 #define FILE_NAME "tst_global_fillval.nc"
 
-#define ERR {if(err!=NC_NOERR){printf("Error at line %d: %s\n",__LINE__,nc_strerror(err)); toterrs++; break;}}
+
 int
 main(int argc, char **argv)
 {
-    int i, ncid, cmode, err, fillv=9;
-    int toterrs = 0;
-    int formats[NUMFORMATS]={0,
-                             NC_64BIT_OFFSET,
+    printf("*** testing proper elatefill return...");
+    {
+
+	int n = 0;
+    int i;
+    int num_formats = 2;
+    int *formats = NULL;
+	/* Determine how many formats are in use. */
+
+#ifdef USE_NETCDF4
+    num_formats += 2;
+#endif
+
 #ifdef USE_CDF5
-                             NC_64BIT_DATA,
+    num_formats++;
 #endif
-                             NC_NETCDF4,
-                             NC_CLASSIC_MODEL | NC_NETCDF4};
-    char *formatnames[NUMFORMATS]={"CDF-1",
-                                   "CDF-2",
+
+    formats = malloc(sizeof(int)*num_formats);
+
+
+	formats[n++] = 0;
+	formats[n++] = NC_64BIT_OFFSET;
 #ifdef USE_CDF5
-                                   "CDF-5",
+	formats[n++] = NC_64BIT_DATA;
+#endif
+#ifdef USE_NETCDF4
+	formats[n++] = NC_NETCDF4;
+	formats[n++] = NC_CLASSIC_MODEL | NC_NETCDF4;
 #endif
-                                   "NETCDF4",
-                                   "CLASSIC_MODEL"};
 
-    for (i=0; i<NUMFORMATS; i++) {
-        cmode = NC_CLOBBER | formats[i];
-        err = nc_create(FILE_NAME, cmode, &ncid); ERR
+	for (i = 0; i < num_formats; i++)
+	{
 
-        err = nc_put_att_int(ncid, NC_GLOBAL, "_FillValue", NC_INT, 1, &fillv);
-        if (err != 0) {
-          toterrs++;
-          printf("%13s Error at line %d: expecting 0 but got %d\n",
-                   formatnames[i],__LINE__,err);
-        }
-        err = nc_close(ncid); ERR;
+      int ncid, cmode, fillv = 9;
+      cmode = NC_CLOBBER | formats[i];
+      if (nc_create(FILE_NAME, cmode, &ncid)) ERR;
+      if (nc_put_att_int(ncid, NC_GLOBAL, "_FillValue", NC_INT, 1, &fillv)) ERR;
+      if (nc_close(ncid)) ERR;
 
+	}
+    free(formats);
     }
-    printf("Total errors: %d\n",toterrs);
-    return toterrs;
+
+    SUMMARIZE_ERR;
+    FINAL_RESULTS;
 }
diff --git a/nc_test/tst_inq_type.c b/nc_test/tst_inq_type.c
index c0f0ccc..8bd0233 100644
--- a/nc_test/tst_inq_type.c
+++ b/nc_test/tst_inq_type.c
@@ -22,144 +22,166 @@
 
 #define FILE_NAME "tst_inq_type.nc"
 
-void
-check_err(const int stat, const int line, const char *file) {
-   if (stat != NC_NOERR) {
-      (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
-      fflush(stderr);
-      exit(1);
-   }
-}
-
-
 int test_type_should_fail(int ncid, int type, char* tstring) {
 
-  printf("\t* Testing Type (Should Fail) %s:\t",tstring);
-  if(!nc_inq_type(ncid,type,NULL,NULL)) ERR;
-  else printf("expected failure.\n");
+   printf("\t* Testing Type (Should Fail) %s:\t",tstring);
+   if(!nc_inq_type(ncid,type,NULL,NULL)) ERR;
+   else printf("expected failure.\n");
 
-  return 0;
+   return 0;
 }
 
 int test_type(int ncid, int type, char* tstring) {
 
-  printf("\t* Testing Type %s:\t",tstring);
-  if(nc_inq_type(ncid,type,NULL,NULL)) ERR;
-  else printf("success.\n");
+   printf("\t* Testing Type %s:\t",tstring);
+   if(nc_inq_type(ncid,type,NULL,NULL)) ERR;
+   else printf("success.\n");
 
-  return 0;
+   return 0;
 }
 
-
-
 int main(int argc, char **argv) {
 
-  int ncid=0;
-
-  {
-    printf("\n* Testing nc_inq_type with netcdf-3\n");
-
-    if(nc_create(FILE_NAME,NC_CLOBBER,&ncid)) ERR;
-
-    test_type(ncid, NC_BYTE,"NC_BYTE");
-    test_type(ncid, NC_CHAR,"NC_CHAR");
-    test_type(ncid, NC_SHORT,"NC_SHORT");
-    test_type(ncid, NC_INT,"NC_INT");
-    test_type(ncid, NC_LONG,"NC_LONG");
-    test_type(ncid, NC_FLOAT,"NC_FLOAT");
-    test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
-
-    /* Not Valid for Classic */
-    /* Valid now, see https://github.com/Unidata/netcdf-c/issues/240 for more
-       information. The types are not valid for use in Classic,
-       but nc_inq_type should return valid info. */
-    test_type(ncid, NC_UBYTE,"NC_UBYTE");
-    test_type(ncid, NC_USHORT,"NC_USHORT");
-    test_type(ncid, NC_UINT,"NC_UINT");
-    test_type(ncid, NC_INT64,"NC_INT64");
-    test_type(ncid, NC_UINT64,"NC_UINT64");
-    test_type(ncid, NC_STRING,"NC_STRING");
-
-    /* Invoke a true negative */
-    test_type_should_fail(ncid, 9999, "NC_GARBAGE");
-    test_type_should_fail(ncid, -1, "NC_GARBAGE_NEGATIVE");
-
-
-    if(nc_close(ncid)) ERR;
-  }
-
-  {
-    printf("\n* Testing nc_inq_type with CDF5\n");
-
-    if(nc_create(FILE_NAME,NC_CLOBBER|NC_CDF5,&ncid)) ERR;
-
-    test_type(ncid, NC_BYTE,"NC_BYTE");
-    test_type(ncid, NC_CHAR,"NC_CHAR");
-    test_type(ncid, NC_SHORT,"NC_SHORT");
-    test_type(ncid, NC_INT,"NC_INT");
-    test_type(ncid, NC_LONG,"NC_LONG");
-    test_type(ncid, NC_FLOAT,"NC_FLOAT");
-    test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
-    test_type(ncid, NC_UBYTE,"NC_UBYTE");
-    test_type(ncid, NC_USHORT,"NC_USHORT");
-    test_type(ncid, NC_UINT,"NC_UINT");
-    test_type(ncid, NC_INT64,"NC_INT64");
-    test_type(ncid, NC_UINT64,"NC_UINT64");
-    test_type(ncid, NC_STRING,"NC_STRING");
-
-    if(nc_close(ncid)) ERR;
-  }
+   int ncid=0;
+
+   printf("\n* Testing nc_inq_type with netcdf-3\n");
+   {
+      if(nc_create(FILE_NAME,NC_CLOBBER,&ncid)) ERR;
+
+      test_type(ncid, NC_BYTE,"NC_BYTE");
+      test_type(ncid, NC_CHAR,"NC_CHAR");
+      test_type(ncid, NC_SHORT,"NC_SHORT");
+      test_type(ncid, NC_INT,"NC_INT");
+      test_type(ncid, NC_LONG,"NC_LONG");
+      test_type(ncid, NC_FLOAT,"NC_FLOAT");
+      test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
+
+      /* Not Valid for Classic */
+      /* Valid now, see https://github.com/Unidata/netcdf-c/issues/240 for more
+	 information. The types are not valid for use in Classic,
+	 but nc_inq_type should return valid info. */
+      test_type(ncid, NC_UBYTE,"NC_UBYTE");
+      test_type(ncid, NC_USHORT,"NC_USHORT");
+      test_type(ncid, NC_UINT,"NC_UINT");
+      test_type(ncid, NC_INT64,"NC_INT64");
+      test_type(ncid, NC_UINT64,"NC_UINT64");
+      test_type(ncid, NC_STRING,"NC_STRING");
+
+      /* Invoke a true negative */
+      test_type_should_fail(ncid, 9999, "NC_GARBAGE");
+      test_type_should_fail(ncid, -1, "NC_GARBAGE_NEGATIVE");
+
+      if(nc_close(ncid)) ERR;
+
+      /* Reopen file to check that we can. */
+      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_create(FILE_NAME, NC_WRITE, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
+
+#ifdef ENABLE_CDF5
+   printf("\n* Testing nc_inq_type with CDF5\n");
+   {
+      if(nc_create(FILE_NAME,NC_CLOBBER|NC_CDF5,&ncid)) ERR;
+
+      test_type(ncid, NC_BYTE,"NC_BYTE");
+      test_type(ncid, NC_CHAR,"NC_CHAR");
+      test_type(ncid, NC_SHORT,"NC_SHORT");
+      test_type(ncid, NC_INT,"NC_INT");
+      test_type(ncid, NC_LONG,"NC_LONG");
+      test_type(ncid, NC_FLOAT,"NC_FLOAT");
+      test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
+      test_type(ncid, NC_UBYTE,"NC_UBYTE");
+      test_type(ncid, NC_USHORT,"NC_USHORT");
+      test_type(ncid, NC_UINT,"NC_UINT");
+      test_type(ncid, NC_INT64,"NC_INT64");
+      test_type(ncid, NC_UINT64,"NC_UINT64");
+      test_type(ncid, NC_STRING,"NC_STRING");
+
+      if(nc_close(ncid)) ERR;
+
+      /* Reopen file to check that we can. */
+      if (nc_open(FILE_NAME, NC_CDF5, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
+#endif /* ENABLE_CDF5 */
 
 #ifdef USE_NETCDF4
-
-  {
-    printf("\n* Testing nc_inq_type with netcdf-4 + Classic Model\n");
-
-    if(nc_create(FILE_NAME,NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL,&ncid)) ERR;
-
-    test_type(ncid, NC_BYTE,"NC_BYTE");
-    test_type(ncid, NC_CHAR,"NC_CHAR");
-    test_type(ncid, NC_SHORT,"NC_SHORT");
-    test_type(ncid, NC_INT,"NC_INT");
-    test_type(ncid, NC_LONG,"NC_LONG");
-    test_type(ncid, NC_FLOAT,"NC_FLOAT");
-    test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
-    test_type(ncid, NC_UBYTE,"NC_UBYTE");
-    test_type(ncid, NC_USHORT,"NC_USHORT");
-    test_type(ncid, NC_UINT,"NC_UINT");
-    test_type(ncid, NC_INT64,"NC_INT64");
-    test_type(ncid, NC_UINT64,"NC_UINT64");
-    test_type(ncid, NC_STRING,"NC_STRING");
-
-
-    if(nc_close(ncid)) ERR;
-  }
-
-  {
-    printf("\n* Testing nc_inq_type with netcdf-4\n");
-
-    if(nc_create(FILE_NAME,NC_CLOBBER|NC_NETCDF4,&ncid)) ERR;
-
-    test_type(ncid, NC_BYTE,"NC_BYTE");
-    test_type(ncid, NC_CHAR,"NC_CHAR");
-    test_type(ncid, NC_SHORT,"NC_SHORT");
-    test_type(ncid, NC_INT,"NC_INT");
-    test_type(ncid, NC_LONG,"NC_LONG");
-    test_type(ncid, NC_FLOAT,"NC_FLOAT");
-    test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
-    test_type(ncid, NC_UBYTE,"NC_UBYTE");
-    test_type(ncid, NC_USHORT,"NC_USHORT");
-    test_type(ncid, NC_UINT,"NC_UINT");
-    test_type(ncid, NC_INT64,"NC_INT64");
-    test_type(ncid, NC_UINT64,"NC_UINT64");
-    test_type(ncid, NC_STRING,"NC_STRING");
-    if(nc_close(ncid)) ERR;
-  }
+   printf("\n* Testing nc_inq_type with netcdf-4 + Classic Model\n");
+   {
+      if(nc_create(FILE_NAME,NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL,&ncid)) ERR;
+
+      test_type(ncid, NC_BYTE,"NC_BYTE");
+      test_type(ncid, NC_CHAR,"NC_CHAR");
+      test_type(ncid, NC_SHORT,"NC_SHORT");
+      test_type(ncid, NC_INT,"NC_INT");
+      test_type(ncid, NC_LONG,"NC_LONG");
+      test_type(ncid, NC_FLOAT,"NC_FLOAT");
+      test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
+      test_type(ncid, NC_UBYTE,"NC_UBYTE");
+      test_type(ncid, NC_USHORT,"NC_USHORT");
+      test_type(ncid, NC_UINT,"NC_UINT");
+      test_type(ncid, NC_INT64,"NC_INT64");
+      test_type(ncid, NC_UINT64,"NC_UINT64");
+      test_type(ncid, NC_STRING,"NC_STRING");
+
+      if(nc_close(ncid)) ERR;
+
+      /* Re-open file to be sure we can. */
+      if (nc_open(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, NC_CLASSIC_MODEL, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
+
+   printf("\n* Testing nc_inq_type with netcdf-4\n");
+   {
+
+      if(nc_create(FILE_NAME,NC_CLOBBER|NC_NETCDF4,&ncid)) ERR;
+
+      test_type(ncid, NC_BYTE,"NC_BYTE");
+      test_type(ncid, NC_CHAR,"NC_CHAR");
+      test_type(ncid, NC_SHORT,"NC_SHORT");
+      test_type(ncid, NC_INT,"NC_INT");
+      test_type(ncid, NC_LONG,"NC_LONG");
+      test_type(ncid, NC_FLOAT,"NC_FLOAT");
+      test_type(ncid, NC_DOUBLE,"NC_DOUBLE");
+      test_type(ncid, NC_UBYTE,"NC_UBYTE");
+      test_type(ncid, NC_USHORT,"NC_USHORT");
+      test_type(ncid, NC_UINT,"NC_UINT");
+      test_type(ncid, NC_INT64,"NC_INT64");
+      test_type(ncid, NC_UINT64,"NC_UINT64");
+      test_type(ncid, NC_STRING,"NC_STRING");
+      if(nc_close(ncid)) ERR;
+
+      /* Re-open file to be sure we can. */
+      if (nc_open(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
 
 #endif // USE_NETCDF4
 
-  printf("* Finished.\n");
+   printf("* Finished.\n");
 
-  SUMMARIZE_ERR;
-  FINAL_RESULTS;
+   FINAL_RESULTS;
 }
+
diff --git a/nc_test/tst_max_var_dims.c b/nc_test/tst_max_var_dims.c
new file mode 100644
index 0000000..3157630
--- /dev/null
+++ b/nc_test/tst_max_var_dims.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <netcdf.h>
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line %d in %s: %s\n", __LINE__,__FILE__, nc_strerror(err));nerrs++;}}
+
+#define EXP_ERR(exp,err) { \
+    if (err != exp) { \
+        nerrs++; \
+        printf("Error at line %d in %s: expecting %s but got %d\n", \
+        __LINE__,__FILE__,#exp, err); \
+    } \
+}
+
+int main(int argc, char *argv[])
+{
+    int i, err, nerrs=0, ncid, dimid[NC_MAX_VAR_DIMS+2], varid;
+
+    err = nc_create("tst_max_var_dims.nc", NC_CLOBBER, &ncid); ERR;
+    err = nc_def_dim(ncid, "dim0", NC_UNLIMITED, &dimid[0]); ERR;
+    err = nc_def_dim(ncid, "dim1", 1, &dimid[1]); ERR;
+
+    for (i=2; i<NC_MAX_VAR_DIMS+2; i++) dimid[i] = dimid[1];
+
+    err = nc_def_var(ncid, "v0", NC_INT, NC_MAX_VAR_DIMS+1, &dimid[0], &varid);
+    EXP_ERR(NC_EMAXDIMS,err)
+
+    err = nc_def_var(ncid, "v1", NC_INT, NC_MAX_VAR_DIMS+1, &dimid[1], &varid);
+    EXP_ERR(NC_EMAXDIMS,err)
+
+    err = nc_set_fill(ncid, NC_NOFILL, NULL); ERR
+    err = nc_close(ncid); ERR
+    return (nerrs > 0);
+}
+
diff --git a/nc_test/tst_misc.c b/nc_test/tst_misc.c
index dc9310f..0c480aa 100644
--- a/nc_test/tst_misc.c
+++ b/nc_test/tst_misc.c
@@ -61,8 +61,30 @@ main(int argc, char **argv)
    }
 
    SUMMARIZE_ERR;
+#ifndef USE_NETCDF4   
+   printf("*** Trying to create netCDF-4 file without netCDF-4...");
+   {
+       int ncid;
+       
+       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid) != NC_ENOTBUILT)
+	   ERR;
+   }
+   SUMMARIZE_ERR;
+#endif /* USE_NETCDF4 undefined */
+#ifndef USE_DISKLESS   
+   printf("*** Trying to create diskless file without diskless...");
+   {
+       int ncid;
+       
+       if (nc_create(FILE_NAME, NC_DISKLESS, &ncid) != NC_ENOTBUILT)
+	   ERR;
+   }
+   SUMMARIZE_ERR;
+#endif /* USE_DISKLESS undefined */
+   
 #ifdef TEST_PNETCDF
    MPI_Finalize();
 #endif
+   
    FINAL_RESULTS;
 }
diff --git a/nc_test/tst_parallel2.c b/nc_test/tst_parallel2.c
index 99d4be3..92c271d 100644
--- a/nc_test/tst_parallel2.c
+++ b/nc_test/tst_parallel2.c
@@ -15,6 +15,8 @@
 #include <mpe.h>
 #endif /* USE_MPE */
 
+#undef DEBUG
+
 #define FILE_NAME "tst_parallel2.nc"
 #define NDIMS 3
 #define DIMSIZE 8
@@ -54,7 +56,9 @@ main(int argc, char **argv)
     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
     MPI_Get_processor_name(mpi_name, &mpi_namelen);
-    /*printf("mpi_name: %s size: %d rank: %d\n", mpi_name, mpi_size, mpi_rank);*/
+#ifdef DEBUG
+    printf("mpi_name: %s size: %d rank: %d\n", mpi_name, mpi_size, mpi_rank);
+#endif
 
     /* Must be able to evenly divide my slabs between processors. */
     if (NUM_SLABS % mpi_size != 0)
@@ -85,12 +89,14 @@ main(int argc, char **argv)
     MPE_Log_event(s_init, 0, "start init");
 #endif /* USE_MPE */
 
-/*     if (!mpi_rank) */
-/*     { */
-/*        printf("\n*** Testing parallel I/O some more.\n"); */
-/*        printf("*** writing a %d x %d x %d file from %d processors...\n",  */
-/*               NUM_SLABS, DIMSIZE, DIMSIZE, mpi_size); */
-/*     } */
+#ifdef DEBUG
+    if (!mpi_rank)
+    {
+       printf("\n*** Testing parallel I/O some more.\n");
+       printf("*** writing a %d x %d x %d file from %d processors...\n",
+              NUM_SLABS, DIMSIZE, DIMSIZE, mpi_size);
+    }
+#endif
 
     /* We will write the same slab over and over. */
     for (i = 0; i < DIMSIZE * DIMSIZE; i++)
@@ -103,6 +109,9 @@ main(int argc, char **argv)
 
     /* Create a parallel netcdf-4 file. */
     sprintf(file_name, "%s/%s", TEMP_LARGE, FILE_NAME);
+#ifdef DEBUG
+    fprintf(stderr,"create: file_name=%s\n",file_name);
+#endif
     if (nc_create_par(file_name, NC_PNETCDF, comm, info, &ncid)) ERR;
 
     /* A global attribute holds the number of processors that created
@@ -168,6 +177,9 @@ main(int argc, char **argv)
 #endif /* USE_MPE */
 
     /* Reopen the file and check it. */
+#ifdef DEBUG
+    fprintf(stderr,"open: file_name=%s\n",file_name);
+#endif
     if (nc_open_par(file_name, NC_NOWRITE|NC_PNETCDF, comm, info, &ncid)) ERR;
     if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
     if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 || 
@@ -209,16 +221,20 @@ main(int argc, char **argv)
     MPE_Log_event(e_close, 0, "end close file");
 #endif /* USE_MPE */
 
-    /* Delete this large file. */
-    remove(file_name); 
+    MPI_Barrier(MPI_COMM_WORLD);
+    if (mpi_rank == 0)
+	remove(file_name);
 
     /* Shut down MPI. */
     MPI_Finalize();
 
-/*     if (!mpi_rank) */
-/*     { */
-/*        SUMMARIZE_ERR; */
-/*        FINAL_RESULTS; */
-/*     } */
+#ifdef DEBUG
+    if (!mpi_rank)
+    {
+       SUMMARIZE_ERR;
+       FINAL_RESULTS;
+    }
+#endif
+
     return total_err;
 }
diff --git a/nc_test/tst_utf8_phrases.c b/nc_test/tst_utf8_phrases.c
index 7a9478f..29ec68c 100644
--- a/nc_test/tst_utf8_phrases.c
+++ b/nc_test/tst_utf8_phrases.c
@@ -7,7 +7,6 @@
 #include <config.h>
 #include <stdlib.h>
 #include <nc_tests.h>
-#include "err_macros.h"
 #include <netcdf.h>
 #include <string.h>
 
@@ -280,7 +279,7 @@ static int
 test(const struct Test* tests, const char* title)
 {
     int status = NC_NOERR;
-    int i,failures = 0;
+    int failures = 0;
     const struct Test* p;
 
     fprintf(stderr,"Testing %s...\n",title);
@@ -318,9 +317,12 @@ test(const struct Test* tests, const char* title)
 	    }
 	}
 	pf = "Pass";
+	free(normal);
 fail:
         fprintf(stderr,"%s: %s %s\n",pf,id,description);
         fflush(stderr);
+	free(id);
+	free(description);
     }
     return failures;
 }
@@ -328,9 +330,7 @@ fail:
 int
 main(int argc, char** argv)
 {
-    int i, status;
     int failures = 0;
-    int tstcnt = 0;
 
     printf("\n Testing UTF-8 sequences.\n");
     failures += test(utf8currency,"Currencies");
diff --git a/nc_test/tst_utf8_validate.c b/nc_test/tst_utf8_validate.c
index c7b53b1..4d7fa7b 100644
Binary files a/nc_test/tst_utf8_validate.c and b/nc_test/tst_utf8_validate.c differ
diff --git a/nc_test/util.c b/nc_test/util.c
index 33b5323..d3cb4f0 100644
--- a/nc_test/util.c
+++ b/nc_test/util.c
@@ -21,10 +21,6 @@ int
 inRange(const double value, const nc_type xtype)
 {
   switch (xtype) {
-    double min = 0.0;
-    double max = 0.0;
-
-
   case NC_CHAR:   return value >= X_CHAR_MIN   && value <= X_CHAR_MAX;
   case NC_BYTE:   return value >= X_BYTE_MIN   && value <= X_BYTE_MAX;
   case NC_SHORT:  return value >= X_SHORT_MIN  && value <= X_SHORT_MAX;
@@ -1252,14 +1248,14 @@ char* nc_err_code_name(int err)
         case (NC_ENOTINDEFINE):			return "NC_ENOTINDEFINE";
         case (NC_EINDEFINE):			return "NC_EINDEFINE";
         case (NC_EINVALCOORDS):			return "NC_EINVALCOORDS";
-        case (NC_EMAXDIMS):			return "NC_EMAXDIMS";
+        case (NC_EMAXDIMS):			return "NC_EMAXDIMS"; /* not enforced after 4.5.0 */
         case (NC_ENAMEINUSE):			return "NC_ENAMEINUSE";
         case (NC_ENOTATT):			return "NC_ENOTATT";
-        case (NC_EMAXATTS):			return "NC_EMAXATTS";
+        case (NC_EMAXATTS):			return "NC_EMAXATTS"; /* not enforced after 4.5.0 */
         case (NC_EBADTYPE):			return "NC_EBADTYPE";
         case (NC_EBADDIM):			return "NC_EBADDIM";
         case (NC_EUNLIMPOS):			return "NC_EUNLIMPOS";
-        case (NC_EMAXVARS):			return "NC_EMAXVARS";
+        case (NC_EMAXVARS):			return "NC_EMAXVARS"; /* not enforced after 4.5.0 */
         case (NC_ENOTVAR):			return "NC_ENOTVAR";
         case (NC_EGLOBAL):			return "NC_EGLOBAL";
         case (NC_ENOTNC):			return "NC_ENOTNC";
@@ -1323,7 +1319,8 @@ char* nc_err_code_name(int err)
         case (NC_EDISKLESS):			return "NC_EDISKLESS";
         case (NC_ECANTEXTEND):			return "NC_ECANTEXTEND";
         case (NC_EMPI):				return "NC_EMPI";
-        // case (NC_EURL):				return "NC_EURL";
+    case (NC_ENULLPAD):             return "NC_NULLPAD";
+          // case (NC_EURL):				return "NC_EURL";
         // case (NC_ECONSTRAINT):			return "NC_ECONSTRAINT";
 #ifdef USE_PNETCDF
         case (NC_ESMALL):			return "NC_ESMALL";
diff --git a/nc_test4/CMakeLists.txt b/nc_test4/CMakeLists.txt
index c64a632..a2ea6a3 100644
--- a/nc_test4/CMakeLists.txt
+++ b/nc_test4/CMakeLists.txt
@@ -1,16 +1,16 @@
 # Some extra tests
-SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars
-  tst_varms tst_unlim_vars tst_converts tst_converts2 tst_grps tst_grps2
-  tst_compounds tst_compounds2 tst_compounds3 tst_opaques tst_strings
-  tst_strings2 tst_interops tst_interops4 tst_interops6
-  tst_enums tst_coords tst_coords2 tst_coords3 tst_vars3 tst_vars4
-  tst_chunks tst_chunks2 tst_utf8 tst_fills tst_fills2 tst_fillbug
-  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_put_vars_two_unlim_dim tst_hdf5_file_compat tst_fill_attr_vanish
-  tst_rehash)
+SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4
+  tst_vars tst_varms tst_unlim_vars tst_converts tst_converts2
+  tst_grps tst_grps2 tst_compounds tst_compounds2 tst_compounds3
+  tst_opaques tst_strings tst_strings2 tst_interops tst_interops4
+  tst_interops6 tst_enums tst_coords tst_coords2 tst_coords3 tst_vars3
+  tst_vars4 tst_chunks tst_chunks2 tst_utf8 tst_fills tst_fills2
+  tst_fillbug tst_xplatform2 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_put_vars_two_unlim_dim
+  tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash tst_types)
+
 
 # Note, renamegroup needs to be compiled before run_grp_rename
 
@@ -19,6 +19,13 @@ IF(BUILD_UTILITIES)
   build_bin_test(renamegroup)
   add_sh_test(nc_test4 run_grp_rename)
   ADD_SH_TEST(nc_test4 tst_misc)
+  build_bin_test(test_filter)
+  build_bin_test(test_filter_misc)
+IF(ENABLE_FILTER_TESTING)
+  ADD_SH_TEST(nc_test4 tst_filter)
+  SET(NC4_TESTS ${NC4_TESTS} tst_filterparser)
+ENDIF(ENABLE_FILTER_TESTING)
+
 ENDIF(BUILD_UTILITIES)
 
 ##
@@ -42,8 +49,12 @@ IF(LARGE_FILE_TESTS)
 ENDIF()
 
 
-IF(USE_HDF4)
-  SET(NC4_TESTS ${NC4_TESTS} tst_interops2)
+IF(USE_SZIP)
+  BUILD_BIN_TEST(test_szip)
+  BUILD_BIN_TEST(h5testszip)
+  IF(BUILD_UTILITIES)
+    add_sh_test(nc_test4 tst_szip)
+  ENDIF()
 ENDIF()
 
 IF(BUILD_BENCHMARKS)
@@ -61,7 +72,7 @@ IF(BUILD_BENCHMARKS)
 ENDIF()
 
 # Copy some test files from current source dir to out-of-tree build dir.
-FILE(GLOB COPY_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.nc ${CMAKE_CURRENT_SOURCE_DIR}/*.sh ${CMAKE_CURRENT_SOURCE_DIR}/*.hdf4)
+FILE(GLOB COPY_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.nc ${CMAKE_CURRENT_SOURCE_DIR}/ref_bzip2.c ${CMAKE_CURRENT_SOURCE_DIR}/*.sh ${CMAKE_CURRENT_SOURCE_DIR}/*.hdf4 ${CMAKE_CURRENT_SOURCE_DIR}/*.h5 ${CMAKE_CURRENT_SOURCE_DIR}/*.cdl)
 FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
 IF(MSVC)
   FILE(COPY ${COPY_FILES} DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}/)
@@ -75,16 +86,18 @@ ENDFOREACH()
 # This must go after the 'foreach' stanza
 # immediately above this comment.
 IF(USE_HDF4_FILE_TESTS AND NOT MSVC)
+    add_bin_test_no_prefix(tst_interops2)
+    build_bin_test_no_prefix(tst_interops3)
     add_sh_test(nc_test4 run_get_hdf4_files)
-    add_bin_test(nc_test4 tst_interops3)
+    add_bin_test(nc_test4 tst_bug324)
     add_sh_test(nc_test4 tst_formatx_hdf4)
     build_bin_test(tst_chunk_hdf4)
     add_sh_test(nc_test4 run_chunk_hdf4)
     add_bin_test(nc_test4 tst_h4_lendian)
     add_sh_test(nc_test4 tst_hdf4_read_var)
+    SET_TESTS_PROPERTIES(nc_test4_tst_hdf4_read_var PROPERTIES DEPENDS tst_interops2)
 ENDIF()
 
-
 IF(TEST_PARALLEL4)
   build_bin_test(tst_mpi_parallel)
   build_bin_test(tst_parallel)
@@ -95,3 +108,7 @@ IF(TEST_PARALLEL4)
   build_bin_test(tst_simplerw_coll_r)
   add_sh_test(nc_test4 run_par_test)
 ENDIF()
+
+ADD_EXTRA_DIST(findplugin.in)
+
+ADD_SUBDIRECTORY(hdf5plugins)
diff --git a/nc_test4/Make0 b/nc_test4/Make0
index f354861..9c7a0c9 100644
--- a/nc_test4/Make0
+++ b/nc_test4/Make0
@@ -1,23 +1,30 @@
 # Test c output
-T=tst_misc
+T=test_filter_misc
+#SRC=hdf5plugins/H5Zmisc.c
+
 #CMD=valgrind --leak-check=full
 CMD=gdb --args
 
+#FILTER=H5Zmisc
+#FILTEROBJ=hdf5plugins/${FILTER}.o
+
 #PAR=1
+#SZIP=1
 
-CFLAGS=-Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I.. -I../include
+CFLAGS = -Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I.. -I../include
+
+LDFLAGS = ../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lm
 
 ifdef PAR
 CC=mpicc
-#CC=/usr/local/bin/mpicc
-LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz  -ldl -lcurl -lpnetcdf -lmpich -lm
+LDFLAGS += -lmpich
 else
 CC=gcc
-#LDFLAGS=../liblib/.libs/libnetcdf.a  -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
-LDFLAGS=../liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz  -ldl -lm -lcurl
 endif
 
-#	cd .. ; ${MAKE} all
+ifdef SZIP
+LDFLAGS += -lsz -laec
+endif
 
 LLP=/usr/local/lib:${LD_LIBRARY_PATH}
 
@@ -27,7 +34,17 @@ all:: cmp
 
 cmp::
 	export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
-	${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}; \
+	${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${FILTEROBJ} ${LDFLAGS}
+
+filter::
+	${CC} ${CFLAGS} -c hdf5plugins/${FILTER}.c ${LDFLAGS}
 
 cpp::
 	${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
+
+H5=h5testszip
+EXT=testszip.nc
+h5::
+	export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
+	${CC} -o h5 ${CFLAGS} ${H5}.c ${SRC} ${LDFLAGS}; \
+	${CMD} ./h5 ${EXT}
diff --git a/nc_test4/Makefile.am b/nc_test4/Makefile.am
index b6250c3..7632fb2 100644
--- a/nc_test4/Makefile.am
+++ b/nc_test4/Makefile.am
@@ -3,44 +3,51 @@
 # See COPYRIGHT file for conditions of use.
 #
 # This entire directory will be skipped if netCDF-4 is not enabled.
-#
+# Ed Hartnett, Ward Fisher
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 include $(top_srcdir)/lib_flags.am
 
+# Un comment to use a more verbose test driver
+#SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+
+# Note which tests depend on other tests. necessary for make -j check
+TEST_EXTENSIONS = .sh
+extradir=
 # Link to our assembled library.
 AM_LDFLAGS += ${top_builddir}/liblib/libnetcdf.la
 
-# These are netCDF-4 test programs.
-NC4_TESTS = tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars	\
-tst_varms tst_unlim_vars tst_converts tst_converts2 tst_grps tst_grps2	\
-tst_compounds tst_compounds2 tst_compounds3 tst_opaques tst_strings	\
-tst_strings2 tst_interops tst_interops4 tst_interops5 tst_interops6	\
-tst_enums tst_coords tst_coords2 tst_coords3 tst_vars3 tst_vars4	\
-tst_chunks tst_chunks2 tst_utf8 tst_fills tst_fills2 tst_fillbug	\
-tst_xplatform tst_xplatform2 tst_h_atts2 tst_endian_fill tst_atts	\
+# These are netCDF-4 C test programs which are built and run.
+NC4_TESTS = tst_dims tst_dims2 tst_dims3 tst_files tst_files4		\
+tst_vars tst_varms tst_unlim_vars tst_converts tst_converts2 tst_grps	\
+tst_grps2 tst_compounds tst_compounds2 tst_compounds3 tst_opaques	\
+tst_strings tst_strings2 tst_interops tst_interops4 tst_interops5	\
+tst_interops6 tst_enums tst_coords tst_coords2 tst_coords3 tst_vars3	\
+tst_vars4 tst_chunks tst_chunks2 tst_utf8 tst_fills tst_fills2		\
+tst_fillbug tst_xplatform tst_xplatform2 tst_endian_fill tst_atts	\
 t_type cdm_sea_soundings tst_camrun tst_vl tst_atts1 tst_atts2		\
-tst_vars2 tst_files5 tst_files6 tst_sync         			\
-tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite 		\
-tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash
+tst_vars2 tst_files5 tst_files6 tst_sync tst_h_scalar tst_rename	\
+tst_h5_endians tst_atts_string_rewrite tst_hdf5_file_compat		\
+tst_fill_attr_vanish tst_rehash tst_filterparser tst_bug324 tst_types
 
 # Temporary I hope
 if !ISCYGWIN
 NC4_TESTS += tst_h_strbug tst_h_refs
 endif
 
-
+# Build test programs plus programs used in test scripts.
 check_PROGRAMS = $(NC4_TESTS) renamegroup tst_empty_vlen_unlim
+TESTS = $(NC4_TESTS)
 
 # Add these if large file tests are turned on.
 if LARGE_FILE_TESTS
 check_PROGRAMS += tst_large tst_large2
+TESTS += tst_large tst_large2
 endif
 
-TESTS = $(NC4_TESTS)
-
 if BUILD_UTILITIES
-	TESTS += run_grp_rename.sh tst_misc.sh
+TESTS += run_grp_rename.sh tst_misc.sh
 endif
 
 TESTS += run_empty_vlen_test.sh
@@ -51,17 +58,11 @@ check_PROGRAMS += tst_v2
 TESTS += tst_v2
 endif # BUILD_V2
 
-if LARGE_FILE_TESTS
-check_PROGRAMS += tst_large
-TESTS += tst_large
-endif # LARGE_FILE_TESTS
-
 # If benchmarks were turned on, build and run a bunch more tests.
 if BUILD_BENCHMARKS
 check_PROGRAMS += tst_create_files bm_file tst_chunks3 tst_ar4	\
 tst_ar4_3d tst_ar4_4d bm_many_objs tst_h_many_atts bm_many_atts	\
-tst_files2 tst_files3 tst_ar5 tst_h_files3 tst_mem tst_knmi     \
-bm_netcdf4_recs
+tst_files2 tst_files3 tst_ar5 tst_mem tst_knmi bm_netcdf4_recs
 
 bm_netcdf4_recs_SOURCES = bm_netcdf4_recs.c tst_utils.c
 bm_many_atts_SOURCES = bm_many_atts.c tst_utils.c
@@ -77,9 +78,8 @@ tst_knmi_SOURCES = tst_knmi.c tst_utils.c
 #WARNING: test_knmi depends on run_get_knmi_files.sh,
 # so they must appear in the appropriate order.
 TESTS += tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh	\
-run_bm_test2.sh run_tst_chunks.sh tst_files2 tst_files3	\
-tst_ar5 tst_h_files3 tst_mem                                            \
-run_get_knmi_files.sh tst_knmi
+run_bm_test2.sh run_tst_chunks.sh tst_files2 tst_files3 tst_ar5		\
+tst_mem run_get_knmi_files.sh tst_knmi
 
 # This will run a parallel I/O benchmark for parallel builds.
 if TEST_PARALLEL4
@@ -97,15 +97,39 @@ endif # BUILD_BENCHMARKS
 # These are the tests for HDF4.
 if USE_HDF4
 check_PROGRAMS += tst_interops2 tst_chunk_hdf4 tst_h4_lendian
-TESTS += tst_interops2  tst_formatx_hdf4.sh run_chunk_hdf4.sh tst_h4_lendian
+
+if BUILD_UTILITIES
+# This test script depends on ncdump.
+TESTS += tst_interops2 tst_formatx_hdf4.sh
+tst_formatx_hdf4.log: tst_interops2.log
+endif # BUILD_UTILITIES
+
+TESTS += run_chunk_hdf4.sh tst_h4_lendian
 if USE_HDF4_FILE_TESTS
 check_PROGRAMS += tst_interops3
-TESTS += run_get_hdf4_files.sh tst_interops3 tst_hdf4_read_var.sh
+TESTS += run_get_hdf4_files.sh tst_hdf4_read_var.sh
+
+tst_hdf4_read_var.log: tst_interops2.log
+
 endif # USE_HDF4_FILE_TESTS
-#tst_interops2_LDADD = ${lib_LTLIBRARIES} -lmfhdf -ldf -ljpeg -lhdf5_hl	\
-#-lhdf5 -lz
 endif # USE_HDF4
 
+# Szip Tests (requires ncdump)
+if USE_SZIP
+if BUILD_UTILITIES
+check_PROGRAMS += test_szip h5testszip
+TESTS += tst_szip.sh
+endif
+endif
+
+# Filter Tests (requires ncdump and ncgen)
+if ENABLE_FILTER_TESTING
+if BUILD_UTILITIES
+extra_PROGRAMS = test_filter test_filter_misc
+TESTS += tst_filter.sh
+endif
+endif
+
 # This will run a bunch of the test programs with valgrind, the memory
 # checking tool. (Valgrind must be present for this to work.)
 if USE_VALGRIND_TESTS
@@ -123,39 +147,46 @@ tst_parallel4 tst_nc4perf tst_mode tst_simplerw_coll_r
 TESTS += run_par_test.sh
 endif
 
-EXTRA_DIST = run_par_test.sh run_bm.sh run_bm_test1.sh run_bm_test2.sh	\
-run_bm_radar_2D.sh run_bm_radar_2D_compression1.sh run_par_bm_test.sh	\
-run_bm_elena.sh run_par_bm_radar_2D.sh run_bm_radar_2D_endianness1.sh	\
-run_tst_chunks.sh ref_chunks1.cdl ref_chunks2.cdl 			\
-run_get_hdf4_files.sh run_valgrind_tests.sh run_valgrind_tests2.sh	\
-run_bm_ar4.sh ref_tst_compounds.nc run_hdf4_valgrind_tests.sh		\
-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 \
-tst_h5_endians.c tst_h4_lendian.c tst_atts_string_rewrite.c \
-tst_put_vars_two_unlim_dim.c tst_empty_vlen_unlim.c run_empty_vlen_test.sh \
-ref_hdf5_compat1.nc ref_hdf5_compat2.nc ref_hdf5_compat3.nc tst_misc.sh \
-tdset.h5 tst_hdf4_read_var.sh ref_contiguous.hdf4 ref_chunked.hdf4
-
-
-CLEANFILES = tst_mpi_parallel.bin cdm_sea_soundings.nc bm_chunking.nc	\
-bm_radar.nc bm_radar1.nc radar_3d_compression_test.txt			\
-radar_3d_compression.txt radar_2d_compression.txt			\
-radar_3d_chunking.txt tst_floats_1D.cdl floats_1D_3.nc floats_1D.cdl	\
-tst_*.nc tst_floats2_*.cdl tst_ints2_*.cdl tst_shorts2_*.cdl		\
-tst_elena_*.cdl tst_simple*.cdl tst_chunks.cdl pr_A1.* tauu_A1.*	\
-usi_01.* thetau_01.* tst_*.nc tst_*.h5                                  \
-tst_grp_rename.cdl tst_grp_rename.nc tst_grp_rename.dmp ref_grp_rename.cdl \
-foo1.nc tst_interops2.h4 tst_h5_endians.nc tst_h4_lendian.h4 test.nc \
-tst_atts_string_rewrite.nc tst_empty_vlen_unlim.nc tst_empty_vlen_lim.nc \
-tst_parallel4_simplerw_coll.nc tst_fill_attr_vanish.nc tst_rehash.nc
+EXTRA_DIST = run_par_test.sh run_bm.sh run_bm_test1.sh                  \
+run_bm_test2.sh run_bm_radar_2D.sh run_bm_radar_2D_compression1.sh      \
+run_par_bm_test.sh run_bm_elena.sh run_par_bm_radar_2D.sh               \
+run_bm_radar_2D_endianness1.sh run_tst_chunks.sh ref_chunks1.cdl        \
+ref_chunks2.cdl run_get_hdf4_files.sh run_valgrind_tests.sh             \
+run_valgrind_tests2.sh run_bm_ar4.sh ref_tst_compounds.nc               \
+run_hdf4_valgrind_tests.sh 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 tst_h5_endians.c                  \
+tst_h4_lendian.c tst_atts_string_rewrite.c                              \
+tst_put_vars_two_unlim_dim.c tst_empty_vlen_unlim.c                     \
+run_empty_vlen_test.sh ref_hdf5_compat1.nc ref_hdf5_compat2.nc          \
+ref_hdf5_compat3.nc tst_misc.sh tdset.h5 tst_hdf4_read_var.sh           \
+ref_contiguous.hdf4 ref_chunked.hdf4 tst_szip.sh ref_szip.h5 ref_szip.cdl \
+tst_filter.sh bzip2.cdl filtered.cdl unfiltered.cdl ref_bzip2.c         \
+findplugin.in
+
+CLEANFILES = tst_mpi_parallel.bin cdm_sea_soundings.nc bm_chunking.nc   \
+bm_radar.nc bm_radar1.nc radar_3d_compression_test.txt                  \
+radar_3d_compression.txt radar_2d_compression.txt                       \
+radar_3d_chunking.txt tst_floats_1D.cdl floats_1D_3.nc floats_1D.cdl    \
+tst_*.nc tst_floats2_*.cdl tst_ints2_*.cdl tst_shorts2_*.cdl            \
+tst_elena_*.cdl tst_simple*.cdl tst_chunks.cdl pr_A1.* tauu_A1.*        \
+usi_01.* thetau_01.* tst_*.nc tst_*.h5 tst_grp_rename.cdl               \
+tst_grp_rename.nc tst_grp_rename.dmp ref_grp_rename.cdl foo1.nc         \
+tst_interops2.h4 tst_h5_endians.nc tst_h4_lendian.h4 test.nc            \
+tst_atts_string_rewrite.nc tst_empty_vlen_unlim.nc                      \
+tst_empty_vlen_lim.nc tst_parallel4_simplerw_coll.nc                    \
+tst_fill_attr_vanish.nc tst_rehash.nc testszip.nc test.h5               \
+szip_dump.cdl
+
+DISTCLEANFILES = findplugin.sh
 
 if USE_HDF4_FILE_TESTS
-DISTCLEANFILES = AMSR_E_L2_Rain_V10_200905312326_A.hdf	\
+DISTCLEANFILES += AMSR_E_L2_Rain_V10_200905312326_A.hdf	\
 AMSR_E_L3_DailyLand_V06_20020619.hdf			\
 MYD29.A2009152.0000.005.2009153124331.hdf		\
 MYD29.A2002185.0000.005.2007160150627.hdf		\
 MOD29.A2000055.0005.005.2006267200024.hdf
-
-
 endif # HDF4_FILE_TESTS
+
+SUBDIRS=hdf5plugins
diff --git a/nc_test4/Makefile.in b/nc_test4/Makefile.in
index 0631ba9..8c1b24d 100644
--- a/nc_test4/Makefile.in
+++ b/nc_test4/Makefile.in
@@ -19,7 +19,7 @@
 # See COPYRIGHT file for conditions of use.
 #
 # This entire directory will be skipped if netCDF-4 is not enabled.
-#
+# Ed Hartnett, Ward Fisher
 
 # This is part of the netCDF package.
 # Copyright 2005 University Corporation for Atmospheric Research/Unidata
@@ -28,6 +28,7 @@
 # Assemble the CPPFLAGS and LDFLAGS that point to all the needed
 # libraries for netCDF-4.
 #
+
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -105,66 +106,76 @@ host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
 
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
 # Temporary I hope
- at ISCYGWIN_FALSE@am__append_3 = tst_h_strbug tst_h_refs
+ at ISCYGWIN_FALSE@am__append_2 = tst_h_strbug tst_h_refs
 check_PROGRAMS = $(am__EXEEXT_2) renamegroup$(EXEEXT) \
 	tst_empty_vlen_unlim$(EXEEXT) $(am__EXEEXT_3) $(am__EXEEXT_4) \
 	$(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7) \
 	$(am__EXEEXT_8) $(am__EXEEXT_9)
+TESTS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__append_5) \
+	run_empty_vlen_test.sh $(am__EXEEXT_4) $(am__EXEEXT_10) \
+	$(am__append_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \
+	$(am__append_15) $(am__append_17) $(am__append_18) \
+	$(am__append_19) $(am__append_20) $(am__append_22)
 
 # Add these if large file tests are turned on.
+ at LARGE_FILE_TESTS_TRUE@am__append_3 = tst_large tst_large2
 @LARGE_FILE_TESTS_TRUE at am__append_4 = tst_large tst_large2
-TESTS = $(am__EXEEXT_2) run_empty_vlen_test.sh $(am__EXEEXT_4) \
-	$(am__EXEEXT_5) $(am__EXEEXT_10) $(am__append_11) \
-	$(am__EXEEXT_11) $(am__EXEEXT_12) $(am__append_16) \
-	$(am__append_17) $(am__append_19)
+ at BUILD_UTILITIES_TRUE@am__append_5 = run_grp_rename.sh tst_misc.sh
 
 # If the v2 API was built, add its test program.
- at BUILD_V2_TRUE@am__append_5 = tst_v2
 @BUILD_V2_TRUE at am__append_6 = tst_v2
- at LARGE_FILE_TESTS_TRUE@am__append_7 = tst_large
- at LARGE_FILE_TESTS_TRUE@am__append_8 = tst_large
+ at BUILD_V2_TRUE@am__append_7 = tst_v2
 
 # If benchmarks were turned on, build and run a bunch more tests.
- at BUILD_BENCHMARKS_TRUE@am__append_9 = tst_create_files bm_file tst_chunks3 tst_ar4	\
+ at BUILD_BENCHMARKS_TRUE@am__append_8 = tst_create_files bm_file tst_chunks3 tst_ar4	\
 @BUILD_BENCHMARKS_TRUE at tst_ar4_3d tst_ar4_4d bm_many_objs tst_h_many_atts bm_many_atts	\
- at BUILD_BENCHMARKS_TRUE@tst_files2 tst_files3 tst_ar5 tst_h_files3 tst_mem tst_knmi     \
- at BUILD_BENCHMARKS_TRUE@bm_netcdf4_recs
+ at BUILD_BENCHMARKS_TRUE@tst_files2 tst_files3 tst_ar5 tst_mem tst_knmi bm_netcdf4_recs
 
 
 #WARNING: test_knmi depends on run_get_knmi_files.sh,
 # so they must appear in the appropriate order.
- at BUILD_BENCHMARKS_TRUE@am__append_10 = tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh	\
- at BUILD_BENCHMARKS_TRUE@run_bm_test2.sh run_tst_chunks.sh tst_files2 tst_files3	\
- at BUILD_BENCHMARKS_TRUE@tst_ar5 tst_h_files3 tst_mem                                            \
- at BUILD_BENCHMARKS_TRUE@run_get_knmi_files.sh tst_knmi
+ at BUILD_BENCHMARKS_TRUE@am__append_9 = tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh	\
+ at BUILD_BENCHMARKS_TRUE@run_bm_test2.sh run_tst_chunks.sh tst_files2 tst_files3 tst_ar5		\
+ at BUILD_BENCHMARKS_TRUE@tst_mem run_get_knmi_files.sh tst_knmi
 
 
 # This will run a parallel I/O benchmark for parallel builds.
- at BUILD_BENCHMARKS_TRUE@@TEST_PARALLEL4_TRUE at am__append_11 = run_par_bm_test.sh
+ at BUILD_BENCHMARKS_TRUE@@TEST_PARALLEL4_TRUE at am__append_10 = run_par_bm_test.sh
 
 # These are the tests for HDF4.
- at USE_HDF4_TRUE@am__append_12 = tst_interops2 tst_chunk_hdf4 tst_h4_lendian
- at USE_HDF4_TRUE@am__append_13 = tst_interops2  tst_formatx_hdf4.sh run_chunk_hdf4.sh tst_h4_lendian
+ at USE_HDF4_TRUE@am__append_11 = tst_interops2 tst_chunk_hdf4 tst_h4_lendian
+
+# This test script depends on ncdump.
+ at BUILD_UTILITIES_TRUE@@USE_HDF4_TRUE at am__append_12 = tst_interops2 tst_formatx_hdf4.sh
+ at USE_HDF4_TRUE@am__append_13 = run_chunk_hdf4.sh tst_h4_lendian
 @USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at am__append_14 = tst_interops3
- at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at am__append_15 = run_get_hdf4_files.sh tst_interops3 tst_hdf4_read_var.sh
-#tst_interops2_LDADD = ${lib_LTLIBRARIES} -lmfhdf -ldf -ljpeg -lhdf5_hl	\
-#-lhdf5 -lz
+ at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at am__append_15 = run_get_hdf4_files.sh tst_hdf4_read_var.sh
+
+# Szip Tests (requires ncdump)
+ at BUILD_UTILITIES_TRUE@@USE_SZIP_TRUE at am__append_16 = test_szip h5testszip
+ at BUILD_UTILITIES_TRUE@@USE_SZIP_TRUE at am__append_17 = tst_szip.sh
+ at BUILD_UTILITIES_TRUE@@ENABLE_FILTER_TESTING_TRUE at extra_PROGRAMS = test_filter$(EXEEXT) \
+ at BUILD_UTILITIES_TRUE@@ENABLE_FILTER_TESTING_TRUE@	test_filter_misc$(EXEEXT)
+ at BUILD_UTILITIES_TRUE@@ENABLE_FILTER_TESTING_TRUE at am__append_18 = tst_filter.sh
 
 # This will run a bunch of the test programs with valgrind, the memory
 # checking tool. (Valgrind must be present for this to work.)
- at USE_VALGRIND_TESTS_TRUE@am__append_16 = run_valgrind_tests.sh run_valgrind_tests2.sh
- at USE_HDF4_TRUE@@USE_VALGRIND_TESTS_TRUE at am__append_17 = run_hdf4_valgrind_tests.sh
+ at USE_VALGRIND_TESTS_TRUE@am__append_19 = run_valgrind_tests.sh run_valgrind_tests2.sh
+ at USE_HDF4_TRUE@@USE_VALGRIND_TESTS_TRUE at am__append_20 = run_hdf4_valgrind_tests.sh
 
 # This are extra tests that will only be run if netcdf-4 is configured
 # with --enable-parallel-tests.
- at TEST_PARALLEL4_TRUE@am__append_18 = tst_mpi_parallel tst_parallel tst_parallel3	\
+ at TEST_PARALLEL4_TRUE@am__append_21 = tst_mpi_parallel tst_parallel tst_parallel3	\
 @TEST_PARALLEL4_TRUE at tst_parallel4 tst_nc4perf tst_mode tst_simplerw_coll_r
 
- at TEST_PARALLEL4_TRUE@am__append_19 = run_par_test.sh
+ at TEST_PARALLEL4_TRUE@am__append_22 = run_par_test.sh
+ at USE_HDF4_FILE_TESTS_TRUE@am__append_23 = AMSR_E_L2_Rain_V10_200905312326_A.hdf	\
+ at USE_HDF4_FILE_TESTS_TRUE@AMSR_E_L3_DailyLand_V06_20020619.hdf			\
+ at USE_HDF4_FILE_TESTS_TRUE@MYD29.A2009152.0000.005.2009153124331.hdf		\
+ at USE_HDF4_FILE_TESTS_TRUE@MYD29.A2002185.0000.005.2007160150627.hdf		\
+ at USE_HDF4_FILE_TESTS_TRUE@MOD29.A2000055.0005.005.2006267200024.hdf
+
 subdir = nc_test4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -176,7 +187,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = findplugin.sh
 CONFIG_CLEAN_VPATH_FILES = ref_hdf5_compat1.nc ref_hdf5_compat2.nc \
 	ref_hdf5_compat3.nc ref_chunked.hdf4 ref_contiguous.hdf4
 @ISCYGWIN_FALSE at am__EXEEXT_1 = tst_h_strbug$(EXEEXT) \
@@ -195,20 +206,20 @@ am__EXEEXT_2 = tst_dims$(EXEEXT) tst_dims2$(EXEEXT) tst_dims3$(EXEEXT) \
 	tst_vars4$(EXEEXT) tst_chunks$(EXEEXT) tst_chunks2$(EXEEXT) \
 	tst_utf8$(EXEEXT) tst_fills$(EXEEXT) tst_fills2$(EXEEXT) \
 	tst_fillbug$(EXEEXT) tst_xplatform$(EXEEXT) \
-	tst_xplatform2$(EXEEXT) tst_h_atts2$(EXEEXT) \
-	tst_endian_fill$(EXEEXT) tst_atts$(EXEEXT) t_type$(EXEEXT) \
-	cdm_sea_soundings$(EXEEXT) tst_camrun$(EXEEXT) tst_vl$(EXEEXT) \
-	tst_atts1$(EXEEXT) tst_atts2$(EXEEXT) tst_vars2$(EXEEXT) \
-	tst_files5$(EXEEXT) tst_files6$(EXEEXT) tst_sync$(EXEEXT) \
-	tst_h_scalar$(EXEEXT) tst_rename$(EXEEXT) \
-	tst_h5_endians$(EXEEXT) tst_atts_string_rewrite$(EXEEXT) \
-	tst_hdf5_file_compat$(EXEEXT) tst_fill_attr_vanish$(EXEEXT) \
-	tst_rehash$(EXEEXT) $(am__EXEEXT_1)
+	tst_xplatform2$(EXEEXT) tst_endian_fill$(EXEEXT) \
+	tst_atts$(EXEEXT) t_type$(EXEEXT) cdm_sea_soundings$(EXEEXT) \
+	tst_camrun$(EXEEXT) tst_vl$(EXEEXT) tst_atts1$(EXEEXT) \
+	tst_atts2$(EXEEXT) tst_vars2$(EXEEXT) tst_files5$(EXEEXT) \
+	tst_files6$(EXEEXT) tst_sync$(EXEEXT) tst_h_scalar$(EXEEXT) \
+	tst_rename$(EXEEXT) tst_h5_endians$(EXEEXT) \
+	tst_atts_string_rewrite$(EXEEXT) tst_hdf5_file_compat$(EXEEXT) \
+	tst_fill_attr_vanish$(EXEEXT) tst_rehash$(EXEEXT) \
+	tst_filterparser$(EXEEXT) tst_bug324$(EXEEXT) \
+	tst_types$(EXEEXT) $(am__EXEEXT_1)
 @LARGE_FILE_TESTS_TRUE at am__EXEEXT_3 = tst_large$(EXEEXT) \
 @LARGE_FILE_TESTS_TRUE@	tst_large2$(EXEEXT)
 @BUILD_V2_TRUE at am__EXEEXT_4 = tst_v2$(EXEEXT)
- at LARGE_FILE_TESTS_TRUE@am__EXEEXT_5 = tst_large$(EXEEXT)
- at BUILD_BENCHMARKS_TRUE@am__EXEEXT_6 = tst_create_files$(EXEEXT) \
+ at BUILD_BENCHMARKS_TRUE@am__EXEEXT_5 = tst_create_files$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	bm_file$(EXEEXT) tst_chunks3$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_ar4$(EXEEXT) tst_ar4_3d$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_ar4_4d$(EXEEXT) \
@@ -216,18 +227,23 @@ am__EXEEXT_2 = tst_dims$(EXEEXT) tst_dims2$(EXEEXT) tst_dims3$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_h_many_atts$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	bm_many_atts$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_files2$(EXEEXT) tst_files3$(EXEEXT) \
- at BUILD_BENCHMARKS_TRUE@	tst_ar5$(EXEEXT) tst_h_files3$(EXEEXT) \
- at BUILD_BENCHMARKS_TRUE@	tst_mem$(EXEEXT) tst_knmi$(EXEEXT) \
+ at BUILD_BENCHMARKS_TRUE@	tst_ar5$(EXEEXT) tst_mem$(EXEEXT) \
+ at BUILD_BENCHMARKS_TRUE@	tst_knmi$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	bm_netcdf4_recs$(EXEEXT)
- at USE_HDF4_TRUE@am__EXEEXT_7 = tst_interops2$(EXEEXT) \
+ at USE_HDF4_TRUE@am__EXEEXT_6 = tst_interops2$(EXEEXT) \
 @USE_HDF4_TRUE@	tst_chunk_hdf4$(EXEEXT) tst_h4_lendian$(EXEEXT)
- at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at am__EXEEXT_8 = tst_interops3$(EXEEXT)
+ at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at am__EXEEXT_7 = tst_interops3$(EXEEXT)
+ at BUILD_UTILITIES_TRUE@@USE_SZIP_TRUE at am__EXEEXT_8 =  \
+ at BUILD_UTILITIES_TRUE@@USE_SZIP_TRUE@	test_szip$(EXEEXT) \
+ at BUILD_UTILITIES_TRUE@@USE_SZIP_TRUE@	h5testszip$(EXEEXT)
 @TEST_PARALLEL4_TRUE at am__EXEEXT_9 = tst_mpi_parallel$(EXEEXT) \
 @TEST_PARALLEL4_TRUE@	tst_parallel$(EXEEXT) \
 @TEST_PARALLEL4_TRUE@	tst_parallel3$(EXEEXT) \
 @TEST_PARALLEL4_TRUE@	tst_parallel4$(EXEEXT) \
 @TEST_PARALLEL4_TRUE@	tst_nc4perf$(EXEEXT) tst_mode$(EXEEXT) \
 @TEST_PARALLEL4_TRUE@	tst_simplerw_coll_r$(EXEEXT)
+am__installdirs = "$(DESTDIR)$(extradir)"
+PROGRAMS = $(extra_PROGRAMS)
 am__bm_file_SOURCES_DIST = bm_file.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at am_bm_file_OBJECTS = bm_file.$(OBJEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_utils.$(OBJEXT)
@@ -258,12 +274,24 @@ bm_netcdf4_recs_LDADD = $(LDADD)
 cdm_sea_soundings_SOURCES = cdm_sea_soundings.c
 cdm_sea_soundings_OBJECTS = cdm_sea_soundings.$(OBJEXT)
 cdm_sea_soundings_LDADD = $(LDADD)
+h5testszip_SOURCES = h5testszip.c
+h5testszip_OBJECTS = h5testszip.$(OBJEXT)
+h5testszip_LDADD = $(LDADD)
 renamegroup_SOURCES = renamegroup.c
 renamegroup_OBJECTS = renamegroup.$(OBJEXT)
 renamegroup_LDADD = $(LDADD)
 t_type_SOURCES = t_type.c
 t_type_OBJECTS = t_type.$(OBJEXT)
 t_type_LDADD = $(LDADD)
+test_filter_SOURCES = test_filter.c
+test_filter_OBJECTS = test_filter.$(OBJEXT)
+test_filter_LDADD = $(LDADD)
+test_filter_misc_SOURCES = test_filter_misc.c
+test_filter_misc_OBJECTS = test_filter_misc.$(OBJEXT)
+test_filter_misc_LDADD = $(LDADD)
+test_szip_SOURCES = test_szip.c
+test_szip_OBJECTS = test_szip.$(OBJEXT)
+test_szip_LDADD = $(LDADD)
 am__tst_ar4_SOURCES_DIST = tst_ar4.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at am_tst_ar4_OBJECTS = tst_ar4.$(OBJEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_utils.$(OBJEXT)
@@ -294,6 +322,9 @@ tst_atts2_LDADD = $(LDADD)
 tst_atts_string_rewrite_SOURCES = tst_atts_string_rewrite.c
 tst_atts_string_rewrite_OBJECTS = tst_atts_string_rewrite.$(OBJEXT)
 tst_atts_string_rewrite_LDADD = $(LDADD)
+tst_bug324_SOURCES = tst_bug324.c
+tst_bug324_OBJECTS = tst_bug324.$(OBJEXT)
+tst_bug324_LDADD = $(LDADD)
 tst_camrun_SOURCES = tst_camrun.c
 tst_camrun_OBJECTS = tst_camrun.$(OBJEXT)
 tst_camrun_LDADD = $(LDADD)
@@ -386,6 +417,9 @@ tst_fills_LDADD = $(LDADD)
 tst_fills2_SOURCES = tst_fills2.c
 tst_fills2_OBJECTS = tst_fills2.$(OBJEXT)
 tst_fills2_LDADD = $(LDADD)
+tst_filterparser_SOURCES = tst_filterparser.c
+tst_filterparser_OBJECTS = tst_filterparser.$(OBJEXT)
+tst_filterparser_LDADD = $(LDADD)
 tst_grps_SOURCES = tst_grps.c
 tst_grps_OBJECTS = tst_grps.$(OBJEXT)
 tst_grps_LDADD = $(LDADD)
@@ -398,12 +432,6 @@ tst_h4_lendian_LDADD = $(LDADD)
 tst_h5_endians_SOURCES = tst_h5_endians.c
 tst_h5_endians_OBJECTS = tst_h5_endians.$(OBJEXT)
 tst_h5_endians_LDADD = $(LDADD)
-tst_h_atts2_SOURCES = tst_h_atts2.c
-tst_h_atts2_OBJECTS = tst_h_atts2.$(OBJEXT)
-tst_h_atts2_LDADD = $(LDADD)
-tst_h_files3_SOURCES = tst_h_files3.c
-tst_h_files3_OBJECTS = tst_h_files3.$(OBJEXT)
-tst_h_files3_LDADD = $(LDADD)
 am__tst_h_many_atts_SOURCES_DIST = tst_h_many_atts.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at am_tst_h_many_atts_OBJECTS =  \
 @BUILD_BENCHMARKS_TRUE@	tst_h_many_atts.$(OBJEXT) \
@@ -493,6 +521,9 @@ tst_strings2_LDADD = $(LDADD)
 tst_sync_SOURCES = tst_sync.c
 tst_sync_OBJECTS = tst_sync.$(OBJEXT)
 tst_sync_LDADD = $(LDADD)
+tst_types_SOURCES = tst_types.c
+tst_types_OBJECTS = tst_types.$(OBJEXT)
+tst_types_LDADD = $(LDADD)
 tst_unlim_vars_SOURCES = tst_unlim_vars.c
 tst_unlim_vars_OBJECTS = tst_unlim_vars.$(OBJEXT)
 tst_unlim_vars_LDADD = $(LDADD)
@@ -562,19 +593,20 @@ am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(bm_file_SOURCES) $(bm_many_atts_SOURCES) \
 	$(bm_many_objs_SOURCES) $(bm_netcdf4_recs_SOURCES) \
-	cdm_sea_soundings.c renamegroup.c t_type.c $(tst_ar4_SOURCES) \
-	$(tst_ar4_3d_SOURCES) $(tst_ar4_4d_SOURCES) tst_ar5.c \
-	tst_atts.c tst_atts1.c tst_atts2.c tst_atts_string_rewrite.c \
-	tst_camrun.c tst_chunk_hdf4.c tst_chunks.c tst_chunks2.c \
-	tst_chunks3.c tst_compounds.c tst_compounds2.c \
-	tst_compounds3.c tst_converts.c tst_converts2.c tst_coords.c \
-	tst_coords2.c tst_coords3.c tst_create_files.c tst_dims.c \
-	tst_dims2.c tst_dims3.c tst_empty_vlen_unlim.c \
-	tst_endian_fill.c tst_enums.c tst_files.c \
-	$(tst_files2_SOURCES) tst_files3.c tst_files4.c tst_files5.c \
-	tst_files6.c tst_fill_attr_vanish.c tst_fillbug.c tst_fills.c \
-	tst_fills2.c tst_grps.c tst_grps2.c tst_h4_lendian.c \
-	tst_h5_endians.c tst_h_atts2.c tst_h_files3.c \
+	cdm_sea_soundings.c h5testszip.c renamegroup.c t_type.c \
+	test_filter.c test_filter_misc.c test_szip.c \
+	$(tst_ar4_SOURCES) $(tst_ar4_3d_SOURCES) $(tst_ar4_4d_SOURCES) \
+	tst_ar5.c tst_atts.c tst_atts1.c tst_atts2.c \
+	tst_atts_string_rewrite.c tst_bug324.c tst_camrun.c \
+	tst_chunk_hdf4.c tst_chunks.c tst_chunks2.c tst_chunks3.c \
+	tst_compounds.c tst_compounds2.c tst_compounds3.c \
+	tst_converts.c tst_converts2.c tst_coords.c tst_coords2.c \
+	tst_coords3.c tst_create_files.c tst_dims.c tst_dims2.c \
+	tst_dims3.c tst_empty_vlen_unlim.c tst_endian_fill.c \
+	tst_enums.c tst_files.c $(tst_files2_SOURCES) tst_files3.c \
+	tst_files4.c tst_files5.c tst_files6.c tst_fill_attr_vanish.c \
+	tst_fillbug.c tst_fills.c tst_fills2.c tst_filterparser.c \
+	tst_grps.c tst_grps2.c tst_h4_lendian.c tst_h5_endians.c \
 	$(tst_h_many_atts_SOURCES) tst_h_refs.c tst_h_scalar.c \
 	tst_h_strbug.c tst_hdf5_file_compat.c tst_interops.c \
 	tst_interops2.c tst_interops3.c tst_interops4.c \
@@ -583,42 +615,60 @@ SOURCES = $(bm_file_SOURCES) $(bm_many_atts_SOURCES) \
 	tst_mpi_parallel.c tst_nc4perf.c tst_opaques.c tst_parallel.c \
 	tst_parallel3.c tst_parallel4.c tst_rehash.c tst_rename.c \
 	tst_simplerw_coll_r.c tst_strings.c tst_strings2.c tst_sync.c \
-	tst_unlim_vars.c tst_utf8.c tst_v2.c tst_varms.c tst_vars.c \
-	tst_vars2.c tst_vars3.c tst_vars4.c tst_vl.c tst_xplatform.c \
-	tst_xplatform2.c
+	tst_types.c tst_unlim_vars.c tst_utf8.c tst_v2.c tst_varms.c \
+	tst_vars.c tst_vars2.c tst_vars3.c tst_vars4.c tst_vl.c \
+	tst_xplatform.c tst_xplatform2.c
 DIST_SOURCES = $(am__bm_file_SOURCES_DIST) \
 	$(am__bm_many_atts_SOURCES_DIST) \
 	$(am__bm_many_objs_SOURCES_DIST) \
 	$(am__bm_netcdf4_recs_SOURCES_DIST) cdm_sea_soundings.c \
-	renamegroup.c t_type.c $(am__tst_ar4_SOURCES_DIST) \
+	h5testszip.c renamegroup.c t_type.c test_filter.c \
+	test_filter_misc.c test_szip.c $(am__tst_ar4_SOURCES_DIST) \
 	$(am__tst_ar4_3d_SOURCES_DIST) $(am__tst_ar4_4d_SOURCES_DIST) \
 	tst_ar5.c tst_atts.c tst_atts1.c tst_atts2.c \
-	tst_atts_string_rewrite.c tst_camrun.c tst_chunk_hdf4.c \
-	tst_chunks.c tst_chunks2.c tst_chunks3.c tst_compounds.c \
-	tst_compounds2.c tst_compounds3.c tst_converts.c \
-	tst_converts2.c tst_coords.c tst_coords2.c tst_coords3.c \
-	tst_create_files.c tst_dims.c tst_dims2.c tst_dims3.c \
-	tst_empty_vlen_unlim.c tst_endian_fill.c tst_enums.c \
-	tst_files.c $(am__tst_files2_SOURCES_DIST) tst_files3.c \
-	tst_files4.c tst_files5.c tst_files6.c tst_fill_attr_vanish.c \
-	tst_fillbug.c tst_fills.c tst_fills2.c tst_grps.c tst_grps2.c \
-	tst_h4_lendian.c tst_h5_endians.c tst_h_atts2.c tst_h_files3.c \
-	$(am__tst_h_many_atts_SOURCES_DIST) tst_h_refs.c \
-	tst_h_scalar.c tst_h_strbug.c tst_hdf5_file_compat.c \
-	tst_interops.c tst_interops2.c tst_interops3.c tst_interops4.c \
-	tst_interops5.c tst_interops6.c $(am__tst_knmi_SOURCES_DIST) \
-	tst_large.c tst_large2.c tst_mem.c tst_mode.c \
-	tst_mpi_parallel.c tst_nc4perf.c tst_opaques.c tst_parallel.c \
-	tst_parallel3.c tst_parallel4.c tst_rehash.c tst_rename.c \
+	tst_atts_string_rewrite.c tst_bug324.c tst_camrun.c \
+	tst_chunk_hdf4.c tst_chunks.c tst_chunks2.c tst_chunks3.c \
+	tst_compounds.c tst_compounds2.c tst_compounds3.c \
+	tst_converts.c tst_converts2.c tst_coords.c tst_coords2.c \
+	tst_coords3.c tst_create_files.c tst_dims.c tst_dims2.c \
+	tst_dims3.c tst_empty_vlen_unlim.c tst_endian_fill.c \
+	tst_enums.c tst_files.c $(am__tst_files2_SOURCES_DIST) \
+	tst_files3.c tst_files4.c tst_files5.c tst_files6.c \
+	tst_fill_attr_vanish.c tst_fillbug.c tst_fills.c tst_fills2.c \
+	tst_filterparser.c tst_grps.c tst_grps2.c tst_h4_lendian.c \
+	tst_h5_endians.c $(am__tst_h_many_atts_SOURCES_DIST) \
+	tst_h_refs.c tst_h_scalar.c tst_h_strbug.c \
+	tst_hdf5_file_compat.c tst_interops.c tst_interops2.c \
+	tst_interops3.c tst_interops4.c tst_interops5.c \
+	tst_interops6.c $(am__tst_knmi_SOURCES_DIST) tst_large.c \
+	tst_large2.c tst_mem.c tst_mode.c tst_mpi_parallel.c \
+	tst_nc4perf.c tst_opaques.c tst_parallel.c tst_parallel3.c \
+	tst_parallel4.c tst_rehash.c tst_rename.c \
 	tst_simplerw_coll_r.c tst_strings.c tst_strings2.c tst_sync.c \
-	tst_unlim_vars.c tst_utf8.c tst_v2.c tst_varms.c tst_vars.c \
-	tst_vars2.c tst_vars3.c tst_vars4.c tst_vl.c tst_xplatform.c \
-	tst_xplatform2.c
+	tst_types.c tst_unlim_vars.c tst_utf8.c tst_v2.c tst_varms.c \
+	tst_vars.c tst_vars2.c tst_vars3.c tst_vars4.c tst_vl.c \
+	tst_xplatform.c tst_xplatform2.c
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	check recheck distdir
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -821,23 +871,19 @@ am__set_TESTS_bases = \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
 RECHECK_LOGS = $(TEST_LOGS)
-AM_RECURSIVE_TARGETS = check recheck
 @BUILD_BENCHMARKS_TRUE at am__EXEEXT_10 = tst_ar4_3d$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	tst_create_files$(EXEEXT) \
 @BUILD_BENCHMARKS_TRUE@	run_bm_test1.sh run_bm_elena.sh \
 @BUILD_BENCHMARKS_TRUE@	run_bm_test2.sh run_tst_chunks.sh \
 @BUILD_BENCHMARKS_TRUE@	tst_files2$(EXEEXT) tst_files3$(EXEEXT) \
- at BUILD_BENCHMARKS_TRUE@	tst_ar5$(EXEEXT) tst_h_files3$(EXEEXT) \
- at BUILD_BENCHMARKS_TRUE@	tst_mem$(EXEEXT) run_get_knmi_files.sh \
- at BUILD_BENCHMARKS_TRUE@	tst_knmi$(EXEEXT)
- at USE_HDF4_TRUE@am__EXEEXT_11 = tst_interops2$(EXEEXT) \
- at USE_HDF4_TRUE@	tst_formatx_hdf4.sh run_chunk_hdf4.sh \
+ at BUILD_BENCHMARKS_TRUE@	tst_ar5$(EXEEXT) tst_mem$(EXEEXT) \
+ at BUILD_BENCHMARKS_TRUE@	run_get_knmi_files.sh tst_knmi$(EXEEXT)
+ at BUILD_UTILITIES_TRUE@@USE_HDF4_TRUE at am__EXEEXT_11 =  \
+ at BUILD_UTILITIES_TRUE@@USE_HDF4_TRUE@	tst_interops2$(EXEEXT) \
+ at BUILD_UTILITIES_TRUE@@USE_HDF4_TRUE@	tst_formatx_hdf4.sh
+ at USE_HDF4_TRUE@am__EXEEXT_12 = run_chunk_hdf4.sh \
 @USE_HDF4_TRUE@	tst_h4_lendian$(EXEEXT)
- at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at am__EXEEXT_12 = run_get_hdf4_files.sh \
- at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE@	tst_interops3$(EXEEXT) \
- at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE@	tst_hdf4_read_var.sh
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
 am__set_b = \
@@ -852,29 +898,50 @@ am__set_b = \
   esac
 am__test_logs1 = $(TESTS:=.log)
 am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ref_chunked.hdf4 \
-	$(srcdir)/ref_contiguous.hdf4 $(srcdir)/ref_hdf5_compat1.nc \
-	$(srcdir)/ref_hdf5_compat2.nc $(srcdir)/ref_hdf5_compat3.nc \
-	$(top_srcdir)/depcomp $(top_srcdir)/lib_flags.am \
-	$(top_srcdir)/test-driver
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/findplugin.in \
+	$(srcdir)/ref_chunked.hdf4 $(srcdir)/ref_contiguous.hdf4 \
+	$(srcdir)/ref_hdf5_compat1.nc $(srcdir)/ref_hdf5_compat2.nc \
+	$(srcdir)/ref_hdf5_compat3.nc $(top_srcdir)/depcomp \
+	$(top_srcdir)/lib_flags.am $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
 ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-
-# Put together AM_CPPFLAGS and AM_LDFLAGS.
-
 # Link to our assembled library.
 AM_LDFLAGS = ${top_builddir}/liblib/libnetcdf.la
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -897,12 +964,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -928,6 +997,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -942,6 +1012,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -1045,9 +1116,19 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
-# These are netCDF-4 test programs.
+# Put together AM_CPPFLAGS and AM_LDFLAGS.
+
+# Un comment to use a more verbose test driver
+#SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+
+# Note which tests depend on other tests. necessary for make -j check
+TEST_EXTENSIONS = .sh
+extradir = 
+
+# These are netCDF-4 C test programs which are built and run.
 NC4_TESTS = tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars \
 	tst_varms tst_unlim_vars tst_converts tst_converts2 tst_grps \
 	tst_grps2 tst_compounds tst_compounds2 tst_compounds3 \
@@ -1055,12 +1136,12 @@ NC4_TESTS = tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars \
 	tst_interops4 tst_interops5 tst_interops6 tst_enums tst_coords \
 	tst_coords2 tst_coords3 tst_vars3 tst_vars4 tst_chunks \
 	tst_chunks2 tst_utf8 tst_fills tst_fills2 tst_fillbug \
-	tst_xplatform tst_xplatform2 tst_h_atts2 tst_endian_fill \
-	tst_atts t_type cdm_sea_soundings tst_camrun tst_vl tst_atts1 \
-	tst_atts2 tst_vars2 tst_files5 tst_files6 tst_sync \
-	tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite \
+	tst_xplatform tst_xplatform2 tst_endian_fill tst_atts t_type \
+	cdm_sea_soundings tst_camrun tst_vl tst_atts1 tst_atts2 \
+	tst_vars2 tst_files5 tst_files6 tst_sync tst_h_scalar \
+	tst_rename tst_h5_endians tst_atts_string_rewrite \
 	tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash \
-	$(am__append_3)
+	tst_filterparser tst_bug324 tst_types $(am__append_2)
 @BUILD_BENCHMARKS_TRUE at bm_netcdf4_recs_SOURCES = bm_netcdf4_recs.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at bm_many_atts_SOURCES = bm_many_atts.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at bm_many_objs_SOURCES = bm_many_objs.c tst_utils.c
@@ -1071,42 +1152,44 @@ NC4_TESTS = tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars \
 @BUILD_BENCHMARKS_TRUE at tst_h_many_atts_SOURCES = tst_h_many_atts.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at bm_file_SOURCES = bm_file.c tst_utils.c
 @BUILD_BENCHMARKS_TRUE at tst_knmi_SOURCES = tst_knmi.c tst_utils.c
-EXTRA_DIST = run_par_test.sh run_bm.sh run_bm_test1.sh run_bm_test2.sh	\
-run_bm_radar_2D.sh run_bm_radar_2D_compression1.sh run_par_bm_test.sh	\
-run_bm_elena.sh run_par_bm_radar_2D.sh run_bm_radar_2D_endianness1.sh	\
-run_tst_chunks.sh ref_chunks1.cdl ref_chunks2.cdl 			\
-run_get_hdf4_files.sh run_valgrind_tests.sh run_valgrind_tests2.sh	\
-run_bm_ar4.sh ref_tst_compounds.nc run_hdf4_valgrind_tests.sh		\
-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 \
-tst_h5_endians.c tst_h4_lendian.c tst_atts_string_rewrite.c \
-tst_put_vars_two_unlim_dim.c tst_empty_vlen_unlim.c run_empty_vlen_test.sh \
-ref_hdf5_compat1.nc ref_hdf5_compat2.nc ref_hdf5_compat3.nc tst_misc.sh \
-tdset.h5 tst_hdf4_read_var.sh ref_contiguous.hdf4 ref_chunked.hdf4
-
-CLEANFILES = tst_mpi_parallel.bin cdm_sea_soundings.nc bm_chunking.nc	\
-bm_radar.nc bm_radar1.nc radar_3d_compression_test.txt			\
-radar_3d_compression.txt radar_2d_compression.txt			\
-radar_3d_chunking.txt tst_floats_1D.cdl floats_1D_3.nc floats_1D.cdl	\
-tst_*.nc tst_floats2_*.cdl tst_ints2_*.cdl tst_shorts2_*.cdl		\
-tst_elena_*.cdl tst_simple*.cdl tst_chunks.cdl pr_A1.* tauu_A1.*	\
-usi_01.* thetau_01.* tst_*.nc tst_*.h5                                  \
-tst_grp_rename.cdl tst_grp_rename.nc tst_grp_rename.dmp ref_grp_rename.cdl \
-foo1.nc tst_interops2.h4 tst_h5_endians.nc tst_h4_lendian.h4 test.nc \
-tst_atts_string_rewrite.nc tst_empty_vlen_unlim.nc tst_empty_vlen_lim.nc \
-tst_parallel4_simplerw_coll.nc tst_fill_attr_vanish.nc tst_rehash.nc
-
- at USE_HDF4_FILE_TESTS_TRUE@DISTCLEANFILES = AMSR_E_L2_Rain_V10_200905312326_A.hdf	\
- at USE_HDF4_FILE_TESTS_TRUE@AMSR_E_L3_DailyLand_V06_20020619.hdf			\
- at USE_HDF4_FILE_TESTS_TRUE@MYD29.A2009152.0000.005.2009153124331.hdf		\
- at USE_HDF4_FILE_TESTS_TRUE@MYD29.A2002185.0000.005.2007160150627.hdf		\
- at USE_HDF4_FILE_TESTS_TRUE@MOD29.A2000055.0005.005.2006267200024.hdf
-
-all: all-am
+EXTRA_DIST = run_par_test.sh run_bm.sh run_bm_test1.sh                  \
+run_bm_test2.sh run_bm_radar_2D.sh run_bm_radar_2D_compression1.sh      \
+run_par_bm_test.sh run_bm_elena.sh run_par_bm_radar_2D.sh               \
+run_bm_radar_2D_endianness1.sh run_tst_chunks.sh ref_chunks1.cdl        \
+ref_chunks2.cdl run_get_hdf4_files.sh run_valgrind_tests.sh             \
+run_valgrind_tests2.sh run_bm_ar4.sh ref_tst_compounds.nc               \
+run_hdf4_valgrind_tests.sh 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 tst_h5_endians.c                  \
+tst_h4_lendian.c tst_atts_string_rewrite.c                              \
+tst_put_vars_two_unlim_dim.c tst_empty_vlen_unlim.c                     \
+run_empty_vlen_test.sh ref_hdf5_compat1.nc ref_hdf5_compat2.nc          \
+ref_hdf5_compat3.nc tst_misc.sh tdset.h5 tst_hdf4_read_var.sh           \
+ref_contiguous.hdf4 ref_chunked.hdf4 tst_szip.sh ref_szip.h5 ref_szip.cdl \
+tst_filter.sh bzip2.cdl filtered.cdl unfiltered.cdl ref_bzip2.c         \
+findplugin.in
+
+CLEANFILES = tst_mpi_parallel.bin cdm_sea_soundings.nc bm_chunking.nc   \
+bm_radar.nc bm_radar1.nc radar_3d_compression_test.txt                  \
+radar_3d_compression.txt radar_2d_compression.txt                       \
+radar_3d_chunking.txt tst_floats_1D.cdl floats_1D_3.nc floats_1D.cdl    \
+tst_*.nc tst_floats2_*.cdl tst_ints2_*.cdl tst_shorts2_*.cdl            \
+tst_elena_*.cdl tst_simple*.cdl tst_chunks.cdl pr_A1.* tauu_A1.*        \
+usi_01.* thetau_01.* tst_*.nc tst_*.h5 tst_grp_rename.cdl               \
+tst_grp_rename.nc tst_grp_rename.dmp ref_grp_rename.cdl foo1.nc         \
+tst_interops2.h4 tst_h5_endians.nc tst_h4_lendian.h4 test.nc            \
+tst_atts_string_rewrite.nc tst_empty_vlen_unlim.nc                      \
+tst_empty_vlen_lim.nc tst_parallel4_simplerw_coll.nc                    \
+tst_fill_attr_vanish.nc tst_rehash.nc testszip.nc test.h5               \
+szip_dump.cdl
+
+DISTCLEANFILES = findplugin.sh $(am__append_23)
+SUBDIRS = hdf5plugins
+all: all-recursive
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+.SUFFIXES: .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -1137,6 +1220,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
+findplugin.sh: $(top_builddir)/config.status $(srcdir)/findplugin.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
 clean-checkPROGRAMS:
 	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -1146,6 +1231,55 @@ clean-checkPROGRAMS:
 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
 	echo " rm -f" $$list; \
 	rm -f $$list
+install-extraPROGRAMS: $(extra_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(extra_PROGRAMS)'; test -n "$(extradir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(extradir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(extradir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(extradir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(extradir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-extraPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(extra_PROGRAMS)'; test -n "$(extradir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(extradir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(extradir)" && rm -f $$files
+
+clean-extraPROGRAMS:
+	@list='$(extra_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
 
 bm_file$(EXEEXT): $(bm_file_OBJECTS) $(bm_file_DEPENDENCIES) $(EXTRA_bm_file_DEPENDENCIES) 
 	@rm -f bm_file$(EXEEXT)
@@ -1167,6 +1301,10 @@ cdm_sea_soundings$(EXEEXT): $(cdm_sea_soundings_OBJECTS) $(cdm_sea_soundings_DEP
 	@rm -f cdm_sea_soundings$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(cdm_sea_soundings_OBJECTS) $(cdm_sea_soundings_LDADD) $(LIBS)
 
+h5testszip$(EXEEXT): $(h5testszip_OBJECTS) $(h5testszip_DEPENDENCIES) $(EXTRA_h5testszip_DEPENDENCIES) 
+	@rm -f h5testszip$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(h5testszip_OBJECTS) $(h5testszip_LDADD) $(LIBS)
+
 renamegroup$(EXEEXT): $(renamegroup_OBJECTS) $(renamegroup_DEPENDENCIES) $(EXTRA_renamegroup_DEPENDENCIES) 
 	@rm -f renamegroup$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(renamegroup_OBJECTS) $(renamegroup_LDADD) $(LIBS)
@@ -1175,6 +1313,18 @@ t_type$(EXEEXT): $(t_type_OBJECTS) $(t_type_DEPENDENCIES) $(EXTRA_t_type_DEPENDE
 	@rm -f t_type$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(t_type_OBJECTS) $(t_type_LDADD) $(LIBS)
 
+test_filter$(EXEEXT): $(test_filter_OBJECTS) $(test_filter_DEPENDENCIES) $(EXTRA_test_filter_DEPENDENCIES) 
+	@rm -f test_filter$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_filter_OBJECTS) $(test_filter_LDADD) $(LIBS)
+
+test_filter_misc$(EXEEXT): $(test_filter_misc_OBJECTS) $(test_filter_misc_DEPENDENCIES) $(EXTRA_test_filter_misc_DEPENDENCIES) 
+	@rm -f test_filter_misc$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_filter_misc_OBJECTS) $(test_filter_misc_LDADD) $(LIBS)
+
+test_szip$(EXEEXT): $(test_szip_OBJECTS) $(test_szip_DEPENDENCIES) $(EXTRA_test_szip_DEPENDENCIES) 
+	@rm -f test_szip$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_szip_OBJECTS) $(test_szip_LDADD) $(LIBS)
+
 tst_ar4$(EXEEXT): $(tst_ar4_OBJECTS) $(tst_ar4_DEPENDENCIES) $(EXTRA_tst_ar4_DEPENDENCIES) 
 	@rm -f tst_ar4$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_ar4_OBJECTS) $(tst_ar4_LDADD) $(LIBS)
@@ -1207,6 +1357,10 @@ tst_atts_string_rewrite$(EXEEXT): $(tst_atts_string_rewrite_OBJECTS) $(tst_atts_
 	@rm -f tst_atts_string_rewrite$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_atts_string_rewrite_OBJECTS) $(tst_atts_string_rewrite_LDADD) $(LIBS)
 
+tst_bug324$(EXEEXT): $(tst_bug324_OBJECTS) $(tst_bug324_DEPENDENCIES) $(EXTRA_tst_bug324_DEPENDENCIES) 
+	@rm -f tst_bug324$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_bug324_OBJECTS) $(tst_bug324_LDADD) $(LIBS)
+
 tst_camrun$(EXEEXT): $(tst_camrun_OBJECTS) $(tst_camrun_DEPENDENCIES) $(EXTRA_tst_camrun_DEPENDENCIES) 
 	@rm -f tst_camrun$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_camrun_OBJECTS) $(tst_camrun_LDADD) $(LIBS)
@@ -1327,6 +1481,10 @@ tst_fills2$(EXEEXT): $(tst_fills2_OBJECTS) $(tst_fills2_DEPENDENCIES) $(EXTRA_ts
 	@rm -f tst_fills2$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_fills2_OBJECTS) $(tst_fills2_LDADD) $(LIBS)
 
+tst_filterparser$(EXEEXT): $(tst_filterparser_OBJECTS) $(tst_filterparser_DEPENDENCIES) $(EXTRA_tst_filterparser_DEPENDENCIES) 
+	@rm -f tst_filterparser$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_filterparser_OBJECTS) $(tst_filterparser_LDADD) $(LIBS)
+
 tst_grps$(EXEEXT): $(tst_grps_OBJECTS) $(tst_grps_DEPENDENCIES) $(EXTRA_tst_grps_DEPENDENCIES) 
 	@rm -f tst_grps$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_grps_OBJECTS) $(tst_grps_LDADD) $(LIBS)
@@ -1343,14 +1501,6 @@ tst_h5_endians$(EXEEXT): $(tst_h5_endians_OBJECTS) $(tst_h5_endians_DEPENDENCIES
 	@rm -f tst_h5_endians$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_h5_endians_OBJECTS) $(tst_h5_endians_LDADD) $(LIBS)
 
-tst_h_atts2$(EXEEXT): $(tst_h_atts2_OBJECTS) $(tst_h_atts2_DEPENDENCIES) $(EXTRA_tst_h_atts2_DEPENDENCIES) 
-	@rm -f tst_h_atts2$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(tst_h_atts2_OBJECTS) $(tst_h_atts2_LDADD) $(LIBS)
-
-tst_h_files3$(EXEEXT): $(tst_h_files3_OBJECTS) $(tst_h_files3_DEPENDENCIES) $(EXTRA_tst_h_files3_DEPENDENCIES) 
-	@rm -f tst_h_files3$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(tst_h_files3_OBJECTS) $(tst_h_files3_LDADD) $(LIBS)
-
 tst_h_many_atts$(EXEEXT): $(tst_h_many_atts_OBJECTS) $(tst_h_many_atts_DEPENDENCIES) $(EXTRA_tst_h_many_atts_DEPENDENCIES) 
 	@rm -f tst_h_many_atts$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_h_many_atts_OBJECTS) $(tst_h_many_atts_LDADD) $(LIBS)
@@ -1463,6 +1613,10 @@ tst_sync$(EXEEXT): $(tst_sync_OBJECTS) $(tst_sync_DEPENDENCIES) $(EXTRA_tst_sync
 	@rm -f tst_sync$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_sync_OBJECTS) $(tst_sync_LDADD) $(LIBS)
 
+tst_types$(EXEEXT): $(tst_types_OBJECTS) $(tst_types_DEPENDENCIES) $(EXTRA_tst_types_DEPENDENCIES) 
+	@rm -f tst_types$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tst_types_OBJECTS) $(tst_types_LDADD) $(LIBS)
+
 tst_unlim_vars$(EXEEXT): $(tst_unlim_vars_OBJECTS) $(tst_unlim_vars_DEPENDENCIES) $(EXTRA_tst_unlim_vars_DEPENDENCIES) 
 	@rm -f tst_unlim_vars$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_unlim_vars_OBJECTS) $(tst_unlim_vars_LDADD) $(LIBS)
@@ -1518,8 +1672,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bm_many_objs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bm_netcdf4_recs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdm_sea_soundings.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/h5testszip.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/renamegroup.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/t_type.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_filter.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_filter_misc.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_szip.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_ar4.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_ar4_3d.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_ar4_4d.Po at am__quote@
@@ -1528,6 +1686,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_atts1.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_atts2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_atts_string_rewrite.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_bug324.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_camrun.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_chunk_hdf4.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_chunks.Po at am__quote@
@@ -1558,12 +1717,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_fillbug.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_fills.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_fills2.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_filterparser.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_grps.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_grps2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h4_lendian.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h5_endians.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_atts2.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_files3.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_many_atts.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_refs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_scalar.Po at am__quote@
@@ -1592,6 +1750,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_strings.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_strings2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_sync.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_types.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_unlim_vars.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_utf8.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_utils.Po at am__quote@
@@ -1635,14 +1794,61 @@ mostlyclean-libtool:
 clean-libtool:
 	-rm -rf .libs _libs
 
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
+tags: tags-recursive
 TAGS: tags
 
 tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
 	set x; \
 	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
 	$(am__define_uniq_tagged_files); \
 	shift; \
 	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
@@ -1655,7 +1861,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
 	      $$unique; \
 	  fi; \
 	fi
-ctags: ctags-am
+ctags: ctags-recursive
 
 CTAGS: ctags
 ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
@@ -1668,7 +1874,7 @@ GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
 	  && $(am__cd) $(top_srcdir) \
 	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
+cscopelist: cscopelist-recursive
 
 cscopelist-am: $(am__tagged_files)
 	list='$(am__tagged_files)'; \
@@ -2080,13 +2286,6 @@ tst_xplatform2.log: tst_xplatform2$(EXEEXT)
 	--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_h_atts2.log: tst_h_atts2$(EXEEXT)
-	@p='tst_h_atts2$(EXEEXT)'; \
-	b='tst_h_atts2'; \
-	$(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_endian_fill.log: tst_endian_fill$(EXEEXT)
 	@p='tst_endian_fill$(EXEEXT)'; \
 	b='tst_endian_fill'; \
@@ -2220,79 +2419,72 @@ tst_rehash.log: tst_rehash$(EXEEXT)
 	--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_h_strbug.log: tst_h_strbug$(EXEEXT)
-	@p='tst_h_strbug$(EXEEXT)'; \
-	b='tst_h_strbug'; \
+tst_filterparser.log: tst_filterparser$(EXEEXT)
+	@p='tst_filterparser$(EXEEXT)'; \
+	b='tst_filterparser'; \
 	$(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_h_refs.log: tst_h_refs$(EXEEXT)
-	@p='tst_h_refs$(EXEEXT)'; \
-	b='tst_h_refs'; \
+tst_bug324.log: tst_bug324$(EXEEXT)
+	@p='tst_bug324$(EXEEXT)'; \
+	b='tst_bug324'; \
 	$(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_empty_vlen_test.sh.log: run_empty_vlen_test.sh
-	@p='run_empty_vlen_test.sh'; \
-	b='run_empty_vlen_test.sh'; \
+tst_types.log: tst_types$(EXEEXT)
+	@p='tst_types$(EXEEXT)'; \
+	b='tst_types'; \
 	$(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_v2.log: tst_v2$(EXEEXT)
-	@p='tst_v2$(EXEEXT)'; \
-	b='tst_v2'; \
-	$(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_large.log: tst_large$(EXEEXT)
-	@p='tst_large$(EXEEXT)'; \
-	b='tst_large'; \
+tst_h_strbug.log: tst_h_strbug$(EXEEXT)
+	@p='tst_h_strbug$(EXEEXT)'; \
+	b='tst_h_strbug'; \
 	$(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_ar4_3d.log: tst_ar4_3d$(EXEEXT)
-	@p='tst_ar4_3d$(EXEEXT)'; \
-	b='tst_ar4_3d'; \
+tst_h_refs.log: tst_h_refs$(EXEEXT)
+	@p='tst_h_refs$(EXEEXT)'; \
+	b='tst_h_refs'; \
 	$(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'; \
+tst_large.log: tst_large$(EXEEXT)
+	@p='tst_large$(EXEEXT)'; \
+	b='tst_large'; \
 	$(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_bm_test1.sh.log: run_bm_test1.sh
-	@p='run_bm_test1.sh'; \
-	b='run_bm_test1.sh'; \
+tst_large2.log: tst_large2$(EXEEXT)
+	@p='tst_large2$(EXEEXT)'; \
+	b='tst_large2'; \
 	$(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_bm_elena.sh.log: run_bm_elena.sh
-	@p='run_bm_elena.sh'; \
-	b='run_bm_elena.sh'; \
+tst_v2.log: tst_v2$(EXEEXT)
+	@p='tst_v2$(EXEEXT)'; \
+	b='tst_v2'; \
 	$(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_bm_test2.sh.log: run_bm_test2.sh
-	@p='run_bm_test2.sh'; \
-	b='run_bm_test2.sh'; \
+tst_ar4_3d.log: tst_ar4_3d$(EXEEXT)
+	@p='tst_ar4_3d$(EXEEXT)'; \
+	b='tst_ar4_3d'; \
 	$(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_tst_chunks.sh.log: run_tst_chunks.sh
-	@p='run_tst_chunks.sh'; \
-	b='run_tst_chunks.sh'; \
+tst_create_files.log: tst_create_files$(EXEEXT)
+	@p='tst_create_files$(EXEEXT)'; \
+	b='tst_create_files'; \
 	$(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) \
@@ -2318,13 +2510,6 @@ tst_ar5.log: tst_ar5$(EXEEXT)
 	--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_h_files3.log: tst_h_files3$(EXEEXT)
-	@p='tst_h_files3$(EXEEXT)'; \
-	b='tst_h_files3'; \
-	$(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_mem.log: tst_mem$(EXEEXT)
 	@p='tst_mem$(EXEEXT)'; \
 	b='tst_mem'; \
@@ -2332,13 +2517,6 @@ tst_mem.log: tst_mem$(EXEEXT)
 	--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_get_knmi_files.sh.log: run_get_knmi_files.sh
-	@p='run_get_knmi_files.sh'; \
-	b='run_get_knmi_files.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_knmi.log: tst_knmi$(EXEEXT)
 	@p='tst_knmi$(EXEEXT)'; \
 	b='tst_knmi'; \
@@ -2346,13 +2524,6 @@ tst_knmi.log: tst_knmi$(EXEEXT)
 	--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_par_bm_test.sh.log: run_par_bm_test.sh
-	@p='run_par_bm_test.sh'; \
-	b='run_par_bm_test.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_interops2.log: tst_interops2$(EXEEXT)
 	@p='tst_interops2$(EXEEXT)'; \
 	b='tst_interops2'; \
@@ -2360,20 +2531,6 @@ tst_interops2.log: tst_interops2$(EXEEXT)
 	--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_formatx_hdf4.sh.log: tst_formatx_hdf4.sh
-	@p='tst_formatx_hdf4.sh'; \
-	b='tst_formatx_hdf4.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_chunk_hdf4.sh.log: run_chunk_hdf4.sh
-	@p='run_chunk_hdf4.sh'; \
-	b='run_chunk_hdf4.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_h4_lendian.log: tst_h4_lendian$(EXEEXT)
 	@p='tst_h4_lendian$(EXEEXT)'; \
 	b='tst_h4_lendian'; \
@@ -2381,68 +2538,19 @@ tst_h4_lendian.log: tst_h4_lendian$(EXEEXT)
 	--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_get_hdf4_files.sh.log: run_get_hdf4_files.sh
-	@p='run_get_hdf4_files.sh'; \
-	b='run_get_hdf4_files.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_interops3.log: tst_interops3$(EXEEXT)
-	@p='tst_interops3$(EXEEXT)'; \
-	b='tst_interops3'; \
-	$(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_hdf4_read_var.sh.log: tst_hdf4_read_var.sh
-	@p='tst_hdf4_read_var.sh'; \
-	b='tst_hdf4_read_var.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_valgrind_tests.sh.log: run_valgrind_tests.sh
-	@p='run_valgrind_tests.sh'; \
-	b='run_valgrind_tests.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_valgrind_tests2.sh.log: run_valgrind_tests2.sh
-	@p='run_valgrind_tests2.sh'; \
-	b='run_valgrind_tests2.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_hdf4_valgrind_tests.sh.log: run_hdf4_valgrind_tests.sh
-	@p='run_hdf4_valgrind_tests.sh'; \
-	b='run_hdf4_valgrind_tests.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_par_test.sh.log: run_par_test.sh
-	@p='run_par_test.sh'; \
-	b='run_par_test.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
@@ -2475,21 +2583,50 @@ distdir: $(DISTFILES)
 	    || exit 1; \
 	  fi; \
 	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
 check-am: all-am
 	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
 	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
-all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+check: check-recursive
+all-am: Makefile $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(extradir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
 
 install-am: all-am
 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
-installcheck: installcheck-am
+installcheck: installcheck-recursive
 install-strip:
 	if test -z '$(STRIP)'; then \
 	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@@ -2516,104 +2653,107 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+clean: clean-recursive
 
-clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
-	mostlyclean-am
+clean-am: clean-checkPROGRAMS clean-extraPROGRAMS clean-generic \
+	clean-libtool mostlyclean-am
 
-distclean: distclean-am
+distclean: distclean-recursive
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
 
-dvi: dvi-am
+dvi: dvi-recursive
 
 dvi-am:
 
-html: html-am
+html: html-recursive
 
 html-am:
 
-info: info-am
+info: info-recursive
 
 info-am:
 
-install-data-am:
+install-data-am: install-extraPROGRAMS
 
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
 
 install-dvi-am:
 
 install-exec-am:
 
-install-html: install-html-am
+install-html: install-html-recursive
 
 install-html-am:
 
-install-info: install-info-am
+install-info: install-info-recursive
 
 install-info-am:
 
 install-man:
 
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
 
 install-pdf-am:
 
-install-ps: install-ps-am
+install-ps: install-ps-recursive
 
 install-ps-am:
 
 installcheck-am:
 
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
 
 mostlyclean-am: mostlyclean-compile mostlyclean-generic \
 	mostlyclean-libtool
 
-pdf: pdf-am
+pdf: pdf-recursive
 
 pdf-am:
 
-ps: ps-am
+ps: ps-recursive
 
 ps-am:
 
-uninstall-am:
+uninstall-am: uninstall-extraPROGRAMS
 
-.MAKE: check-am install-am install-strip
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
-	clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-TESTS check-am clean clean-checkPROGRAMS \
+	clean-extraPROGRAMS clean-generic clean-libtool cscopelist-am \
 	ctags ctags-am distclean distclean-compile distclean-generic \
 	distclean-libtool distclean-tags distdir dvi dvi-am html \
 	html-am info info-am install install-am install-data \
 	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	recheck tags tags-am uninstall uninstall-am
+	install-exec-am install-extraPROGRAMS install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
+	uninstall uninstall-am uninstall-extraPROGRAMS
 
 .PRECIOUS: Makefile
 
 
- at BUILD_UTILITIES_TRUE@	TESTS += run_grp_rename.sh tst_misc.sh
-
 @BUILD_BENCHMARKS_TRUE at benchmarks: check
 @BUILD_BENCHMARKS_TRUE@	./run_bm_radar_2D.sh
 @BUILD_BENCHMARKS_TRUE@	./run_bm_radar_2D_compression1.sh
 @BUILD_BENCHMARKS_TRUE@	./run_bm.sh
 @BUILD_BENCHMARKS_TRUE@	./run_tst_chunks.sh
 @BUILD_BENCHMARKS_TRUE@	./run_bm_ar4.sh
+ at BUILD_UTILITIES_TRUE@@USE_HDF4_TRUE at tst_formatx_hdf4.log: tst_interops2.log
+
+ at USE_HDF4_FILE_TESTS_TRUE@@USE_HDF4_TRUE at tst_hdf4_read_var.log: tst_interops2.log
 
 # 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/nc_test4/bzip2.cdl b/nc_test4/bzip2.cdl
new file mode 100644
index 0000000..9b0c903
--- /dev/null
+++ b/nc_test4/bzip2.cdl
@@ -0,0 +1,83 @@
+netcdf bzip2 {
+dimensions:
+	dim0 = 4 ;
+	dim1 = 4 ;
+	dim2 = 4 ;
+	dim3 = 4 ;
+variables:
+	float var(dim0, dim1, dim2, dim3) ;
+		var:_Storage = "chunked" ;
+		var:_ChunkSizes = 4, 4, 4, 4 ;
+		var:_Filter = "307,9" ;
+ 		var:_NoFill = "true" ;
+
+// global attributes:
+		:_Format = "netCDF-4" ;
+data:
+
+ 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,
+  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, 241, 242, 243,
+  244, 245, 246, 247,
+  248, 249, 250, 251,
+  252, 253, 254, 255 ;
+}
diff --git a/nc_test4/filter_test/CMakeLists.txt b/nc_test4/filter_test/CMakeLists.txt
new file mode 100644
index 0000000..2d95ade
--- /dev/null
+++ b/nc_test4/filter_test/CMakeLists.txt
@@ -0,0 +1,34 @@
+# This cmake file is here as a placeholder.
+# It cannot yet be used to run the filter test.
+
+if(ENABLE_FILTER_TEST)
+SET(BZIP2SRC blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c)
+ADD_EXECUTABLE(fake fake.c H5Zbzip2.c ${BZIP2SRC})
+
+SET(BZIP2OBJ blocksort.o huffman.o crctable.o randtable.o compress.o decompress.o bzlib.o)
+
+SET(LIBNAME "lib${FILTERNAME}.so")
+
+SET(bzip__LIBS H5Zbzip2.o ${BZIP2OBJ})
+FOREACH(LIBS ${bzip_LIBS})
+  SET(LARGS ${LARGS} $<TARGET_OBJECTS:${LIBS}>)
+ENDFOREACH()
+ADD_LIBRARY(bzip2 ${LARGS} )
+SET(TLL_LIBS "")
+SET(TLL_LIBS ${TLL_LIBS} ${HDF5_hdf5_hl_LIBRARY} ${HDF5_hdf5_LIBRARY} ${ZLIB_LIBRARY})
+TARGET_LINK_LIBRARIES(bzip2 ${TLL_LIBS})
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES LINK_FLAGS -shared)
+
+build_bin_test(test_filter)
+IF(BUILD_UTILITIES)
+  ADD_SH_TEST(nc_test4 tst_filter)
+ENDIF(BUILD_UTILITIES)
+
+ENDIF(ENABLE_FILTER_TEST)
+
+FILE(GLOB COPY_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*)
+FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+
+FILE(GLOB CUR_EXTRA_DIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
+SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am)
+ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
diff --git a/nc_test4/filter_test/H5Zbzip2.c b/nc_test4/filter_test/H5Zbzip2.c
new file mode 100644
index 0000000..7c18b7c
--- /dev/null
+++ b/nc_test4/filter_test/H5Zbzip2.c
@@ -0,0 +1,171 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+#include "h5bzip2.h"
+
+
+const H5Z_class2_t H5Z_BZIP2[1] = {{
+    H5Z_CLASS_T_VERS,       /* H5Z_class_t version */
+    (H5Z_filter_t)H5Z_FILTER_BZIP2,         /* Filter id number             */
+    1,              /* encoder_present flag (set to true) */
+    1,              /* decoder_present flag (set to true) */
+    "bzip2",                  /* Filter name for debugging    */
+    NULL,                       /* The "can apply" callback     */
+    NULL,                       /* The "set local" callback     */
+    (H5Z_func_t)H5Z_filter_bzip2,         /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_BZIP2;
+}
+
+size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
+		     const unsigned int cd_values[], size_t nbytes,
+		     size_t *buf_size, void **buf);
+
+
+size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+  char *outbuf = NULL;
+  size_t outbuflen, outdatalen;
+  int ret;
+
+  if (flags & H5Z_FLAG_REVERSE) {
+
+    /** Decompress data.
+     **
+     ** This process is troublesome since the size of uncompressed data
+     ** is unknown, so the low-level interface must be used.
+     ** Data is decompressed to the output buffer (which is sized
+     ** for the average case); if it gets full, its size is doubled
+     ** and decompression continues.  This avoids repeatedly trying to
+     ** decompress the whole block, which could be really inefficient.
+     **/
+
+    bz_stream stream;
+    char *newbuf = NULL;
+    size_t newbuflen;
+
+    /* Prepare the output buffer. */
+    outbuflen = nbytes * 3 + 1;  /* average bzip2 compression ratio is 3:1 */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Use standard malloc()/free() for internal memory handling. */
+    stream.bzalloc = NULL;
+    stream.bzfree = NULL;
+    stream.opaque = NULL;
+
+    /* Start decompression. */
+    ret = BZ2_bzDecompressInit(&stream, 0, 0);
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 decompression start failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+
+    /* Feed data to the decompression process and get decompressed data. */
+    stream.next_out = outbuf;
+    stream.avail_out = outbuflen;
+    stream.next_in = *buf;
+    stream.avail_in = nbytes;
+    do {
+      ret = BZ2_bzDecompress(&stream);
+      if (ret < 0) {
+	fprintf(stderr, "BUG: bzip2 decompression failed with error %d\n", ret);
+	goto cleanupAndFail;
+      }
+
+      if (ret != BZ_STREAM_END && stream.avail_out == 0) {
+        /* Grow the output buffer. */
+        newbuflen = outbuflen * 2;
+        newbuf = realloc(outbuf, newbuflen);
+        if (newbuf == NULL) {
+          fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
+          goto cleanupAndFail;
+        }
+        stream.next_out = newbuf + outbuflen;  /* half the new buffer behind */
+        stream.avail_out = outbuflen;  /* half the new buffer ahead */
+        outbuf = newbuf;
+        outbuflen = newbuflen;
+      }
+    } while (ret != BZ_STREAM_END);
+
+    /* End compression. */
+    outdatalen = stream.total_out_lo32;
+    ret = BZ2_bzDecompressEnd(&stream);
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 compression end failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+
+  } else {
+
+    /** Compress data.
+     **
+     ** This is quite simple, since the size of compressed data in the worst
+     ** case is known and it is not much bigger than the size of uncompressed
+     ** data.  This allows us to use the simplified one-shot interface to
+     ** compression.
+     **/
+
+    unsigned int odatalen;  /* maybe not the same size as outdatalen */
+    int blockSize100k = 9;
+
+    /* Get compression block size if present. */
+    if (cd_nelmts > 0) {
+      blockSize100k = cd_values[0];
+      if (blockSize100k < 1 || blockSize100k > 9) {
+	fprintf(stderr, "invalid compression block size: %d\n", blockSize100k);
+	goto cleanupAndFail;
+      }
+    }
+
+    /* Prepare the output buffer. */
+    outbuflen = nbytes + nbytes / 100 + 600;  /* worst case (bzip2 docs) */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for bzip2 compression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Compress data. */
+    odatalen = outbuflen;
+    ret = BZ2_bzBuffToBuffCompress(outbuf, &odatalen, *buf, nbytes,
+                                   blockSize100k, 0, 0);
+    outdatalen = odatalen;
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 compression failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+  }
+
+  /* Always replace the input buffer with the output buffer. */
+  free(*buf);
+  *buf = outbuf;
+  *buf_size = outbuflen;
+  return outdatalen;
+
+ cleanupAndFail:
+  if (outbuf)
+    free(outbuf);
+  return 0;
+}
diff --git a/nc_test4/filter_test/H5Ztemplate.c b/nc_test4/filter_test/H5Ztemplate.c
new file mode 100644
index 0000000..bc15a33
--- /dev/null
+++ b/nc_test4/filter_test/H5Ztemplate.c
@@ -0,0 +1,104 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+#include "xxxx.h"
+
+/*
+Provide a textual template (not a C++ template)
+from which one can construct a new filter.
+The filter "name is marked with "XXXX" or "xxxx"
+
+*/
+
+const H5Z_class2_t H5Z_XXXX[1] = {{
+    H5Z_CLASS_T_VERS,       /* H5Z_class_t version */
+    (H5Z_filter_t)H5Z_FILTER_XXXX, /* Filter id number             */
+    1,                             /* encoder_present flag (set to true) */
+    1,                             /* decoder_present flag (set to true) */
+    "xxxx",                        /* Filter name for debugging    */
+    NULL,                          /* The "can apply" callback     */
+    NULL,                          /* The "set local" callback     */
+    (H5Z_func_t)H5Z_filter_xxxx,   /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_XXXX;
+}
+
+size_t H5Z_filter_xxxx(unsigned int flags, size_t cd_nelmts,
+		     const unsigned int cd_values[], size_t nbytes,
+		     size_t *buf_size, void **buf);
+
+
+size_t H5Z_filter_xxxx(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+  char *outbuf = NULL;
+  size_t outbuflen, outdatalen;
+  int ret;
+
+  if (flags & H5Z_FLAG_REVERSE) {
+
+    /** Decompress data.
+     **
+     ** This process is troublesome since the size of uncompressed data
+     ** is unknown, so the low-level interface must be used.
+     ** Data is decompressed to the output buffer (which is sized
+     ** for the average case); if it gets full, its size is doubled
+     ** and decompression continues.  This avoids repeatedly trying to
+     ** decompress the whole block, which could be really inefficient.
+     **/
+
+    char *newbuf = NULL;
+    size_t newbuflen;
+
+  } else {
+
+    /** Compress data.
+     **
+     ** This is quite simple, since the size of compressed data in the worst
+     ** case is known and it is not much bigger than the size of uncompressed
+     ** data.  This allows us to use the simplified one-shot interface to
+     ** compression.
+     **/
+
+    unsigned int odatalen;  /* maybe not the same size as outdatalen */
+
+    /* Prepare the output buffer. */
+    outbuflen = M;  /* worst case */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for xxxx compression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Compress data. */
+
+  }
+
+  /* Always replace the input buffer with the output buffer. */
+  free(*buf);
+  *buf = outbuf;
+  *buf_size = outbuflen;
+  return outdatalen;
+
+ cleanupAndFail:
+  if (outbuf)
+    free(outbuf);
+  return 0;
+}
diff --git a/nc_test4/filter_test/H5Ztest.c b/nc_test4/filter_test/H5Ztest.c
new file mode 100644
index 0000000..7cccaf7
--- /dev/null
+++ b/nc_test4/filter_test/H5Ztest.c
@@ -0,0 +1,207 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+
+#include "h5test.h"
+
+#undef DEBUG 
+
+static int paramcheck(size_t nparams, const unsigned int* params);
+static void byteswap8(unsigned char* mem);
+static void mismatch(size_t i, const char* which);
+
+const H5Z_class2_t H5Z_TEST[1] = {{
+    H5Z_CLASS_T_VERS,                /* H5Z_class_t version */
+    (H5Z_filter_t)(H5Z_FILTER_TEST), /* Filter id number */
+    1,                               /* encoder_present flag (set to true) */
+    1,                               /* decoder_present flag (set to true) */
+    "test",                          /* Filter name for debugging    */
+    NULL,                            /* The "can apply" callback     */
+    NULL,                            /* The "set local" callback     */
+    (H5Z_func_t)H5Z_filter_test,     /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_TEST;
+}
+
+/*
+This filter does some verification
+that the parameters passed to the filter
+are correct. Specifically, that endian-ness
+is correct. As a filter, it is the identify
+function, passing input to output unchanged.
+
+Test cases format:
+1.The first param is the test index i.e. which test to execute.
+2. The remaining parameters are those for the test chosen in #1
+
+*/
+
+size_t
+H5Z_filter_test(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+    int ret;
+    void* newbuf;
+    unsigned int testcase = 0;
+
+    if(cd_nelmts == 0)
+	goto fail;
+
+    testcase = cd_values[0];
+
+    if(testcase == TC_ENDIAN) {
+	if(!paramcheck(cd_nelmts,cd_values))
+	    goto fail;
+    }
+
+    if (flags & H5Z_FLAG_REVERSE) {
+
+        /* Replace buffer */
+        newbuf = malloc(*buf_size);
+        if(newbuf == NULL) abort();
+        memcpy(newbuf,*buf,*buf_size);
+        *buf = newbuf;
+
+    } else {
+
+        /* Replace buffer */
+        newbuf = malloc(*buf_size);
+        if(newbuf == NULL) abort();
+        memcpy(newbuf,*buf,*buf_size);
+        *buf = newbuf;
+
+    }
+
+    return *buf_size;
+
+fail:
+    return 0;
+}
+
+static int
+paramcheck(size_t nparams, const unsigned int* params)
+{
+    size_t i;
+    /* Test endianness of this machine */
+    const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
+    int endianness = (1 == *(unsigned int*)b); /* 1=>big 0=>little*/
+
+    if(nparams != 14) {
+	fprintf(stderr,"Too few parameters: need=16 sent=%ld\n",nparams);
+	return 0;
+    }       
+
+    for(i=0;i<nparams;i++) {
+        switch (i) {
+        case 0: break; /* this is the testcase # */
+        case 1: if(((signed char)-17) != (signed int)(params[i]))
+	    {mismatch(i,"signed byte"); return 0; };
+	    break;
+        case 2: if(((unsigned char)23) != (unsigned int)(params[i]))
+	    {mismatch(i,"unsigned byte"); return 0; };
+	    break;
+        case 3: if(((signed short)-25) != (signed int)(params[i]))
+	    {mismatch(i,"signed short"); return 0; };
+	    break;
+        case 4: if(((unsigned short)27) != (unsigned int)(params[i]))
+	    {mismatch(i,"unsigned short"); return 0; };
+	    break;
+        case 5: if(77 != (signed int)(params[i]))
+	    {mismatch(i,"signed int"); return 0; };
+	    break;
+        case 6: if(93u != (unsigned int)(params[i]))
+	    {mismatch(i,"unsigned int"); return 0; };
+	    break;
+        case 7: if(789.0f != *(float*)(&params[i]))
+	    {mismatch(i,"float"); return 0; };
+	    break;
+        case 8: {/*double*/
+            double x = *(double*)&params[i];
+            i++; /* takes two parameters */
+            if(endianness == 1)
+		byteswap8((unsigned char*)&x);
+            if(12345678.12345678d != x) {
+                mismatch(i,"double");
+                return 0;
+            }
+            }; break;
+        case 10: {/*signed long long*/
+            signed long long x = *(signed long long*)&params[i];
+            i++; /* takes two parameters */
+            if(endianness == 1)
+		byteswap8((unsigned char*)&x);
+            if(-9223372036854775807L != x) {
+                mismatch(i,"signed long long");
+                return 0;
+            }
+            }; break;
+        case 12: {/*unsigned long long*/
+            unsigned long long x = *(unsigned long long*)&params[i];
+            i++; /* takes two parameters */
+            if(endianness == 1)
+		byteswap8((unsigned char*)&x);
+            if(18446744073709551615UL != x) {
+                mismatch(i,"unsigned long long");
+                return 0;
+            }
+            }; break;
+        default:
+            mismatch(i,"unexpected parameter");
+            return 0;
+            break;
+        }
+    }
+
+#ifdef DEBUG
+    {
+	size_t i;
+	fprintf(stderr,"endianness=%d nparams=%d params=\n",endianness,nparams);
+	for(i=0;i<nparams;i++) {
+	    fprintf(stderr,"[%d] %ud %d %f\n", (unsigned int)i, params[i],(signed int)params[i],*(float*)&params[i]);
+	}
+	fflush(stderr);
+    }
+#endif
+}
+
+static void
+byteswap8(unsigned char* mem)
+{
+    unsigned char c;
+    c = mem[0];
+    mem[0] = mem[7];
+    mem[7] = c;
+    c = mem[1];
+    mem[1] = mem[6];
+    mem[6] = c;
+    c = mem[2];
+    mem[2] = mem[5];
+    mem[5] = c;
+    c = mem[3];
+    mem[3] = mem[4];
+    mem[4] = c;
+}
+
+static void
+mismatch(size_t i, const char* which)
+{
+    fprintf(stderr,"mismatch: [%ld] %s\n",i,which);
+    fflush(stderr);
+}
diff --git a/nc_test4/filter_test/Make0 b/nc_test4/filter_test/Make0
new file mode 100644
index 0000000..1a08b12
--- /dev/null
+++ b/nc_test4/filter_test/Make0
@@ -0,0 +1,38 @@
+# Test c output
+T=test_misc
+#CMD=valgrind --leak-check=full
+CMD=gdb --args
+
+EXECDIR=../..
+SRCDIR=../..
+
+#PAR=1
+SZIP=1
+
+CFLAGS = -Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I${SRCDIR} -I${SRCDIR}/include
+
+LDFLAGS = ${EXECDIR}/liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lm
+
+ifdef PAR
+CC=mpicc
+LDFLAGS += -lmpich
+else
+CC=gcc
+endif
+
+ifdef SZIP
+LDFLAGS += -lsz -laec
+endif
+
+LLP=/usr/local/lib:${LD_LIBRARY_PATH}
+
+all:: cmp
+	export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
+	${CMD} ./t
+
+cmp::
+	export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
+	${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}
+
+cpp::
+	${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
diff --git a/nc_test4/filter_test/Makefile.am b/nc_test4/filter_test/Makefile.am
new file mode 100644
index 0000000..34238bf
--- /dev/null
+++ b/nc_test4/filter_test/Makefile.am
@@ -0,0 +1,77 @@
+# Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
+# See the COPYRIGHT file for more information.
+
+# Put together AM_CPPFLAGS and AM_LDFLAGS.
+include $(top_srcdir)/lib_flags.am
+
+FILTERNAME=bzip2
+
+BZIP2HDRS=bzlib.h bzlib_private.h
+BZIP2SRC=\
+      blocksort.c  \
+      huffman.c    \
+      crctable.c   \
+      randtable.c  \
+      compress.c   \
+      decompress.c \
+      bzlib.c
+
+PLUGINSRC=H5Zbzip2.c
+PLUGINHDRS=h5bzip2.h
+
+#bin_PROGRAMS = fake
+#fake_SOURCES = fake.c H5Zbzip2.c ${BZIP2SRC}
+
+# Link to our assembled library.
+test_filter_LDFLAGS = ${top_builddir}/liblib/libnetcdf.la
+test_filter_SOURCE = test_filter.c
+test_misc_LDFLAGS = ${top_builddir}/liblib/libnetcdf.la
+test_misc_SOURCE = test_misc.c
+
+BZIP2OBJ=${BZIP2SRC:%.o=%.c}
+
+if ISCYGWIN
+LIBNAME=cyg${FILTERNAME}.dll
+TESTLIB=cygtest.dll
+else
+LIBNAME=lib${FILTERNAME}.so
+TESTLIB=libtest.so
+endif
+
+EXTRA_DIST=${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS} \
+	tst_filter.sh bzip2.cdl unfiltered.cdl filtered.cdl ref_bzip2.c \
+	H5Ztemplate.c h5test.h H5Ztest.c \
+	CMakeLists.txt
+CLEANFILES = ${LIBNAME} ${TESTLIB} *.nc *.dump tmp
+
+if ENABLE_FILTER_TEST
+
+check_PROGRAMS = test_filter test_misc
+TESTS = tst_filter.sh
+
+# In order to create the bzip shared object,
+# we provide an explicit target for it that
+# must be invoked before 'make check'
+
+# You may need to change this if HDF5 is installed elsewhere
+HDF5LIBDIR = /usr/local/lib
+# Ditto for zlib
+ZLIBDIR = ${HDF5LIBDIR}
+
+BUILT_SOURCES = ${LIBNAME} ${TESTLIB}
+${LIBNAME}: ${PLUGINSRC:${srcdir}%.c=%.c} ${BZIP2SRC:${srcdir}%.c=%.c}
+	SDIR=${srcdir} ;\
+	for f in ${PLUGINSRC} ${BZIP2SRC} ; do \
+        DLLSRC="$${DLLSRC} $${SDIR}/$$f" ; \
+	done ; \
+	gcc -g -O0 -shared -o ${LIBNAME} $${DLLSRC} \
+	-L${HDF5LIBDIR} -lhdf5_hl -lhdf5 -L${ZLIBDIR} -lz
+
+${TESTLIB}: ${srcdir}/H5Ztest.c
+	SDIR=${srcdir} ;\
+        DLLSRC="$${DLLSRC} $${SDIR}/H5Ztest.c" ; \
+	gcc -g -O0 -shared -o ${TESTLIB} $${DLLSRC} \
+	-L${HDF5LIBDIR} -lhdf5_hl -lhdf5 -L${ZLIBDIR} -lz
+
+
+endif
diff --git a/nc_test4/filter_test/blocksort.c b/nc_test4/filter_test/blocksort.c
new file mode 100644
index 0000000..d0d662c
--- /dev/null
+++ b/nc_test4/filter_test/blocksort.c
@@ -0,0 +1,1094 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+__inline__
+void fallbackSimpleSort ( UInt32* fmap, 
+                          UInt32* eclass, 
+                          Int32   lo, 
+                          Int32   hi )
+{
+   Int32 i, j, tmp;
+   UInt32 ec_tmp;
+
+   if (lo == hi) return;
+
+   if (hi - lo > 3) {
+      for ( i = hi-4; i >= lo; i-- ) {
+         tmp = fmap[i];
+         ec_tmp = eclass[tmp];
+         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+            fmap[j-4] = fmap[j];
+         fmap[j-4] = tmp;
+      }
+   }
+
+   for ( i = hi-1; i >= lo; i-- ) {
+      tmp = fmap[i];
+      ec_tmp = eclass[tmp];
+      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+         fmap[j-1] = fmap[j];
+      fmap[j-1] = tmp;
+   }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      fswap(fmap[yyp1], fmap[yyp2]);  \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+                       stackHi[sp] = hz; \
+                       sp++; }
+
+#define fpop(lz,hz) { sp--;              \
+                      lz = stackLo[sp];  \
+                      hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap, 
+                      UInt32* eclass,
+                      Int32   loSt, 
+                      Int32   hiSt )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m;
+   Int32 sp, lo, hi;
+   UInt32 med, r, r3;
+   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+   r = 0;
+
+   sp = 0;
+   fpush ( loSt, hiSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+      fpop ( lo, hi );
+      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+         fallbackSimpleSort ( fmap, eclass, lo, hi );
+         continue;
+      }
+
+      /* Random partitioning.  Median of 3 sometimes fails to
+         avoid bad cases.  Median of 9 seems to help but 
+         looks rather expensive.  This too seems to work but
+         is cheaper.  Guidance for the magic constants 
+         7621 and 32768 is taken from Sedgewick's algorithms
+         book, chapter 35.
+      */
+      r = ((r * 7621) + 1) % 32768;
+      r3 = r % 3;
+      if (r3 == 0) med = eclass[fmap[lo]]; else
+      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+                   med = eclass[fmap[hi]];
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (1) {
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unLo], fmap[ltLo]); 
+               ltLo++; unLo++; 
+               continue; 
+            };
+            if (n > 0) break;
+            unLo++;
+         }
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unHi], fmap[gtHi]); 
+               gtHi--; unHi--; 
+               continue; 
+            };
+            if (n < 0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+      if (gtHi < ltLo) continue;
+
+      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      if (n - lo > hi - m) {
+         fpush ( lo, n );
+         fpush ( m, hi );
+      } else {
+         fpush ( m, hi );
+         fpush ( lo, n );
+      }
+   }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      eclass exists for [0 .. nblock-1]
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      All other areas of eclass destroyed
+      fmap [0 .. nblock-1] holds sorted order
+      bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define      WORD_BH(zz)  bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    UInt32* bhtab,
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   /*--
+      Initial 1-char radix sort to generate
+      initial fmap and initial BH bits.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        bucket sorting ...\n" );
+   for (i = 0; i < 257;    i++) ftab[i] = 0;
+   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i < nblock; i++) {
+      j = eclass8[i];
+      k = ftab[j] - 1;
+      ftab[j] = k;
+      fmap[k] = i;
+   }
+
+   nBhtab = 2 + (nblock / 32);
+   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+   /*--
+      Inductively refine the buckets.  Kind-of an
+      "exponential radix sort" (!), inspired by the
+      Manber-Myers suffix array construction algorithm.
+   --*/
+
+   /*-- set sentinel bits for block-end detection --*/
+   for (i = 0; i < 32; i++) { 
+      SET_BH(nblock + 2*i);
+      CLEAR_BH(nblock + 2*i + 1);
+   }
+
+   /*-- the log(N) loop --*/
+   H = 1;
+   while (1) {
+
+      if (verb >= 4) 
+         VPrintf1 ( "        depth %6d has ", H );
+
+      j = 0;
+      for (i = 0; i < nblock; i++) {
+         if (ISSET_BH(i)) j = i;
+         k = fmap[i] - H; if (k < 0) k += nblock;
+         eclass[k] = j;
+      }
+
+      nNotDone = 0;
+      r = -1;
+      while (1) {
+
+	 /*-- find the next non-singleton bucket --*/
+         k = r + 1;
+         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (ISSET_BH(k)) {
+            while (WORD_BH(k) == 0xffffffff) k += 32;
+            while (ISSET_BH(k)) k++;
+         }
+         l = k - 1;
+         if (l >= nblock) break;
+         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (!ISSET_BH(k)) {
+            while (WORD_BH(k) == 0x00000000) k += 32;
+            while (!ISSET_BH(k)) k++;
+         }
+         r = k - 1;
+         if (r >= nblock) break;
+
+         /*-- now [l, r] bracket current bucket --*/
+         if (r > l) {
+            nNotDone += (r - l + 1);
+            fallbackQSort3 ( fmap, eclass, l, r );
+
+            /*-- scan bucket and generate header bits-- */
+            cc = -1;
+            for (i = l; i <= r; i++) {
+               cc1 = eclass[fmap[i]];
+               if (cc != cc1) { SET_BH(i); cc = cc1; };
+            }
+         }
+      }
+
+      if (verb >= 4) 
+         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+      H *= 2;
+      if (H > nblock || nNotDone == 0) break;
+   }
+
+   /*-- 
+      Reconstruct the original block in
+      eclass8 [0 .. nblock-1], since the
+      previous phase destroyed it.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        reconstructing block ...\n" );
+   j = 0;
+   for (i = 0; i < nblock; i++) {
+      while (ftabCopy[j] == 0) j++;
+      ftabCopy[j]--;
+      eclass8[fmap[i]] = (UChar)j;
+   }
+   AssertH ( j < 256, 1005 );
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for "normal"       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32  i1, 
+               UInt32  i2,
+               UChar*  block, 
+               UInt16* quadrant,
+               UInt32  nblock,
+               Int32*  budget )
+{
+   Int32  k;
+   UChar  c1, c2;
+   UInt16 s1, s2;
+
+   AssertD ( i1 != i2, "mainGtU" );
+   /* 1 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 2 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 3 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 4 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 5 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 6 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 7 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 8 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 9 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 10 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 11 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 12 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+
+   k = nblock + 8;
+
+   do {
+      /* 1 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 2 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 3 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 4 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 5 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 6 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 7 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 8 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+
+      if (i1 >= nblock) i1 -= nblock;
+      if (i2 >= nblock) i2 -= nblock;
+
+      k -= 8;
+      (*budget)--;
+   }
+      while (k >= 0);
+
+   return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Knuth's increments seem to work better
+   than Incerpi-Sedgewick here.  Possibly
+   because the number of elems to sort is
+   usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+                   9841, 29524, 88573, 265720,
+                   797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+                      UChar*  block,
+                      UInt16* quadrant,
+                      Int32   nblock,
+                      Int32   lo, 
+                      Int32   hi, 
+                      Int32   d,
+                      Int32*  budget )
+{
+   Int32 i, j, h, bigN, hp;
+   UInt32 v;
+
+   bigN = hi - lo + 1;
+   if (bigN < 2) return;
+
+   hp = 0;
+   while (incs[hp] < bigN) hp++;
+   hp--;
+
+   for (; hp >= 0; hp--) {
+      h = incs[hp];
+
+      i = lo + h;
+      while (True) {
+
+         /*-- copy 1 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 2 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 3 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         if (*budget < 0) return;
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+/*--
+   The following is an implementation of
+   an elegant 3-way quicksort for strings,
+   described in a paper "Fast Algorithms for
+   Sorting and Searching Strings", by Robert
+   Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      mswap(ptr[yyp1], ptr[yyp2]);    \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+static 
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+   UChar t;
+   if (a > b) { t = a; a = b; b = t; };
+   if (b > c) { 
+      b = c;
+      if (a > b) b = a;
+   }
+   return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+                          stackHi[sp] = hz; \
+                          stackD [sp] = dz; \
+                          sp++; }
+
+#define mpop(lz,hz,dz) { sp--;             \
+                         lz = stackLo[sp]; \
+                         hz = stackHi[sp]; \
+                         dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz)                                        \
+   { Int32 tz;                                                  \
+     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+                  UChar*  block,
+                  UInt16* quadrant,
+                  Int32   nblock,
+                  Int32   loSt, 
+                  Int32   hiSt, 
+                  Int32   dSt,
+                  Int32*  budget )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+   Int32 sp, lo, hi, d;
+
+   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+   Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+   Int32 nextLo[3];
+   Int32 nextHi[3];
+   Int32 nextD [3];
+
+   sp = 0;
+   mpush ( loSt, hiSt, dSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+      mpop ( lo, hi, d );
+      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
+          d > MAIN_QSORT_DEPTH_THRESH) {
+         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+         if (*budget < 0) return;
+         continue;
+      }
+
+      med = (Int32) 
+            mmed3 ( block[ptr[ lo         ]+d],
+                    block[ptr[ hi         ]+d],
+                    block[ptr[ (lo+hi)>>1 ]+d] );
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (True) {
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unLo]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unLo], ptr[ltLo]); 
+               ltLo++; unLo++; continue; 
+            };
+            if (n >  0) break;
+            unLo++;
+         }
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unHi]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unHi], ptr[gtHi]); 
+               gtHi--; unHi--; continue; 
+            };
+            if (n <  0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+      if (gtHi < ltLo) {
+         mpush(lo, hi, d+1 );
+         continue;
+      }
+
+      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+      mpush (nextLo[0], nextHi[0], nextD[0]);
+      mpush (nextLo[1], nextHi[1], nextD[1]);
+      mpush (nextLo[2], nextHi[2], nextD[2]);
+   }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > N_OVERSHOOT
+      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      All other areas of block32 destroyed
+      ftab [0 .. 65536 ] destroyed
+      ptr [0 .. nblock-1] holds sorted order
+      if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr, 
+                UChar*  block,
+                UInt16* quadrant, 
+                UInt32* ftab,
+                Int32   nblock,
+                Int32   verb,
+                Int32*  budget )
+{
+   Int32  i, j, k, ss, sb;
+   Int32  runningOrder[256];
+   Bool   bigDone[256];
+   Int32  copyStart[256];
+   Int32  copyEnd  [256];
+   UChar  c1;
+   Int32  numQSorted;
+   UInt16 s;
+   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
+
+   /*-- set up the 2-byte frequency table --*/
+   for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+   j = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+      quadrant[i-1] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+      ftab[j]++;
+      quadrant[i-2] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+      ftab[j]++;
+      quadrant[i-3] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+      ftab[j]++;
+   }
+   for (; i >= 0; i--) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+   }
+
+   /*-- (emphasises close relationship of block & quadrant) --*/
+   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+      block   [nblock+i] = block[i];
+      quadrant[nblock+i] = 0;
+   }
+
+   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
+
+   /*-- Complete the initial radix sort --*/
+   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+   s = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+      s = (s >> 8) | (block[i-1] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-1;
+      s = (s >> 8) | (block[i-2] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-2;
+      s = (s >> 8) | (block[i-3] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-3;
+   }
+   for (; i >= 0; i--) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+   }
+
+   /*--
+      Now ftab contains the first loc of every small bucket.
+      Calculate the running order, from smallest to largest
+      big bucket.
+   --*/
+   for (i = 0; i <= 255; i++) {
+      bigDone     [i] = False;
+      runningOrder[i] = i;
+   }
+
+   {
+      Int32 vv;
+      Int32 h = 1;
+      do h = 3 * h + 1; while (h <= 256);
+      do {
+         h = h / 3;
+         for (i = h; i <= 255; i++) {
+            vv = runningOrder[i];
+            j = i;
+            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+               runningOrder[j] = runningOrder[j-h];
+               j = j - h;
+               if (j <= (h - 1)) goto zero;
+            }
+            zero:
+            runningOrder[j] = vv;
+         }
+      } while (h != 1);
+   }
+
+   /*--
+      The main sorting loop.
+   --*/
+
+   numQSorted = 0;
+
+   for (i = 0; i <= 255; i++) {
+
+      /*--
+         Process big buckets, starting with the least full.
+         Basically this is a 3-step process in which we call
+         mainQSort3 to sort the small buckets [ss, j], but
+         also make a big effort to avoid the calls if we can.
+      --*/
+      ss = runningOrder[i];
+
+      /*--
+         Step 1:
+         Complete the big bucket [ss] by quicksorting
+         any unsorted small buckets [ss, j], for j != ss.  
+         Hopefully previous pointer-scanning phases have already
+         completed many of the small buckets [ss, j], so
+         we don't have to sort them at all.
+      --*/
+      for (j = 0; j <= 255; j++) {
+         if (j != ss) {
+            sb = (ss << 8) + j;
+            if ( ! (ftab[sb] & SETMASK) ) {
+               Int32 lo = ftab[sb]   & CLEARMASK;
+               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+               if (hi > lo) {
+                  if (verb >= 4)
+                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
+                                "done %d   this %d\n",
+                                ss, j, numQSorted, hi - lo + 1 );
+                  mainQSort3 ( 
+                     ptr, block, quadrant, nblock, 
+                     lo, hi, BZ_N_RADIX, budget 
+                  );   
+                  numQSorted += (hi - lo + 1);
+                  if (*budget < 0) return;
+               }
+            }
+            ftab[sb] |= SETMASK;
+         }
+      }
+
+      AssertH ( !bigDone[ss], 1006 );
+
+      /*--
+         Step 2:
+         Now scan this big bucket [ss] so as to synthesise the
+         sorted order for small buckets [t, ss] for all t,
+         including, magically, the bucket [ss,ss] too.
+         This will avoid doing Real Work in subsequent Step 1's.
+      --*/
+      {
+         for (j = 0; j <= 255; j++) {
+            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
+            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+         }
+         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1])
+               ptr[ copyStart[c1]++ ] = k;
+         }
+         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1]) 
+               ptr[ copyEnd[c1]-- ] = k;
+         }
+      }
+
+      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+                || 
+                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+                   Necessity for this case is demonstrated by compressing 
+                   a sequence of approximately 48.5 million of character 
+                   251; 1.0.0/1.0.1 will then die here. */
+                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+                1007 )
+
+      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+      /*--
+         Step 3:
+         The [ss] big bucket is now done.  Record this fact,
+         and update the quadrant descriptors.  Remember to
+         update quadrants in the overshoot area too, if
+         necessary.  The "if (i < 255)" test merely skips
+         this updating for the last bucket processed, since
+         updating for the last bucket is pointless.
+
+         The quadrant array provides a way to incrementally
+         cache sort orderings, as they appear, so as to 
+         make subsequent comparisons in fullGtU() complete
+         faster.  For repetitive blocks this makes a big
+         difference (but not big enough to be able to avoid
+         the fallback sorting mechanism, exponential radix sort).
+
+         The precise meaning is: at all times:
+
+            for 0 <= i < nblock and 0 <= j <= nblock
+
+            if block[i] != block[j], 
+
+               then the relative values of quadrant[i] and 
+                    quadrant[j] are meaningless.
+
+               else {
+                  if quadrant[i] < quadrant[j]
+                     then the string starting at i lexicographically
+                     precedes the string starting at j
+
+                  else if quadrant[i] > quadrant[j]
+                     then the string starting at j lexicographically
+                     precedes the string starting at i
+
+                  else
+                     the relative ordering of the strings starting
+                     at i and j has not yet been determined.
+               }
+      --*/
+      bigDone[ss] = True;
+
+      if (i < 255) {
+         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
+         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+         Int32 shifts   = 0;
+
+         while ((bbSize >> shifts) > 65534) shifts++;
+
+         for (j = bbSize-1; j >= 0; j--) {
+            Int32 a2update     = ptr[bbStart + j];
+            UInt16 qVal        = (UInt16)(j >> shifts);
+            quadrant[a2update] = qVal;
+            if (a2update < BZ_N_OVERSHOOT)
+               quadrant[a2update + nblock] = qVal;
+         }
+         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+      }
+
+   }
+
+   if (verb >= 4)
+      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
+                 nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)arr2)  [0 .. nblock-1] holds block
+      arr1 exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)arr2) [0 .. nblock-1] holds block
+      All other areas of block destroyed
+      ftab [ 0 .. 65536 ] destroyed
+      arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+   UInt32* ptr    = s->ptr; 
+   UChar*  block  = s->block;
+   UInt32* ftab   = s->ftab;
+   Int32   nblock = s->nblock;
+   Int32   verb   = s->verbosity;
+   Int32   wfact  = s->workFactor;
+   UInt16* quadrant;
+   Int32   budget;
+   Int32   budgetInit;
+   Int32   i;
+
+   if (nblock < 10000) {
+      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+   } else {
+      /* Calculate the location for quadrant, remembering to get
+         the alignment right.  Assumes that &(block[0]) is at least
+         2-byte aligned -- this should be ok since block is really
+         the first section of arr2.
+      */
+      i = nblock+BZ_N_OVERSHOOT;
+      if (i & 1) i++;
+      quadrant = (UInt16*)(&(block[i]));
+
+      /* (wfact-1) / 3 puts the default-factor-30
+         transition point at very roughly the same place as 
+         with v0.1 and v0.9.0.  
+         Not that it particularly matters any more, since the
+         resulting compressed stream is now the same regardless
+         of whether or not we use the main sort or fallback sort.
+      */
+      if (wfact < 1  ) wfact = 1;
+      if (wfact > 100) wfact = 100;
+      budgetInit = nblock * ((wfact-1) / 3);
+      budget = budgetInit;
+
+      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+      if (verb >= 3) 
+         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
+                    budgetInit - budget,
+                    nblock, 
+                    (float)(budgetInit - budget) /
+                    (float)(nblock==0 ? 1 : nblock) ); 
+      if (budget < 0) {
+         if (verb >= 2) 
+            VPrintf0 ( "    too repetitive; using fallback"
+                       " sorting algorithm\n" );
+         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+      }
+   }
+
+   s->origPtr = -1;
+   for (i = 0; i < s->nblock; i++)
+      if (ptr[i] == 0)
+         { s->origPtr = i; break; };
+
+   AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/bzlib.c b/nc_test4/filter_test/bzlib.c
new file mode 100644
index 0000000..bd358a7
--- /dev/null
+++ b/nc_test4/filter_test/bzlib.c
@@ -0,0 +1,1572 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* CHANGES
+   0.9.0    -- original version.
+   0.9.0a/b -- no changes in this file.
+   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+     fixed bzWrite/bzRead to ignore zero-length requests.
+     fixed bzread to correctly handle read requests after EOF.
+     wrong parameter order in call to bzDecompressInit in
+     bzBuffToBuffDecompress.  Fixed.
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+   fprintf(stderr, 
+      "\n\nbzip2/libbzip2: internal error number %d.\n"
+      "This is a bug in bzip2/libbzip2, %s.\n"
+      "Please report it to me at: jseward at bzip.org.  If this happened\n"
+      "when you were using some program which uses libbzip2 as a\n"
+      "component, you should also report this bug to the author(s)\n"
+      "of that program.  Please make an effort to report this bug;\n"
+      "timely and accurate bug reports eventually lead to higher\n"
+      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
+      errcode,
+      BZ2_bzlibVersion()
+   );
+
+   if (errcode == 1007) {
+   fprintf(stderr,
+      "\n*** A special note about internal error number 1007 ***\n"
+      "\n"
+      "Experience suggests that a common cause of i.e. 1007\n"
+      "is unreliable memory or other hardware.  The 1007 assertion\n"
+      "just happens to cross-check the results of huge numbers of\n"
+      "memory reads/writes, and so acts (unintendedly) as a stress\n"
+      "test of your memory system.\n"
+      "\n"
+      "I suggest the following: try compressing the file again,\n"
+      "possibly monitoring progress in detail with the -vv flag.\n"
+      "\n"
+      "* If the error cannot be reproduced, and/or happens at different\n"
+      "  points in compression, you may have a flaky memory system.\n"
+      "  Try a memory-test program.  I have used Memtest86\n"
+      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
+      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
+      "  power-on test, and may find failures that the BIOS doesn't.\n"
+      "\n"
+      "* If the error can be repeatably reproduced, this is a bug in\n"
+      "  bzip2, and I would very much like to hear about it.  Please\n"
+      "  let me know, and, ideally, save a copy of the file causing the\n"
+      "  problem -- without which I will be unable to investigate it.\n"
+      "\n"
+   );
+   }
+
+   exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+   if (sizeof(int)   != 4) return 0;
+   if (sizeof(short) != 2) return 0;
+   if (sizeof(char)  != 1) return 0;
+   return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+   void* v = malloc ( items * size );
+   return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+   if (addr != NULL) free ( addr );
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+   Int32 i;
+   s->nblock = 0;
+   s->numZ = 0;
+   s->state_out_pos = 0;
+   BZ_INITIALISE_CRC ( s->blockCRC );
+   for (i = 0; i < 256; i++) s->inUse[i] = False;
+   s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+   s->state_in_ch  = 256;
+   s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+   if (s->state_in_ch < 256 && s->state_in_len > 0)
+      return False; else
+      return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit) 
+                    ( bz_stream* strm, 
+                     int        blockSize100k,
+                     int        verbosity,
+                     int        workFactor )
+{
+   Int32   n;
+   EState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL || 
+       blockSize100k < 1 || blockSize100k > 9 ||
+       workFactor < 0 || workFactor > 250)
+     return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(EState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm = strm;
+
+   s->arr1 = NULL;
+   s->arr2 = NULL;
+   s->ftab = NULL;
+
+   n       = 100000 * blockSize100k;
+   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
+   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
+
+   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+      if (s->arr1 != NULL) BZFREE(s->arr1);
+      if (s->arr2 != NULL) BZFREE(s->arr2);
+      if (s->ftab != NULL) BZFREE(s->ftab);
+      if (s       != NULL) BZFREE(s);
+      return BZ_MEM_ERROR;
+   }
+
+   s->blockNo           = 0;
+   s->state             = BZ_S_INPUT;
+   s->mode              = BZ_M_RUNNING;
+   s->combinedCRC       = 0;
+   s->blockSize100k     = blockSize100k;
+   s->nblockMAX         = 100000 * blockSize100k - 19;
+   s->verbosity         = verbosity;
+   s->workFactor        = workFactor;
+
+   s->block             = (UChar*)s->arr2;
+   s->mtfv              = (UInt16*)s->arr1;
+   s->zbits             = NULL;
+   s->ptr               = (UInt32*)s->arr1;
+
+   strm->state          = s;
+   strm->total_in_lo32  = 0;
+   strm->total_in_hi32  = 0;
+   strm->total_out_lo32 = 0;
+   strm->total_out_hi32 = 0;
+   init_RL ( s );
+   prepare_new_block ( s );
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+   Int32 i;
+   UChar ch = (UChar)(s->state_in_ch);
+   for (i = 0; i < s->state_in_len; i++) {
+      BZ_UPDATE_CRC( s->blockCRC, ch );
+   }
+   s->inUse[s->state_in_ch] = True;
+   switch (s->state_in_len) {
+      case 1:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 2:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 3:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      default:
+         s->inUse[s->state_in_len-4] = True;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+         s->nblock++;
+         break;
+   }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+   if (s->state_in_ch < 256) add_pair_to_block ( s );
+   init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
+{                                                 \
+   UInt32 zchh = (UInt32)(zchh0);                 \
+   /*-- fast track the common case --*/           \
+   if (zchh != zs->state_in_ch &&                 \
+       zs->state_in_len == 1) {                   \
+      UChar ch = (UChar)(zs->state_in_ch);        \
+      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
+      zs->inUse[zs->state_in_ch] = True;          \
+      zs->block[zs->nblock] = (UChar)ch;          \
+      zs->nblock++;                               \
+      zs->state_in_ch = zchh;                     \
+   }                                              \
+   else                                           \
+   /*-- general, uncommon cases --*/              \
+   if (zchh != zs->state_in_ch ||                 \
+      zs->state_in_len == 255) {                  \
+      if (zs->state_in_ch < 256)                  \
+         add_pair_to_block ( zs );                \
+      zs->state_in_ch = zchh;                     \
+      zs->state_in_len = 1;                       \
+   } else {                                       \
+      zs->state_in_len++;                         \
+   }                                              \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+   Bool progress_in = False;
+
+   if (s->mode == BZ_M_RUNNING) {
+
+      /*-- fast track the common case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+      }
+
+   } else {
+
+      /*-- general, uncommon case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         /*-- flush/finish end? --*/
+         if (s->avail_in_expect == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+         s->avail_in_expect--;
+      }
+   }
+   return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+   Bool progress_out = False;
+
+   while (True) {
+
+      /*-- no output space? --*/
+      if (s->strm->avail_out == 0) break;
+
+      /*-- block done? --*/
+      if (s->state_out_pos >= s->numZ) break;
+
+      progress_out = True;
+      *(s->strm->next_out) = s->zbits[s->state_out_pos];
+      s->state_out_pos++;
+      s->strm->avail_out--;
+      s->strm->next_out++;
+      s->strm->total_out_lo32++;
+      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+   }
+
+   return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+   Bool progress_in  = False;
+   Bool progress_out = False;
+   EState* s = strm->state;
+   
+   while (True) {
+
+      if (s->state == BZ_S_OUTPUT) {
+         progress_out |= copy_output_until_stop ( s );
+         if (s->state_out_pos < s->numZ) break;
+         if (s->mode == BZ_M_FINISHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+         prepare_new_block ( s );
+         s->state = BZ_S_INPUT;
+         if (s->mode == BZ_M_FLUSHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+      }
+
+      if (s->state == BZ_S_INPUT) {
+         progress_in |= copy_input_until_stop ( s );
+         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+            flush_RL ( s );
+            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->nblock >= s->nblockMAX) {
+            BZ2_compressBlock ( s, False );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->strm->avail_in == 0) {
+            break;
+         }
+      }
+
+   }
+
+   return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+   Bool progress;
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   preswitch:
+   switch (s->mode) {
+
+      case BZ_M_IDLE:
+         return BZ_SEQUENCE_ERROR;
+
+      case BZ_M_RUNNING:
+         if (action == BZ_RUN) {
+            progress = handle_compress ( strm );
+            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+         } 
+         else
+	 if (action == BZ_FLUSH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FLUSHING;
+            goto preswitch;
+         }
+         else
+         if (action == BZ_FINISH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FINISHING;
+            goto preswitch;
+         }
+         else 
+            return BZ_PARAM_ERROR;
+
+      case BZ_M_FLUSHING:
+         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+         s->mode = BZ_M_RUNNING;
+         return BZ_RUN_OK;
+
+      case BZ_M_FINISHING:
+         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (!progress) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+         s->mode = BZ_M_IDLE;
+         return BZ_STREAM_END;
+   }
+   return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+{
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->arr1 != NULL) BZFREE(s->arr1);
+   if (s->arr2 != NULL) BZFREE(s->arr2);
+   if (s->ftab != NULL) BZFREE(s->ftab);
+   BZFREE(strm->state);
+
+   strm->state = NULL;   
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit) 
+                     ( bz_stream* strm, 
+                       int        verbosity,
+                       int        small )
+{
+   DState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(DState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm                  = strm;
+   strm->state              = s;
+   s->state                 = BZ_X_MAGIC_1;
+   s->bsLive                = 0;
+   s->bsBuff                = 0;
+   s->calculatedCombinedCRC = 0;
+   strm->total_in_lo32      = 0;
+   strm->total_in_hi32      = 0;
+   strm->total_out_lo32     = 0;
+   strm->total_out_hi32     = 0;
+   s->smallDecompress       = (Bool)small;
+   s->ll4                   = NULL;
+   s->ll16                  = NULL;
+   s->tt                    = NULL;
+   s->currBlockNo           = 0;
+   s->verbosity             = verbosity;
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+               
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      /* restore */
+      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
+      UChar         c_state_out_ch       = s->state_out_ch;
+      Int32         c_state_out_len      = s->state_out_len;
+      Int32         c_nblock_used        = s->nblock_used;
+      Int32         c_k0                 = s->k0;
+      UInt32*       c_tt                 = s->tt;
+      UInt32        c_tPos               = s->tPos;
+      char*         cs_next_out          = s->strm->next_out;
+      unsigned int  cs_avail_out         = s->strm->avail_out;
+      Int32         ro_blockSize100k     = s->blockSize100k;
+      /* end restore */
+
+      UInt32       avail_out_INIT = cs_avail_out;
+      Int32        s_save_nblockPP = s->save_nblock+1;
+      unsigned int total_out_lo32_old;
+
+      while (True) {
+
+         /* try to finish existing run */
+         if (c_state_out_len > 0) {
+            while (True) {
+               if (cs_avail_out == 0) goto return_notr;
+               if (c_state_out_len == 1) break;
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               c_state_out_len--;
+               cs_next_out++;
+               cs_avail_out--;
+            }
+            s_state_out_len_eq_one:
+            {
+               if (cs_avail_out == 0) { 
+                  c_state_out_len = 1; goto return_notr;
+               };
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               cs_next_out++;
+               cs_avail_out--;
+            }
+         }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used > s_save_nblockPP)
+            return True;
+
+         /* can a new run be started? */
+         if (c_nblock_used == s_save_nblockPP) {
+            c_state_out_len = 0; goto return_notr;
+         };   
+         c_state_out_ch = c_k0;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (k1 != c_k0) { 
+            c_k0 = k1; goto s_state_out_len_eq_one; 
+         };
+         if (c_nblock_used == s_save_nblockPP) 
+            goto s_state_out_len_eq_one;
+   
+         c_state_out_len = 2;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         c_state_out_len = 3;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         c_state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST_C(c_k0); c_nblock_used++;
+      }
+
+      return_notr:
+      total_out_lo32_old = s->strm->total_out_lo32;
+      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+      if (s->strm->total_out_lo32 < total_out_lo32_old)
+         s->strm->total_out_hi32++;
+
+      /* save */
+      s->calculatedBlockCRC = c_calculatedBlockCRC;
+      s->state_out_ch       = c_state_out_ch;
+      s->state_out_len      = c_state_out_len;
+      s->nblock_used        = c_nblock_used;
+      s->k0                 = c_k0;
+      s->tt                 = c_tt;
+      s->tPos               = c_tPos;
+      s->strm->next_out     = cs_next_out;
+      s->strm->avail_out    = cs_avail_out;
+      /* end save */
+   }
+   return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+   Int32 nb, na, mid;
+   nb = 0;
+   na = 256;
+   do {
+      mid = (nb + na) >> 1;
+      if (indx >= cftab[mid]) nb = mid; else na = mid;
+   }
+   while (na - nb != 1);
+   return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); s->nblock_used++;
+      }
+
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+   Bool    corrupt;
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   while (True) {
+      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+      if (s->state == BZ_X_OUTPUT) {
+         if (s->smallDecompress)
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
+         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+            if (s->verbosity >= 3) 
+               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
+                          s->calculatedBlockCRC );
+            if (s->verbosity >= 2) VPrintf0 ( "]" );
+            if (s->calculatedBlockCRC != s->storedBlockCRC)
+               return BZ_DATA_ERROR;
+            s->calculatedCombinedCRC 
+               = (s->calculatedCombinedCRC << 1) | 
+                    (s->calculatedCombinedCRC >> 31);
+            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+            s->state = BZ_X_BLKHDR_1;
+         } else {
+            return BZ_OK;
+         }
+      }
+      if (s->state >= BZ_X_MAGIC_1) {
+         Int32 r = BZ2_decompress ( s );
+         if (r == BZ_STREAM_END) {
+            if (s->verbosity >= 3)
+               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
+                          s->storedCombinedCRC, s->calculatedCombinedCRC );
+            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+               return BZ_DATA_ERROR;
+            return r;
+         }
+         if (s->state != BZ_X_OUTPUT) return r;
+      }
+   }
+
+   AssertH ( 0, 6001 );
+
+   return 0;  /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+{
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->tt   != NULL) BZFREE(s->tt);
+   if (s->ll16 != NULL) BZFREE(s->ll16);
+   if (s->ll4  != NULL) BZFREE(s->ll4);
+
+   BZFREE(strm->state);
+   strm->state = NULL;
+
+   return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff                              ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee)                    \
+{                                         \
+   if (bzerror != NULL) *bzerror = eee;   \
+   if (bzf != NULL) bzf->lastErr = eee;   \
+}
+
+typedef 
+   struct {
+      FILE*     handle;
+      Char      buf[BZ_MAX_UNUSED];
+      Int32     bufN;
+      Bool      writing;
+      bz_stream strm;
+      Int32     lastErr;
+      Bool      initialisedOk;
+   }
+   bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen) 
+                    ( int*  bzerror,      
+                      FILE* f, 
+                      int   blockSize100k, 
+                      int   verbosity,
+                      int   workFactor )
+{
+   Int32   ret;
+   bzFile* bzf = NULL;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL ||
+       (blockSize100k < 1 || blockSize100k > 9) ||
+       (workFactor < 0 || workFactor > 250) ||
+       (verbosity < 0 || verbosity > 4))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+   bzf->initialisedOk = False;
+   bzf->bufN          = 0;
+   bzf->handle        = f;
+   bzf->writing       = True;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+
+   if (workFactor == 0) workFactor = 30;
+   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = 0;
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+             ( int*    bzerror, 
+               BZFILE* b, 
+               void*   buf, 
+               int     len )
+{
+   Int32 n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return; };
+
+   bzf->strm.avail_in = len;
+   bzf->strm.next_in  = buf;
+
+   while (True) {
+      bzf->strm.avail_out = BZ_MAX_UNUSED;
+      bzf->strm.next_out = bzf->buf;
+      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+      if (ret != BZ_RUN_OK)
+         { BZ_SETERR(ret); return; };
+
+      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                       n, bzf->handle );
+         if (n != n2 || ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return; };
+      }
+
+      if (bzf->strm.avail_in == 0)
+         { BZ_SETERR(BZ_OK); return; };
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in,
+                    unsigned int* nbytes_out )
+{
+   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
+                        nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in_lo32,
+                    unsigned int* nbytes_in_hi32,
+                    unsigned int* nbytes_out_lo32,
+                    unsigned int* nbytes_out_hi32 )
+{
+   Int32   n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+   if ((!abandon) && bzf->lastErr == BZ_OK) {
+      while (True) {
+         bzf->strm.avail_out = BZ_MAX_UNUSED;
+         bzf->strm.next_out = bzf->buf;
+         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+            { BZ_SETERR(ret); return; };
+
+         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                          n, bzf->handle );
+            if (n != n2 || ferror(bzf->handle))
+               { BZ_SETERR(BZ_IO_ERROR); return; };
+         }
+
+         if (ret == BZ_STREAM_END) break;
+      }
+   }
+
+   if ( !abandon && !ferror ( bzf->handle ) ) {
+      fflush ( bzf->handle );
+      if (ferror(bzf->handle))
+         { BZ_SETERR(BZ_IO_ERROR); return; };
+   }
+
+   if (nbytes_in_lo32 != NULL)
+      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+   if (nbytes_in_hi32 != NULL)
+      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+   if (nbytes_out_lo32 != NULL)
+      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+   if (nbytes_out_hi32 != NULL)
+      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+   BZ_SETERR(BZ_OK);
+   BZ2_bzCompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen) 
+                   ( int*  bzerror, 
+                     FILE* f, 
+                     int   verbosity,
+                     int   small,
+                     void* unused,
+                     int   nUnused )
+{
+   bzFile* bzf = NULL;
+   int     ret;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL || 
+       (small != 0 && small != 1) ||
+       (verbosity < 0 || verbosity > 4) ||
+       (unused == NULL && nUnused != 0) ||
+       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL) 
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+
+   bzf->initialisedOk = False;
+   bzf->handle        = f;
+   bzf->bufN          = 0;
+   bzf->writing       = False;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+   
+   while (nUnused > 0) {
+      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+      unused = ((void*)( 1 + ((UChar*)(unused))  ));
+      nUnused--;
+   }
+
+   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = bzf->bufN;
+   bzf->strm.next_in  = bzf->buf;
+
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+   if (bzf->initialisedOk)
+      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead) 
+           ( int*    bzerror, 
+             BZFILE* b, 
+             void*   buf, 
+             int     len )
+{
+   Int32   n, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return 0; };
+
+   bzf->strm.avail_out = len;
+   bzf->strm.next_out = buf;
+
+   while (True) {
+
+      if (ferror(bzf->handle)) 
+         { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+         n = fread ( bzf->buf, sizeof(UChar), 
+                     BZ_MAX_UNUSED, bzf->handle );
+         if (ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return 0; };
+         bzf->bufN = n;
+         bzf->strm.avail_in = bzf->bufN;
+         bzf->strm.next_in = bzf->buf;
+      }
+
+      ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+      if (ret != BZ_OK && ret != BZ_STREAM_END)
+         { BZ_SETERR(ret); return 0; };
+
+      if (ret == BZ_OK && myfeof(bzf->handle) && 
+          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+      if (ret == BZ_STREAM_END)
+         { BZ_SETERR(BZ_STREAM_END);
+           return len - bzf->strm.avail_out; };
+      if (bzf->strm.avail_out == 0)
+         { BZ_SETERR(BZ_OK); return len; };
+      
+   }
+
+   return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused) 
+                     ( int*    bzerror, 
+                       BZFILE* b, 
+                       void**  unused, 
+                       int*    nUnused )
+{
+   bzFile* bzf = (bzFile*)b;
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (bzf->lastErr != BZ_STREAM_END)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (unused == NULL || nUnused == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+   BZ_SETERR(BZ_OK);
+   *nUnused = bzf->strm.avail_in;
+   *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress) 
+                         ( char*         dest, 
+                           unsigned int* destLen,
+                           char*         source, 
+                           unsigned int  sourceLen,
+                           int           blockSize100k, 
+                           int           verbosity, 
+                           int           workFactor )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       blockSize100k < 1 || blockSize100k > 9 ||
+       verbosity < 0 || verbosity > 4 ||
+       workFactor < 0 || workFactor > 250) 
+      return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+   if (ret == BZ_FINISH_OK) goto output_overflow;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;   
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow:
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OUTBUFF_FULL;
+
+   errhandler:
+   BZ2_bzCompressEnd ( &strm );
+   return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress) 
+                           ( char*         dest, 
+                             unsigned int* destLen,
+                             char*         source, 
+                             unsigned int  sourceLen,
+                             int           small,
+                             int           verbosity )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       (small != 0 && small != 1) ||
+       verbosity < 0 || verbosity > 4) 
+          return BZ_PARAM_ERROR;
+
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzDecompress ( &strm );
+   if (ret == BZ_OK) goto output_overflow_or_eof;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;
+   BZ2_bzDecompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow_or_eof:
+   if (strm.avail_out > 0) {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_UNEXPECTED_EOF;
+   } else {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_OUTBUFF_FULL;
+   };      
+
+   errhandler:
+   BZ2_bzDecompressEnd ( &strm );
+   return ret; 
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+   return version like "0.9.5d, 4-Sept-1999".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+   return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#   include <fcntl.h>
+#   include <io.h>
+#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+               ( const char *path,   /* no use when bzdopen */
+                 int fd,             /* no use when bzdopen */
+                 const char *mode,
+                 int open_mode)      /* bzopen: 0, bzdopen:1 */
+{
+   int    bzerr;
+   char   unused[BZ_MAX_UNUSED];
+   int    blockSize100k = 9;
+   int    writing       = 0;
+   char   mode2[10]     = "";
+   FILE   *fp           = NULL;
+   BZFILE *bzfp         = NULL;
+   int    verbosity     = 0;
+   int    workFactor    = 30;
+   int    smallMode     = 0;
+   int    nUnused       = 0; 
+
+   if (mode == NULL) return NULL;
+   while (*mode) {
+      switch (*mode) {
+      case 'r':
+         writing = 0; break;
+      case 'w':
+         writing = 1; break;
+      case 's':
+         smallMode = 1; break;
+      default:
+         if (isdigit((int)(*mode))) {
+            blockSize100k = *mode-BZ_HDR_0;
+         }
+      }
+      mode++;
+   }
+   strcat(mode2, writing ? "w" : "r" );
+   strcat(mode2,"b");   /* binary mode */
+
+   if (open_mode==0) {
+      if (path==NULL || strcmp(path,"")==0) {
+        fp = (writing ? stdout : stdin);
+        SET_BINARY_MODE(fp);
+      } else {
+        fp = fopen(path,mode2);
+      }
+   } else {
+#ifdef BZ_STRICT_ANSI
+      fp = NULL;
+#else
+      fp = fdopen(fd,mode2);
+#endif
+   }
+   if (fp == NULL) return NULL;
+
+   if (writing) {
+      /* Guard against total chaos and anarchy -- JRS */
+      if (blockSize100k < 1) blockSize100k = 1;
+      if (blockSize100k > 9) blockSize100k = 9; 
+      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+                             verbosity,workFactor);
+   } else {
+      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+                            unused,nUnused);
+   }
+   if (bzfp == NULL) {
+      if (fp != stdin && fp != stdout) fclose(fp);
+      return NULL;
+   }
+   return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   open file for read or write.
+      ex) bzopen("file","w9")
+      case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+               ( const char *path,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+               ( int fd,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+   int bzerr, nread;
+   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+   nread = BZ2_bzRead(&bzerr,b,buf,len);
+   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+      return nread;
+   } else {
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+   int bzerr;
+
+   BZ2_bzWrite(&bzerr,b,buf,len);
+   if(bzerr == BZ_OK){
+      return len;
+   }else{
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+   /* do nothing now... */
+   return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+   int bzerr;
+   FILE *fp;
+   
+   if (b==NULL) {return;}
+   fp = ((bzFile *)b)->handle;
+   if(((bzFile*)b)->writing){
+      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+      if(bzerr != BZ_OK){
+         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+      }
+   }else{
+      BZ2_bzReadClose(&bzerr,b);
+   }
+   if(fp!=stdin && fp!=stdout){
+      fclose(fp);
+   }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   return last error code 
+--*/
+static const char *bzerrorstrings[] = {
+       "OK"
+      ,"SEQUENCE_ERROR"
+      ,"PARAM_ERROR"
+      ,"MEM_ERROR"
+      ,"DATA_ERROR"
+      ,"DATA_ERROR_MAGIC"
+      ,"IO_ERROR"
+      ,"UNEXPECTED_EOF"
+      ,"OUTBUFF_FULL"
+      ,"CONFIG_ERROR"
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+   int err = ((bzFile *)b)->lastErr;
+
+   if(err>0) err = 0;
+   *errnum = err;
+   return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/bzlib.h b/nc_test4/filter_test/bzlib.h
new file mode 100644
index 0000000..8277123
--- /dev/null
+++ b/nc_test4/filter_test/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef 
+   struct {
+      char *next_in;
+      unsigned int avail_in;
+      unsigned int total_in_lo32;
+      unsigned int total_in_hi32;
+
+      char *next_out;
+      unsigned int avail_out;
+      unsigned int total_out_lo32;
+      unsigned int total_out_hi32;
+
+      void *state;
+
+      void *(*bzalloc)(void *,int,int);
+      void (*bzfree)(void *,void *);
+      void *opaque;
+   } 
+   bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+#   include <windows.h>
+#   ifdef small
+      /* windows.h define small to char */
+#      undef small
+#   endif
+#   ifdef BZ_EXPORT
+#   define BZ_API(func) WINAPI func
+#   define BZ_EXTERN extern
+#   else
+   /* import windows dll dynamically */
+#   define BZ_API(func) (WINAPI * func)
+#   define BZ_EXTERN
+#   endif
+#else
+#   define BZ_API(func) func
+#   define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
+      bz_stream* strm, 
+      int        blockSize100k, 
+      int        verbosity, 
+      int        workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
+      bz_stream* strm, 
+      int action 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
+      bz_stream *strm, 
+      int       verbosity, 
+      int       small
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
+      bz_stream *strm 
+   );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
+      int*  bzerror,   
+      FILE* f, 
+      int   verbosity, 
+      int   small,
+      void* unused,    
+      int   nUnused 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
+      int*    bzerror, 
+      BZFILE* b 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void**  unused,  
+      int*    nUnused 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
+      int*  bzerror,      
+      FILE* f, 
+      int   blockSize100k, 
+      int   verbosity, 
+      int   workFactor 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in, 
+      unsigned int* nbytes_out 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in_lo32, 
+      unsigned int* nbytes_in_hi32, 
+      unsigned int* nbytes_out_lo32, 
+      unsigned int* nbytes_out_hi32
+   );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           blockSize100k, 
+      int           verbosity, 
+      int           workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           small, 
+      int           verbosity 
+   );
+
+
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+      void
+   );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+      const char *path,
+      const char *mode
+   );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+      int        fd,
+      const char *mode
+   );
+         
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+      BZFILE* b, 
+      void* buf, 
+      int len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+      BZFILE* b
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+      BZFILE* b
+   );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+      BZFILE *b, 
+      int    *errnum
+   );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/bzlib_private.h b/nc_test4/filter_test/bzlib_private.h
new file mode 100644
index 0000000..5d0217f
--- /dev/null
+++ b/nc_test4/filter_test/bzlib_private.h
@@ -0,0 +1,509 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include <stdlib.h>
+
+#ifndef BZ_NO_STDIO
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "bzlib.h"
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION  "1.0.6, 6-Sept-2010"
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__  /* */
+#endif 
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+   { if (!(cond)) {       \
+      fprintf ( stderr,   \
+        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+      exit(1); \
+   }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+   fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+   fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+   fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+   fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+   fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+   fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg)                do { } while (0)
+#define VPrintf0(zf)                     do { } while (0)
+#define VPrintf1(zf,za1)                 do { } while (0)
+#define VPrintf2(zf,za1,za2)             do { } while (0)
+#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+  
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS                          \
+   Int32 rNToGo;                               \
+   Int32 rTPos                                 \
+
+#define BZ_RAND_INIT_MASK                      \
+   s->rNToGo = 0;                              \
+   s->rTPos  = 0                               \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK                       \
+   if (s->rNToGo == 0) {                       \
+      s->rNToGo = BZ2_rNums[s->rTPos];         \
+      s->rTPos++;                              \
+      if (s->rTPos == 512) s->rTPos = 0;       \
+   }                                           \
+   s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar)              \
+{                                              \
+   crcVar = 0xffffffffL;                       \
+}
+
+#define BZ_FINALISE_CRC(crcVar)                \
+{                                              \
+   crcVar = ~(crcVar);                         \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha)              \
+{                                              \
+   crcVar = (crcVar << 8) ^                    \
+            BZ2_crc32Table[(crcVar >> 24) ^    \
+                           ((UChar)cha)];      \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* mode this stream is in, and whether inputting */
+      /* or outputting data */
+      Int32    mode;
+      Int32    state;
+
+      /* remembers avail_in when flush/finish requested */
+      UInt32   avail_in_expect;
+
+      /* for doing the block sorting */
+      UInt32*  arr1;
+      UInt32*  arr2;
+      UInt32*  ftab;
+      Int32    origPtr;
+
+      /* aliases for arr1 and arr2 */
+      UInt32*  ptr;
+      UChar*   block;
+      UInt16*  mtfv;
+      UChar*   zbits;
+
+      /* for deciding when to use the fallback sorting algorithm */
+      Int32    workFactor;
+
+      /* run-length-encoding of the input */
+      UInt32   state_in_ch;
+      Int32    state_in_len;
+      BZ_RAND_DECLS;
+
+      /* input and output limits and current posns */
+      Int32    nblock;
+      Int32    nblockMAX;
+      Int32    numZ;
+      Int32    state_out_pos;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      UChar    unseqToSeq[256];
+
+      /* the buffer for bit stream creation */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* block and combined CRCs */
+      UInt32   blockCRC;
+      UInt32   combinedCRC;
+
+      /* misc administratium */
+      Int32    verbosity;
+      Int32    blockNo;
+      Int32    blockSize100k;
+
+      /* stuff for coding the MTF values */
+      Int32    nMTF;
+      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+
+      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      /* second dimension: only 3 needed; 4 makes index calculations faster */
+      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+   }
+   EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void 
+BZ2_blockSort ( EState* );
+
+extern void 
+BZ2_compressBlock ( EState*, Bool );
+
+extern void 
+BZ2_bsInitWrite ( EState* );
+
+extern void 
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void 
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE        1
+#define BZ_X_OUTPUT      2
+
+#define BZ_X_MAGIC_1     10
+#define BZ_X_MAGIC_2     11
+#define BZ_X_MAGIC_3     12
+#define BZ_X_MAGIC_4     13
+#define BZ_X_BLKHDR_1    14
+#define BZ_X_BLKHDR_2    15
+#define BZ_X_BLKHDR_3    16
+#define BZ_X_BLKHDR_4    17
+#define BZ_X_BLKHDR_5    18
+#define BZ_X_BLKHDR_6    19
+#define BZ_X_BCRC_1      20
+#define BZ_X_BCRC_2      21
+#define BZ_X_BCRC_3      22
+#define BZ_X_BCRC_4      23
+#define BZ_X_RANDBIT     24
+#define BZ_X_ORIGPTR_1   25
+#define BZ_X_ORIGPTR_2   26
+#define BZ_X_ORIGPTR_3   27
+#define BZ_X_MAPPING_1   28
+#define BZ_X_MAPPING_2   29
+#define BZ_X_SELECTOR_1  30
+#define BZ_X_SELECTOR_2  31
+#define BZ_X_SELECTOR_3  32
+#define BZ_X_CODING_1    33
+#define BZ_X_CODING_2    34
+#define BZ_X_CODING_3    35
+#define BZ_X_MTF_1       36
+#define BZ_X_MTF_2       37
+#define BZ_X_MTF_3       38
+#define BZ_X_MTF_4       39
+#define BZ_X_MTF_5       40
+#define BZ_X_MTF_6       41
+#define BZ_X_ENDHDR_2    42
+#define BZ_X_ENDHDR_3    43
+#define BZ_X_ENDHDR_4    44
+#define BZ_X_ENDHDR_5    45
+#define BZ_X_ENDHDR_6    46
+#define BZ_X_CCRC_1      47
+#define BZ_X_CCRC_2      48
+#define BZ_X_CCRC_3      49
+#define BZ_X_CCRC_4      50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* state indicator for this stream */
+      Int32    state;
+
+      /* for doing the final run-length decoding */
+      UChar    state_out_ch;
+      Int32    state_out_len;
+      Bool     blockRandomised;
+      BZ_RAND_DECLS;
+
+      /* the buffer for bit stream reading */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* misc administratium */
+      Int32    blockSize100k;
+      Bool     smallDecompress;
+      Int32    currBlockNo;
+      Int32    verbosity;
+
+      /* for undoing the Burrows-Wheeler transform */
+      Int32    origPtr;
+      UInt32   tPos;
+      Int32    k0;
+      Int32    unzftab[256];
+      Int32    nblock_used;
+      Int32    cftab[257];
+      Int32    cftabCopy[257];
+
+      /* for undoing the Burrows-Wheeler transform (FAST) */
+      UInt32   *tt;
+
+      /* for undoing the Burrows-Wheeler transform (SMALL) */
+      UInt16   *ll16;
+      UChar    *ll4;
+
+      /* stored and calculated CRCs */
+      UInt32   storedBlockCRC;
+      UInt32   storedCombinedCRC;
+      UInt32   calculatedBlockCRC;
+      UInt32   calculatedCombinedCRC;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      Bool     inUse16[16];
+      UChar    seqToUnseq[256];
+
+      /* for decoding the MTF values */
+      UChar    mtfa   [MTFA_SIZE];
+      Int32    mtfbase[256 / MTFL_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    minLens[BZ_N_GROUPS];
+
+      /* save area for scalars in the main decompress code */
+      Int32    save_i;
+      Int32    save_j;
+      Int32    save_t;
+      Int32    save_alphaSize;
+      Int32    save_nGroups;
+      Int32    save_nSelectors;
+      Int32    save_EOB;
+      Int32    save_groupNo;
+      Int32    save_groupPos;
+      Int32    save_nextSym;
+      Int32    save_nblockMAX;
+      Int32    save_nblock;
+      Int32    save_es;
+      Int32    save_N;
+      Int32    save_curr;
+      Int32    save_zt;
+      Int32    save_zn; 
+      Int32    save_zvec;
+      Int32    save_zj;
+      Int32    save_gSel;
+      Int32    save_gMinlen;
+      Int32*   save_gLimit;
+      Int32*   save_gBase;
+      Int32*   save_gPerm;
+
+   }
+   DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc)                     \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    s->tPos = s->tt[s->tPos];                 \
+    cccc = (UChar)(s->tPos & 0xff);           \
+    s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc)                   \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+    c_tPos = c_tt[c_tPos];                    \
+    cccc = (UChar)(c_tPos & 0xff);            \
+    c_tPos >>= 8;
+
+#define SET_LL4(i,n)                                          \
+   { if (((i) & 0x1) == 0)                                    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
+   }
+
+#define GET_LL4(i)                             \
+   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n)                          \
+   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
+     SET_LL4(i, n >> 16);                    \
+   }
+
+#define GET_LL(i) \
+   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc)                            \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
+    s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32 
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32 
+BZ2_decompress ( DState* );
+
+extern void 
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+                           Int32,  Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/compress.c b/nc_test4/filter_test/compress.c
new file mode 100644
index 0000000..caf7696
--- /dev/null
+++ b/nc_test4/filter_test/compress.c
@@ -0,0 +1,672 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s->bsLive = 0;
+   s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s->bsLive > 0) {
+      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+      s->numZ++;
+      s->bsBuff <<= 8;
+      s->bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s->bsLive >= 8) {                   \
+      s->zbits[s->numZ]                       \
+         = (UChar)(s->bsBuff >> 24);          \
+      s->numZ++;                              \
+      s->bsBuff <<= 8;                        \
+      s->bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s->bsBuff |= (v << (32 - s->bsLive - n));
+   s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u >> 24) & 0xffL );
+   bsW ( s, 8, (u >> 16) & 0xffL );
+   bsW ( s, 8, (u >>  8) & 0xffL );
+   bsW ( s, 8,  u        & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->unseqToSeq[i] = s->nInUse;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s->ptr;
+   UChar* block  = s->block;
+   UInt16* mtfv  = s->mtfv;
+
+   makeMaps_e ( s );
+   EOB = s->nInUse+1;
+
+   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i < s->nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr <= i, "generateMTFValues(1)" );
+      j = ptr[i]-1; if (j < 0) j += s->nblock;
+      ll_i = s->unseqToSeq[block[j]];
+      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend > 0) {
+            zPend--;
+            while (True) {
+               if (zPend & 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s->mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s->mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend < 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &(yy[0]);
+            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend > 0) {
+      zPend--;
+      while (True) {
+         if (zPend & 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s->mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s->mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend < 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+   s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s->mtfv;
+
+   if (s->verbosity >= 3)
+      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
+                "%d+2 syms in use\n", 
+                s->nblock, s->nMTF, s->nInUse );
+
+   alphaSize = s->nInUse+2;
+   for (t = 0; t < BZ_N_GROUPS; t++)
+      for (v = 0; v < alphaSize; v++)
+         s->len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s->nMTF > 0, 3001 );
+   if (s->nMTF < 200)  nGroups = 2; else
+   if (s->nMTF < 600)  nGroups = 3; else
+   if (s->nMTF < 1200) nGroups = 4; else
+   if (s->nMTF < 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s->nMTF;
+      gs = 0;
+      while (nPart > 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq < tFreq && ge < alphaSize-1) {
+            ge++;
+            aFreq += s->mtfFreq[ge];
+         }
+
+         if (ge > gs 
+             && nPart != nGroups && nPart != 1 
+             && ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s->mtfFreq[ge];
+            ge--;
+         }
+
+         if (s->verbosity >= 3)
+            VPrintf5( "      initial group %d, [%d .. %d], "
+                      "has %d syms (%4.1f%%)\n",
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
+ 
+         for (v = 0; v < alphaSize; v++)
+            if (v >= gs && v <= ge) 
+               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s->len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+      for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t < nGroups; t++)
+         for (v = 0; v < alphaSize; v++)
+            s->rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v < alphaSize; v++) {
+            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start & end marks. --*/
+         if (gs >= s->nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge >= s->nMTF) ge = s->nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s->len_pack[icv][0]; \
+               cost23 += s->len_pack[icv][1]; \
+               cost45 += s->len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t < nGroups; t++)
+            if (cost[t] < bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s->selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++)
+               s->rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s->verbosity >= 3) {
+         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
+                   iter+1, totc/8 );
+         for (t = 0; t < nGroups; t++)
+            VPrintf1 ( "%d ", fave[t] );
+         VPrintf0 ( "\n" );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t < nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups < 8, 3002 );
+   AssertH( nSelectors < 32768 &&
+            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i < nGroups; i++) pos[i] = i;
+      for (i = 0; i < nSelectors; i++) {
+         ll_i = s->selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s->selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t < nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i < alphaSize; i++) {
+         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+         if (s->len[t][i] < minLen) minLen = s->len[t][i];
+      }
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen < 1),  3005 );
+      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i < 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j < 16; j++)
+             if (s->inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s->numZ;
+      for (i = 0; i < 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i < 16; i++)
+         if (inUse16[i])
+            for (j = 0; j < 16; j++) {
+               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s->verbosity >= 3) 
+         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s->numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i < nSelectors; i++) { 
+      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s->verbosity >= 3)
+      VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s->numZ;
+
+   for (t = 0; t < nGroups; t++) {
+      Int32 curr = s->len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i < alphaSize; i++) {
+         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s->verbosity >= 3)
+      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s->numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs >= s->nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge >= s->nMTF) ge = s->nMTF-1;
+      AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+      if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &(s->len[s->selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &(s->code[s->selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i <= ge; i++) {
+            bsW ( s, 
+                  s->len  [s->selector[selCtr]] [mtfv[i]],
+                  s->code [s->selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s->verbosity >= 3)
+      VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s->nblock > 0) {
+
+      BZ_FINALISE_CRC ( s->blockCRC );
+      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+      s->combinedCRC ^= s->blockCRC;
+      if (s->blockNo > 1) s->numZ = 0;
+
+      if (s->verbosity >= 2)
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
+                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s->blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+   }
+
+   if (s->nblock > 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s->blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s->origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s->combinedCRC );
+      if (s->verbosity >= 2)
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/crctable.c b/nc_test4/filter_test/crctable.c
new file mode 100644
index 0000000..1fea7e9
--- /dev/null
+++ b/nc_test4/filter_test/crctable.c
@@ -0,0 +1,104 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs                                  ---*/
+/*---                                            crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*--
+  I think this is an implementation of the AUTODIN-II,
+  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
+  from code by Rob Warnock, in Section 51 of the
+  comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+   /*-- Ugly, innit? --*/
+
+   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/decompress.c b/nc_test4/filter_test/decompress.c
new file mode 100644
index 0000000..311f566
--- /dev/null
+++ b/nc_test4/filter_test/decompress.c
@@ -0,0 +1,646 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery                               ---*/
+/*---                                          decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->seqToUnseq[s->nInUse] = i;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr)                               \
+   { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn)                     \
+   case lll: s->state = lll;                      \
+   while (True) {                                 \
+      if (s->bsLive >= nnn) {                     \
+         UInt32 v;                                \
+         v = (s->bsBuff >>                        \
+             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
+         s->bsLive -= nnn;                        \
+         vvv = v;                                 \
+         break;                                   \
+      }                                           \
+      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
+      s->bsBuff                                   \
+         = (s->bsBuff << 8) |                     \
+           ((UInt32)                              \
+              (*((UChar*)(s->strm->next_in))));   \
+      s->bsLive += 8;                             \
+      s->strm->next_in++;                         \
+      s->strm->avail_in--;                        \
+      s->strm->total_in_lo32++;                   \
+      if (s->strm->total_in_lo32 == 0)            \
+         s->strm->total_in_hi32++;                \
+   }
+
+#define GET_UCHAR(lll,uuu)                        \
+   GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu)                          \
+   GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval)           \
+{                                                 \
+   if (groupPos == 0) {                           \
+      groupNo++;                                  \
+      if (groupNo >= nSelectors)                  \
+         RETURN(BZ_DATA_ERROR);                   \
+      groupPos = BZ_G_SIZE;                       \
+      gSel = s->selector[groupNo];                \
+      gMinlen = s->minLens[gSel];                 \
+      gLimit = &(s->limit[gSel][0]);              \
+      gPerm = &(s->perm[gSel][0]);                \
+      gBase = &(s->base[gSel][0]);                \
+   }                                              \
+   groupPos--;                                    \
+   zn = gMinlen;                                  \
+   GET_BITS(label1, zvec, zn);                    \
+   while (1) {                                    \
+      if (zn > 20 /* the longest code */)         \
+         RETURN(BZ_DATA_ERROR);                   \
+      if (zvec <= gLimit[zn]) break;              \
+      zn++;                                       \
+      GET_BIT(label2, zj);                        \
+      zvec = (zvec << 1) | zj;                    \
+   };                                             \
+   if (zvec - gBase[zn] < 0                       \
+       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
+      RETURN(BZ_DATA_ERROR);                      \
+   lval = gPerm[zvec - gBase[zn]];                \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+   UChar      uc;
+   Int32      retVal;
+   Int32      minLen, maxLen;
+   bz_stream* strm = s->strm;
+
+   /* stuff that needs to be saved/restored */
+   Int32  i;
+   Int32  j;
+   Int32  t;
+   Int32  alphaSize;
+   Int32  nGroups;
+   Int32  nSelectors;
+   Int32  EOB;
+   Int32  groupNo;
+   Int32  groupPos;
+   Int32  nextSym;
+   Int32  nblockMAX;
+   Int32  nblock;
+   Int32  es;
+   Int32  N;
+   Int32  curr;
+   Int32  zt;
+   Int32  zn; 
+   Int32  zvec;
+   Int32  zj;
+   Int32  gSel;
+   Int32  gMinlen;
+   Int32* gLimit;
+   Int32* gBase;
+   Int32* gPerm;
+
+   if (s->state == BZ_X_MAGIC_1) {
+      /*initialise the save area*/
+      s->save_i           = 0;
+      s->save_j           = 0;
+      s->save_t           = 0;
+      s->save_alphaSize   = 0;
+      s->save_nGroups     = 0;
+      s->save_nSelectors  = 0;
+      s->save_EOB         = 0;
+      s->save_groupNo     = 0;
+      s->save_groupPos    = 0;
+      s->save_nextSym     = 0;
+      s->save_nblockMAX   = 0;
+      s->save_nblock      = 0;
+      s->save_es          = 0;
+      s->save_N           = 0;
+      s->save_curr        = 0;
+      s->save_zt          = 0;
+      s->save_zn          = 0;
+      s->save_zvec        = 0;
+      s->save_zj          = 0;
+      s->save_gSel        = 0;
+      s->save_gMinlen     = 0;
+      s->save_gLimit      = NULL;
+      s->save_gBase       = NULL;
+      s->save_gPerm       = NULL;
+   }
+
+   /*restore from the save area*/
+   i           = s->save_i;
+   j           = s->save_j;
+   t           = s->save_t;
+   alphaSize   = s->save_alphaSize;
+   nGroups     = s->save_nGroups;
+   nSelectors  = s->save_nSelectors;
+   EOB         = s->save_EOB;
+   groupNo     = s->save_groupNo;
+   groupPos    = s->save_groupPos;
+   nextSym     = s->save_nextSym;
+   nblockMAX   = s->save_nblockMAX;
+   nblock      = s->save_nblock;
+   es          = s->save_es;
+   N           = s->save_N;
+   curr        = s->save_curr;
+   zt          = s->save_zt;
+   zn          = s->save_zn; 
+   zvec        = s->save_zvec;
+   zj          = s->save_zj;
+   gSel        = s->save_gSel;
+   gMinlen     = s->save_gMinlen;
+   gLimit      = s->save_gLimit;
+   gBase       = s->save_gBase;
+   gPerm       = s->save_gPerm;
+
+   retVal = BZ_OK;
+
+   switch (s->state) {
+
+      GET_UCHAR(BZ_X_MAGIC_1, uc);
+      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_2, uc);
+      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_3, uc)
+      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
+          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+      s->blockSize100k -= BZ_HDR_0;
+
+      if (s->smallDecompress) {
+         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+         s->ll4  = BZALLOC( 
+                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
+                   );
+         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+      } else {
+         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+      }
+
+      GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+      if (uc == 0x17) goto endhdr_2;
+      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_2, uc);
+      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_3, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_4, uc);
+      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_5, uc);
+      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_6, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+      s->currBlockNo++;
+      if (s->verbosity >= 2)
+         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
+ 
+      s->storedBlockCRC = 0;
+      GET_UCHAR(BZ_X_BCRC_1, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_2, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_3, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_4, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+      s->origPtr = 0;
+      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+      if (s->origPtr < 0)
+         RETURN(BZ_DATA_ERROR);
+      if (s->origPtr > 10 + 100000*s->blockSize100k) 
+         RETURN(BZ_DATA_ERROR);
+
+      /*--- Receive the mapping table ---*/
+      for (i = 0; i < 16; i++) {
+         GET_BIT(BZ_X_MAPPING_1, uc);
+         if (uc == 1) 
+            s->inUse16[i] = True; else 
+            s->inUse16[i] = False;
+      }
+
+      for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+      for (i = 0; i < 16; i++)
+         if (s->inUse16[i])
+            for (j = 0; j < 16; j++) {
+               GET_BIT(BZ_X_MAPPING_2, uc);
+               if (uc == 1) s->inUse[i * 16 + j] = True;
+            }
+      makeMaps_d ( s );
+      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+      alphaSize = s->nInUse+2;
+
+      /*--- Now the selectors ---*/
+      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+      for (i = 0; i < nSelectors; i++) {
+         j = 0;
+         while (True) {
+            GET_BIT(BZ_X_SELECTOR_3, uc);
+            if (uc == 0) break;
+            j++;
+            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+         }
+         s->selectorMtf[i] = j;
+      }
+
+      /*--- Undo the MTF values for the selectors. ---*/
+      {
+         UChar pos[BZ_N_GROUPS], tmp, v;
+         for (v = 0; v < nGroups; v++) pos[v] = v;
+   
+         for (i = 0; i < nSelectors; i++) {
+            v = s->selectorMtf[i];
+            tmp = pos[v];
+            while (v > 0) { pos[v] = pos[v-1]; v--; }
+            pos[0] = tmp;
+            s->selector[i] = tmp;
+         }
+      }
+
+      /*--- Now the coding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         GET_BITS(BZ_X_CODING_1, curr, 5);
+         for (i = 0; i < alphaSize; i++) {
+            while (True) {
+               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+               GET_BIT(BZ_X_CODING_2, uc);
+               if (uc == 0) break;
+               GET_BIT(BZ_X_CODING_3, uc);
+               if (uc == 0) curr++; else curr--;
+            }
+            s->len[t][i] = curr;
+         }
+      }
+
+      /*--- Create the Huffman decoding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         minLen = 32;
+         maxLen = 0;
+         for (i = 0; i < alphaSize; i++) {
+            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+            if (s->len[t][i] < minLen) minLen = s->len[t][i];
+         }
+         BZ2_hbCreateDecodeTables ( 
+            &(s->limit[t][0]), 
+            &(s->base[t][0]), 
+            &(s->perm[t][0]), 
+            &(s->len[t][0]),
+            minLen, maxLen, alphaSize
+         );
+         s->minLens[t] = minLen;
+      }
+
+      /*--- Now the MTF values ---*/
+
+      EOB      = s->nInUse+1;
+      nblockMAX = 100000 * s->blockSize100k;
+      groupNo  = -1;
+      groupPos = 0;
+
+      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+      /*-- MTF init --*/
+      {
+         Int32 ii, jj, kk;
+         kk = MTFA_SIZE-1;
+         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+               kk--;
+            }
+            s->mtfbase[ii] = kk + 1;
+         }
+      }
+      /*-- end MTF init --*/
+
+      nblock = 0;
+      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+      while (True) {
+
+         if (nextSym == EOB) break;
+
+         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+            es = -1;
+            N = 1;
+            do {
+               /* Check that N doesn't get too big, so that es doesn't
+                  go negative.  The maximum value that can be
+                  RUNA/RUNB encoded is equal to the block size (post
+                  the initial RLE), viz, 900k, so bounding N at 2
+                  million should guard against overflow without
+                  rejecting any legitimate inputs. */
+               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
+               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+               N = N * 2;
+               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+            }
+               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+            es++;
+            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+            s->unzftab[uc] += es;
+
+            if (s->smallDecompress)
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->ll16[nblock] = (UInt16)uc;
+                  nblock++;
+                  es--;
+               }
+            else
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->tt[nblock] = (UInt32)uc;
+                  nblock++;
+                  es--;
+               };
+
+            continue;
+
+         } else {
+
+            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+            /*-- uc = MTF ( nextSym-1 ) --*/
+            {
+               Int32 ii, jj, kk, pp, lno, off;
+               UInt32 nn;
+               nn = (UInt32)(nextSym - 1);
+
+               if (nn < MTFL_SIZE) {
+                  /* avoid general-case expense */
+                  pp = s->mtfbase[0];
+                  uc = s->mtfa[pp+nn];
+                  while (nn > 3) {
+                     Int32 z = pp+nn;
+                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
+                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
+                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
+                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
+                     nn -= 4;
+                  }
+                  while (nn > 0) { 
+                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
+                  };
+                  s->mtfa[pp] = uc;
+               } else { 
+                  /* general case */
+                  lno = nn / MTFL_SIZE;
+                  off = nn % MTFL_SIZE;
+                  pp = s->mtfbase[lno] + off;
+                  uc = s->mtfa[pp];
+                  while (pp > s->mtfbase[lno]) { 
+                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
+                  };
+                  s->mtfbase[lno]++;
+                  while (lno > 0) {
+                     s->mtfbase[lno]--;
+                     s->mtfa[s->mtfbase[lno]] 
+                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s->mtfbase[0]--;
+                  s->mtfa[s->mtfbase[0]] = uc;
+                  if (s->mtfbase[0] == 0) {
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s->mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+            }
+            /*-- end uc = MTF ( nextSym-1 ) --*/
+
+            s->unzftab[s->seqToUnseq[uc]]++;
+            if (s->smallDecompress)
+               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
+            nblock++;
+
+            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+            continue;
+         }
+      }
+
+      /* Now we know what nblock is, we can do a better sanity
+         check on s->origPtr.
+      */
+      if (s->origPtr < 0 || s->origPtr >= nblock)
+         RETURN(BZ_DATA_ERROR);
+
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      /* Check: unzftab entries in range. */
+      for (i = 0; i <= 255; i++) {
+         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+            RETURN(BZ_DATA_ERROR);
+      }
+      /* Actually generate cftab. */
+      s->cftab[0] = 0;
+      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      /* Check: cftab entries in range. */
+      for (i = 0; i <= 256; i++) {
+         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+            /* s->cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+      /* Check: cftab entries non-descending. */
+      for (i = 1; i <= 256; i++) {
+         if (s->cftab[i-1] > s->cftab[i]) {
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
+      s->state_out_len = 0;
+      s->state_out_ch  = 0;
+      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+      s->state = BZ_X_OUTPUT;
+      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+      if (s->smallDecompress) {
+
+         /*-- Make a copy of cftab, used in generation of T --*/
+         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+         /*-- compute the T vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->ll16[i]);
+            SET_LL(i, s->cftabCopy[uc]);
+            s->cftabCopy[uc]++;
+         }
+
+         /*-- Compute T^(-1) by pointer reversal on T --*/
+         i = s->origPtr;
+         j = GET_LL(i);
+         do {
+            Int32 tmp = GET_LL(j);
+            SET_LL(j, i);
+            i = j;
+            j = tmp;
+         }
+            while (i != s->origPtr);
+
+         s->tPos = s->origPtr;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+         }
+
+      } else {
+
+         /*-- compute the T^(-1) vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->tt[i] & 0xff);
+            s->tt[s->cftab[uc]] |= (i << 8);
+            s->cftab[uc]++;
+         }
+
+         s->tPos = s->tt[s->origPtr] >> 8;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+         }
+
+      }
+
+      RETURN(BZ_OK);
+
+
+
+    endhdr_2:
+
+      GET_UCHAR(BZ_X_ENDHDR_2, uc);
+      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_3, uc);
+      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_4, uc);
+      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_5, uc);
+      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_6, uc);
+      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+      s->storedCombinedCRC = 0;
+      GET_UCHAR(BZ_X_CCRC_1, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_2, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_3, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_4, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+      s->state = BZ_X_IDLE;
+      RETURN(BZ_STREAM_END);
+
+      default: AssertH ( False, 4001 );
+   }
+
+   AssertH ( False, 4002 );
+
+   save_state_and_return:
+
+   s->save_i           = i;
+   s->save_j           = j;
+   s->save_t           = t;
+   s->save_alphaSize   = alphaSize;
+   s->save_nGroups     = nGroups;
+   s->save_nSelectors  = nSelectors;
+   s->save_EOB         = EOB;
+   s->save_groupNo     = groupNo;
+   s->save_groupPos    = groupPos;
+   s->save_nextSym     = nextSym;
+   s->save_nblockMAX   = nblockMAX;
+   s->save_nblock      = nblock;
+   s->save_es          = es;
+   s->save_N           = N;
+   s->save_curr        = curr;
+   s->save_zt          = zt;
+   s->save_zn          = zn;
+   s->save_zvec        = zvec;
+   s->save_zj          = zj;
+   s->save_gSel        = gSel;
+   s->save_gMinlen     = gMinlen;
+   s->save_gLimit      = gLimit;
+   s->save_gBase       = gBase;
+   s->save_gPerm       = gPerm;
+
+   return retVal;   
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                      decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/fake.c b/nc_test4/filter_test/fake.c
new file mode 100644
index 0000000..1949917
--- /dev/null
+++ b/nc_test4/filter_test/fake.c
@@ -0,0 +1,5 @@
+int
+main()
+{
+    return 0;
+}
diff --git a/nc_test4/filter_test/h5bzip2.h b/nc_test4/filter_test/h5bzip2.h
new file mode 100644
index 0000000..f8e8488
--- /dev/null
+++ b/nc_test4/filter_test/h5bzip2.h
@@ -0,0 +1,12 @@
+#include "bzlib.h"
+
+/* use an integer greater than 256 to be id of the registered filter. */
+#define H5Z_FILTER_BZIP2 307
+
+const H5Z_class2_t H5Z_BZIP2[1]; 
+
+
+/* declare a filter function */
+size_t H5Z_filter_bzip2(unsigned flags,size_t cd_nelmts,const unsigned cd_values[],
+                    size_t nbytes,size_t *buf_size,void**buf);
+
diff --git a/nc_test4/filter_test/h5test.h b/nc_test4/filter_test/h5test.h
new file mode 100644
index 0000000..7fd375a
--- /dev/null
+++ b/nc_test4/filter_test/h5test.h
@@ -0,0 +1,18 @@
+#include "bzlib.h"
+
+/* use an integer greater than 256 to be id of the registered filter. */
+#define H5Z_FILTER_TEST 32768
+
+/* Define the test cases */
+
+typedef enum H5testcase {
+TC_NONE = 0,
+TC_ENDIAN = 1,
+} H5testcase;
+
+const H5Z_class2_t H5Z_TEST[1]; 
+
+/* declare a filter function */
+extern size_t H5Z_filter_test(unsigned flags,size_t cd_nelmts,const unsigned cd_values[],
+                    size_t nbytes,size_t *buf_size,void**buf);
+
diff --git a/nc_test4/filter_test/huffman.c b/nc_test4/filter_test/huffman.c
new file mode 100644
index 0000000..2283fdb
--- /dev/null
+++ b/nc_test4/filter_test/huffman.c
@@ -0,0 +1,205 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2)                           \
+   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
+   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z)                                     \
+{                                                     \
+   Int32 zz, tmp;                                     \
+   zz = z; tmp = heap[zz];                            \
+   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
+      heap[zz] = heap[zz >> 1];                       \
+      zz >>= 1;                                       \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+#define DOWNHEAP(z)                                   \
+{                                                     \
+   Int32 zz, yy, tmp;                                 \
+   zz = z; tmp = heap[zz];                            \
+   while (True) {                                     \
+      yy = zz << 1;                                   \
+      if (yy > nHeap) break;                          \
+      if (yy < nHeap &&                               \
+          weight[heap[yy+1]] < weight[heap[yy]])      \
+         yy++;                                        \
+      if (weight[tmp] < weight[heap[yy]]) break;      \
+      heap[zz] = heap[yy];                            \
+      zz = yy;                                        \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len, 
+                             Int32 *freq,
+                             Int32 alphaSize,
+                             Int32 maxLen )
+{
+   /*--
+      Nodes and heap entries run from 1.  Entry 0
+      for both the heap and nodes is a sentinel.
+   --*/
+   Int32 nNodes, nHeap, n1, n2, i, j, k;
+   Bool  tooLong;
+
+   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
+   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+
+   for (i = 0; i < alphaSize; i++)
+      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+   while (True) {
+
+      nNodes = alphaSize;
+      nHeap = 0;
+
+      heap[0] = 0;
+      weight[0] = 0;
+      parent[0] = -2;
+
+      for (i = 1; i <= alphaSize; i++) {
+         parent[i] = -1;
+         nHeap++;
+         heap[nHeap] = i;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+   
+      while (nHeap > 1) {
+         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         nNodes++;
+         parent[n1] = parent[n2] = nNodes;
+         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+         parent[nNodes] = -1;
+         nHeap++;
+         heap[nHeap] = nNodes;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+      tooLong = False;
+      for (i = 1; i <= alphaSize; i++) {
+         j = 0;
+         k = i;
+         while (parent[k] >= 0) { k = parent[k]; j++; }
+         len[i-1] = j;
+         if (j > maxLen) tooLong = True;
+      }
+      
+      if (! tooLong) break;
+
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i < alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i <= alphaSize; i++) {
+         j = weight[i] >> 8;
+         j = 1 + (j / 2);
+         weight[i] = j << 8;
+      }
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+                         UChar *length,
+                         Int32 minLen,
+                         Int32 maxLen,
+                         Int32 alphaSize )
+{
+   Int32 n, vec, i;
+
+   vec = 0;
+   for (n = minLen; n <= maxLen; n++) {
+      for (i = 0; i < alphaSize; i++)
+         if (length[i] == n) { code[i] = vec; vec++; };
+      vec <<= 1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+                                Int32 *base,
+                                Int32 *perm,
+                                UChar *length,
+                                Int32 minLen,
+                                Int32 maxLen,
+                                Int32 alphaSize )
+{
+   Int32 pp, i, j, vec;
+
+   pp = 0;
+   for (i = minLen; i <= maxLen; i++)
+      for (j = 0; j < alphaSize; j++)
+         if (length[j] == i) { perm[pp] = j; pp++; };
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   vec = 0;
+
+   for (i = minLen; i <= maxLen; i++) {
+      vec += (base[i+1] - base[i]);
+      limit[i] = vec-1;
+      vec <<= 1;
+   }
+   for (i = minLen + 1; i <= maxLen; i++)
+      base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/randtable.c b/nc_test4/filter_test/randtable.c
new file mode 100644
index 0000000..6d62459
--- /dev/null
+++ b/nc_test4/filter_test/randtable.c
@@ -0,0 +1,84 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks               ---*/
+/*---                                           randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = { 
+   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
+   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
+   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
+   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
+   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
+   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
+   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
+   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
+   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
+   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
+   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
+   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
+   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
+   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
+   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
+   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
+   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
+   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
+   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
+   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
+   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
+   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
+   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
+   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
+   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
+   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
+   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
+   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
+   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
+   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
+   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
+   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
+   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
+   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
+   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
+   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
+   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
+   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
+   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
+   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
+   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
+   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
+   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
+   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
+   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
+   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
+   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
+   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
+   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
+   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
+   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
+   936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       randtable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/filter_test/test_filter.c b/nc_test4/filter_test/test_filter.c
new file mode 100644
index 0000000..a8f5f2f
--- /dev/null
+++ b/nc_test4/filter_test/test_filter.c
@@ -0,0 +1,493 @@
+/*
+  Copyright 2008, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
+
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "netcdf.h"
+
+//#define BASELINE 1
+
+#define USEFLOAT 1
+
+/* Write using var1_T instead of var_T */
+#undef VAR1
+
+#define BZIP2_ID 307
+#define BZIP2_LEVEL 9
+
+#define MAXERRS 8
+
+#define MAXPARAMS 32
+
+/* Following 3 must be consistent */
+#ifdef USEFLOAT
+#define T float
+#else
+#define T int
+#endif
+
+#define NC_PUT_VAR1 nc_put_var1_float
+#define NC_PUT_VAR nc_put_var_float
+
+typedef enum XZIP { NOZIP=0, BZIP2=1} XZIP;
+
+/* Created Meta-data 
+netcdf zip {
+dimensions:
+	dim1 = .. ;
+	dim2 = ... ;
+	dim3 = ... ;
+	...
+	dimn = ... ;
+variables:
+	int var(dim1, dim2, dim3,...dimn) ;
+}
+*/
+
+#define MAXDIMS 8
+
+#define DEFAULTACTUALDIMS 4
+#define DEFAULTDIMSIZE 4
+#define DEFAULTCHUNKSIZE 4
+
+static size_t dimsize = DEFAULTDIMSIZE;
+static size_t chunksize = DEFAULTCHUNKSIZE;
+static size_t actualdims = DEFAULTACTUALDIMS;
+static size_t pattern[MAXDIMS];
+
+static size_t totalproduct = 1; /* x-product over max dims */
+static size_t actualproduct = 1; /* x-product over actualdims */
+static size_t chunkproduct = 1; /* x-product over actual chunks */
+
+static size_t dims[MAXDIMS];
+static size_t chunks[MAXDIMS];
+
+static int nerrs = 0;
+
+static int ncid, varid;
+static int dimids[MAXDIMS];
+static size_t odom[MAXDIMS];
+static T* array = NULL;
+static T* expected = NULL;
+static unsigned int filterid = 0;
+static size_t nparams = 0;
+static unsigned int* params = NULL;
+
+/* Forward */
+static int test_bzip2(void);
+static void init(int argc, char** argv);
+static void reset(void);
+static void odom_reset(void);
+static int odom_more(void);
+static int odom_next(void);
+static int odom_offset(void);
+static T expectedvalue(void);
+
+#define ERRR do { \
+fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
+fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
+	__FILE__, __LINE__);				    \
+nerrs++;\
+} while (0)
+
+static int
+check(int err,int line)
+{
+    if(err != NC_NOERR) {
+	fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
+	fflush(stderr);
+	exit(1);
+    }
+    return NC_NOERR;
+}
+
+#define CHECK(x) check(x,__LINE__)
+
+static char*
+filenamefor(XZIP encoder)
+{
+    static char testfile[2048];
+    snprintf(testfile,sizeof(testfile),"%s.nc",
+		(encoder == NOZIP?"nozip":"bzip2"));
+    return testfile;
+}
+
+static int
+verifychunks(void)
+{
+    int i;
+    int store = -1;
+    size_t chunksizes[MAXDIMS];
+    memset(chunksizes,0,sizeof(chunksizes));
+    CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes));
+    if(store != NC_CHUNKED) {
+	fprintf(stderr,"bad chunk store\n");
+	return 0;
+    }
+    for(i=0;i<actualdims;i++) {
+        if(chunksizes[i] != chunks[i]) {
+	    fprintf(stderr,"bad chunk size: %d\n",i);
+	    return 0;
+	}
+    }
+    return 1;
+}
+
+static int
+create(XZIP encoder)
+{
+    int i;
+    char* testfile = filenamefor(encoder);
+
+    /* Create a file with one big variable. */
+    CHECK(nc_create(testfile, NC_NETCDF4|NC_CLOBBER, &ncid));
+    CHECK(nc_set_fill(ncid, NC_NOFILL, NULL));
+    for(i=0;i<actualdims;i++) {
+	char dimname[1024];
+	snprintf(dimname,sizeof(dimname),"dim%d",i);
+        CHECK(nc_def_dim(ncid, dimname, dims[i], &dimids[i]));
+    }
+    CHECK(nc_def_var(ncid, "var", NC_FLOAT, actualdims, dimids, &varid));
+    return NC_NOERR;
+}
+
+static void
+setvarfilter(XZIP encoder)
+{
+    unsigned int level = BZIP2_LEVEL;
+    unsigned int id=0;
+    size_t nparams = 0;
+    if(encoder == BZIP2) {
+        CHECK(nc_def_var_filter(ncid,varid,BZIP2_ID,1,&level));
+	level = 0;
+        CHECK(nc_inq_var_filter(ncid,varid,&id,&nparams,&level));
+	if(id != BZIP2_ID || nparams != 1 || level != BZIP2_LEVEL)
+	    printf("setvarfilter: def/inq mismatch\n");
+    }
+}
+
+static int
+open(XZIP encoder)
+{
+    char* testfile = filenamefor(encoder);
+
+    /* Open the file and check it. */
+    CHECK(nc_open(testfile, NC_NOWRITE, &ncid));
+    CHECK(nc_inq_varid(ncid, "var", &varid));
+
+    if(0 || encoder != NOZIP) {
+        /* Check the compression algorithm */
+	filterid = 0;
+	nparams = 0;
+	params = NULL;
+        CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,NULL));
+	if(nparams > 0) {
+	    params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
+	    if(params == NULL)
+		return NC_ENOMEM;
+            CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+	}
+        if(filterid != BZIP2_ID) {
+	    printf("Bzip2 id mismatch: %d\n",filterid);
+	    return NC_EFILTER;
+        }
+	if(nparams != 1 && params != NULL && params[0] != BZIP2_LEVEL) {
+	    printf("Compression parameter mismatch\n");
+	    return NC_EFILTER; 
+	}
+    }
+
+    /* Verify chunking */
+    if(!verifychunks())
+	return 0;
+    fflush(stderr);
+    return 1;
+}
+
+static int
+setchunking(void)
+{
+    int i;
+    int store;
+
+    store = NC_CHUNKED;
+    CHECK(nc_def_var_chunking(ncid,varid,store,chunks));
+    if(!verifychunks())
+	return NC_EINVAL;
+    return NC_NOERR;
+}
+
+static void
+fill(void)
+{
+   odom_reset();
+   if(1) {
+	int i;
+if(actualproduct <= 1) abort();
+	for(i=0;i<actualproduct;i++)
+	    expected[i] = (T)i;
+   } else {
+       while(odom_more()) {
+	    int offset = odom_offset();
+	    T expect = expectedvalue();
+	    expected[offset] = expect;
+	    odom_next();
+	}
+   }
+}
+
+static int
+write(void)
+{
+   int stat = NC_NOERR;
+#ifdef VAR1
+   odom_reset();
+   while(odom_more()) {
+	size_t offset = odom_offset();
+	CHECK(NC_PUT_VAR1(ncid,varid,odom,&expected[offset]));
+	odom_next();
+   }
+#else
+   stat = NC_PUT_VAR(ncid,varid,expected);
+#endif
+   return stat;
+}
+
+
+static int
+compare(void)
+{
+    int errs = 0;
+    printf("data comparison: |array|=%d\n",actualproduct);
+    if(1)
+    {
+	int i;
+	for(i=0;i<actualproduct;i++) {
+	    if(expected[i] != array[i]) {
+                printf("mismatch: array[%d]=%f expected[%d]=%f\n",
+                            i,array[i],i,expected[i]);
+                errs++;
+                if(errs >= MAXERRS)
+                    break;
+            }
+	}
+   } else
+   {
+       odom_reset();
+       while(odom_more()) {
+            int offset = odom_offset();
+            float expect = expectedvalue();
+            if(array[offset] != expect) {
+                printf("mismatch: array[%d]=%f expected=%f\n",
+                            offset,array[offset],expect);
+                errs++;
+                if(errs >= MAXERRS)
+                    break;
+            }
+            odom_next();
+       }
+   }
+
+   if(errs == 0)
+        printf("no data errors\n");
+   return (errs == 0);
+}
+
+static void
+showparameters(XZIP encoding)
+{
+    int i;
+    printf("bzip2:");
+    for(i=0;i<nparams;i++) {
+	printf(" %u",params[i]);
+    }
+    printf("\n");
+    for(i=0;i<actualdims;i++)
+	printf("%s%d",(i==0?" chunks=":","),chunks[i]);
+    printf("\n");
+}
+
+static int
+test_bzip2(void)
+{
+    int ok = 1;
+    unsigned int param = BZIP2_LEVEL;
+
+    printf("\n*** Testing API: bzip2 compression.\n");
+    reset();
+
+    create(BZIP2);
+    setchunking();
+    setvarfilter(BZIP2); showparameters(BZIP2);
+    CHECK(nc_enddef(ncid));
+
+    /* Fill in the array */
+    fill();
+    /* write array */
+    CHECK(write());
+    CHECK(nc_close(ncid));
+
+    printf("\n*** Testing API: bzip2 decompression.\n");
+    reset();
+    open(BZIP2);
+    CHECK(nc_get_var_float(ncid, varid, array));
+    ok = compare();
+    CHECK(nc_close(ncid));
+    return ok;
+}
+
+#ifdef BASELINE
+static int
+test_nozip(void)
+{
+    int ok = 1;
+
+    printf("\n*** Testing nozip compression.\n");
+    reset();
+
+    create(NOZIP);
+    setchunking();
+
+    CHECK(nc_enddef(ncid));
+
+    /* Fill in the array */
+    fill();
+    /* write array */
+    CHECK(write());
+    CHECK(nc_close(ncid));
+
+    printf("\n*** Testing nozip decompression.\n");
+    reset();
+    open(NOZIP);
+    CHECK(nc_get_var_float(ncid, varid, array));
+    ok = compare();
+    CHECK(nc_close(ncid));
+    return ok;
+}
+#endif
+
+/**************************************************/
+/* Utilities */
+
+static void
+reset()
+{
+    memset(array,0,sizeof(T)*actualproduct);
+}
+
+static void
+odom_reset(void)
+{
+    memset(odom,0,sizeof(odom));
+}
+
+static int
+odom_more(void)
+{
+    return (odom[0] < dims[0]);
+}
+
+static int
+odom_next(void)
+{
+    int i; /* do not make unsigned */
+    for(i=actualdims-1;i>=0;i--) {
+        odom[i] += 1;
+        if(odom[i] < dims[i]) break;
+	if(i == 0) return 0; /* leave the 0th entry if it overflows*/
+	odom[i] = 0; /* reset this position*/
+    }
+    return 1;
+}
+
+static int
+odom_offset(void)
+{
+    int i;
+    int offset = 0;
+    for(i=0;i<actualdims;i++) {
+	offset *= dims[i];
+	offset += odom[i];
+    } 
+    return offset;
+}
+
+static T
+expectedvalue(void)
+{
+    int i;
+    T offset = 0;
+
+    for(i=0;i<actualdims;i++) {
+	offset *= dims[i];
+	offset += odom[i];
+    } 
+    return offset;
+}
+
+#if 0
+#ifndef USEFLOAT
+static size_t
+getint(const char* arg)
+{
+    char* p;
+    long l = strtol(arg,&p,10);
+    if(*p == '\0')
+	return (size_t)l;
+    fprintf(stderr,"expected integer: found %s\n", arg);
+    exit(1);
+}
+#else
+static double
+getdouble(const char* arg)
+{
+    char* p;
+    double d = strtod(arg,&p);
+    if(*p == '\0')
+	return d;
+    fprintf(stderr,"expected double: found %s\n", arg);
+    exit(1);
+}
+#endif
+#endif
+
+static void
+init(int argc, char** argv)
+{
+    int i;
+    /* Setup various variables */
+    totalproduct = 1;
+    actualproduct = 1;
+    chunkproduct = 1;
+    for(i=0;i<MAXDIMS;i++) {
+	dims[i] = dimsize;
+	chunks[i] = (pattern[i] == 1 ? 1 : chunksize);
+	totalproduct *= dims[i];
+	if(i < actualdims) {
+	    actualproduct *= dims[i];
+	    chunkproduct *= chunks[i];
+	}
+    }
+    /* Allocate max size */
+    array = (T*)calloc(1,sizeof(T)*actualproduct);
+    expected = (T*)calloc(1,sizeof(T)*actualproduct);
+}
+
+/**************************************************/
+int
+main(int argc, char **argv)
+{
+    init(argc,argv);
+#ifdef BASELINE
+    if(!test_nozip()) ERRR;
+#endif
+    if(!test_bzip2()) ERRR;
+    exit(nerrs > 0?1:0);
+}
+
diff --git a/nc_test4/filter_test/test_misc.c b/nc_test4/filter_test/test_misc.c
new file mode 100644
index 0000000..8809640
--- /dev/null
+++ b/nc_test4/filter_test/test_misc.c
@@ -0,0 +1,414 @@
+/*
+  Copyright 2008, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "netcdf.h"
+
+#define TEST_ID 32768
+
+#define MAXERRS 8
+
+#define MAXPARAMS 32
+
+#define NBASELINE 14
+
+static const unsigned int baseline[NBASELINE] = {
+1,   /* 0 testcase # */
+-17, /* 1 signed int*/
+23,  /* 2 unsigned int*/
+-25, /* 3 signed int*/
+27,  /* 4 unsigned int*/
+77,  /* 5 signed int*/
+93,  /* 65 unsigned int*/
+1145389056U, /* 7 float*/
+697067329, 2723935171,    /* 8-9 double*/
+128, 16777216,            /* 10-11 signed long long*/
+4294967295, 4294967295,   /* 12-13 unsigned long long*/
+};
+
+#define MAXDIMS 8
+
+#define DEFAULTACTUALDIMS 4
+#define DEFAULTDIMSIZE 4
+#define DEFAULTCHUNKSIZE 4
+
+static size_t dimsize = DEFAULTDIMSIZE;
+static size_t chunksize = DEFAULTCHUNKSIZE;
+static size_t actualdims = DEFAULTACTUALDIMS;
+static size_t pattern[MAXDIMS];
+
+static size_t totalproduct = 1; /* x-product over max dims */
+static size_t actualproduct = 1; /* x-product over actualdims */
+static size_t chunkproduct = 1; /* x-product over actual chunks */
+
+static size_t dims[MAXDIMS];
+static size_t chunks[MAXDIMS];
+
+static int nerrs = 0;
+
+static int ncid, varid;
+static int dimids[MAXDIMS];
+static size_t odom[MAXDIMS];
+static float* array = NULL;
+static float* expected = NULL;
+
+static unsigned int filterid = 0;
+static size_t nparams = 0;
+static unsigned int params[MAXPARAMS];
+
+/* Forward */
+static int test_test1(void);
+static void init(int argc, char** argv);
+static void reset(void);
+static void odom_reset(void);
+static int odom_more(void);
+static int odom_next(void);
+static int odom_offset(void);
+static float expectedvalue(void);
+static void verifyparams(void);
+
+#define ERRR do { \
+fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
+fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
+        __FILE__, __LINE__);                                \
+nerrs++;\
+} while (0)
+
+static int
+check(int err,int line)
+{
+    if(err != NC_NOERR) {
+        fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
+    }
+    return NC_NOERR;
+}
+
+static void
+report(const char* msg, int lineno)
+{
+    fprintf(stderr,"fail: line=%d %s\n",lineno,msg);
+    exit(1);
+}
+
+#define CHECK(x) check(x,__LINE__)
+#define REPORT(x) report(x,__LINE__)
+
+static char*
+filenamefor(void)
+{
+    return strdup("testmisc.nc");
+}
+
+static int
+verifychunks(void)
+{
+    int i;
+    int store = -1;
+    size_t chunksizes[MAXDIMS];
+    memset(chunksizes,0,sizeof(chunksizes));
+    CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes));
+    if(store != NC_CHUNKED) {
+        fprintf(stderr,"bad chunk store\n");
+        return 0;
+    }
+    for(i=0;i<actualdims;i++) {
+        if(chunksizes[i] != chunks[i]) {
+            fprintf(stderr,"bad chunk size: %d\n",i);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int
+create(void)
+{
+    int i;
+    char* testfile = filenamefor();
+
+    /* Create a file with one big variable. */
+    CHECK(nc_create(testfile, NC_NETCDF4|NC_CLOBBER, &ncid));
+    CHECK(nc_set_fill(ncid, NC_NOFILL, NULL));
+    for(i=0;i<actualdims;i++) {
+        char dimname[1024];
+        snprintf(dimname,sizeof(dimname),"dim%d",i);
+        CHECK(nc_def_dim(ncid, dimname, dims[i], &dimids[i]));
+    }
+    CHECK(nc_def_var(ncid, "var", NC_FLOAT, actualdims, dimids, &varid));
+    return NC_NOERR;
+}
+
+static void
+setvarfilter(void)
+{
+    size_t i;
+    CHECK(nc_def_var_filter(ncid,varid,TEST_ID,NBASELINE,baseline));
+    verifyparams();
+}
+
+static void
+verifyparams(void)
+{
+    size_t i;
+    CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+    if(filterid != TEST_ID) REPORT("id mismatch");
+    if(nparams != NBASELINE) REPORT("nparams mismatch");
+    for(i=0;i<nparams;i++) {
+        if(params[i] != baseline[i])
+            REPORT("param mismatch");
+    }
+}
+
+static int
+open(void)
+{
+    char* testfile = filenamefor();
+    unsigned int* params;
+
+    /* Open the file and check it. */
+    CHECK(nc_open(testfile, NC_NOWRITE, &ncid));
+    CHECK(nc_inq_varid(ncid, "var", &varid));
+
+    /* Check the compression algorithm */
+    CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,NULL));
+    if(nparams > 0) {
+        params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
+        if(params == NULL)
+            return NC_ENOMEM;
+        CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+    }
+    if(filterid != TEST_ID) {
+        printf("open: test id mismatch: %d\n",filterid);
+        return NC_EFILTER;
+    }
+    if(nparams != NBASELINE) {
+	size_t i;
+	unsigned int inqparams[MAXPARAMS];
+        printf("nparams  mismatch\n");
+        for(nerrs=0,i=0;i<nparams;i++) {
+            if(inqparams[i] != baseline[i]) {
+                printf("open: testparam mismatch: %d\n",i);
+		nerrs++;
+	    }
+	}
+    }
+    if(nerrs > 0) return NC_EFILTER; 
+
+    /* Verify chunking */
+    if(!verifychunks())
+        return 0;
+    fflush(stderr);
+    return 1;
+}
+
+static int
+setchunking(void)
+{
+    int i;
+    int store;
+
+    store = NC_CHUNKED;
+    CHECK(nc_def_var_chunking(ncid,varid,store,chunks));
+    if(!verifychunks())
+        return NC_EINVAL;
+    return NC_NOERR;
+}
+
+static void
+fill(void)
+{
+   odom_reset();
+   if(1) {
+        int i;
+        if(actualproduct <= 1) abort();
+        for(i=0;i<actualproduct;i++)
+            expected[i] = (float)i;
+   } else {
+       while(odom_more()) {
+            int offset = odom_offset();
+            float expect = expectedvalue();
+            expected[offset] = expect;
+            odom_next();
+        }
+   }
+}
+
+
+static int
+compare(void)
+{
+    int errs = 0;
+    fprintf(stderr,"data comparison: |array|=%d\n",actualproduct);
+    if(1)
+    {
+        int i;
+        for(i=0;i<actualproduct;i++) {
+            if(expected[i] != array[i]) {
+                fprintf(stderr,"mismatch: array[%d]=%f expected[%d]=%f\n",
+                            i,array[i],i,expected[i]);
+                errs++;
+                if(errs >= MAXERRS)
+                    break;
+            }
+        }
+   } else
+   {
+       odom_reset();
+       while(odom_more()) {
+            int offset = odom_offset();
+            float expect = expectedvalue();
+            if(array[offset] != expect) {
+                fprintf(stderr,"mismatch: array[%d]=%f expected=%f\n",
+                            offset,array[offset],expect);
+                errs++;
+                if(errs >= MAXERRS)
+                    break;
+            }
+            odom_next();
+       }
+   }
+
+   if(errs == 0)
+        fprintf(stderr,"no data errors\n");
+   return (errs == 0);
+}
+
+static void
+showparameters(void)
+{
+    int i;
+    printf("test: nparams=%ld: params=",(unsigned long)nparams);
+    for(i=0;i<nparams;i++) {
+        printf(" %u",params[i]);
+    }
+    printf("\n");
+    for(i=0;i<actualdims;i++)
+        printf("%s%d",(i==0?" chunks=":","),chunks[i]);
+    printf("\n");
+}
+
+static int
+test_test1(void)
+{
+    int ok = 1;
+
+    reset();
+
+    printf("test1: compression.\n");
+    create();
+    setchunking();
+    setvarfilter();
+    showparameters();
+    CHECK(nc_enddef(ncid));
+
+    /* Fill in the array */
+    fill();
+    /* write array */
+    CHECK(nc_put_var(ncid,varid,expected));
+    CHECK(nc_close(ncid));
+
+    printf("test1: decompression.\n");
+    reset();
+    open();
+    CHECK(nc_get_var_float(ncid, varid, array));
+    ok = compare();
+    CHECK(nc_close(ncid));
+    return ok;
+}
+
+/**************************************************/
+/* Utilities */
+
+static void
+reset()
+{
+    memset(array,0,sizeof(float)*actualproduct);
+}
+
+static void
+odom_reset(void)
+{
+    memset(odom,0,sizeof(odom));
+}
+
+static int
+odom_more(void)
+{
+    return (odom[0] < dims[0]);
+}
+
+static int
+odom_next(void)
+{
+    int i; /* do not make unsigned */
+    for(i=actualdims-1;i>=0;i--) {
+        odom[i] += 1;
+        if(odom[i] < dims[i]) break;
+        if(i == 0) return 0; /* leave the 0th entry if it overflows*/
+        odom[i] = 0; /* reset this position*/
+    }
+    return 1;
+}
+
+static int
+odom_offset(void)
+{
+    int i;
+    int offset = 0;
+    for(i=0;i<actualdims;i++) {
+        offset *= dims[i];
+        offset += odom[i];
+    } 
+    return offset;
+}
+
+static float
+expectedvalue(void)
+{
+    int i;
+    float offset = 0;
+
+    for(i=0;i<actualdims;i++) {
+        offset *= dims[i];
+        offset += odom[i];
+    } 
+    return offset;
+}
+
+static void
+init(int argc, char** argv)
+{
+    int i;
+    /* Setup various variables */
+    totalproduct = 1;
+    actualproduct = 1;
+    chunkproduct = 1;
+    for(i=0;i<MAXDIMS;i++) {
+        dims[i] = dimsize;
+        chunks[i] = (pattern[i] == 1 ? 1 : chunksize);
+        totalproduct *= dims[i];
+        if(i < actualdims) {
+            actualproduct *= dims[i];
+            chunkproduct *= chunks[i];
+        }
+    }
+    /* Allocate max size */
+    array = (float*)calloc(1,sizeof(float)*actualproduct);
+    expected = (float*)calloc(1,sizeof(float)*actualproduct);
+}
+
+/**************************************************/
+int
+main(int argc, char **argv)
+{
+    init(argc,argv);
+    if(!test_test1()) ERRR;
+    exit(nerrs > 0?1:0);
+}
+
diff --git a/nc_test4/filter_test/tst_filter.sh b/nc_test4/filter_test/tst_filter.sh
new file mode 100644
index 0000000..5f59e59
--- /dev/null
+++ b/nc_test4/filter_test/tst_filter.sh
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../../test_common.sh
+
+set -e
+export HDF5_PLUGIN_PATH=`pwd`
+
+# Which test cases to exercise
+API=1
+NG=1
+NCP=1
+UNK=1
+NGC=1
+MISC=1
+
+# Function to remove selected -s attributes from file;
+# These attributes might be platform dependent
+sclean() {
+cat $1 \
+  | sed -e '/var:_Endianness/d' \
+  | sed -e '/_NCProperties/d' \
+  | sed -e '/_SuperblockVersion/d' \
+  | sed -e '/_IsNetcdf4/d' \
+  | cat > $2
+}
+
+# Function to extract _Filter attribute from a file
+# These attributes might be platform dependent
+getfilterattr() {
+sed -e '/var:_Filter/p' -ed <$1 >$2
+}
+
+trimleft() {
+sed -e 's/[ 	]*\([^ 	].*\)/\1/' <$1 >$2
+}
+
+if test "x$API" = x1 ; then
+echo "*** Testing dynamic filters using API"
+rm -f ./bzip2.nc ./bzip2.dump ./tmp
+${execdir}/test_filter
+$NCDUMP -s ./bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp ./bzip2.dump
+diff -b -w ${srcdir}/bzip2.cdl ./bzip2.dump
+echo "*** Pass: API dynamic filter"
+fi
+
+if test "x$MISC" = x1 ; then
+echo
+echo "*** Testing dynamic filters parameter passing"
+rm -f ./testmisc.nc tmp tmp2
+${execdir}/test_misc
+# Verify the parameters via ncdump
+$NCDUMP -s ./testmisc.nc > ./tmp
+# Extract the parameters
+getfilterattr ./tmp ./tmp2
+rm -f ./tmp
+trimleft ./tmp2 ./tmp
+rm -f ./tmp2
+cat >./tmp2 <<EOF
+var:_Filter = "32768,1,4294967279,23,4294967271,27,77,93,1145389056,697067329,2723935171,128,16777216,4294967295,4294967295" ;
+EOF
+diff -b -w ./tmp ./tmp2
+echo "*** Pass: parameter passing"
+fi
+
+if test "x$NG" = x1 ; then
+echo "*** Testing dynamic filters using ncgen"
+rm -f ./bzip2.nc ./bzip2.dump ./tmp
+$NCGEN -lb -4 -o bzip2.nc ${srcdir}/bzip2.cdl
+$NCDUMP -s ./bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp ./bzip2.dump
+diff -b -w ${srcdir}/bzip2.cdl ./bzip2.dump
+echo "*** Pass: ncgen dynamic filter"
+fi
+
+if test "x$NCP" = x1 ; then
+echo "*** Testing dynamic filters using nccopy"
+rm -f ./unfiltered.nc ./filtered.nc ./filtered.dump ./tmp
+$NCGEN -4 -lb -o unfiltered.nc ${srcdir}/unfiltered.cdl
+$NCCOPY -F "/g/var,307,9,4" unfiltered.nc filtered.nc
+$NCDUMP -s ./filtered.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp ./filtered.dump
+diff -b -w ${srcdir}/filtered.cdl ./filtered.dump
+echo "*** Pass: nccopy dynamic filter"
+fi
+
+if test "x$UNK" = x1 ; then
+echo "*** Testing access to filter info when filter dll is not available"
+rm -f bzip2.nc ./tmp
+# build bzip2.nc
+$NCGEN -lb -4 -o bzip2.nc ${srcdir}/bzip2.cdl
+for f in cygbzip2.dll libbzip2.so ; do
+  if test -f ${execdir}/$f ; then LIBNAME=${execdir}/$f; fi;
+done
+# dump and clean bzip2.nc header only when filter is avail
+$NCDUMP -hs ./bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp bzip2.dump
+# Now hide the filter code
+mv ${LIBNAME} ${LIBNAME}.save
+# dump and clean bzip2.nc header only when filter is not avail
+rm -f ./tmp
+$NCDUMP -hs ./bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp bzip2x.dump
+# Restore the filter code
+mv ${LIBNAME}.save ${LIBNAME}
+diff -b -w ./bzip2.dump ./bzip2x.dump
+echo "*** Pass: ncgen dynamic filter"
+fi
+
+if test "x$NGC" = x1 ; then
+rm -f ./test_bzip2.c
+echo "*** Testing dynamic filters using ncgen with -lc"
+$NCGEN -lc -4 ${srcdir}/bzip2.cdl > test_bzip2.c
+diff -b -w ${srcdir}/ref_bzip2.c ./test_bzip2.c
+echo "*** Pass: ncgen dynamic filter"
+fi
+
+#cleanup
+rm -f ./bzip*.nc ./unfiltered.nc ./filtered.nc ./tmp ./tmp2 *.dump bzip*hdr.*
+rm -fr ./test_bzip2.c
+rm -fr ./testmisc.nc
+exit 0
diff --git a/nc_test4/filtered.cdl b/nc_test4/filtered.cdl
new file mode 100644
index 0000000..e23cf4b
--- /dev/null
+++ b/nc_test4/filtered.cdl
@@ -0,0 +1,88 @@
+netcdf filtered {
+dimensions:
+	dim0 = 4 ;
+	dim1 = 4 ;
+	dim2 = 4 ;
+	dim3 = 4 ;
+
+// global attributes:
+		:_Format = "netCDF-4" ;
+
+group: g {
+  variables:
+  	float var(dim0, dim1, dim2, dim3) ;
+  		var:_Storage = "chunked" ;
+  		var:_ChunkSizes = 4, 4, 4, 4 ;
+		var:_Filter = "307,9,4";
+   		var:_NoFill = "true" ;
+
+  // group attributes:
+  data:
+
+   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,
+  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, 241, 242, 243,
+  244, 245, 246, 247,
+  248, 249, 250, 251,
+  252, 253, 254, 255 ;
+  } // group g
+}
diff --git a/nc_test4/findplugin.in b/nc_test4/findplugin.in
new file mode 100644
index 0000000..f395e0e
--- /dev/null
+++ b/nc_test4/findplugin.in
@@ -0,0 +1,99 @@
+#!/bin/bash
+
+# Define a function that attempts to locate a
+# plugin with a given canonical name.
+# Assumptions:
+#   1. hdf5plugins is a directory in this current directory
+# Inputs:
+#   $1 is the canonical name
+#   $2 is 1 if we are running under cmake
+#   $3 is 1 if we are running using Visual Studio, blank otherwise
+#   $4 is the build type; only used if $3 is 1
+# Outputs:
+#   return code is 0 is success, 1 if failed
+#   Variable HDF5_PLUGIN_LIB is set to the library file name
+#   Variable HDF5_PLUGIN_PATH is setthe absolute path to the
+#                    directory containing the plugin library file
+# Local variables are prefixed with FP_
+#
+# Note: we assume that the use of the CMAKE_BUILD_TYPE
+# is obviated by setting the LIBRARY_OUTPUT_DIRECTORY
+# variables: see hdf5plugins/CMakeLists.txt
+
+findplugin() {
+
+FP_NAME="$1"
+
+# Figure out the compiler (some values from ./configure)
+FP_ISCMAKE=@ISCMAKE@
+FP_ISMSVC=@MSVC@
+
+# Are we operating under OS-X? (test using uname)
+FP_OS=`uname | cut -d '_'  -f 1`
+if test "x$FP_OS" = xDarwin ; then FP_ISOSX=1; fi
+
+# Are we operating under CYGWIN? (test using uname)
+FP_OS=`uname | cut -d '_'  -f 1`
+if test "x$FP_OS" = xCYGWIN ; then FP_ISCYGWIN=1; fi
+
+FP_PLUGINS=`pwd`
+FP_PLUGINS="$FP_PLUGINS/hdf5plugins"
+
+FP_PLUGIN_LIB=
+FP_PLUGIN_PATH=
+
+# Figure out the plugin file name
+# Test for visual studio before cygwin since both might be true
+if test "x$FP_ISMSVC" != x ; then
+  FP_PLUGIN_LIB="${FP_NAME}.dll"
+elif test "x$FP_ISCYGWIN" != x ; then
+  FP_PLUGIN_LIB="cyg${FP_NAME}.dll"
+elif test "x$FP_ISOSX" != x ; then
+  FP_PLUGIN_LIB="lib${FP_NAME}.so" # Should this include the version number in the name?
+else # Presumably some form on *nix"
+  FP_PLUGIN_LIB="lib${FP_NAME}.so"
+fi
+
+# Figure out the path to where the lib is stored
+# This can probably be simplified
+# Case 1: Cmake with Visual Studio
+# Do not know where to look for a dylib
+# Case 1: Cmake with Visual Studio
+if test "x$FP_ISCMAKE" != x -a "x${FP_ISMSVC}" != x ; then
+  # Case 1a: ignore the build type directory
+  if test -f "${FP_PLUGINS}/${FP_PLUGIN_LIB}" ; then
+    FP_PLUGIN_PATH="${FP_PLUGINS}"
+  fi
+else # Case 2: automake
+  # Case 2a: look in .libs
+  if test -f "${FP_PLUGINS}/.libs/${FP_PLUGIN_LIB}" ; then
+    FP_PLUGIN_PATH="${FP_PLUGINS}/.libs"
+  else # Case 2: look in FP_PLUGINS directly
+    if test -f "${FP_PLUGINS}/${FP_PLUGIN_LIB}" ; then
+      FP_PLUGIN_PATH="${FP_PLUGINS}"
+    fi
+  fi
+fi
+
+# Verify
+if test "x$FP_PLUGIN_PATH" = x ; then
+  echo "***Fail: Could not locate a usable HDF5_PLUGIN_PATH"
+  return 1
+fi
+if ! test -f "$FP_PLUGIN_PATH/$FP_PLUGIN_LIB" ; then
+  echo "***Fail: Could not locate a usable HDF5_PLUGIN_LIB"
+  return 1
+fi
+
+# If we are operating using both Visual Studio and Cygwin,
+# then we need to convert the FP_PLUGIN_PATH to windows format
+if test "x$FP_ISMSVC" != x -a "x$FP_ISCYGWIN" != x ; then
+FP_PLUGIN_PATH=`cygpath -wl $FP_PLUGIN_PATH`
+fi
+
+# Set the final output variables
+HDF5_PLUGIN_LIB="$FP_PLUGIN_LIB"
+HDF5_PLUGIN_PATH="$FP_PLUGIN_PATH"
+
+return 0
+}
diff --git a/nc_test4/h5testszip.c b/nc_test4/h5testszip.c
new file mode 100755
index 0000000..8615b05
--- /dev/null
+++ b/nc_test4/h5testszip.c
@@ -0,0 +1,182 @@
+/*
+ * Example illustrates the use of SZIP compression in HDF5
+ */
+
+#include <stdio.h>
+#include "hdf5.h"
+
+#define NX 500
+#define NY 600
+#define CH_NX 100
+#define CH_NY 25
+
+static void initialize(void);
+static int compare(void);
+
+static float buf[NX][NY];
+static float buf_r[NX][NY];
+
+static const char* filename = "test.h5";
+
+static int
+writeszip()
+{
+   hid_t file;
+   hid_t dataset32;
+   hid_t properties;
+   hid_t lcpl_id, dapl_id;
+   hid_t data_space;
+   hsize_t dims[2], chunk_size[2];
+   unsigned szip_options_mask;
+   unsigned szip_pixels_per_block;
+
+  /*
+   * Create a new file using read/write access, default file 
+   * creation properties, and default file access properties.
+   */
+   file = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+   /* Describe the size of the array. */
+   dims[0] = NX;
+   dims[1] = NY;
+   data_space = H5Screate_simple (2, dims, NULL);
+
+  /*
+   * Set the dataset creation property list to specify that
+   * the raw data is to be partitioned into 100x100 element
+   * chunks and that each chunk is to be compressed.
+   */
+   chunk_size[0] = CH_NX;
+   chunk_size[1] = CH_NY;
+   properties = H5Pcreate (H5P_DATASET_CREATE);
+   H5Pset_chunk (properties, 2, chunk_size);
+
+  /* 
+   * Set parameters for SZIP compression; check the description of
+   * the H5Pset_szip function in the HDF5 Reference Manual for more 
+   * information.
+   */
+   szip_options_mask=H5_SZIP_NN_OPTION_MASK;
+   szip_pixels_per_block=32;
+
+   H5Pset_szip (properties, szip_options_mask, szip_pixels_per_block);
+
+  /*
+   * Create a new dataset within the file.  The datatype
+   * and data space describe the data on disk, which may
+   * be different from the format used in the application's
+   * memory.
+   */
+
+   lcpl_id = H5Pcreate (H5P_LINK_CREATE);
+   dapl_id = H5Pcreate (H5P_DATASET_ACCESS);
+
+   dataset32 = H5Dcreate (file, "datasetF32", H5T_NATIVE_FLOAT, data_space, lcpl_id, properties, dapl_id);
+
+  /*
+   * Write the array to the file.  The datatype and dataspace
+   * describe the format of the data in the `buf' buffer.
+   * The raw data is translated to the format required on disk, 
+   * as defined above.  We use default raw data transfer properties.
+   */
+
+   H5Dwrite (dataset32, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
+            H5P_DEFAULT, buf);
+
+   H5Sclose (data_space);
+   H5Pclose(lcpl_id);
+   H5Pclose(dapl_id);
+   H5Pclose (properties);
+   H5Dclose (dataset32);
+   H5Fclose (file);
+
+   return 1;
+}
+
+static int
+readszip()
+{
+    hid_t file;
+    hid_t dataset32;
+    hid_t properties;
+    int errcnt = 0;
+
+    file = H5Fopen (filename, H5F_ACC_RDONLY, H5P_DEFAULT);
+    properties = H5Pcreate(H5P_DATASET_ACCESS);
+    dataset32 = H5Dopen(file, "datasetF32", properties);
+
+    /*
+     * Read the array.  This is similar to writing data,
+     * except the data flows in the opposite direction.
+     * Note: Decompression is automatic.
+     */
+
+    H5Dread(dataset32, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_r);
+
+    errcnt = compare();
+
+    H5Pclose(properties);
+    H5Dclose (dataset32);
+    H5Fclose (file);
+
+    return (errcnt==0 ? 1 : 0);
+}
+
+static int
+compare(void)
+{
+    int i,j;
+    int errs = 0;
+    
+    /* Do comparison */
+    for (i=0; i < NX; i++) {
+	for (j=0; j < NY; j++) {
+            if(buf[i][j] != buf_r[i][j]) {
+		errs++;
+	        printf("mismatch: [%d][%d]: write = %f read=%f\n",
+		        i,j,buf[i][j],buf_r[i][j]);
+	}
+     }
+   }
+   return errs;
+}
+
+static void
+initialize(void)
+{
+   int i, j;
+   /* Initialize data buffer with some bogus data. */
+   for(i=0; i < NX; i++) {
+     for(j=0; j < NY; j++) {
+       buf[i][j] = (float)(i + j);
+     }
+   }
+}
+
+int
+main(int argc, char** argv)
+{
+    int extfile = 0;
+    if(argc > 1) {
+	filename = argv[1];
+	extfile = 1;
+    }
+
+    initialize();
+    if(!extfile) {
+	if(!writeszip()) {
+	    fprintf(stderr,"writeszip failed.\n");
+	    goto fail;
+	}
+    }
+
+    if(!readszip()) {
+	fprintf(stderr,"openfile failed.\n");
+	goto fail;
+    }
+    fprintf(stderr,"***PASS\n");
+    return 0;
+fail:
+    fprintf(stderr,"***FAIL\n");
+    return 1;
+}
diff --git a/nc_test4/hdf5plugins/CMakeLists.txt b/nc_test4/hdf5plugins/CMakeLists.txt
new file mode 100644
index 0000000..f61b227
--- /dev/null
+++ b/nc_test4/hdf5plugins/CMakeLists.txt
@@ -0,0 +1,37 @@
+SET(CMAKE_BUILD_TYPE "")
+
+SET(libbzip2_SOURCES blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c H5Zbzip2.c)
+
+SET(libmisc_SOURCES H5Zmisc.c)
+
+IF(ENABLE_FILTER_TESTING)
+IF(BUILD_UTILITIES)
+
+# LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+
+IF(MSVC)
+SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}")
+SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_BINARY_DIR}")
+ENDIF()
+
+ADD_LIBRARY(bzip2 MODULE ${libbzip2_SOURCES})
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES LIBRARY_OUTPUT_NAME "bzip2")
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES ARCHIVE_OUTPUT_NAME "bzip2")
+SET_TARGET_PROPERTIES(bzip2 PROPERTIES RUNTIME_OUTPUT_NAME "bzip2")
+TARGET_LINK_LIBRARIES(bzip2 ${HDF5_HL_LIBRARIES} ${HDF5_C_LIBRARIES})
+
+ADD_LIBRARY(misc MODULE ${libmisc_SOURCES})
+SET_TARGET_PROPERTIES(misc PROPERTIES LIBRARY_OUTPUT_NAME "misc")
+SET_TARGET_PROPERTIES(misc PROPERTIES ARCHIVE_OUTPUT_NAME "misc")
+SET_TARGET_PROPERTIES(misc PROPERTIES RUNTIME_OUTPUT_NAME "misc")
+TARGET_LINK_LIBRARIES(misc ${HDF5_HL_LIBRARIES} ${HDF5_C_LIBRARIES})
+
+ENDIF(BUILD_UTILITIES)
+ENDIF(ENABLE_FILTER_TESTING)
+
+# Copy some test files from current source dir to out-of-tree build dir.
+FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+IF(MSVC)
+  FILE(COPY ${COPY_FILES} DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}/)
+ENDIF()
diff --git a/nc_test4/hdf5plugins/H5Zbzip2.c b/nc_test4/hdf5plugins/H5Zbzip2.c
new file mode 100644
index 0000000..99c98b2
--- /dev/null
+++ b/nc_test4/hdf5plugins/H5Zbzip2.c
@@ -0,0 +1,181 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+
+#ifndef DLL_EXPORT
+#define DLL_EXPORT
+#endif
+
+#include "h5bzip2.h"
+
+const H5Z_class2_t H5Z_BZIP2[1] = {{
+    H5Z_CLASS_T_VERS,       /* H5Z_class_t version */
+    (H5Z_filter_t)H5Z_FILTER_BZIP2,         /* Filter id number             */
+    1,              /* encoder_present flag (set to true) */
+    1,              /* decoder_present flag (set to true) */
+    "bzip2",                  /* Filter name for debugging    */
+    (H5Z_can_apply_func_t)H5Z_bzip2_can_apply, /* The "can apply" callback  */
+    NULL,                       /* The "set local" callback     */
+    (H5Z_func_t)H5Z_filter_bzip2,         /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_BZIP2;
+}
+
+/* Make this explicit */
+/*
+ * The "can_apply" callback returns positive a valid combination, zero for an
+ * invalid combination and negative for an error.
+ */
+htri_t
+H5Z_bzip2_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+{
+    return 1; /* Assume it can always apply */
+}
+
+size_t H5Z_filter_bzip2(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+  char *outbuf = NULL;
+  size_t outbuflen, outdatalen;
+  int ret;
+
+  if (flags & H5Z_FLAG_REVERSE) {
+
+    /** Decompress data.
+     **
+     ** This process is troublesome since the size of uncompressed data
+     ** is unknown, so the low-level interface must be used.
+     ** Data is decompressed to the output buffer (which is sized
+     ** for the average case); if it gets full, its size is doubled
+     ** and decompression continues.  This avoids repeatedly trying to
+     ** decompress the whole block, which could be really inefficient.
+     **/
+
+    bz_stream stream;
+    char *newbuf = NULL;
+    size_t newbuflen;
+
+    /* Prepare the output buffer. */
+    outbuflen = nbytes * 3 + 1;  /* average bzip2 compression ratio is 3:1 */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Use standard malloc()/free() for internal memory handling. */
+    stream.bzalloc = NULL;
+    stream.bzfree = NULL;
+    stream.opaque = NULL;
+
+    /* Start decompression. */
+    ret = BZ2_bzDecompressInit(&stream, 0, 0);
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 decompression start failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+
+    /* Feed data to the decompression process and get decompressed data. */
+    stream.next_out = outbuf;
+    stream.avail_out = outbuflen;
+    stream.next_in = *buf;
+    stream.avail_in = nbytes;
+    do {
+      ret = BZ2_bzDecompress(&stream);
+      if (ret < 0) {
+	fprintf(stderr, "BUG: bzip2 decompression failed with error %d\n", ret);
+	goto cleanupAndFail;
+      }
+
+      if (ret != BZ_STREAM_END && stream.avail_out == 0) {
+        /* Grow the output buffer. */
+        newbuflen = outbuflen * 2;
+        newbuf = realloc(outbuf, newbuflen);
+        if (newbuf == NULL) {
+          fprintf(stderr, "memory allocation failed for bzip2 decompression\n");
+          goto cleanupAndFail;
+        }
+        stream.next_out = newbuf + outbuflen;  /* half the new buffer behind */
+        stream.avail_out = outbuflen;  /* half the new buffer ahead */
+        outbuf = newbuf;
+        outbuflen = newbuflen;
+      }
+    } while (ret != BZ_STREAM_END);
+
+    /* End compression. */
+    outdatalen = stream.total_out_lo32;
+    ret = BZ2_bzDecompressEnd(&stream);
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 compression end failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+
+  } else {
+
+    /** Compress data.
+     **
+     ** This is quite simple, since the size of compressed data in the worst
+     ** case is known and it is not much bigger than the size of uncompressed
+     ** data.  This allows us to use the simplified one-shot interface to
+     ** compression.
+     **/
+
+    unsigned int odatalen;  /* maybe not the same size as outdatalen */
+    int blockSize100k = 9;
+
+    /* Get compression block size if present. */
+    if (cd_nelmts > 0) {
+      blockSize100k = cd_values[0];
+      if (blockSize100k < 1 || blockSize100k > 9) {
+	fprintf(stderr, "invalid compression block size: %d\n", blockSize100k);
+	goto cleanupAndFail;
+      }
+    }
+
+    /* Prepare the output buffer. */
+    outbuflen = nbytes + nbytes / 100 + 600;  /* worst case (bzip2 docs) */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for bzip2 compression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Compress data. */
+    odatalen = outbuflen;
+    ret = BZ2_bzBuffToBuffCompress(outbuf, &odatalen, *buf, nbytes,
+                                   blockSize100k, 0, 0);
+    outdatalen = odatalen;
+    if (ret != BZ_OK) {
+      fprintf(stderr, "bzip2 compression failed with error %d\n", ret);
+      goto cleanupAndFail;
+    }
+  }
+
+  /* Always replace the input buffer with the output buffer. */
+  free(*buf);
+  *buf = outbuf;
+  *buf_size = outbuflen;
+  return outdatalen;
+
+ cleanupAndFail:
+  if (outbuf)
+    free(outbuf);
+  return 0;
+}
diff --git a/nc_test4/hdf5plugins/H5Zmisc.c b/nc_test4/hdf5plugins/H5Zmisc.c
new file mode 100644
index 0000000..b267051
--- /dev/null
+++ b/nc_test4/hdf5plugins/H5Zmisc.c
@@ -0,0 +1,252 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+
+#ifndef DLL_EXPORT
+#define DLL_EXPORT
+#endif
+
+#include "h5misc.h"
+
+#if defined  _MSC_VER || defined __APPLE__
+#define DBLVAL 12345678.12345678
+#else
+#define DBLVAL 12345678.12345678d
+#endif
+
+#undef DEBUG
+
+static int paramcheck(size_t nparams, const unsigned int* params);
+static void byteswap8(unsigned char* mem);
+static void mismatch(size_t i, const char* which);
+
+const H5Z_class2_t H5Z_TEST[1] = {{
+    H5Z_CLASS_T_VERS,                /* H5Z_class_t version */
+    (H5Z_filter_t)(H5Z_FILTER_TEST), /* Filter id number */
+    1,                               /* encoder_present flag (set to true) */
+    1,                               /* decoder_present flag (set to true) */
+    "test",                          /* Filter name for debugging    */
+    (H5Z_can_apply_func_t)H5Z_test_can_apply, /* The "can apply" callback  */
+    NULL,			     /* The "set local" callback  */
+    (H5Z_func_t)H5Z_filter_test,     /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_TEST;
+}
+
+/* Make this explicit */
+/*
+ * The "can_apply" callback returns positive a valid combination, zero for an
+ * invalid combination and negative for an error.
+ */
+htri_t
+H5Z_test_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+{
+    return 1; /* Assume it can always apply */
+}
+
+/*
+This filter does some verification
+that the parameters passed to the filter
+are correct. Specifically, that endian-ness
+is correct. As a filter, it is the identify
+function, passing input to output unchanged.
+
+Test cases format:
+1.The first param is the test index i.e. which test to execute.
+2. The remaining parameters are those for the test chosen in #1
+
+*/
+
+size_t
+H5Z_filter_test(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+    void* newbuf;
+    unsigned int testcase = 0;
+
+    if(cd_nelmts == 0)
+	goto fail;
+
+    testcase = cd_values[0];
+
+    if(testcase == TC_ENDIAN) {
+	if(!paramcheck(cd_nelmts,cd_values))
+	    goto fail;
+    }
+
+    if (flags & H5Z_FLAG_REVERSE) {
+
+        /* Replace buffer */
+        newbuf = malloc(*buf_size);
+        if(newbuf == NULL) abort();
+        memcpy(newbuf,*buf,*buf_size);
+        *buf = newbuf;
+
+    } else {
+
+        /* Replace buffer */
+        newbuf = malloc(*buf_size);
+        if(newbuf == NULL) abort();
+        memcpy(newbuf,*buf,*buf_size);
+        *buf = newbuf;
+
+    }
+
+    return *buf_size;
+
+fail:
+    return 0;
+}
+
+static int
+paramcheck(size_t nparams, const unsigned int* params)
+{
+    size_t i;
+    /* Test endianness of this machine */
+    const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
+    int bigendian = (1 == *(unsigned int*)b); /* 1=>big 0=>little*/
+
+    if(nparams != 14) {
+	fprintf(stderr,"Too few parameters: need=16 sent=%ld\n",(unsigned long)nparams);
+	goto fail;
+    }
+
+    for(i=0;i<nparams;i++) {
+	unsigned int ival;
+	unsigned long long lval;
+	float fval;
+	double dval;
+        switch (i) {
+        case 0: break; /* this is the testcase # */
+        case 1:
+	    ival = (-17) & 0xff;
+	    if(ival != (signed int)(params[i]))
+	    {mismatch(i,"signed byte"); goto fail; };
+	    break;
+        case 2:
+	    ival = 23;
+	    if(ival != (unsigned int)(params[i]))
+	    {mismatch(i,"unsigned byte"); goto fail; };
+	    break;
+        case 3:
+	    ival = (-25) & 0xffff;
+	    if(ival != (signed int)(params[i]))
+	    {mismatch(i,"signed short"); goto fail; };
+	    break;
+        case 4:
+	    ival = 27;
+	    if(ival != (unsigned int)(params[i]))
+	    {mismatch(i,"unsigned short"); goto fail; };
+	    break;
+        case 5:
+	    ival = 77;
+	    if(ival != (signed int)(params[i]))
+	    {mismatch(i,"signed int"); goto fail; };
+	    break;
+        case 6:
+	    ival = 93u;
+	    if(ival != (unsigned int)(params[i]))
+	    {mismatch(i,"unsigned int"); goto fail; };
+	    break;
+        case 7:
+	    fval = 789.0f;
+	    if(fval != *(float*)(&params[i]))
+	    {mismatch(i,"float"); goto fail; };
+	    break;
+        case 8: {/*double*/
+            double x = *(double*)&params[i];
+	    dval = DBLVAL;
+            i++; /* takes two parameters */
+            if(bigendian)
+		byteswap8((unsigned char*)&x);
+	    if(dval != x) {
+                mismatch(i,"double");
+                goto fail;
+            }
+            }; break;
+        case 10: {/*signed long long*/
+            signed long long x = *(signed long long*)&params[i];
+	    lval = -9223372036854775807L;
+            i++; /* takes two parameters */
+            if(bigendian)
+		byteswap8((unsigned char*)&x);
+            if(lval != x) {
+                mismatch(i,"signed long long");
+                goto fail;
+            }
+            }; break;
+        case 12: {/*unsigned long long*/
+            unsigned long long x = *(unsigned long long*)&params[i];
+	    lval = 18446744073709551615UL;
+            i++; /* takes two parameters */
+            if(bigendian)
+		byteswap8((unsigned char*)&x);
+            if(lval != x) {
+                mismatch(i,"unsigned long long");
+                goto fail;
+            }
+            }; break;
+
+        default:
+            mismatch(i,"unexpected parameter");
+            goto fail;
+            break;
+        }
+    }
+
+#ifdef DEBUG
+    {
+	size_t i;
+	fprintf(stderr,"bigendian=%d nparams=%d params=\n",bigendian,nparams);
+	for(i=0;i<nparams;i++) {
+	    fprintf(stderr,"[%d] %ud %d %f\n", (unsigned int)i, params[i],(signed int)params[i],*(float*)&params[i]);
+	}
+	fflush(stderr);
+    }
+#endif
+    return 1;
+fail:
+    return 0;
+}
+
+static void
+byteswap8(unsigned char* mem)
+{
+    unsigned char c;
+    c = mem[0];
+    mem[0] = mem[7];
+    mem[7] = c;
+    c = mem[1];
+    mem[1] = mem[6];
+    mem[6] = c;
+    c = mem[2];
+    mem[2] = mem[5];
+    mem[5] = c;
+    c = mem[3];
+    mem[3] = mem[4];
+    mem[4] = c;
+}
+
+static void
+mismatch(size_t i, const char* which)
+{
+    fprintf(stderr,"mismatch: [%ld] %s\n",(unsigned long)i,which);
+    fflush(stderr);
+}
diff --git a/nc_test4/hdf5plugins/H5Ztemplate.c b/nc_test4/hdf5plugins/H5Ztemplate.c
new file mode 100644
index 0000000..bc15a33
--- /dev/null
+++ b/nc_test4/hdf5plugins/H5Ztemplate.c
@@ -0,0 +1,104 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <hdf5.h>
+/* Older versions of the hdf library may define H5PL_type_t here */
+#include <H5PLextern.h>
+#include "xxxx.h"
+
+/*
+Provide a textual template (not a C++ template)
+from which one can construct a new filter.
+The filter "name is marked with "XXXX" or "xxxx"
+
+*/
+
+const H5Z_class2_t H5Z_XXXX[1] = {{
+    H5Z_CLASS_T_VERS,       /* H5Z_class_t version */
+    (H5Z_filter_t)H5Z_FILTER_XXXX, /* Filter id number             */
+    1,                             /* encoder_present flag (set to true) */
+    1,                             /* decoder_present flag (set to true) */
+    "xxxx",                        /* Filter name for debugging    */
+    NULL,                          /* The "can apply" callback     */
+    NULL,                          /* The "set local" callback     */
+    (H5Z_func_t)H5Z_filter_xxxx,   /* The actual filter function   */
+}};
+
+/* External Discovery Functions */
+H5PL_type_t
+H5PLget_plugin_type(void)
+{
+    return H5PL_TYPE_FILTER;
+}
+
+const void*
+H5PLget_plugin_info(void)
+{
+    return H5Z_XXXX;
+}
+
+size_t H5Z_filter_xxxx(unsigned int flags, size_t cd_nelmts,
+		     const unsigned int cd_values[], size_t nbytes,
+		     size_t *buf_size, void **buf);
+
+
+size_t H5Z_filter_xxxx(unsigned int flags, size_t cd_nelmts,
+                     const unsigned int cd_values[], size_t nbytes,
+                     size_t *buf_size, void **buf)
+{
+  char *outbuf = NULL;
+  size_t outbuflen, outdatalen;
+  int ret;
+
+  if (flags & H5Z_FLAG_REVERSE) {
+
+    /** Decompress data.
+     **
+     ** This process is troublesome since the size of uncompressed data
+     ** is unknown, so the low-level interface must be used.
+     ** Data is decompressed to the output buffer (which is sized
+     ** for the average case); if it gets full, its size is doubled
+     ** and decompression continues.  This avoids repeatedly trying to
+     ** decompress the whole block, which could be really inefficient.
+     **/
+
+    char *newbuf = NULL;
+    size_t newbuflen;
+
+  } else {
+
+    /** Compress data.
+     **
+     ** This is quite simple, since the size of compressed data in the worst
+     ** case is known and it is not much bigger than the size of uncompressed
+     ** data.  This allows us to use the simplified one-shot interface to
+     ** compression.
+     **/
+
+    unsigned int odatalen;  /* maybe not the same size as outdatalen */
+
+    /* Prepare the output buffer. */
+    outbuflen = M;  /* worst case */
+    outbuf = malloc(outbuflen);
+    if (outbuf == NULL) {
+      fprintf(stderr, "memory allocation failed for xxxx compression\n");
+      goto cleanupAndFail;
+    }
+
+    /* Compress data. */
+
+  }
+
+  /* Always replace the input buffer with the output buffer. */
+  free(*buf);
+  *buf = outbuf;
+  *buf_size = outbuflen;
+  return outdatalen;
+
+ cleanupAndFail:
+  if (outbuf)
+    free(outbuf);
+  return 0;
+}
diff --git a/nc_test4/hdf5plugins/Makefile.am b/nc_test4/hdf5plugins/Makefile.am
new file mode 100644
index 0000000..044e14b
--- /dev/null
+++ b/nc_test4/hdf5plugins/Makefile.am
@@ -0,0 +1,26 @@
+#    Copyright 2018, UCAR/Unidata
+#    See netcdf/COPYRIGHT file for copying and redistribution conditions.
+
+
+BZIP2HDRS=bzlib.h bzlib_private.h
+BZIP2SRC= blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
+
+PLUGINSRC=H5Zbzip2.c
+PLUGINHDRS=h5bzip2.h
+
+EXTRA_DIST=${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS} \
+		H5Ztemplate.c H5Zmisc.c CMakeLists.txt
+
+if ENABLE_FILTER_TESTING
+
+DLLSRC=${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS}
+
+lib_LTLIBRARIES = libbzip2.la libmisc.la
+
+libbzip2_la_SOURCES = ${DLLSRC}
+libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+
+libmisc_la_SOURCES = H5Zmisc.c h5misc.h
+libmisc_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+
+endif #ENABLE_FILTER_TESTING
diff --git a/liblib/Makefile.in b/nc_test4/hdf5plugins/Makefile.in
similarity index 80%
copy from liblib/Makefile.in
copy to nc_test4/hdf5plugins/Makefile.in
index c2a4318..5e70130 100644
--- a/liblib/Makefile.in
+++ b/nc_test4/hdf5plugins/Makefile.in
@@ -14,20 +14,8 @@
 
 @SET_MAKE@
 
-# Copyright 2010, see the COPYRIGHT file for more information.
-
-# This Makefile assembles the correct libnetcdf based on various
-# configure flags. It is assumed that all the relevant convenience
-# libraries have been built (e.g. libsrc, libsrc4, libncdap3, libcdmr,
-# libncdap4, fortran).
-
-# This is part of the netCDF package.
-# Copyright 2005 University Corporation for Atmospheric Research/Unidata
-# See COPYRIGHT file for conditions of use.
-# 
-# Assemble the CPPFLAGS and LDFLAGS that point to all the needed
-# libraries for netCDF-4.
-#
+#    Copyright 2018, UCAR/Unidata
+#    See netcdf/COPYRIGHT file for copying and redistribution conditions.
 
 VPATH = @srcdir@
 am__is_gnu_make = { \
@@ -104,39 +92,7 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
- at USE_DAP_TRUE@am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
-
-# Turn on some extra stuff when building a DLL for windows.
- at BUILD_DLL_TRUE@am__append_3 = -no-undefined -Wl,--output-def,netcdfdll.def
- at BUILD_DLL_TRUE@am__append_4 = -DDLL_EXPORT
-
-# The v2 API...
- at BUILD_V2_TRUE@am__append_5 = ${top_builddir}/libdispatch/libnetcdf2.la
-
-# + pnetcdf
- at USE_PNETCDF_TRUE@am__append_6 = -I${top_srcdir}/libsrcp
- at USE_PNETCDF_TRUE@am__append_7 = ${top_builddir}/libsrcp/libnetcdfp.la
-
-# + dap
- at ENABLE_DAP_TRUE@am__append_8 = -I${top_srcdir}/libdap2 -I${top_srcdir}/oc
- at ENABLE_DAP_TRUE@am__append_9 = ${top_builddir}/libdap2/libdap2.la \
- at ENABLE_DAP_TRUE@	${top_builddir}/oc2/liboc.la
- at ENABLE_DAP4_TRUE@am__append_10 = -I${top_srcdir}/libdap4
- at ENABLE_DAP4_TRUE@am__append_11 = ${top_builddir}/libdap4/libdap4.la
-
-# NetCDF-4 ...
- at USE_NETCDF4_TRUE@am__append_12 = -I${top_srcdir}/libsrc4
- at USE_NETCDF4_TRUE@am__append_13 = ${top_builddir}/libsrc4/libnetcdf4.la
-
-# Not ready for prime time yet
-# libnetcdf_la_LIBADD += ${top_builddir}/libdiskless/libdiskless.la
-
-# Force binary mode for file read/write
- at ISCYGWIN_TRUE@am__append_14 = -lbinmode
-subdir = liblib
+subdir = nc_test4/hdf5plugins
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -178,19 +134,35 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
-libnetcdf_la_DEPENDENCIES = $(am__append_5) \
-	${top_builddir}/libdispatch/libdispatch.la \
-	${top_builddir}/libsrc/libnetcdf3.la $(am__append_7) \
-	$(am__append_9) $(am__append_11) $(am__append_13)
-am_libnetcdf_la_OBJECTS = libnetcdf_la-nc_initialize.lo
-libnetcdf_la_OBJECTS = $(am_libnetcdf_la_OBJECTS)
+libbzip2_la_LIBADD =
+am__libbzip2_la_SOURCES_DIST = H5Zbzip2.c blocksort.c huffman.c \
+	crctable.c randtable.c compress.c decompress.c bzlib.c \
+	h5bzip2.h bzlib.h bzlib_private.h
+am__objects_1 = H5Zbzip2.lo
+am__objects_2 = blocksort.lo huffman.lo crctable.lo randtable.lo \
+	compress.lo decompress.lo bzlib.lo
+am__objects_3 =
+ at ENABLE_FILTER_TESTING_TRUE@am__objects_4 = $(am__objects_1) \
+ at ENABLE_FILTER_TESTING_TRUE@	$(am__objects_2) $(am__objects_3) \
+ at ENABLE_FILTER_TESTING_TRUE@	$(am__objects_3)
+ at ENABLE_FILTER_TESTING_TRUE@am_libbzip2_la_OBJECTS = $(am__objects_4)
+libbzip2_la_OBJECTS = $(am_libbzip2_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-libnetcdf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+libbzip2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libbzip2_la_LDFLAGS) $(LDFLAGS) -o $@
+ at ENABLE_FILTER_TESTING_TRUE@am_libbzip2_la_rpath = -rpath $(libdir)
+libmisc_la_LIBADD =
+am__libmisc_la_SOURCES_DIST = H5Zmisc.c h5misc.h
+ at ENABLE_FILTER_TESTING_TRUE@am_libmisc_la_OBJECTS = H5Zmisc.lo
+libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS)
+libmisc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(libnetcdf_la_LDFLAGS) $(LDFLAGS) -o $@
+	$(libmisc_la_LDFLAGS) $(LDFLAGS) -o $@
+ at ENABLE_FILTER_TESTING_TRUE@am_libmisc_la_rpath = -rpath $(libdir)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -225,8 +197,9 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libnetcdf_la_SOURCES)
-DIST_SOURCES = $(libnetcdf_la_SOURCES)
+SOURCES = $(libbzip2_la_SOURCES) $(libmisc_la_SOURCES)
+DIST_SOURCES = $(am__libbzip2_la_SOURCES_DIST) \
+	$(am__libmisc_la_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -251,20 +224,16 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/lib_flags.am
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
-	$(am__append_6) $(am__append_8) $(am__append_10) \
-	$(am__append_12)
+AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AM_LDFLAGS = $(am__append_14)
+AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -287,12 +256,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -318,6 +289,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -332,6 +304,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -435,35 +408,24 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
-
-# Put together AM_CPPFLAGS and AM_LDFLAGS.
-
-# This is our output, the netcdf library the user will install.
-lib_LTLIBRARIES = libnetcdf.la
-
-# These linker flags specify libtool version info.
-# See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
-# for information regarding incrementing `-version-info`.
-libnetcdf_la_LDFLAGS = -version-info 13:0:0 $(am__append_3)
-libnetcdf_la_CPPFLAGS = ${AM_CPPFLAGS} $(am__append_4)
-
-# The output library will always include netcdf3 and dispatch
-# libraries
-libnetcdf_la_LIBADD = $(am__append_5) \
-	${top_builddir}/libdispatch/libdispatch.la \
-	${top_builddir}/libsrc/libnetcdf3.la $(am__append_7) \
-	$(am__append_9) $(am__append_11) $(am__append_13)
-CLEANFILES = 
-
-# We need at least one source file
-libnetcdf_la_SOURCES = nc_initialize.c
-EXTRA_DIST = CMakeLists.txt
+BZIP2HDRS = bzlib.h bzlib_private.h
+BZIP2SRC = blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
+PLUGINSRC = H5Zbzip2.c
+PLUGINHDRS = h5bzip2.h
+EXTRA_DIST = ${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS} \
+		H5Ztemplate.c H5Zmisc.c CMakeLists.txt
+
+ at ENABLE_FILTER_TESTING_TRUE@DLLSRC = ${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS}
+ at ENABLE_FILTER_TESTING_TRUE@lib_LTLIBRARIES = libbzip2.la libmisc.la
+ at ENABLE_FILTER_TESTING_TRUE@libbzip2_la_SOURCES = ${DLLSRC}
+ at ENABLE_FILTER_TESTING_TRUE@libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
+ at ENABLE_FILTER_TESTING_TRUE@libmisc_la_SOURCES = H5Zmisc.c h5misc.h
+ at ENABLE_FILTER_TESTING_TRUE@libmisc_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
 all: all-am
 
 .SUFFIXES:
 .SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
@@ -472,9 +434,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign liblib/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign nc_test4/hdf5plugins/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign liblib/Makefile
+	  $(AUTOMAKE) --foreign nc_test4/hdf5plugins/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -483,7 +445,6 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
-$(top_srcdir)/lib_flags.am $(am__empty):
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -529,8 +490,11 @@ clean-libLTLIBRARIES:
 	  rm -f $${locs}; \
 	}
 
-libnetcdf.la: $(libnetcdf_la_OBJECTS) $(libnetcdf_la_DEPENDENCIES) $(EXTRA_libnetcdf_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libnetcdf_la_LINK) -rpath $(libdir) $(libnetcdf_la_OBJECTS) $(libnetcdf_la_LIBADD) $(LIBS)
+libbzip2.la: $(libbzip2_la_OBJECTS) $(libbzip2_la_DEPENDENCIES) $(EXTRA_libbzip2_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libbzip2_la_LINK) $(am_libbzip2_la_rpath) $(libbzip2_la_OBJECTS) $(libbzip2_la_LIBADD) $(LIBS)
+
+libmisc.la: $(libmisc_la_OBJECTS) $(libmisc_la_DEPENDENCIES) $(EXTRA_libmisc_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libmisc_la_LINK) $(am_libmisc_la_rpath) $(libmisc_la_OBJECTS) $(libmisc_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -538,7 +502,15 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libnetcdf_la-nc_initialize.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/H5Zbzip2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/H5Zmisc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/blocksort.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bzlib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/compress.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/crctable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/decompress.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/huffman.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/randtable.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -564,13 +536,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
-libnetcdf_la-nc_initialize.lo: nc_initialize.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetcdf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetcdf_la-nc_initialize.lo -MD -MP -MF $(DEPDIR)/libnetcdf_la-nc_initialize.Tpo -c -o libnetcdf_la-nc_initialize.lo `test -f 'nc_initialize.c' || echo '$(srcdir)/'`nc_initialize.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libnetcdf_la-nc_initialize.Tpo $(DEPDIR)/libnetcdf_la-nc_initialize.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nc_initialize.c' object='libnetcdf_la-nc_initialize.lo' libtool=yes @AMDEPBACKSLASH@
- at 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) $(libnetcdf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetcdf_la-nc_initialize.lo `test -f 'nc_initialize.c' || echo '$(srcdir)/'`nc_initialize.c
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -688,7 +653,6 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
-	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
diff --git a/nc_test4/hdf5plugins/blocksort.c b/nc_test4/hdf5plugins/blocksort.c
new file mode 100644
index 0000000..d0d662c
--- /dev/null
+++ b/nc_test4/hdf5plugins/blocksort.c
@@ -0,0 +1,1094 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+__inline__
+void fallbackSimpleSort ( UInt32* fmap, 
+                          UInt32* eclass, 
+                          Int32   lo, 
+                          Int32   hi )
+{
+   Int32 i, j, tmp;
+   UInt32 ec_tmp;
+
+   if (lo == hi) return;
+
+   if (hi - lo > 3) {
+      for ( i = hi-4; i >= lo; i-- ) {
+         tmp = fmap[i];
+         ec_tmp = eclass[tmp];
+         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+            fmap[j-4] = fmap[j];
+         fmap[j-4] = tmp;
+      }
+   }
+
+   for ( i = hi-1; i >= lo; i-- ) {
+      tmp = fmap[i];
+      ec_tmp = eclass[tmp];
+      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+         fmap[j-1] = fmap[j];
+      fmap[j-1] = tmp;
+   }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      fswap(fmap[yyp1], fmap[yyp2]);  \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+                       stackHi[sp] = hz; \
+                       sp++; }
+
+#define fpop(lz,hz) { sp--;              \
+                      lz = stackLo[sp];  \
+                      hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap, 
+                      UInt32* eclass,
+                      Int32   loSt, 
+                      Int32   hiSt )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m;
+   Int32 sp, lo, hi;
+   UInt32 med, r, r3;
+   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+   r = 0;
+
+   sp = 0;
+   fpush ( loSt, hiSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+      fpop ( lo, hi );
+      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+         fallbackSimpleSort ( fmap, eclass, lo, hi );
+         continue;
+      }
+
+      /* Random partitioning.  Median of 3 sometimes fails to
+         avoid bad cases.  Median of 9 seems to help but 
+         looks rather expensive.  This too seems to work but
+         is cheaper.  Guidance for the magic constants 
+         7621 and 32768 is taken from Sedgewick's algorithms
+         book, chapter 35.
+      */
+      r = ((r * 7621) + 1) % 32768;
+      r3 = r % 3;
+      if (r3 == 0) med = eclass[fmap[lo]]; else
+      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+                   med = eclass[fmap[hi]];
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (1) {
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unLo], fmap[ltLo]); 
+               ltLo++; unLo++; 
+               continue; 
+            };
+            if (n > 0) break;
+            unLo++;
+         }
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unHi], fmap[gtHi]); 
+               gtHi--; unHi--; 
+               continue; 
+            };
+            if (n < 0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+      if (gtHi < ltLo) continue;
+
+      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      if (n - lo > hi - m) {
+         fpush ( lo, n );
+         fpush ( m, hi );
+      } else {
+         fpush ( m, hi );
+         fpush ( lo, n );
+      }
+   }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      eclass exists for [0 .. nblock-1]
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      All other areas of eclass destroyed
+      fmap [0 .. nblock-1] holds sorted order
+      bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define      WORD_BH(zz)  bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    UInt32* bhtab,
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   /*--
+      Initial 1-char radix sort to generate
+      initial fmap and initial BH bits.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        bucket sorting ...\n" );
+   for (i = 0; i < 257;    i++) ftab[i] = 0;
+   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i < nblock; i++) {
+      j = eclass8[i];
+      k = ftab[j] - 1;
+      ftab[j] = k;
+      fmap[k] = i;
+   }
+
+   nBhtab = 2 + (nblock / 32);
+   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+   /*--
+      Inductively refine the buckets.  Kind-of an
+      "exponential radix sort" (!), inspired by the
+      Manber-Myers suffix array construction algorithm.
+   --*/
+
+   /*-- set sentinel bits for block-end detection --*/
+   for (i = 0; i < 32; i++) { 
+      SET_BH(nblock + 2*i);
+      CLEAR_BH(nblock + 2*i + 1);
+   }
+
+   /*-- the log(N) loop --*/
+   H = 1;
+   while (1) {
+
+      if (verb >= 4) 
+         VPrintf1 ( "        depth %6d has ", H );
+
+      j = 0;
+      for (i = 0; i < nblock; i++) {
+         if (ISSET_BH(i)) j = i;
+         k = fmap[i] - H; if (k < 0) k += nblock;
+         eclass[k] = j;
+      }
+
+      nNotDone = 0;
+      r = -1;
+      while (1) {
+
+	 /*-- find the next non-singleton bucket --*/
+         k = r + 1;
+         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (ISSET_BH(k)) {
+            while (WORD_BH(k) == 0xffffffff) k += 32;
+            while (ISSET_BH(k)) k++;
+         }
+         l = k - 1;
+         if (l >= nblock) break;
+         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (!ISSET_BH(k)) {
+            while (WORD_BH(k) == 0x00000000) k += 32;
+            while (!ISSET_BH(k)) k++;
+         }
+         r = k - 1;
+         if (r >= nblock) break;
+
+         /*-- now [l, r] bracket current bucket --*/
+         if (r > l) {
+            nNotDone += (r - l + 1);
+            fallbackQSort3 ( fmap, eclass, l, r );
+
+            /*-- scan bucket and generate header bits-- */
+            cc = -1;
+            for (i = l; i <= r; i++) {
+               cc1 = eclass[fmap[i]];
+               if (cc != cc1) { SET_BH(i); cc = cc1; };
+            }
+         }
+      }
+
+      if (verb >= 4) 
+         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+      H *= 2;
+      if (H > nblock || nNotDone == 0) break;
+   }
+
+   /*-- 
+      Reconstruct the original block in
+      eclass8 [0 .. nblock-1], since the
+      previous phase destroyed it.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        reconstructing block ...\n" );
+   j = 0;
+   for (i = 0; i < nblock; i++) {
+      while (ftabCopy[j] == 0) j++;
+      ftabCopy[j]--;
+      eclass8[fmap[i]] = (UChar)j;
+   }
+   AssertH ( j < 256, 1005 );
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for "normal"       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32  i1, 
+               UInt32  i2,
+               UChar*  block, 
+               UInt16* quadrant,
+               UInt32  nblock,
+               Int32*  budget )
+{
+   Int32  k;
+   UChar  c1, c2;
+   UInt16 s1, s2;
+
+   AssertD ( i1 != i2, "mainGtU" );
+   /* 1 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 2 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 3 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 4 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 5 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 6 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 7 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 8 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 9 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 10 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 11 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 12 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+
+   k = nblock + 8;
+
+   do {
+      /* 1 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 2 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 3 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 4 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 5 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 6 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 7 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 8 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+
+      if (i1 >= nblock) i1 -= nblock;
+      if (i2 >= nblock) i2 -= nblock;
+
+      k -= 8;
+      (*budget)--;
+   }
+      while (k >= 0);
+
+   return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Knuth's increments seem to work better
+   than Incerpi-Sedgewick here.  Possibly
+   because the number of elems to sort is
+   usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+                   9841, 29524, 88573, 265720,
+                   797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+                      UChar*  block,
+                      UInt16* quadrant,
+                      Int32   nblock,
+                      Int32   lo, 
+                      Int32   hi, 
+                      Int32   d,
+                      Int32*  budget )
+{
+   Int32 i, j, h, bigN, hp;
+   UInt32 v;
+
+   bigN = hi - lo + 1;
+   if (bigN < 2) return;
+
+   hp = 0;
+   while (incs[hp] < bigN) hp++;
+   hp--;
+
+   for (; hp >= 0; hp--) {
+      h = incs[hp];
+
+      i = lo + h;
+      while (True) {
+
+         /*-- copy 1 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 2 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 3 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         if (*budget < 0) return;
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+/*--
+   The following is an implementation of
+   an elegant 3-way quicksort for strings,
+   described in a paper "Fast Algorithms for
+   Sorting and Searching Strings", by Robert
+   Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      mswap(ptr[yyp1], ptr[yyp2]);    \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+static 
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+   UChar t;
+   if (a > b) { t = a; a = b; b = t; };
+   if (b > c) { 
+      b = c;
+      if (a > b) b = a;
+   }
+   return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+                          stackHi[sp] = hz; \
+                          stackD [sp] = dz; \
+                          sp++; }
+
+#define mpop(lz,hz,dz) { sp--;             \
+                         lz = stackLo[sp]; \
+                         hz = stackHi[sp]; \
+                         dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz)                                        \
+   { Int32 tz;                                                  \
+     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+                  UChar*  block,
+                  UInt16* quadrant,
+                  Int32   nblock,
+                  Int32   loSt, 
+                  Int32   hiSt, 
+                  Int32   dSt,
+                  Int32*  budget )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+   Int32 sp, lo, hi, d;
+
+   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+   Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+   Int32 nextLo[3];
+   Int32 nextHi[3];
+   Int32 nextD [3];
+
+   sp = 0;
+   mpush ( loSt, hiSt, dSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+      mpop ( lo, hi, d );
+      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
+          d > MAIN_QSORT_DEPTH_THRESH) {
+         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+         if (*budget < 0) return;
+         continue;
+      }
+
+      med = (Int32) 
+            mmed3 ( block[ptr[ lo         ]+d],
+                    block[ptr[ hi         ]+d],
+                    block[ptr[ (lo+hi)>>1 ]+d] );
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (True) {
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unLo]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unLo], ptr[ltLo]); 
+               ltLo++; unLo++; continue; 
+            };
+            if (n >  0) break;
+            unLo++;
+         }
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unHi]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unHi], ptr[gtHi]); 
+               gtHi--; unHi--; continue; 
+            };
+            if (n <  0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+      if (gtHi < ltLo) {
+         mpush(lo, hi, d+1 );
+         continue;
+      }
+
+      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+      mpush (nextLo[0], nextHi[0], nextD[0]);
+      mpush (nextLo[1], nextHi[1], nextD[1]);
+      mpush (nextLo[2], nextHi[2], nextD[2]);
+   }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > N_OVERSHOOT
+      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      All other areas of block32 destroyed
+      ftab [0 .. 65536 ] destroyed
+      ptr [0 .. nblock-1] holds sorted order
+      if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr, 
+                UChar*  block,
+                UInt16* quadrant, 
+                UInt32* ftab,
+                Int32   nblock,
+                Int32   verb,
+                Int32*  budget )
+{
+   Int32  i, j, k, ss, sb;
+   Int32  runningOrder[256];
+   Bool   bigDone[256];
+   Int32  copyStart[256];
+   Int32  copyEnd  [256];
+   UChar  c1;
+   Int32  numQSorted;
+   UInt16 s;
+   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
+
+   /*-- set up the 2-byte frequency table --*/
+   for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+   j = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+      quadrant[i-1] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+      ftab[j]++;
+      quadrant[i-2] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+      ftab[j]++;
+      quadrant[i-3] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+      ftab[j]++;
+   }
+   for (; i >= 0; i--) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+   }
+
+   /*-- (emphasises close relationship of block & quadrant) --*/
+   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+      block   [nblock+i] = block[i];
+      quadrant[nblock+i] = 0;
+   }
+
+   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
+
+   /*-- Complete the initial radix sort --*/
+   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+   s = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+      s = (s >> 8) | (block[i-1] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-1;
+      s = (s >> 8) | (block[i-2] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-2;
+      s = (s >> 8) | (block[i-3] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-3;
+   }
+   for (; i >= 0; i--) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+   }
+
+   /*--
+      Now ftab contains the first loc of every small bucket.
+      Calculate the running order, from smallest to largest
+      big bucket.
+   --*/
+   for (i = 0; i <= 255; i++) {
+      bigDone     [i] = False;
+      runningOrder[i] = i;
+   }
+
+   {
+      Int32 vv;
+      Int32 h = 1;
+      do h = 3 * h + 1; while (h <= 256);
+      do {
+         h = h / 3;
+         for (i = h; i <= 255; i++) {
+            vv = runningOrder[i];
+            j = i;
+            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+               runningOrder[j] = runningOrder[j-h];
+               j = j - h;
+               if (j <= (h - 1)) goto zero;
+            }
+            zero:
+            runningOrder[j] = vv;
+         }
+      } while (h != 1);
+   }
+
+   /*--
+      The main sorting loop.
+   --*/
+
+   numQSorted = 0;
+
+   for (i = 0; i <= 255; i++) {
+
+      /*--
+         Process big buckets, starting with the least full.
+         Basically this is a 3-step process in which we call
+         mainQSort3 to sort the small buckets [ss, j], but
+         also make a big effort to avoid the calls if we can.
+      --*/
+      ss = runningOrder[i];
+
+      /*--
+         Step 1:
+         Complete the big bucket [ss] by quicksorting
+         any unsorted small buckets [ss, j], for j != ss.  
+         Hopefully previous pointer-scanning phases have already
+         completed many of the small buckets [ss, j], so
+         we don't have to sort them at all.
+      --*/
+      for (j = 0; j <= 255; j++) {
+         if (j != ss) {
+            sb = (ss << 8) + j;
+            if ( ! (ftab[sb] & SETMASK) ) {
+               Int32 lo = ftab[sb]   & CLEARMASK;
+               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+               if (hi > lo) {
+                  if (verb >= 4)
+                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
+                                "done %d   this %d\n",
+                                ss, j, numQSorted, hi - lo + 1 );
+                  mainQSort3 ( 
+                     ptr, block, quadrant, nblock, 
+                     lo, hi, BZ_N_RADIX, budget 
+                  );   
+                  numQSorted += (hi - lo + 1);
+                  if (*budget < 0) return;
+               }
+            }
+            ftab[sb] |= SETMASK;
+         }
+      }
+
+      AssertH ( !bigDone[ss], 1006 );
+
+      /*--
+         Step 2:
+         Now scan this big bucket [ss] so as to synthesise the
+         sorted order for small buckets [t, ss] for all t,
+         including, magically, the bucket [ss,ss] too.
+         This will avoid doing Real Work in subsequent Step 1's.
+      --*/
+      {
+         for (j = 0; j <= 255; j++) {
+            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
+            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+         }
+         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1])
+               ptr[ copyStart[c1]++ ] = k;
+         }
+         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1]) 
+               ptr[ copyEnd[c1]-- ] = k;
+         }
+      }
+
+      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+                || 
+                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+                   Necessity for this case is demonstrated by compressing 
+                   a sequence of approximately 48.5 million of character 
+                   251; 1.0.0/1.0.1 will then die here. */
+                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+                1007 )
+
+      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+      /*--
+         Step 3:
+         The [ss] big bucket is now done.  Record this fact,
+         and update the quadrant descriptors.  Remember to
+         update quadrants in the overshoot area too, if
+         necessary.  The "if (i < 255)" test merely skips
+         this updating for the last bucket processed, since
+         updating for the last bucket is pointless.
+
+         The quadrant array provides a way to incrementally
+         cache sort orderings, as they appear, so as to 
+         make subsequent comparisons in fullGtU() complete
+         faster.  For repetitive blocks this makes a big
+         difference (but not big enough to be able to avoid
+         the fallback sorting mechanism, exponential radix sort).
+
+         The precise meaning is: at all times:
+
+            for 0 <= i < nblock and 0 <= j <= nblock
+
+            if block[i] != block[j], 
+
+               then the relative values of quadrant[i] and 
+                    quadrant[j] are meaningless.
+
+               else {
+                  if quadrant[i] < quadrant[j]
+                     then the string starting at i lexicographically
+                     precedes the string starting at j
+
+                  else if quadrant[i] > quadrant[j]
+                     then the string starting at j lexicographically
+                     precedes the string starting at i
+
+                  else
+                     the relative ordering of the strings starting
+                     at i and j has not yet been determined.
+               }
+      --*/
+      bigDone[ss] = True;
+
+      if (i < 255) {
+         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
+         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+         Int32 shifts   = 0;
+
+         while ((bbSize >> shifts) > 65534) shifts++;
+
+         for (j = bbSize-1; j >= 0; j--) {
+            Int32 a2update     = ptr[bbStart + j];
+            UInt16 qVal        = (UInt16)(j >> shifts);
+            quadrant[a2update] = qVal;
+            if (a2update < BZ_N_OVERSHOOT)
+               quadrant[a2update + nblock] = qVal;
+         }
+         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+      }
+
+   }
+
+   if (verb >= 4)
+      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
+                 nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)arr2)  [0 .. nblock-1] holds block
+      arr1 exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)arr2) [0 .. nblock-1] holds block
+      All other areas of block destroyed
+      ftab [ 0 .. 65536 ] destroyed
+      arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+   UInt32* ptr    = s->ptr; 
+   UChar*  block  = s->block;
+   UInt32* ftab   = s->ftab;
+   Int32   nblock = s->nblock;
+   Int32   verb   = s->verbosity;
+   Int32   wfact  = s->workFactor;
+   UInt16* quadrant;
+   Int32   budget;
+   Int32   budgetInit;
+   Int32   i;
+
+   if (nblock < 10000) {
+      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+   } else {
+      /* Calculate the location for quadrant, remembering to get
+         the alignment right.  Assumes that &(block[0]) is at least
+         2-byte aligned -- this should be ok since block is really
+         the first section of arr2.
+      */
+      i = nblock+BZ_N_OVERSHOOT;
+      if (i & 1) i++;
+      quadrant = (UInt16*)(&(block[i]));
+
+      /* (wfact-1) / 3 puts the default-factor-30
+         transition point at very roughly the same place as 
+         with v0.1 and v0.9.0.  
+         Not that it particularly matters any more, since the
+         resulting compressed stream is now the same regardless
+         of whether or not we use the main sort or fallback sort.
+      */
+      if (wfact < 1  ) wfact = 1;
+      if (wfact > 100) wfact = 100;
+      budgetInit = nblock * ((wfact-1) / 3);
+      budget = budgetInit;
+
+      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+      if (verb >= 3) 
+         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
+                    budgetInit - budget,
+                    nblock, 
+                    (float)(budgetInit - budget) /
+                    (float)(nblock==0 ? 1 : nblock) ); 
+      if (budget < 0) {
+         if (verb >= 2) 
+            VPrintf0 ( "    too repetitive; using fallback"
+                       " sorting algorithm\n" );
+         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+      }
+   }
+
+   s->origPtr = -1;
+   for (i = 0; i < s->nblock; i++)
+      if (ptr[i] == 0)
+         { s->origPtr = i; break; };
+
+   AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/bzip2.nc b/nc_test4/hdf5plugins/bzip2.nc
new file mode 100644
index 0000000..8d1bd8b
Binary files /dev/null and b/nc_test4/hdf5plugins/bzip2.nc differ
diff --git a/nc_test4/hdf5plugins/bzlib.c b/nc_test4/hdf5plugins/bzlib.c
new file mode 100644
index 0000000..bd358a7
--- /dev/null
+++ b/nc_test4/hdf5plugins/bzlib.c
@@ -0,0 +1,1572 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* CHANGES
+   0.9.0    -- original version.
+   0.9.0a/b -- no changes in this file.
+   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+     fixed bzWrite/bzRead to ignore zero-length requests.
+     fixed bzread to correctly handle read requests after EOF.
+     wrong parameter order in call to bzDecompressInit in
+     bzBuffToBuffDecompress.  Fixed.
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+   fprintf(stderr, 
+      "\n\nbzip2/libbzip2: internal error number %d.\n"
+      "This is a bug in bzip2/libbzip2, %s.\n"
+      "Please report it to me at: jseward at bzip.org.  If this happened\n"
+      "when you were using some program which uses libbzip2 as a\n"
+      "component, you should also report this bug to the author(s)\n"
+      "of that program.  Please make an effort to report this bug;\n"
+      "timely and accurate bug reports eventually lead to higher\n"
+      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
+      errcode,
+      BZ2_bzlibVersion()
+   );
+
+   if (errcode == 1007) {
+   fprintf(stderr,
+      "\n*** A special note about internal error number 1007 ***\n"
+      "\n"
+      "Experience suggests that a common cause of i.e. 1007\n"
+      "is unreliable memory or other hardware.  The 1007 assertion\n"
+      "just happens to cross-check the results of huge numbers of\n"
+      "memory reads/writes, and so acts (unintendedly) as a stress\n"
+      "test of your memory system.\n"
+      "\n"
+      "I suggest the following: try compressing the file again,\n"
+      "possibly monitoring progress in detail with the -vv flag.\n"
+      "\n"
+      "* If the error cannot be reproduced, and/or happens at different\n"
+      "  points in compression, you may have a flaky memory system.\n"
+      "  Try a memory-test program.  I have used Memtest86\n"
+      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
+      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
+      "  power-on test, and may find failures that the BIOS doesn't.\n"
+      "\n"
+      "* If the error can be repeatably reproduced, this is a bug in\n"
+      "  bzip2, and I would very much like to hear about it.  Please\n"
+      "  let me know, and, ideally, save a copy of the file causing the\n"
+      "  problem -- without which I will be unable to investigate it.\n"
+      "\n"
+   );
+   }
+
+   exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+   if (sizeof(int)   != 4) return 0;
+   if (sizeof(short) != 2) return 0;
+   if (sizeof(char)  != 1) return 0;
+   return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+   void* v = malloc ( items * size );
+   return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+   if (addr != NULL) free ( addr );
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+   Int32 i;
+   s->nblock = 0;
+   s->numZ = 0;
+   s->state_out_pos = 0;
+   BZ_INITIALISE_CRC ( s->blockCRC );
+   for (i = 0; i < 256; i++) s->inUse[i] = False;
+   s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+   s->state_in_ch  = 256;
+   s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+   if (s->state_in_ch < 256 && s->state_in_len > 0)
+      return False; else
+      return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit) 
+                    ( bz_stream* strm, 
+                     int        blockSize100k,
+                     int        verbosity,
+                     int        workFactor )
+{
+   Int32   n;
+   EState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL || 
+       blockSize100k < 1 || blockSize100k > 9 ||
+       workFactor < 0 || workFactor > 250)
+     return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(EState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm = strm;
+
+   s->arr1 = NULL;
+   s->arr2 = NULL;
+   s->ftab = NULL;
+
+   n       = 100000 * blockSize100k;
+   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
+   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
+
+   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+      if (s->arr1 != NULL) BZFREE(s->arr1);
+      if (s->arr2 != NULL) BZFREE(s->arr2);
+      if (s->ftab != NULL) BZFREE(s->ftab);
+      if (s       != NULL) BZFREE(s);
+      return BZ_MEM_ERROR;
+   }
+
+   s->blockNo           = 0;
+   s->state             = BZ_S_INPUT;
+   s->mode              = BZ_M_RUNNING;
+   s->combinedCRC       = 0;
+   s->blockSize100k     = blockSize100k;
+   s->nblockMAX         = 100000 * blockSize100k - 19;
+   s->verbosity         = verbosity;
+   s->workFactor        = workFactor;
+
+   s->block             = (UChar*)s->arr2;
+   s->mtfv              = (UInt16*)s->arr1;
+   s->zbits             = NULL;
+   s->ptr               = (UInt32*)s->arr1;
+
+   strm->state          = s;
+   strm->total_in_lo32  = 0;
+   strm->total_in_hi32  = 0;
+   strm->total_out_lo32 = 0;
+   strm->total_out_hi32 = 0;
+   init_RL ( s );
+   prepare_new_block ( s );
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+   Int32 i;
+   UChar ch = (UChar)(s->state_in_ch);
+   for (i = 0; i < s->state_in_len; i++) {
+      BZ_UPDATE_CRC( s->blockCRC, ch );
+   }
+   s->inUse[s->state_in_ch] = True;
+   switch (s->state_in_len) {
+      case 1:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 2:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 3:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      default:
+         s->inUse[s->state_in_len-4] = True;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+         s->nblock++;
+         break;
+   }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+   if (s->state_in_ch < 256) add_pair_to_block ( s );
+   init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
+{                                                 \
+   UInt32 zchh = (UInt32)(zchh0);                 \
+   /*-- fast track the common case --*/           \
+   if (zchh != zs->state_in_ch &&                 \
+       zs->state_in_len == 1) {                   \
+      UChar ch = (UChar)(zs->state_in_ch);        \
+      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
+      zs->inUse[zs->state_in_ch] = True;          \
+      zs->block[zs->nblock] = (UChar)ch;          \
+      zs->nblock++;                               \
+      zs->state_in_ch = zchh;                     \
+   }                                              \
+   else                                           \
+   /*-- general, uncommon cases --*/              \
+   if (zchh != zs->state_in_ch ||                 \
+      zs->state_in_len == 255) {                  \
+      if (zs->state_in_ch < 256)                  \
+         add_pair_to_block ( zs );                \
+      zs->state_in_ch = zchh;                     \
+      zs->state_in_len = 1;                       \
+   } else {                                       \
+      zs->state_in_len++;                         \
+   }                                              \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+   Bool progress_in = False;
+
+   if (s->mode == BZ_M_RUNNING) {
+
+      /*-- fast track the common case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+      }
+
+   } else {
+
+      /*-- general, uncommon case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         /*-- flush/finish end? --*/
+         if (s->avail_in_expect == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+         s->avail_in_expect--;
+      }
+   }
+   return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+   Bool progress_out = False;
+
+   while (True) {
+
+      /*-- no output space? --*/
+      if (s->strm->avail_out == 0) break;
+
+      /*-- block done? --*/
+      if (s->state_out_pos >= s->numZ) break;
+
+      progress_out = True;
+      *(s->strm->next_out) = s->zbits[s->state_out_pos];
+      s->state_out_pos++;
+      s->strm->avail_out--;
+      s->strm->next_out++;
+      s->strm->total_out_lo32++;
+      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+   }
+
+   return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+   Bool progress_in  = False;
+   Bool progress_out = False;
+   EState* s = strm->state;
+   
+   while (True) {
+
+      if (s->state == BZ_S_OUTPUT) {
+         progress_out |= copy_output_until_stop ( s );
+         if (s->state_out_pos < s->numZ) break;
+         if (s->mode == BZ_M_FINISHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+         prepare_new_block ( s );
+         s->state = BZ_S_INPUT;
+         if (s->mode == BZ_M_FLUSHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+      }
+
+      if (s->state == BZ_S_INPUT) {
+         progress_in |= copy_input_until_stop ( s );
+         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+            flush_RL ( s );
+            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->nblock >= s->nblockMAX) {
+            BZ2_compressBlock ( s, False );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->strm->avail_in == 0) {
+            break;
+         }
+      }
+
+   }
+
+   return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+   Bool progress;
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   preswitch:
+   switch (s->mode) {
+
+      case BZ_M_IDLE:
+         return BZ_SEQUENCE_ERROR;
+
+      case BZ_M_RUNNING:
+         if (action == BZ_RUN) {
+            progress = handle_compress ( strm );
+            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+         } 
+         else
+	 if (action == BZ_FLUSH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FLUSHING;
+            goto preswitch;
+         }
+         else
+         if (action == BZ_FINISH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FINISHING;
+            goto preswitch;
+         }
+         else 
+            return BZ_PARAM_ERROR;
+
+      case BZ_M_FLUSHING:
+         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+         s->mode = BZ_M_RUNNING;
+         return BZ_RUN_OK;
+
+      case BZ_M_FINISHING:
+         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (!progress) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+         s->mode = BZ_M_IDLE;
+         return BZ_STREAM_END;
+   }
+   return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+{
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->arr1 != NULL) BZFREE(s->arr1);
+   if (s->arr2 != NULL) BZFREE(s->arr2);
+   if (s->ftab != NULL) BZFREE(s->ftab);
+   BZFREE(strm->state);
+
+   strm->state = NULL;   
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit) 
+                     ( bz_stream* strm, 
+                       int        verbosity,
+                       int        small )
+{
+   DState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(DState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm                  = strm;
+   strm->state              = s;
+   s->state                 = BZ_X_MAGIC_1;
+   s->bsLive                = 0;
+   s->bsBuff                = 0;
+   s->calculatedCombinedCRC = 0;
+   strm->total_in_lo32      = 0;
+   strm->total_in_hi32      = 0;
+   strm->total_out_lo32     = 0;
+   strm->total_out_hi32     = 0;
+   s->smallDecompress       = (Bool)small;
+   s->ll4                   = NULL;
+   s->ll16                  = NULL;
+   s->tt                    = NULL;
+   s->currBlockNo           = 0;
+   s->verbosity             = verbosity;
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+               
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      /* restore */
+      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
+      UChar         c_state_out_ch       = s->state_out_ch;
+      Int32         c_state_out_len      = s->state_out_len;
+      Int32         c_nblock_used        = s->nblock_used;
+      Int32         c_k0                 = s->k0;
+      UInt32*       c_tt                 = s->tt;
+      UInt32        c_tPos               = s->tPos;
+      char*         cs_next_out          = s->strm->next_out;
+      unsigned int  cs_avail_out         = s->strm->avail_out;
+      Int32         ro_blockSize100k     = s->blockSize100k;
+      /* end restore */
+
+      UInt32       avail_out_INIT = cs_avail_out;
+      Int32        s_save_nblockPP = s->save_nblock+1;
+      unsigned int total_out_lo32_old;
+
+      while (True) {
+
+         /* try to finish existing run */
+         if (c_state_out_len > 0) {
+            while (True) {
+               if (cs_avail_out == 0) goto return_notr;
+               if (c_state_out_len == 1) break;
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               c_state_out_len--;
+               cs_next_out++;
+               cs_avail_out--;
+            }
+            s_state_out_len_eq_one:
+            {
+               if (cs_avail_out == 0) { 
+                  c_state_out_len = 1; goto return_notr;
+               };
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               cs_next_out++;
+               cs_avail_out--;
+            }
+         }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used > s_save_nblockPP)
+            return True;
+
+         /* can a new run be started? */
+         if (c_nblock_used == s_save_nblockPP) {
+            c_state_out_len = 0; goto return_notr;
+         };   
+         c_state_out_ch = c_k0;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (k1 != c_k0) { 
+            c_k0 = k1; goto s_state_out_len_eq_one; 
+         };
+         if (c_nblock_used == s_save_nblockPP) 
+            goto s_state_out_len_eq_one;
+   
+         c_state_out_len = 2;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         c_state_out_len = 3;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         c_state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST_C(c_k0); c_nblock_used++;
+      }
+
+      return_notr:
+      total_out_lo32_old = s->strm->total_out_lo32;
+      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+      if (s->strm->total_out_lo32 < total_out_lo32_old)
+         s->strm->total_out_hi32++;
+
+      /* save */
+      s->calculatedBlockCRC = c_calculatedBlockCRC;
+      s->state_out_ch       = c_state_out_ch;
+      s->state_out_len      = c_state_out_len;
+      s->nblock_used        = c_nblock_used;
+      s->k0                 = c_k0;
+      s->tt                 = c_tt;
+      s->tPos               = c_tPos;
+      s->strm->next_out     = cs_next_out;
+      s->strm->avail_out    = cs_avail_out;
+      /* end save */
+   }
+   return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+   Int32 nb, na, mid;
+   nb = 0;
+   na = 256;
+   do {
+      mid = (nb + na) >> 1;
+      if (indx >= cftab[mid]) nb = mid; else na = mid;
+   }
+   while (na - nb != 1);
+   return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); s->nblock_used++;
+      }
+
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+   Bool    corrupt;
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   while (True) {
+      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+      if (s->state == BZ_X_OUTPUT) {
+         if (s->smallDecompress)
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
+         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+            if (s->verbosity >= 3) 
+               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
+                          s->calculatedBlockCRC );
+            if (s->verbosity >= 2) VPrintf0 ( "]" );
+            if (s->calculatedBlockCRC != s->storedBlockCRC)
+               return BZ_DATA_ERROR;
+            s->calculatedCombinedCRC 
+               = (s->calculatedCombinedCRC << 1) | 
+                    (s->calculatedCombinedCRC >> 31);
+            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+            s->state = BZ_X_BLKHDR_1;
+         } else {
+            return BZ_OK;
+         }
+      }
+      if (s->state >= BZ_X_MAGIC_1) {
+         Int32 r = BZ2_decompress ( s );
+         if (r == BZ_STREAM_END) {
+            if (s->verbosity >= 3)
+               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
+                          s->storedCombinedCRC, s->calculatedCombinedCRC );
+            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+               return BZ_DATA_ERROR;
+            return r;
+         }
+         if (s->state != BZ_X_OUTPUT) return r;
+      }
+   }
+
+   AssertH ( 0, 6001 );
+
+   return 0;  /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+{
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->tt   != NULL) BZFREE(s->tt);
+   if (s->ll16 != NULL) BZFREE(s->ll16);
+   if (s->ll4  != NULL) BZFREE(s->ll4);
+
+   BZFREE(strm->state);
+   strm->state = NULL;
+
+   return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff                              ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee)                    \
+{                                         \
+   if (bzerror != NULL) *bzerror = eee;   \
+   if (bzf != NULL) bzf->lastErr = eee;   \
+}
+
+typedef 
+   struct {
+      FILE*     handle;
+      Char      buf[BZ_MAX_UNUSED];
+      Int32     bufN;
+      Bool      writing;
+      bz_stream strm;
+      Int32     lastErr;
+      Bool      initialisedOk;
+   }
+   bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen) 
+                    ( int*  bzerror,      
+                      FILE* f, 
+                      int   blockSize100k, 
+                      int   verbosity,
+                      int   workFactor )
+{
+   Int32   ret;
+   bzFile* bzf = NULL;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL ||
+       (blockSize100k < 1 || blockSize100k > 9) ||
+       (workFactor < 0 || workFactor > 250) ||
+       (verbosity < 0 || verbosity > 4))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+   bzf->initialisedOk = False;
+   bzf->bufN          = 0;
+   bzf->handle        = f;
+   bzf->writing       = True;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+
+   if (workFactor == 0) workFactor = 30;
+   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = 0;
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+             ( int*    bzerror, 
+               BZFILE* b, 
+               void*   buf, 
+               int     len )
+{
+   Int32 n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return; };
+
+   bzf->strm.avail_in = len;
+   bzf->strm.next_in  = buf;
+
+   while (True) {
+      bzf->strm.avail_out = BZ_MAX_UNUSED;
+      bzf->strm.next_out = bzf->buf;
+      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+      if (ret != BZ_RUN_OK)
+         { BZ_SETERR(ret); return; };
+
+      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                       n, bzf->handle );
+         if (n != n2 || ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return; };
+      }
+
+      if (bzf->strm.avail_in == 0)
+         { BZ_SETERR(BZ_OK); return; };
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in,
+                    unsigned int* nbytes_out )
+{
+   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
+                        nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in_lo32,
+                    unsigned int* nbytes_in_hi32,
+                    unsigned int* nbytes_out_lo32,
+                    unsigned int* nbytes_out_hi32 )
+{
+   Int32   n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+   if ((!abandon) && bzf->lastErr == BZ_OK) {
+      while (True) {
+         bzf->strm.avail_out = BZ_MAX_UNUSED;
+         bzf->strm.next_out = bzf->buf;
+         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+            { BZ_SETERR(ret); return; };
+
+         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                          n, bzf->handle );
+            if (n != n2 || ferror(bzf->handle))
+               { BZ_SETERR(BZ_IO_ERROR); return; };
+         }
+
+         if (ret == BZ_STREAM_END) break;
+      }
+   }
+
+   if ( !abandon && !ferror ( bzf->handle ) ) {
+      fflush ( bzf->handle );
+      if (ferror(bzf->handle))
+         { BZ_SETERR(BZ_IO_ERROR); return; };
+   }
+
+   if (nbytes_in_lo32 != NULL)
+      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+   if (nbytes_in_hi32 != NULL)
+      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+   if (nbytes_out_lo32 != NULL)
+      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+   if (nbytes_out_hi32 != NULL)
+      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+   BZ_SETERR(BZ_OK);
+   BZ2_bzCompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen) 
+                   ( int*  bzerror, 
+                     FILE* f, 
+                     int   verbosity,
+                     int   small,
+                     void* unused,
+                     int   nUnused )
+{
+   bzFile* bzf = NULL;
+   int     ret;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL || 
+       (small != 0 && small != 1) ||
+       (verbosity < 0 || verbosity > 4) ||
+       (unused == NULL && nUnused != 0) ||
+       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL) 
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+
+   bzf->initialisedOk = False;
+   bzf->handle        = f;
+   bzf->bufN          = 0;
+   bzf->writing       = False;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+   
+   while (nUnused > 0) {
+      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+      unused = ((void*)( 1 + ((UChar*)(unused))  ));
+      nUnused--;
+   }
+
+   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = bzf->bufN;
+   bzf->strm.next_in  = bzf->buf;
+
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+   if (bzf->initialisedOk)
+      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead) 
+           ( int*    bzerror, 
+             BZFILE* b, 
+             void*   buf, 
+             int     len )
+{
+   Int32   n, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return 0; };
+
+   bzf->strm.avail_out = len;
+   bzf->strm.next_out = buf;
+
+   while (True) {
+
+      if (ferror(bzf->handle)) 
+         { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+         n = fread ( bzf->buf, sizeof(UChar), 
+                     BZ_MAX_UNUSED, bzf->handle );
+         if (ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return 0; };
+         bzf->bufN = n;
+         bzf->strm.avail_in = bzf->bufN;
+         bzf->strm.next_in = bzf->buf;
+      }
+
+      ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+      if (ret != BZ_OK && ret != BZ_STREAM_END)
+         { BZ_SETERR(ret); return 0; };
+
+      if (ret == BZ_OK && myfeof(bzf->handle) && 
+          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+      if (ret == BZ_STREAM_END)
+         { BZ_SETERR(BZ_STREAM_END);
+           return len - bzf->strm.avail_out; };
+      if (bzf->strm.avail_out == 0)
+         { BZ_SETERR(BZ_OK); return len; };
+      
+   }
+
+   return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused) 
+                     ( int*    bzerror, 
+                       BZFILE* b, 
+                       void**  unused, 
+                       int*    nUnused )
+{
+   bzFile* bzf = (bzFile*)b;
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (bzf->lastErr != BZ_STREAM_END)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (unused == NULL || nUnused == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+   BZ_SETERR(BZ_OK);
+   *nUnused = bzf->strm.avail_in;
+   *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress) 
+                         ( char*         dest, 
+                           unsigned int* destLen,
+                           char*         source, 
+                           unsigned int  sourceLen,
+                           int           blockSize100k, 
+                           int           verbosity, 
+                           int           workFactor )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       blockSize100k < 1 || blockSize100k > 9 ||
+       verbosity < 0 || verbosity > 4 ||
+       workFactor < 0 || workFactor > 250) 
+      return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+   if (ret == BZ_FINISH_OK) goto output_overflow;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;   
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow:
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OUTBUFF_FULL;
+
+   errhandler:
+   BZ2_bzCompressEnd ( &strm );
+   return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress) 
+                           ( char*         dest, 
+                             unsigned int* destLen,
+                             char*         source, 
+                             unsigned int  sourceLen,
+                             int           small,
+                             int           verbosity )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       (small != 0 && small != 1) ||
+       verbosity < 0 || verbosity > 4) 
+          return BZ_PARAM_ERROR;
+
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzDecompress ( &strm );
+   if (ret == BZ_OK) goto output_overflow_or_eof;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;
+   BZ2_bzDecompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow_or_eof:
+   if (strm.avail_out > 0) {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_UNEXPECTED_EOF;
+   } else {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_OUTBUFF_FULL;
+   };      
+
+   errhandler:
+   BZ2_bzDecompressEnd ( &strm );
+   return ret; 
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+   return version like "0.9.5d, 4-Sept-1999".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+   return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#   include <fcntl.h>
+#   include <io.h>
+#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+               ( const char *path,   /* no use when bzdopen */
+                 int fd,             /* no use when bzdopen */
+                 const char *mode,
+                 int open_mode)      /* bzopen: 0, bzdopen:1 */
+{
+   int    bzerr;
+   char   unused[BZ_MAX_UNUSED];
+   int    blockSize100k = 9;
+   int    writing       = 0;
+   char   mode2[10]     = "";
+   FILE   *fp           = NULL;
+   BZFILE *bzfp         = NULL;
+   int    verbosity     = 0;
+   int    workFactor    = 30;
+   int    smallMode     = 0;
+   int    nUnused       = 0; 
+
+   if (mode == NULL) return NULL;
+   while (*mode) {
+      switch (*mode) {
+      case 'r':
+         writing = 0; break;
+      case 'w':
+         writing = 1; break;
+      case 's':
+         smallMode = 1; break;
+      default:
+         if (isdigit((int)(*mode))) {
+            blockSize100k = *mode-BZ_HDR_0;
+         }
+      }
+      mode++;
+   }
+   strcat(mode2, writing ? "w" : "r" );
+   strcat(mode2,"b");   /* binary mode */
+
+   if (open_mode==0) {
+      if (path==NULL || strcmp(path,"")==0) {
+        fp = (writing ? stdout : stdin);
+        SET_BINARY_MODE(fp);
+      } else {
+        fp = fopen(path,mode2);
+      }
+   } else {
+#ifdef BZ_STRICT_ANSI
+      fp = NULL;
+#else
+      fp = fdopen(fd,mode2);
+#endif
+   }
+   if (fp == NULL) return NULL;
+
+   if (writing) {
+      /* Guard against total chaos and anarchy -- JRS */
+      if (blockSize100k < 1) blockSize100k = 1;
+      if (blockSize100k > 9) blockSize100k = 9; 
+      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+                             verbosity,workFactor);
+   } else {
+      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+                            unused,nUnused);
+   }
+   if (bzfp == NULL) {
+      if (fp != stdin && fp != stdout) fclose(fp);
+      return NULL;
+   }
+   return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   open file for read or write.
+      ex) bzopen("file","w9")
+      case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+               ( const char *path,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+               ( int fd,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+   int bzerr, nread;
+   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+   nread = BZ2_bzRead(&bzerr,b,buf,len);
+   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+      return nread;
+   } else {
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+   int bzerr;
+
+   BZ2_bzWrite(&bzerr,b,buf,len);
+   if(bzerr == BZ_OK){
+      return len;
+   }else{
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+   /* do nothing now... */
+   return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+   int bzerr;
+   FILE *fp;
+   
+   if (b==NULL) {return;}
+   fp = ((bzFile *)b)->handle;
+   if(((bzFile*)b)->writing){
+      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+      if(bzerr != BZ_OK){
+         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+      }
+   }else{
+      BZ2_bzReadClose(&bzerr,b);
+   }
+   if(fp!=stdin && fp!=stdout){
+      fclose(fp);
+   }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   return last error code 
+--*/
+static const char *bzerrorstrings[] = {
+       "OK"
+      ,"SEQUENCE_ERROR"
+      ,"PARAM_ERROR"
+      ,"MEM_ERROR"
+      ,"DATA_ERROR"
+      ,"DATA_ERROR_MAGIC"
+      ,"IO_ERROR"
+      ,"UNEXPECTED_EOF"
+      ,"OUTBUFF_FULL"
+      ,"CONFIG_ERROR"
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+   int err = ((bzFile *)b)->lastErr;
+
+   if(err>0) err = 0;
+   *errnum = err;
+   return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/bzlib.h b/nc_test4/hdf5plugins/bzlib.h
new file mode 100644
index 0000000..8277123
--- /dev/null
+++ b/nc_test4/hdf5plugins/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef 
+   struct {
+      char *next_in;
+      unsigned int avail_in;
+      unsigned int total_in_lo32;
+      unsigned int total_in_hi32;
+
+      char *next_out;
+      unsigned int avail_out;
+      unsigned int total_out_lo32;
+      unsigned int total_out_hi32;
+
+      void *state;
+
+      void *(*bzalloc)(void *,int,int);
+      void (*bzfree)(void *,void *);
+      void *opaque;
+   } 
+   bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+#   include <windows.h>
+#   ifdef small
+      /* windows.h define small to char */
+#      undef small
+#   endif
+#   ifdef BZ_EXPORT
+#   define BZ_API(func) WINAPI func
+#   define BZ_EXTERN extern
+#   else
+   /* import windows dll dynamically */
+#   define BZ_API(func) (WINAPI * func)
+#   define BZ_EXTERN
+#   endif
+#else
+#   define BZ_API(func) func
+#   define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
+      bz_stream* strm, 
+      int        blockSize100k, 
+      int        verbosity, 
+      int        workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
+      bz_stream* strm, 
+      int action 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
+      bz_stream *strm, 
+      int       verbosity, 
+      int       small
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
+      bz_stream *strm 
+   );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
+      int*  bzerror,   
+      FILE* f, 
+      int   verbosity, 
+      int   small,
+      void* unused,    
+      int   nUnused 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
+      int*    bzerror, 
+      BZFILE* b 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void**  unused,  
+      int*    nUnused 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
+      int*  bzerror,      
+      FILE* f, 
+      int   blockSize100k, 
+      int   verbosity, 
+      int   workFactor 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in, 
+      unsigned int* nbytes_out 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in_lo32, 
+      unsigned int* nbytes_in_hi32, 
+      unsigned int* nbytes_out_lo32, 
+      unsigned int* nbytes_out_hi32
+   );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           blockSize100k, 
+      int           verbosity, 
+      int           workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           small, 
+      int           verbosity 
+   );
+
+
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+      void
+   );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+      const char *path,
+      const char *mode
+   );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+      int        fd,
+      const char *mode
+   );
+         
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+      BZFILE* b, 
+      void* buf, 
+      int len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+      BZFILE* b
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+      BZFILE* b
+   );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+      BZFILE *b, 
+      int    *errnum
+   );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/bzlib_private.h b/nc_test4/hdf5plugins/bzlib_private.h
new file mode 100644
index 0000000..5d0217f
--- /dev/null
+++ b/nc_test4/hdf5plugins/bzlib_private.h
@@ -0,0 +1,509 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include <stdlib.h>
+
+#ifndef BZ_NO_STDIO
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "bzlib.h"
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION  "1.0.6, 6-Sept-2010"
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__  /* */
+#endif 
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+   { if (!(cond)) {       \
+      fprintf ( stderr,   \
+        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+      exit(1); \
+   }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+   fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+   fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+   fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+   fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+   fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+   fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg)                do { } while (0)
+#define VPrintf0(zf)                     do { } while (0)
+#define VPrintf1(zf,za1)                 do { } while (0)
+#define VPrintf2(zf,za1,za2)             do { } while (0)
+#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+  
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS                          \
+   Int32 rNToGo;                               \
+   Int32 rTPos                                 \
+
+#define BZ_RAND_INIT_MASK                      \
+   s->rNToGo = 0;                              \
+   s->rTPos  = 0                               \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK                       \
+   if (s->rNToGo == 0) {                       \
+      s->rNToGo = BZ2_rNums[s->rTPos];         \
+      s->rTPos++;                              \
+      if (s->rTPos == 512) s->rTPos = 0;       \
+   }                                           \
+   s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar)              \
+{                                              \
+   crcVar = 0xffffffffL;                       \
+}
+
+#define BZ_FINALISE_CRC(crcVar)                \
+{                                              \
+   crcVar = ~(crcVar);                         \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha)              \
+{                                              \
+   crcVar = (crcVar << 8) ^                    \
+            BZ2_crc32Table[(crcVar >> 24) ^    \
+                           ((UChar)cha)];      \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* mode this stream is in, and whether inputting */
+      /* or outputting data */
+      Int32    mode;
+      Int32    state;
+
+      /* remembers avail_in when flush/finish requested */
+      UInt32   avail_in_expect;
+
+      /* for doing the block sorting */
+      UInt32*  arr1;
+      UInt32*  arr2;
+      UInt32*  ftab;
+      Int32    origPtr;
+
+      /* aliases for arr1 and arr2 */
+      UInt32*  ptr;
+      UChar*   block;
+      UInt16*  mtfv;
+      UChar*   zbits;
+
+      /* for deciding when to use the fallback sorting algorithm */
+      Int32    workFactor;
+
+      /* run-length-encoding of the input */
+      UInt32   state_in_ch;
+      Int32    state_in_len;
+      BZ_RAND_DECLS;
+
+      /* input and output limits and current posns */
+      Int32    nblock;
+      Int32    nblockMAX;
+      Int32    numZ;
+      Int32    state_out_pos;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      UChar    unseqToSeq[256];
+
+      /* the buffer for bit stream creation */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* block and combined CRCs */
+      UInt32   blockCRC;
+      UInt32   combinedCRC;
+
+      /* misc administratium */
+      Int32    verbosity;
+      Int32    blockNo;
+      Int32    blockSize100k;
+
+      /* stuff for coding the MTF values */
+      Int32    nMTF;
+      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+
+      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      /* second dimension: only 3 needed; 4 makes index calculations faster */
+      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+   }
+   EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void 
+BZ2_blockSort ( EState* );
+
+extern void 
+BZ2_compressBlock ( EState*, Bool );
+
+extern void 
+BZ2_bsInitWrite ( EState* );
+
+extern void 
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void 
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE        1
+#define BZ_X_OUTPUT      2
+
+#define BZ_X_MAGIC_1     10
+#define BZ_X_MAGIC_2     11
+#define BZ_X_MAGIC_3     12
+#define BZ_X_MAGIC_4     13
+#define BZ_X_BLKHDR_1    14
+#define BZ_X_BLKHDR_2    15
+#define BZ_X_BLKHDR_3    16
+#define BZ_X_BLKHDR_4    17
+#define BZ_X_BLKHDR_5    18
+#define BZ_X_BLKHDR_6    19
+#define BZ_X_BCRC_1      20
+#define BZ_X_BCRC_2      21
+#define BZ_X_BCRC_3      22
+#define BZ_X_BCRC_4      23
+#define BZ_X_RANDBIT     24
+#define BZ_X_ORIGPTR_1   25
+#define BZ_X_ORIGPTR_2   26
+#define BZ_X_ORIGPTR_3   27
+#define BZ_X_MAPPING_1   28
+#define BZ_X_MAPPING_2   29
+#define BZ_X_SELECTOR_1  30
+#define BZ_X_SELECTOR_2  31
+#define BZ_X_SELECTOR_3  32
+#define BZ_X_CODING_1    33
+#define BZ_X_CODING_2    34
+#define BZ_X_CODING_3    35
+#define BZ_X_MTF_1       36
+#define BZ_X_MTF_2       37
+#define BZ_X_MTF_3       38
+#define BZ_X_MTF_4       39
+#define BZ_X_MTF_5       40
+#define BZ_X_MTF_6       41
+#define BZ_X_ENDHDR_2    42
+#define BZ_X_ENDHDR_3    43
+#define BZ_X_ENDHDR_4    44
+#define BZ_X_ENDHDR_5    45
+#define BZ_X_ENDHDR_6    46
+#define BZ_X_CCRC_1      47
+#define BZ_X_CCRC_2      48
+#define BZ_X_CCRC_3      49
+#define BZ_X_CCRC_4      50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* state indicator for this stream */
+      Int32    state;
+
+      /* for doing the final run-length decoding */
+      UChar    state_out_ch;
+      Int32    state_out_len;
+      Bool     blockRandomised;
+      BZ_RAND_DECLS;
+
+      /* the buffer for bit stream reading */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* misc administratium */
+      Int32    blockSize100k;
+      Bool     smallDecompress;
+      Int32    currBlockNo;
+      Int32    verbosity;
+
+      /* for undoing the Burrows-Wheeler transform */
+      Int32    origPtr;
+      UInt32   tPos;
+      Int32    k0;
+      Int32    unzftab[256];
+      Int32    nblock_used;
+      Int32    cftab[257];
+      Int32    cftabCopy[257];
+
+      /* for undoing the Burrows-Wheeler transform (FAST) */
+      UInt32   *tt;
+
+      /* for undoing the Burrows-Wheeler transform (SMALL) */
+      UInt16   *ll16;
+      UChar    *ll4;
+
+      /* stored and calculated CRCs */
+      UInt32   storedBlockCRC;
+      UInt32   storedCombinedCRC;
+      UInt32   calculatedBlockCRC;
+      UInt32   calculatedCombinedCRC;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      Bool     inUse16[16];
+      UChar    seqToUnseq[256];
+
+      /* for decoding the MTF values */
+      UChar    mtfa   [MTFA_SIZE];
+      Int32    mtfbase[256 / MTFL_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    minLens[BZ_N_GROUPS];
+
+      /* save area for scalars in the main decompress code */
+      Int32    save_i;
+      Int32    save_j;
+      Int32    save_t;
+      Int32    save_alphaSize;
+      Int32    save_nGroups;
+      Int32    save_nSelectors;
+      Int32    save_EOB;
+      Int32    save_groupNo;
+      Int32    save_groupPos;
+      Int32    save_nextSym;
+      Int32    save_nblockMAX;
+      Int32    save_nblock;
+      Int32    save_es;
+      Int32    save_N;
+      Int32    save_curr;
+      Int32    save_zt;
+      Int32    save_zn; 
+      Int32    save_zvec;
+      Int32    save_zj;
+      Int32    save_gSel;
+      Int32    save_gMinlen;
+      Int32*   save_gLimit;
+      Int32*   save_gBase;
+      Int32*   save_gPerm;
+
+   }
+   DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc)                     \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    s->tPos = s->tt[s->tPos];                 \
+    cccc = (UChar)(s->tPos & 0xff);           \
+    s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc)                   \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+    c_tPos = c_tt[c_tPos];                    \
+    cccc = (UChar)(c_tPos & 0xff);            \
+    c_tPos >>= 8;
+
+#define SET_LL4(i,n)                                          \
+   { if (((i) & 0x1) == 0)                                    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
+   }
+
+#define GET_LL4(i)                             \
+   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n)                          \
+   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
+     SET_LL4(i, n >> 16);                    \
+   }
+
+#define GET_LL(i) \
+   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc)                            \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
+    s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32 
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32 
+BZ2_decompress ( DState* );
+
+extern void 
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+                           Int32,  Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/compress.c b/nc_test4/hdf5plugins/compress.c
new file mode 100644
index 0000000..caf7696
--- /dev/null
+++ b/nc_test4/hdf5plugins/compress.c
@@ -0,0 +1,672 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s->bsLive = 0;
+   s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s->bsLive > 0) {
+      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+      s->numZ++;
+      s->bsBuff <<= 8;
+      s->bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s->bsLive >= 8) {                   \
+      s->zbits[s->numZ]                       \
+         = (UChar)(s->bsBuff >> 24);          \
+      s->numZ++;                              \
+      s->bsBuff <<= 8;                        \
+      s->bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s->bsBuff |= (v << (32 - s->bsLive - n));
+   s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u >> 24) & 0xffL );
+   bsW ( s, 8, (u >> 16) & 0xffL );
+   bsW ( s, 8, (u >>  8) & 0xffL );
+   bsW ( s, 8,  u        & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->unseqToSeq[i] = s->nInUse;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s->ptr;
+   UChar* block  = s->block;
+   UInt16* mtfv  = s->mtfv;
+
+   makeMaps_e ( s );
+   EOB = s->nInUse+1;
+
+   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i < s->nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr <= i, "generateMTFValues(1)" );
+      j = ptr[i]-1; if (j < 0) j += s->nblock;
+      ll_i = s->unseqToSeq[block[j]];
+      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend > 0) {
+            zPend--;
+            while (True) {
+               if (zPend & 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s->mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s->mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend < 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &(yy[0]);
+            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend > 0) {
+      zPend--;
+      while (True) {
+         if (zPend & 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s->mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s->mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend < 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+   s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s->mtfv;
+
+   if (s->verbosity >= 3)
+      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
+                "%d+2 syms in use\n", 
+                s->nblock, s->nMTF, s->nInUse );
+
+   alphaSize = s->nInUse+2;
+   for (t = 0; t < BZ_N_GROUPS; t++)
+      for (v = 0; v < alphaSize; v++)
+         s->len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s->nMTF > 0, 3001 );
+   if (s->nMTF < 200)  nGroups = 2; else
+   if (s->nMTF < 600)  nGroups = 3; else
+   if (s->nMTF < 1200) nGroups = 4; else
+   if (s->nMTF < 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s->nMTF;
+      gs = 0;
+      while (nPart > 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq < tFreq && ge < alphaSize-1) {
+            ge++;
+            aFreq += s->mtfFreq[ge];
+         }
+
+         if (ge > gs 
+             && nPart != nGroups && nPart != 1 
+             && ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s->mtfFreq[ge];
+            ge--;
+         }
+
+         if (s->verbosity >= 3)
+            VPrintf5( "      initial group %d, [%d .. %d], "
+                      "has %d syms (%4.1f%%)\n",
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
+ 
+         for (v = 0; v < alphaSize; v++)
+            if (v >= gs && v <= ge) 
+               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s->len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+      for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t < nGroups; t++)
+         for (v = 0; v < alphaSize; v++)
+            s->rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v < alphaSize; v++) {
+            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start & end marks. --*/
+         if (gs >= s->nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge >= s->nMTF) ge = s->nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s->len_pack[icv][0]; \
+               cost23 += s->len_pack[icv][1]; \
+               cost45 += s->len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t < nGroups; t++)
+            if (cost[t] < bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s->selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++)
+               s->rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s->verbosity >= 3) {
+         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
+                   iter+1, totc/8 );
+         for (t = 0; t < nGroups; t++)
+            VPrintf1 ( "%d ", fave[t] );
+         VPrintf0 ( "\n" );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t < nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups < 8, 3002 );
+   AssertH( nSelectors < 32768 &&
+            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i < nGroups; i++) pos[i] = i;
+      for (i = 0; i < nSelectors; i++) {
+         ll_i = s->selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s->selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t < nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i < alphaSize; i++) {
+         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+         if (s->len[t][i] < minLen) minLen = s->len[t][i];
+      }
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen < 1),  3005 );
+      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i < 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j < 16; j++)
+             if (s->inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s->numZ;
+      for (i = 0; i < 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i < 16; i++)
+         if (inUse16[i])
+            for (j = 0; j < 16; j++) {
+               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s->verbosity >= 3) 
+         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s->numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i < nSelectors; i++) { 
+      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s->verbosity >= 3)
+      VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s->numZ;
+
+   for (t = 0; t < nGroups; t++) {
+      Int32 curr = s->len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i < alphaSize; i++) {
+         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s->verbosity >= 3)
+      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s->numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs >= s->nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge >= s->nMTF) ge = s->nMTF-1;
+      AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+      if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &(s->len[s->selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &(s->code[s->selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i <= ge; i++) {
+            bsW ( s, 
+                  s->len  [s->selector[selCtr]] [mtfv[i]],
+                  s->code [s->selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s->verbosity >= 3)
+      VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s->nblock > 0) {
+
+      BZ_FINALISE_CRC ( s->blockCRC );
+      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+      s->combinedCRC ^= s->blockCRC;
+      if (s->blockNo > 1) s->numZ = 0;
+
+      if (s->verbosity >= 2)
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
+                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s->blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+   }
+
+   if (s->nblock > 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s->blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s->origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s->combinedCRC );
+      if (s->verbosity >= 2)
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/crctable.c b/nc_test4/hdf5plugins/crctable.c
new file mode 100644
index 0000000..1fea7e9
--- /dev/null
+++ b/nc_test4/hdf5plugins/crctable.c
@@ -0,0 +1,104 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs                                  ---*/
+/*---                                            crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*--
+  I think this is an implementation of the AUTODIN-II,
+  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
+  from code by Rob Warnock, in Section 51 of the
+  comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+   /*-- Ugly, innit? --*/
+
+   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/decompress.c b/nc_test4/hdf5plugins/decompress.c
new file mode 100644
index 0000000..311f566
--- /dev/null
+++ b/nc_test4/hdf5plugins/decompress.c
@@ -0,0 +1,646 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery                               ---*/
+/*---                                          decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->seqToUnseq[s->nInUse] = i;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr)                               \
+   { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn)                     \
+   case lll: s->state = lll;                      \
+   while (True) {                                 \
+      if (s->bsLive >= nnn) {                     \
+         UInt32 v;                                \
+         v = (s->bsBuff >>                        \
+             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
+         s->bsLive -= nnn;                        \
+         vvv = v;                                 \
+         break;                                   \
+      }                                           \
+      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
+      s->bsBuff                                   \
+         = (s->bsBuff << 8) |                     \
+           ((UInt32)                              \
+              (*((UChar*)(s->strm->next_in))));   \
+      s->bsLive += 8;                             \
+      s->strm->next_in++;                         \
+      s->strm->avail_in--;                        \
+      s->strm->total_in_lo32++;                   \
+      if (s->strm->total_in_lo32 == 0)            \
+         s->strm->total_in_hi32++;                \
+   }
+
+#define GET_UCHAR(lll,uuu)                        \
+   GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu)                          \
+   GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval)           \
+{                                                 \
+   if (groupPos == 0) {                           \
+      groupNo++;                                  \
+      if (groupNo >= nSelectors)                  \
+         RETURN(BZ_DATA_ERROR);                   \
+      groupPos = BZ_G_SIZE;                       \
+      gSel = s->selector[groupNo];                \
+      gMinlen = s->minLens[gSel];                 \
+      gLimit = &(s->limit[gSel][0]);              \
+      gPerm = &(s->perm[gSel][0]);                \
+      gBase = &(s->base[gSel][0]);                \
+   }                                              \
+   groupPos--;                                    \
+   zn = gMinlen;                                  \
+   GET_BITS(label1, zvec, zn);                    \
+   while (1) {                                    \
+      if (zn > 20 /* the longest code */)         \
+         RETURN(BZ_DATA_ERROR);                   \
+      if (zvec <= gLimit[zn]) break;              \
+      zn++;                                       \
+      GET_BIT(label2, zj);                        \
+      zvec = (zvec << 1) | zj;                    \
+   };                                             \
+   if (zvec - gBase[zn] < 0                       \
+       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
+      RETURN(BZ_DATA_ERROR);                      \
+   lval = gPerm[zvec - gBase[zn]];                \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+   UChar      uc;
+   Int32      retVal;
+   Int32      minLen, maxLen;
+   bz_stream* strm = s->strm;
+
+   /* stuff that needs to be saved/restored */
+   Int32  i;
+   Int32  j;
+   Int32  t;
+   Int32  alphaSize;
+   Int32  nGroups;
+   Int32  nSelectors;
+   Int32  EOB;
+   Int32  groupNo;
+   Int32  groupPos;
+   Int32  nextSym;
+   Int32  nblockMAX;
+   Int32  nblock;
+   Int32  es;
+   Int32  N;
+   Int32  curr;
+   Int32  zt;
+   Int32  zn; 
+   Int32  zvec;
+   Int32  zj;
+   Int32  gSel;
+   Int32  gMinlen;
+   Int32* gLimit;
+   Int32* gBase;
+   Int32* gPerm;
+
+   if (s->state == BZ_X_MAGIC_1) {
+      /*initialise the save area*/
+      s->save_i           = 0;
+      s->save_j           = 0;
+      s->save_t           = 0;
+      s->save_alphaSize   = 0;
+      s->save_nGroups     = 0;
+      s->save_nSelectors  = 0;
+      s->save_EOB         = 0;
+      s->save_groupNo     = 0;
+      s->save_groupPos    = 0;
+      s->save_nextSym     = 0;
+      s->save_nblockMAX   = 0;
+      s->save_nblock      = 0;
+      s->save_es          = 0;
+      s->save_N           = 0;
+      s->save_curr        = 0;
+      s->save_zt          = 0;
+      s->save_zn          = 0;
+      s->save_zvec        = 0;
+      s->save_zj          = 0;
+      s->save_gSel        = 0;
+      s->save_gMinlen     = 0;
+      s->save_gLimit      = NULL;
+      s->save_gBase       = NULL;
+      s->save_gPerm       = NULL;
+   }
+
+   /*restore from the save area*/
+   i           = s->save_i;
+   j           = s->save_j;
+   t           = s->save_t;
+   alphaSize   = s->save_alphaSize;
+   nGroups     = s->save_nGroups;
+   nSelectors  = s->save_nSelectors;
+   EOB         = s->save_EOB;
+   groupNo     = s->save_groupNo;
+   groupPos    = s->save_groupPos;
+   nextSym     = s->save_nextSym;
+   nblockMAX   = s->save_nblockMAX;
+   nblock      = s->save_nblock;
+   es          = s->save_es;
+   N           = s->save_N;
+   curr        = s->save_curr;
+   zt          = s->save_zt;
+   zn          = s->save_zn; 
+   zvec        = s->save_zvec;
+   zj          = s->save_zj;
+   gSel        = s->save_gSel;
+   gMinlen     = s->save_gMinlen;
+   gLimit      = s->save_gLimit;
+   gBase       = s->save_gBase;
+   gPerm       = s->save_gPerm;
+
+   retVal = BZ_OK;
+
+   switch (s->state) {
+
+      GET_UCHAR(BZ_X_MAGIC_1, uc);
+      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_2, uc);
+      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_3, uc)
+      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
+          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+      s->blockSize100k -= BZ_HDR_0;
+
+      if (s->smallDecompress) {
+         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+         s->ll4  = BZALLOC( 
+                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
+                   );
+         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+      } else {
+         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+      }
+
+      GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+      if (uc == 0x17) goto endhdr_2;
+      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_2, uc);
+      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_3, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_4, uc);
+      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_5, uc);
+      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_6, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+      s->currBlockNo++;
+      if (s->verbosity >= 2)
+         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
+ 
+      s->storedBlockCRC = 0;
+      GET_UCHAR(BZ_X_BCRC_1, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_2, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_3, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_4, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+      s->origPtr = 0;
+      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+      if (s->origPtr < 0)
+         RETURN(BZ_DATA_ERROR);
+      if (s->origPtr > 10 + 100000*s->blockSize100k) 
+         RETURN(BZ_DATA_ERROR);
+
+      /*--- Receive the mapping table ---*/
+      for (i = 0; i < 16; i++) {
+         GET_BIT(BZ_X_MAPPING_1, uc);
+         if (uc == 1) 
+            s->inUse16[i] = True; else 
+            s->inUse16[i] = False;
+      }
+
+      for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+      for (i = 0; i < 16; i++)
+         if (s->inUse16[i])
+            for (j = 0; j < 16; j++) {
+               GET_BIT(BZ_X_MAPPING_2, uc);
+               if (uc == 1) s->inUse[i * 16 + j] = True;
+            }
+      makeMaps_d ( s );
+      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+      alphaSize = s->nInUse+2;
+
+      /*--- Now the selectors ---*/
+      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+      for (i = 0; i < nSelectors; i++) {
+         j = 0;
+         while (True) {
+            GET_BIT(BZ_X_SELECTOR_3, uc);
+            if (uc == 0) break;
+            j++;
+            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+         }
+         s->selectorMtf[i] = j;
+      }
+
+      /*--- Undo the MTF values for the selectors. ---*/
+      {
+         UChar pos[BZ_N_GROUPS], tmp, v;
+         for (v = 0; v < nGroups; v++) pos[v] = v;
+   
+         for (i = 0; i < nSelectors; i++) {
+            v = s->selectorMtf[i];
+            tmp = pos[v];
+            while (v > 0) { pos[v] = pos[v-1]; v--; }
+            pos[0] = tmp;
+            s->selector[i] = tmp;
+         }
+      }
+
+      /*--- Now the coding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         GET_BITS(BZ_X_CODING_1, curr, 5);
+         for (i = 0; i < alphaSize; i++) {
+            while (True) {
+               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+               GET_BIT(BZ_X_CODING_2, uc);
+               if (uc == 0) break;
+               GET_BIT(BZ_X_CODING_3, uc);
+               if (uc == 0) curr++; else curr--;
+            }
+            s->len[t][i] = curr;
+         }
+      }
+
+      /*--- Create the Huffman decoding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         minLen = 32;
+         maxLen = 0;
+         for (i = 0; i < alphaSize; i++) {
+            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+            if (s->len[t][i] < minLen) minLen = s->len[t][i];
+         }
+         BZ2_hbCreateDecodeTables ( 
+            &(s->limit[t][0]), 
+            &(s->base[t][0]), 
+            &(s->perm[t][0]), 
+            &(s->len[t][0]),
+            minLen, maxLen, alphaSize
+         );
+         s->minLens[t] = minLen;
+      }
+
+      /*--- Now the MTF values ---*/
+
+      EOB      = s->nInUse+1;
+      nblockMAX = 100000 * s->blockSize100k;
+      groupNo  = -1;
+      groupPos = 0;
+
+      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+      /*-- MTF init --*/
+      {
+         Int32 ii, jj, kk;
+         kk = MTFA_SIZE-1;
+         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+               kk--;
+            }
+            s->mtfbase[ii] = kk + 1;
+         }
+      }
+      /*-- end MTF init --*/
+
+      nblock = 0;
+      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+      while (True) {
+
+         if (nextSym == EOB) break;
+
+         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+            es = -1;
+            N = 1;
+            do {
+               /* Check that N doesn't get too big, so that es doesn't
+                  go negative.  The maximum value that can be
+                  RUNA/RUNB encoded is equal to the block size (post
+                  the initial RLE), viz, 900k, so bounding N at 2
+                  million should guard against overflow without
+                  rejecting any legitimate inputs. */
+               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
+               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+               N = N * 2;
+               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+            }
+               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+            es++;
+            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+            s->unzftab[uc] += es;
+
+            if (s->smallDecompress)
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->ll16[nblock] = (UInt16)uc;
+                  nblock++;
+                  es--;
+               }
+            else
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->tt[nblock] = (UInt32)uc;
+                  nblock++;
+                  es--;
+               };
+
+            continue;
+
+         } else {
+
+            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+            /*-- uc = MTF ( nextSym-1 ) --*/
+            {
+               Int32 ii, jj, kk, pp, lno, off;
+               UInt32 nn;
+               nn = (UInt32)(nextSym - 1);
+
+               if (nn < MTFL_SIZE) {
+                  /* avoid general-case expense */
+                  pp = s->mtfbase[0];
+                  uc = s->mtfa[pp+nn];
+                  while (nn > 3) {
+                     Int32 z = pp+nn;
+                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
+                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
+                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
+                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
+                     nn -= 4;
+                  }
+                  while (nn > 0) { 
+                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
+                  };
+                  s->mtfa[pp] = uc;
+               } else { 
+                  /* general case */
+                  lno = nn / MTFL_SIZE;
+                  off = nn % MTFL_SIZE;
+                  pp = s->mtfbase[lno] + off;
+                  uc = s->mtfa[pp];
+                  while (pp > s->mtfbase[lno]) { 
+                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
+                  };
+                  s->mtfbase[lno]++;
+                  while (lno > 0) {
+                     s->mtfbase[lno]--;
+                     s->mtfa[s->mtfbase[lno]] 
+                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s->mtfbase[0]--;
+                  s->mtfa[s->mtfbase[0]] = uc;
+                  if (s->mtfbase[0] == 0) {
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s->mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+            }
+            /*-- end uc = MTF ( nextSym-1 ) --*/
+
+            s->unzftab[s->seqToUnseq[uc]]++;
+            if (s->smallDecompress)
+               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
+            nblock++;
+
+            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+            continue;
+         }
+      }
+
+      /* Now we know what nblock is, we can do a better sanity
+         check on s->origPtr.
+      */
+      if (s->origPtr < 0 || s->origPtr >= nblock)
+         RETURN(BZ_DATA_ERROR);
+
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      /* Check: unzftab entries in range. */
+      for (i = 0; i <= 255; i++) {
+         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+            RETURN(BZ_DATA_ERROR);
+      }
+      /* Actually generate cftab. */
+      s->cftab[0] = 0;
+      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      /* Check: cftab entries in range. */
+      for (i = 0; i <= 256; i++) {
+         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+            /* s->cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+      /* Check: cftab entries non-descending. */
+      for (i = 1; i <= 256; i++) {
+         if (s->cftab[i-1] > s->cftab[i]) {
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
+      s->state_out_len = 0;
+      s->state_out_ch  = 0;
+      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+      s->state = BZ_X_OUTPUT;
+      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+      if (s->smallDecompress) {
+
+         /*-- Make a copy of cftab, used in generation of T --*/
+         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+         /*-- compute the T vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->ll16[i]);
+            SET_LL(i, s->cftabCopy[uc]);
+            s->cftabCopy[uc]++;
+         }
+
+         /*-- Compute T^(-1) by pointer reversal on T --*/
+         i = s->origPtr;
+         j = GET_LL(i);
+         do {
+            Int32 tmp = GET_LL(j);
+            SET_LL(j, i);
+            i = j;
+            j = tmp;
+         }
+            while (i != s->origPtr);
+
+         s->tPos = s->origPtr;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+         }
+
+      } else {
+
+         /*-- compute the T^(-1) vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->tt[i] & 0xff);
+            s->tt[s->cftab[uc]] |= (i << 8);
+            s->cftab[uc]++;
+         }
+
+         s->tPos = s->tt[s->origPtr] >> 8;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+         }
+
+      }
+
+      RETURN(BZ_OK);
+
+
+
+    endhdr_2:
+
+      GET_UCHAR(BZ_X_ENDHDR_2, uc);
+      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_3, uc);
+      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_4, uc);
+      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_5, uc);
+      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_6, uc);
+      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+      s->storedCombinedCRC = 0;
+      GET_UCHAR(BZ_X_CCRC_1, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_2, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_3, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_4, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+      s->state = BZ_X_IDLE;
+      RETURN(BZ_STREAM_END);
+
+      default: AssertH ( False, 4001 );
+   }
+
+   AssertH ( False, 4002 );
+
+   save_state_and_return:
+
+   s->save_i           = i;
+   s->save_j           = j;
+   s->save_t           = t;
+   s->save_alphaSize   = alphaSize;
+   s->save_nGroups     = nGroups;
+   s->save_nSelectors  = nSelectors;
+   s->save_EOB         = EOB;
+   s->save_groupNo     = groupNo;
+   s->save_groupPos    = groupPos;
+   s->save_nextSym     = nextSym;
+   s->save_nblockMAX   = nblockMAX;
+   s->save_nblock      = nblock;
+   s->save_es          = es;
+   s->save_N           = N;
+   s->save_curr        = curr;
+   s->save_zt          = zt;
+   s->save_zn          = zn;
+   s->save_zvec        = zvec;
+   s->save_zj          = zj;
+   s->save_gSel        = gSel;
+   s->save_gMinlen     = gMinlen;
+   s->save_gLimit      = gLimit;
+   s->save_gBase       = gBase;
+   s->save_gPerm       = gPerm;
+
+   return retVal;   
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                      decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/h5bzip2.h b/nc_test4/hdf5plugins/h5bzip2.h
new file mode 100644
index 0000000..8a9a06c
--- /dev/null
+++ b/nc_test4/hdf5plugins/h5bzip2.h
@@ -0,0 +1,30 @@
+#ifndef H5BZIP2_H
+#define H5BZIP2_H
+
+#include "bzlib.h"
+
+#ifdef _MSC_VER
+  #ifdef DLL_EXPORT /* define when building the library */
+    #define DECLSPEC __declspec(dllexport)
+  #else
+    #define DECLSPEC __declspec(dllimport)
+  #endif
+#else
+  #define DECLSPEC extern
+#endif
+
+/* use an integer greater than 256 to be id of the registered filter. */
+#define H5Z_FILTER_BZIP2 307
+
+/* declare the hdf5 interface */
+DECLSPEC H5PL_type_t H5PLget_plugin_type(void);
+DECLSPEC const void* H5PLget_plugin_info(void);
+DECLSPEC const H5Z_class2_t H5Z_BZIP2[1]; 
+
+/* Declare  filter specific functions */
+DECLSPEC htri_t H5Z_bzip2_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+DECLSPEC size_t H5Z_filter_bzip2(unsigned flags,size_t cd_nelmts,const unsigned cd_values[],
+                    size_t nbytes,size_t *buf_size,void**buf);
+
+#endif /*H5BZIP2_H*/
+
diff --git a/nc_test4/hdf5plugins/h5misc.h b/nc_test4/hdf5plugins/h5misc.h
new file mode 100644
index 0000000..d6be421
--- /dev/null
+++ b/nc_test4/hdf5plugins/h5misc.h
@@ -0,0 +1,34 @@
+#ifndef H5MISC_H
+#define H5MISC_H
+
+#ifdef _MSC_VER
+  #ifdef DLL_EXPORT /* define when building the library */
+    #define DECLSPEC __declspec(dllexport)
+  #else
+    #define DECLSPEC __declspec(dllimport)
+  #endif
+#else
+  #define DECLSPEC extern
+#endif
+
+/* use an integer greater than 256 to be id of the registered filter. */
+#define H5Z_FILTER_TEST 32768
+
+/* Define the test cases */
+
+typedef enum H5testcase {
+TC_NONE = 0,
+TC_ENDIAN = 1,
+} H5testcase;
+
+/* declare the hdf5 interface */
+DECLSPEC H5PL_type_t H5PLget_plugin_type(void);
+DECLSPEC const void* H5PLget_plugin_info(void);
+DECLSPEC const H5Z_class2_t H5Z_TEST[1]; 
+
+/* Declare filter specific functions */
+DECLSPEC htri_t H5Z_test_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+DECLSPEC size_t H5Z_filter_test(unsigned flags,size_t cd_nelmts,const unsigned cd_values[],
+                    size_t nbytes,size_t *buf_size,void**buf);
+
+#endif /*H5MISC_H*/
diff --git a/nc_test4/hdf5plugins/huffman.c b/nc_test4/hdf5plugins/huffman.c
new file mode 100644
index 0000000..2283fdb
--- /dev/null
+++ b/nc_test4/hdf5plugins/huffman.c
@@ -0,0 +1,205 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2)                           \
+   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
+   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z)                                     \
+{                                                     \
+   Int32 zz, tmp;                                     \
+   zz = z; tmp = heap[zz];                            \
+   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
+      heap[zz] = heap[zz >> 1];                       \
+      zz >>= 1;                                       \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+#define DOWNHEAP(z)                                   \
+{                                                     \
+   Int32 zz, yy, tmp;                                 \
+   zz = z; tmp = heap[zz];                            \
+   while (True) {                                     \
+      yy = zz << 1;                                   \
+      if (yy > nHeap) break;                          \
+      if (yy < nHeap &&                               \
+          weight[heap[yy+1]] < weight[heap[yy]])      \
+         yy++;                                        \
+      if (weight[tmp] < weight[heap[yy]]) break;      \
+      heap[zz] = heap[yy];                            \
+      zz = yy;                                        \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len, 
+                             Int32 *freq,
+                             Int32 alphaSize,
+                             Int32 maxLen )
+{
+   /*--
+      Nodes and heap entries run from 1.  Entry 0
+      for both the heap and nodes is a sentinel.
+   --*/
+   Int32 nNodes, nHeap, n1, n2, i, j, k;
+   Bool  tooLong;
+
+   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
+   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+
+   for (i = 0; i < alphaSize; i++)
+      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+   while (True) {
+
+      nNodes = alphaSize;
+      nHeap = 0;
+
+      heap[0] = 0;
+      weight[0] = 0;
+      parent[0] = -2;
+
+      for (i = 1; i <= alphaSize; i++) {
+         parent[i] = -1;
+         nHeap++;
+         heap[nHeap] = i;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+   
+      while (nHeap > 1) {
+         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         nNodes++;
+         parent[n1] = parent[n2] = nNodes;
+         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+         parent[nNodes] = -1;
+         nHeap++;
+         heap[nHeap] = nNodes;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+      tooLong = False;
+      for (i = 1; i <= alphaSize; i++) {
+         j = 0;
+         k = i;
+         while (parent[k] >= 0) { k = parent[k]; j++; }
+         len[i-1] = j;
+         if (j > maxLen) tooLong = True;
+      }
+      
+      if (! tooLong) break;
+
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i < alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i <= alphaSize; i++) {
+         j = weight[i] >> 8;
+         j = 1 + (j / 2);
+         weight[i] = j << 8;
+      }
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+                         UChar *length,
+                         Int32 minLen,
+                         Int32 maxLen,
+                         Int32 alphaSize )
+{
+   Int32 n, vec, i;
+
+   vec = 0;
+   for (n = minLen; n <= maxLen; n++) {
+      for (i = 0; i < alphaSize; i++)
+         if (length[i] == n) { code[i] = vec; vec++; };
+      vec <<= 1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+                                Int32 *base,
+                                Int32 *perm,
+                                UChar *length,
+                                Int32 minLen,
+                                Int32 maxLen,
+                                Int32 alphaSize )
+{
+   Int32 pp, i, j, vec;
+
+   pp = 0;
+   for (i = minLen; i <= maxLen; i++)
+      for (j = 0; j < alphaSize; j++)
+         if (length[j] == i) { perm[pp] = j; pp++; };
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   vec = 0;
+
+   for (i = minLen; i <= maxLen; i++) {
+      vec += (base[i+1] - base[i]);
+      limit[i] = vec-1;
+      vec <<= 1;
+   }
+   for (i = minLen + 1; i <= maxLen; i++)
+      base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/hdf5plugins/randtable.c b/nc_test4/hdf5plugins/randtable.c
new file mode 100644
index 0000000..6d62459
--- /dev/null
+++ b/nc_test4/hdf5plugins/randtable.c
@@ -0,0 +1,84 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks               ---*/
+/*---                                           randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = { 
+   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
+   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
+   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
+   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
+   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
+   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
+   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
+   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
+   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
+   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
+   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
+   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
+   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
+   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
+   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
+   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
+   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
+   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
+   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
+   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
+   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
+   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
+   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
+   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
+   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
+   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
+   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
+   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
+   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
+   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
+   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
+   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
+   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
+   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
+   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
+   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
+   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
+   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
+   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
+   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
+   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
+   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
+   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
+   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
+   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
+   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
+   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
+   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
+   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
+   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
+   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
+   936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       randtable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/nc_test4/ref_bzip2.c b/nc_test4/ref_bzip2.c
new file mode 100644
index 0000000..e93f3ca
--- /dev/null
+++ b/nc_test4/ref_bzip2.c
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <netcdf.h>
+
+
+static size_t var_chunksizes[4] = {4, 4, 4, 4} ;
+static unsigned int var_filterparams[1] = {9U} ;
+
+void
+check_err(const int stat, const int line, const char *file) {
+    if (stat != NC_NOERR) {
+        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
+        fflush(stderr);
+        exit(1);
+    }
+}
+
+int
+main() {/* create bzip2.nc */
+
+    int  stat;  /* return status */
+    int  ncid;  /* netCDF id */
+
+    /* group ids */
+    int bzip2_grp;
+
+    /* dimension ids */
+    int dim0_dim;
+    int dim1_dim;
+    int dim2_dim;
+    int dim3_dim;
+
+    /* dimension lengths */
+    size_t dim0_len = 4;
+    size_t dim1_len = 4;
+    size_t dim2_len = 4;
+    size_t dim3_len = 4;
+
+    /* variable ids */
+    int var_id;
+
+    /* rank (number of dimensions) for each variable */
+#   define RANK_var 4
+
+    /* variable shapes */
+    int var_dims[RANK_var];
+
+    /* enter define mode */
+    stat = nc_create("bzip2.nc", NC_CLOBBER|NC_NETCDF4, &ncid);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_put_att_text(ncid, NC_GLOBAL, "_Format", 1, "netCDF-4");
+    check_err(stat,__LINE__,__FILE__);
+    bzip2_grp = ncid;
+
+    /* define dimensions */
+    stat = nc_def_dim(bzip2_grp, "dim0", dim0_len, &dim0_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(bzip2_grp, "dim1", dim1_len, &dim1_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(bzip2_grp, "dim2", dim2_len, &dim2_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(bzip2_grp, "dim3", dim3_len, &dim3_dim);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* define variables */
+
+    var_dims[0] = dim0_dim;
+    var_dims[1] = dim1_dim;
+    var_dims[2] = dim2_dim;
+    var_dims[3] = dim3_dim;
+    stat = nc_def_var(bzip2_grp, "var", NC_FLOAT, RANK_var, var_dims, &var_id);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_var_chunking(bzip2_grp, var_id, NC_CHUNKED, var_chunksizes);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_var_fill(bzip2_grp, var_id, NC_NOFILL, NULL);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_var_filter(bzip2_grp, var_id, 307, 1, var_filterparams);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* leave define mode */
+    stat = nc_enddef (bzip2_grp);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* assign variable data */
+
+    {
+    float var_data[256] = {((float)0), ((float)1), ((float)2), ((float)3), ((float)4), ((float)5), ((float)6), ((float)7), ((float)8), ((float)9), ((float)10), ((float)11), ((float)12), ((float)13), ((float)14), ((float)15), ((float)16), ((float)17), ((float)18), ((float)19), ((float)20), ((float)21), ((float)22), ((float)23), ((float)24), ((float)25), ((float)26), ((float)27), ((float)28), ((float)29), ((float)30), ((float)31), ((float)32), ((float)33), ((float)34), ((float)35), ((float [...]
+    size_t var_startset[4] = {0, 0, 0, 0} ;
+    size_t var_countset[4] = {4, 4, 4, 4};
+    stat = nc_put_vara(bzip2_grp, var_id, var_startset, var_countset, var_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    stat = nc_close(bzip2_grp);
+    check_err(stat,__LINE__,__FILE__);
+    return 0;
+}
diff --git a/nc_test4/ref_szip.cdl b/nc_test4/ref_szip.cdl
new file mode 100644
index 0000000..dafb3bb
--- /dev/null
+++ b/nc_test4/ref_szip.cdl
@@ -0,0 +1,85 @@
+netcdf ref_szip {
+dimensions:
+	phony_dim_0 = 40 ;
+	phony_dim_1 = 20 ;
+variables:
+	int dset_szip(phony_dim_0, phony_dim_1) ;
+data:
+
+ dset_szip =
+  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, 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, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 
+    255, 256, 257, 258, 259,
+  260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 
+    275, 276, 277, 278, 279,
+  280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 
+    295, 296, 297, 298, 299,
+  300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 
+    315, 316, 317, 318, 319,
+  320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 
+    335, 336, 337, 338, 339,
+  340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 
+    355, 356, 357, 358, 359,
+  360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 
+    375, 376, 377, 378, 379,
+  380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 
+    395, 396, 397, 398, 399,
+  400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 
+    415, 416, 417, 418, 419,
+  420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 
+    435, 436, 437, 438, 439,
+  440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 
+    455, 456, 457, 458, 459,
+  460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 
+    475, 476, 477, 478, 479,
+  480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 
+    495, 496, 497, 498, 499,
+  500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 
+    515, 516, 517, 518, 519,
+  520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 
+    535, 536, 537, 538, 539,
+  540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 
+    555, 556, 557, 558, 559,
+  560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 
+    575, 576, 577, 578, 579,
+  580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 
+    595, 596, 597, 598, 599,
+  600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 
+    615, 616, 617, 618, 619,
+  620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 
+    635, 636, 637, 638, 639,
+  640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 
+    655, 656, 657, 658, 659,
+  660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 
+    675, 676, 677, 678, 679,
+  680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 
+    695, 696, 697, 698, 699,
+  700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 
+    715, 716, 717, 718, 719,
+  720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 
+    735, 736, 737, 738, 739,
+  740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 
+    755, 756, 757, 758, 759,
+  760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 
+    775, 776, 777, 778, 779,
+  780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 
+    795, 796, 797, 798, 799 ;
+}
diff --git a/nc_test4/ref_szip.h5 b/nc_test4/ref_szip.h5
new file mode 100644
index 0000000..b16d169
Binary files /dev/null and b/nc_test4/ref_szip.h5 differ
diff --git a/nc_test4/renamegroup.c b/nc_test4/renamegroup.c
index 3f59dcf..695f64d 100644
--- a/nc_test4/renamegroup.c
+++ b/nc_test4/renamegroup.c
@@ -38,7 +38,7 @@ check(int status)
 int
 main(int argc, char **argv)
 {
-    int i,stat;
+    int stat;
     int ncid, grpid;
     char* filename;
     char* oldname;
diff --git a/nc_test4/run_get_hdf4_files.sh b/nc_test4/run_get_hdf4_files.sh
index 562969b..929878b 100755
--- a/nc_test4/run_get_hdf4_files.sh
+++ b/nc_test4/run_get_hdf4_files.sh
@@ -1,11 +1,18 @@
 #!/bin/sh
 
-# This shell gets files from the netCDF ftp site for testing.
+# This shell gets some sample HDF4 files from the netCDF ftp site for
+# testing. Then it runs program tst_interops3 on the test file to
+# check that HDF4 reading works.
 
-# $Id: run_get_hdf4_files.sh,v 1.4 2009/07/15 15:16:05 ed Exp $
+# Ed Hartnett
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../test_common.sh
 
 set -e
 echo ""
+echo "Getting HDF4 sample files from Unidata FTP site..."
+
 file_list="AMSR_E_L2_Rain_V10_200905312326_A.hdf AMSR_E_L3_DailyLand_V06_20020619.hdf \
     MYD29.A2009152.0000.005.2009153124331.hdf MYD29.A2002185.0000.005.2007160150627.hdf \
     MOD29.A2000055.0005.005.2006267200024.hdf"
@@ -19,6 +26,11 @@ do
     fi
 done
 
+
+echo ""
+echo "Running test program to check HDF4 sample files..."
+${execdir}/tst_interops3
+
 echo "SUCCESS!!!"
 
 exit 0
diff --git a/nc_test4/run_par_test.sh b/nc_test4/run_par_test.sh
index 5c5ab5b..d1135c4 100755
--- a/nc_test4/run_par_test.sh
+++ b/nc_test4/run_par_test.sh
@@ -36,3 +36,4 @@ echo
 echo "Parallel I/O test for Collective I/O, contributed by HDF Group."
 mpiexec -n 1 ./tst_simplerw_coll_r
 mpiexec -n 2 ./tst_simplerw_coll_r
+mpiexec -n 4 ./tst_simplerw_coll_r
diff --git a/nc_test4/test_filter.c b/nc_test4/test_filter.c
new file mode 100644
index 0000000..2922a6b
--- /dev/null
+++ b/nc_test4/test_filter.c
@@ -0,0 +1,306 @@
+/*
+  Copyright 2018, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
+*/
+
+/*! \file
+Example program for write then read of a variable using bzip2 compression.
+
+\ingroup tutorial
+
+This is an example which 
+creates a file with a variable that is compressed using bzip2.
+Then it reads that file and verifies that it returned the correct
+uncompressed data.
+
+The meta-data (.cdl) for the created file is as follows:
+\code
+netcdf bzip2 {
+dimensions:
+	dim0 = 4 ;
+	dim1 = 4 ;
+	dim2 = 4 ;
+	dim3 = 4 ;
+variables:
+	float var(dim0, dim1, dim2, dim3) ;
+		var:_Storage = "chunked" ;
+		var:_ChunkSizes = 4, 4, 4, 4 ;
+		var:_Filter = "307,9" ;
+		var:_NoFill = "true" ;
+data:
+
+ var =
+  0, 1, 2, 3,
+  4, 5, 6, 7,
+  ...
+  252, 253, 254, 255 ;
+}
+\endcode
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <hdf5.h>
+#include "netcdf.h"
+
+/* The HDF assigned id for bzip compression */
+#define BZIP2_ID 307
+/* The compression level used in this example */
+#define BZIP2_LEVEL 9
+
+#define TESTFILE "bzip2.nc"
+
+/* Point at which we give up */
+#define MAXERRS 8
+
+#define NDIMS 4
+#define DIMSIZE 4
+#define CHUNKSIZE 4 /* Note: not the total size of the chunk, but size wrt a dim*/
+
+static size_t dimsize = DIMSIZE;
+static size_t chunksize = CHUNKSIZE;
+static size_t actualdims = NDIMS;
+
+static size_t actualproduct = 1; /* x-product over dim sizes */
+static size_t chunkproduct = 1; /* x-product over chunksizes */
+
+static size_t dims[NDIMS];
+static size_t chunks[NDIMS];
+
+static int nerrs = 0;
+
+static int ncid, varid;
+static int dimids[NDIMS];
+static float* array = NULL;
+static float* expected = NULL;
+static unsigned int filterid = 0;
+static unsigned int* params = NULL;
+
+/* Forward */
+static void init(int argc, char** argv);
+static int test_bzip2(void);
+static int verifychunks(void);
+
+#define ERRR do { \
+fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
+fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
+	__FILE__, __LINE__);				    \
+nerrs++;\
+} while (0)
+
+static int
+check(int err,int line)
+{
+    if(err != NC_NOERR) {
+	fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
+	fflush(stderr);
+	exit(1);
+    }
+    return NC_NOERR;
+}
+
+#define CHECK(x) check(x,__LINE__)
+
+/*
+Read the chunking information about the variable
+and verify that it is as expected.
+*/
+
+static int
+verifychunks(void)
+{
+    int i;
+    int store = -1;
+    size_t chunksizes[NDIMS];
+    memset(chunksizes,0,sizeof(chunksizes));
+    CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes));
+    /* Storate must be chunked, not contiguous */
+    if(store != NC_CHUNKED) {
+	fprintf(stderr,"bad chunk store\n");
+	return NC_ESTORAGE;
+    }
+    /* Chunk sizes must match our predefined set */
+    for(i=0;i<actualdims;i++) {
+        if(chunksizes[i] != chunks[i]) {
+	    fprintf(stderr,"bad chunk size: %d\n",i);
+	    return NC_EBADCHUNK;
+	}
+    }
+    return 1;
+}
+
+/*
+Compare the data we wrote against the data we read.
+*/
+
+static int
+compare(void)
+{
+    int errs = 0;
+    int i;
+    printf("data comparison: |array|=%ld\n",(unsigned long)actualproduct);
+    for(i=0;i<actualproduct;i++) {
+	if(expected[i] != array[i]) {
+	    printf("mismatch: array[%d]=%f expected[%d]=%f\n",
+                            i,array[i],i,expected[i]);
+            errs++;
+            if(errs >= MAXERRS)
+                break;
+	}
+   }
+   if(errs == 0)
+        printf("no data errors\n");
+   if(actualproduct <= 1)
+	return NC_EBADDIM;
+   return (errs == 0 ? NC_NOERR: NC_EINVAL);
+}
+
+/*
+Create the file, write it, then re-read for comparison.
+*/
+static int
+test_bzip2(void)
+{
+    int i;
+    unsigned int level = BZIP2_LEVEL;
+    unsigned int id=0;
+    size_t nparams = 0;
+
+    printf("\n*** Testing API: bzip2 compression.\n");
+
+    /* Clear the data array */
+    memset(array,0,sizeof(float)*actualproduct);
+
+    /* Create a file */
+    CHECK(nc_create(TESTFILE, NC_NETCDF4|NC_CLOBBER, &ncid));
+
+    /* Do not use fill for this file */
+    CHECK(nc_set_fill(ncid, NC_NOFILL, NULL));
+
+    /* Define the dimensions */
+    for(i=0;i<actualdims;i++) {
+	char dimname[1024];
+	snprintf(dimname,sizeof(dimname),"dim%d",i);
+        CHECK(nc_def_dim(ncid, dimname, dims[i], &dimids[i]));
+    }
+
+    /* Define the variable */
+    CHECK(nc_def_var(ncid, "var", NC_FLOAT, actualdims, dimids, &varid));
+
+    /* Set chunking on the variable */
+    CHECK(nc_def_var_chunking(ncid,varid,NC_CHUNKED,chunks));
+
+    /* Verify that chunking succeeded */
+    if(!verifychunks())
+	return NC_EINVAL;
+    /* Set bzip2 compression for the variable: takes one parameter == level */
+    CHECK(nc_def_var_filter(ncid,varid,BZIP2_ID,1,&level));
+
+    /* Read back the compression info and verify it */
+    level = 0;
+    CHECK(nc_inq_var_filter(ncid,varid,&id,&nparams,&level));
+    if(id != BZIP2_ID || nparams != 1 || level != BZIP2_LEVEL) {
+        printf("test_filter: filter def/inq mismatch\n");
+	return NC_EFILTER;
+    }
+    /* Show the level */
+    printf("show parameters for bzip2: level=%u\n",level);
+    /* Show chunking */ 
+    printf("show chunks:");
+    for(i=0;i<actualdims;i++)
+	printf("%s%ld",(i==0?" chunks=":","),(unsigned long)chunks[i]);
+    printf("\n");
+
+    /* prepare to write */
+    CHECK(nc_enddef(ncid));
+
+    /* Fill in the array */
+    for(i=0;i<actualproduct;i++)
+	expected[i] = (float)i;
+
+    /* write array */
+    CHECK(nc_put_var(ncid,varid,expected));
+
+    /* Close file */
+    CHECK(nc_close(ncid));
+
+    /* Now re-open and verify */
+    printf("\n*** Testing API: bzip2 decompression.\n");
+
+    /* Clear the data array */
+    memset(array,0,sizeof(float)*actualproduct);
+
+    /* Open the file */
+    CHECK(nc_open(TESTFILE, NC_NOWRITE, &ncid));
+
+    /* Get the variable id */
+    CHECK(nc_inq_varid(ncid, "var", &varid));
+
+    /* Check the compression algorithm */
+    filterid = 0;
+    nparams = 0;
+    params = NULL;
+    CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,NULL));
+    if(nparams > 0) {
+        params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
+	if(params == NULL)
+	    return NC_ENOMEM;
+        CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+    }
+    if(filterid != BZIP2_ID) {
+         printf("Bzip2 id mismatch: %d\n",filterid);
+	return NC_EFILTER;
+    }
+    if(nparams != 1 && params != NULL && params[0] != BZIP2_LEVEL) {
+	printf("Compression parameter mismatch\n");
+	return NC_EFILTER; 
+    }
+
+    /* Verify chunking */
+    if(!verifychunks())
+	return 0;
+
+    /* Read the data */
+    CHECK(nc_get_var_float(ncid, varid, array));
+
+    /* Close the file */
+    CHECK(nc_close(ncid));
+    return (compare() == NC_NOERR ? 0 : 1);
+}
+
+/**************************************************/
+/* Utilities */
+
+static void
+init(int argc, char** argv)
+{
+    int i;
+    /* Setup various variables */
+    actualproduct = 1;
+    chunkproduct = 1;
+    for(i=0;i<NDIMS;i++) {
+	dims[i] = dimsize;
+	chunks[i] = chunksize;
+	if(i < actualdims) {
+	    actualproduct *= dims[i];
+	    chunkproduct *= chunks[i];
+	}
+    }
+    /* Allocate max size */
+    array = (float*)calloc(1,sizeof(float)*actualproduct);
+    expected = (float*)calloc(1,sizeof(float)*actualproduct);
+}
+
+/**************************************************/
+int
+main(int argc, char **argv)
+{
+    H5Eprint(stderr);
+    init(argc,argv);
+    if(test_bzip2() != NC_NOERR) ERRR;
+    exit(nerrs > 0?1:0);
+}
+
diff --git a/nc_test4/test_filter_misc.c b/nc_test4/test_filter_misc.c
new file mode 100644
index 0000000..fdec17e
--- /dev/null
+++ b/nc_test4/test_filter_misc.c
@@ -0,0 +1,452 @@
+/*
+  Copyright 2008, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <hdf5.h>
+#include "netcdf.h"
+
+#if defined  _MSC_VER || defined __APPLE__
+#define DBLVAL 12345678.12345678
+#else
+#define DBLVAL 12345678.12345678d
+#endif
+
+#define TEST_ID 32768
+
+#define MAXERRS 8
+
+#define MAXPARAMS 32
+
+#define NPARAMS 14
+
+static unsigned int baseline[NPARAMS];
+
+#define MAXDIMS 8
+
+#define DEFAULTACTUALDIMS 4
+#define DEFAULTDIMSIZE 4
+#define DEFAULTCHUNKSIZE 4
+
+#define TESTFILE "testmisc.nc"
+
+#define spec "32768, -17b, 23ub, -25S, 27US, 77, 93U, 789f, 12345678.12345678d, -9223372036854775807L, 18446744073709551615UL"
+
+static size_t dimsize = DEFAULTDIMSIZE;
+static size_t chunksize = DEFAULTCHUNKSIZE;
+static size_t actualdims = DEFAULTACTUALDIMS;
+static size_t pattern[MAXDIMS];
+
+static size_t totalproduct = 1; /* x-product over max dims */
+static size_t actualproduct = 1; /* x-product over actualdims */
+static size_t chunkproduct = 1; /* x-product over actual chunks */
+
+static size_t dims[MAXDIMS];
+static size_t chunks[MAXDIMS];
+
+static int nerrs = 0;
+
+static int ncid, varid;
+static int dimids[MAXDIMS];
+static size_t odom[MAXDIMS];
+static float* array = NULL;
+static float* expected = NULL;
+
+static unsigned int filterid = 0;
+static size_t nparams = 0;
+static unsigned int params[MAXPARAMS];
+
+/* Forward */
+static int test_test1(void);
+static void init(int argc, char** argv);
+static void reset(void);
+static void odom_reset(void);
+static int odom_more(void);
+static int odom_next(void);
+static int odom_offset(void);
+static float expectedvalue(void);
+static void verifyparams(void);
+
+#define ERRR do { \
+fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
+fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
+        __FILE__, __LINE__);                                \
+nerrs++;\
+} while (0)
+
+static int
+check(int err,int line)
+{
+    if(err != NC_NOERR) {
+        fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
+    }
+    return NC_NOERR;
+}
+
+static void
+report(const char* msg, int lineno)
+{
+    fprintf(stderr,"fail: line=%d %s\n",lineno,msg);
+    exit(1);
+}
+
+#define CHECK(x) check(x,__LINE__)
+#define REPORT(x) report(x,__LINE__)
+
+static int
+verifychunks(void)
+{
+    int i;
+    int store = -1;
+    size_t chunksizes[MAXDIMS];
+    memset(chunksizes,0,sizeof(chunksizes));
+    CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes));
+    if(store != NC_CHUNKED) {
+        fprintf(stderr,"bad chunk store\n");
+        return 0;
+    }
+    for(i=0;i<actualdims;i++) {
+        if(chunksizes[i] != chunks[i]) {
+            fprintf(stderr,"bad chunk size: %d\n",i);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int
+create(void)
+{
+    int i;
+
+    /* Create a file with one big variable. */
+    CHECK(nc_create(TESTFILE, NC_NETCDF4|NC_CLOBBER, &ncid));
+    CHECK(nc_set_fill(ncid, NC_NOFILL, NULL));
+    for(i=0;i<actualdims;i++) {
+        char dimname[1024];
+        snprintf(dimname,sizeof(dimname),"dim%d",i);
+        CHECK(nc_def_dim(ncid, dimname, dims[i], &dimids[i]));
+    }
+    CHECK(nc_def_var(ncid, "var", NC_FLOAT, actualdims, dimids, &varid));
+    return NC_NOERR;
+}
+
+static void
+setvarfilter(void)
+{
+    CHECK(nc_def_var_filter(ncid,varid,TEST_ID,NPARAMS,baseline));
+    verifyparams();
+}
+
+static void
+verifyparams(void)
+{
+    int i;
+    CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+    if(filterid != TEST_ID) REPORT("id mismatch");
+    if(nparams != NPARAMS) REPORT("nparams mismatch");
+    for(i=0;i<nparams;i++) {
+        if(params[i] != baseline[i])
+            REPORT("param mismatch");
+    }
+}
+
+static int
+openfile(void)
+{
+    unsigned int* params;
+
+    /* Open the file and check it. */
+    CHECK(nc_open(TESTFILE, NC_NOWRITE, &ncid));
+    CHECK(nc_inq_varid(ncid, "var", &varid));
+
+    /* Check the compression algorithm */
+    CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,NULL));
+    if(nparams > 0) {
+        params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
+        if(params == NULL)
+            return NC_ENOMEM;
+        CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
+    }
+    if(filterid != TEST_ID) {
+        fprintf(stderr,"open: test id mismatch: %d\n",filterid);
+        return NC_EFILTER;
+    }
+    if(nparams != NPARAMS) {
+	size_t i;
+	unsigned int inqparams[MAXPARAMS];
+        fprintf(stderr,"nparams  mismatch\n");
+        for(nerrs=0,i=0;i<nparams;i++) {
+            if(inqparams[i] != baseline[i]) {
+                fprintf(stderr,"open: testparam mismatch: %ld\n",(unsigned long)i);
+		nerrs++;
+	    }
+	}
+    }
+    if(nerrs > 0) return NC_EFILTER; 
+
+    /* Verify chunking */
+    if(!verifychunks())
+        return 0;
+    fflush(stderr);
+    return 1;
+}
+
+static int
+setchunking(void)
+{
+    int store;
+
+    store = NC_CHUNKED;
+    CHECK(nc_def_var_chunking(ncid,varid,store,chunks));
+    if(!verifychunks())
+        return NC_EINVAL;
+    return NC_NOERR;
+}
+
+static void
+fill(void)
+{
+   odom_reset();
+   if(1) {
+        int i;
+        if(actualproduct <= 1) abort();
+        for(i=0;i<actualproduct;i++)
+            expected[i] = (float)i;
+   } else {
+       while(odom_more()) {
+            int offset = odom_offset();
+            float expect = expectedvalue();
+            expected[offset] = expect;
+            odom_next();
+        }
+   }
+}
+
+
+static int
+compare(void)
+{
+    int errs = 0;
+    fprintf(stderr,"data comparison: |array|=%ld\n",(unsigned long)actualproduct);
+    if(1)
+    {
+        int i;
+        for(i=0;i<actualproduct;i++) {
+            if(expected[i] != array[i]) {
+                fprintf(stderr,"data mismatch: array[%d]=%f expected[%d]=%f\n",
+                            i,array[i],i,expected[i]);
+                errs++;
+                if(errs >= MAXERRS)
+                    break;
+            }
+        }
+   } else
+   {
+       odom_reset();
+       while(odom_more()) {
+            int offset = odom_offset();
+            float expect = expectedvalue();
+            if(array[offset] != expect) {
+                fprintf(stderr,"data mismatch: array[%d]=%f expected=%f\n",
+                            offset,array[offset],expect);
+                errs++;
+                if(errs >= MAXERRS)
+                    break;
+            }
+            odom_next();
+       }
+   }
+
+   if(errs == 0)
+        fprintf(stderr,"no data errors\n");
+   return (errs == 0);
+}
+
+static void
+showparameters(void)
+{
+    int i;
+    fprintf(stderr,"test: nparams=%ld: params=",(unsigned long)nparams);
+    for(i=0;i<nparams;i++) {
+        fprintf(stderr," %u",params[i]);
+    }
+    fprintf(stderr,"\n");
+    for(i=0;i<actualdims;i++)
+        fprintf(stderr,"%s%ld",(i==0?" chunks=":","),(unsigned long)chunks[i]);
+    fprintf(stderr,"\n");
+    fflush(stderr);
+}
+
+static void
+insert(int index, void* src, size_t size)
+{
+    void* dst = &baseline[index];
+    memcpy(dst,src,size);
+}
+
+static void
+buildbaseline(unsigned int testcasenumber)
+{
+    unsigned int val4;
+    unsigned long long val8;
+    float float4;
+    double float8;
+
+    baseline[0] = testcasenumber;
+    switch (testcasenumber) {
+    case 1:
+        val4 = ((unsigned int)-17) & 0xff;
+        insert(1,&val4,sizeof(val4)); /* 1 signed int*/
+	val4 = (unsigned int)23;
+        insert(2,&val4,sizeof(val4)); /* 2 unsigned int*/
+        val4 = ((unsigned int)-25) & 0xffff;
+        insert(3,&val4,sizeof(val4)); /* 3 signed int*/
+	val4 = (unsigned int)27;
+        insert(4,&val4,sizeof(val4)); /* 4 unsigned int*/
+	val4 = (unsigned int)77;
+        insert(5,&val4,sizeof(val4)); /* 5 signed int*/
+	val4 = (unsigned int)93;
+        insert(6,&val4,sizeof(val4)); /* 6 unsigned int*/
+	float4 = 789.0f;
+        insert(7,&float4,sizeof(float4)); /* 7 float */
+	float8 = DBLVAL;
+        insert(8,&float8,sizeof(float8)); /* 8 double */
+	val8 = -9223372036854775807L;
+        insert(10,&val8,sizeof(val8)); /* 10 signed long long */
+	val8 = 18446744073709551615UL;
+        insert(12,&val8,sizeof(val8)); /* 12 unsigned long long */
+	break;
+    default:
+	fprintf(stderr,"Unknown testcase number: %d\n",testcasenumber);
+	abort();
+    }
+}
+
+static int
+test_test1(void)
+{
+    int ok = 1;
+
+    reset();
+
+    buildbaseline(1);
+
+    fprintf(stderr,"test1: compression.\n");
+    create();
+    setchunking();
+    setvarfilter();
+    showparameters();
+    CHECK(nc_enddef(ncid));
+
+    /* Fill in the array */
+    fill();
+    /* write array */
+    CHECK(nc_put_var(ncid,varid,expected));
+    CHECK(nc_close(ncid));
+
+    fprintf(stderr,"test1: decompression.\n");
+    reset();
+    openfile();
+    CHECK(nc_get_var_float(ncid, varid, array));
+    ok = compare();
+    CHECK(nc_close(ncid));
+    return ok;
+}
+
+/**************************************************/
+/* Utilities */
+
+static void
+reset()
+{
+    memset(array,0,sizeof(float)*actualproduct);
+}
+
+static void
+odom_reset(void)
+{
+    memset(odom,0,sizeof(odom));
+}
+
+static int
+odom_more(void)
+{
+    return (odom[0] < dims[0]);
+}
+
+static int
+odom_next(void)
+{
+    int i; /* do not make unsigned */
+    for(i=actualdims-1;i>=0;i--) {
+        odom[i] += 1;
+        if(odom[i] < dims[i]) break;
+        if(i == 0) return 0; /* leave the 0th entry if it overflows*/
+        odom[i] = 0; /* reset this position*/
+    }
+    return 1;
+}
+
+static int
+odom_offset(void)
+{
+    int i;
+    int offset = 0;
+    for(i=0;i<actualdims;i++) {
+        offset *= dims[i];
+        offset += odom[i];
+    }
+    return offset;
+}
+
+static float
+expectedvalue(void)
+{
+    int i;
+    float offset = 0;
+
+    for(i=0;i<actualdims;i++) {
+        offset *= dims[i];
+        offset += odom[i];
+    }
+    return offset;
+}
+
+static void
+init(int argc, char** argv)
+{
+    int i;
+    /* Setup various variables */
+    totalproduct = 1;
+    actualproduct = 1;
+    chunkproduct = 1;
+    for(i=0;i<MAXDIMS;i++) {
+        dims[i] = dimsize;
+        chunks[i] = (pattern[i] == 1 ? 1 : chunksize);
+        totalproduct *= dims[i];
+        if(i < actualdims) {
+            actualproduct *= dims[i];
+            chunkproduct *= chunks[i];
+        }
+    }
+    /* Allocate max size */
+    array = (float*)calloc(1,sizeof(float)*actualproduct);
+    expected = (float*)calloc(1,sizeof(float)*actualproduct);
+}
+
+/**************************************************/
+int
+main(int argc, char **argv)
+{
+    H5Eprint(stderr);
+    nc_set_log_level(1);
+    init(argc,argv);
+    if(!test_test1()) ERRR;
+    exit(nerrs > 0?1:0);
+}
diff --git a/nc_test4/test_szip.c b/nc_test4/test_szip.c
new file mode 100644
index 0000000..9aece77
--- /dev/null
+++ b/nc_test4/test_szip.c
@@ -0,0 +1,155 @@
+/* This is part of the netCDF package.
+   Copyright 2005 University Corporation for Atmospheric Research/Unidata
+   See COPYRIGHT file for conditions of use.
+*/
+
+/*
+ * Example illustrates the use of SZIP compression in netCDF5
+ * Taken from HDF5 example.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "nc_tests.h"
+#include "err_macros.h"
+#include "netcdf.h"
+
+#undef PLAIN
+#define USECLOSE
+
+/* Szip Constants. */
+#define HDF5_FILTER_SZIP 4
+#define H5_SZIP_MAX_PIXELS_PER_BLOCK 32
+
+/* Option Mask Flags (Refere to HDF5 szip documentation)  */
+#define H5_SZIP_ALLOW_K13_OPTION_MASK 1 /*Allows k split = 13 compression mode. (Default)*/
+#define H5_SZIP_CHIP_OPTION_MASK      2 /*Compresses exactly as in hardware*/
+#define H5_SZIP_EC_OPTION_MASK        4 /*Selects entropy coding method. (Default)*/
+#define H5_SZIP_NN_OPTION_MASK       32 /*Selects nearest neighbor coding method*/
+
+#define NX 500
+#define NY 600
+#define CH_NX 100
+#define CH_NY 25
+
+
+static void initialize(void);
+static int compare(void);
+
+static float buf[NX][NY];
+static float buf_r[NX][NY];
+
+int
+main(void)
+{
+    int ncid, varid, dimids[2];
+    size_t dims[2], chunk_size[2];
+    unsigned int szip_params[2]; /* [0]=options_mask [1]=pixels_per_block */
+    int errcnt = 0;
+
+    /* Create a new file using read/write access. */
+    if(nc_create("testszip.nc", NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
+
+    /* Create dims */
+    dims[0] = NX;
+    dims[1] = NY;
+    if(nc_def_dim(ncid, "x", dims[0], &dimids[0])) ERR;
+    if(nc_def_dim(ncid, "y", dims[1], &dimids[1])) ERR;
+
+    /* Create a dimensioned variable */
+    if(nc_def_var(ncid, "datasetF32", NC_FLOAT, 2, dimids, &varid)) ERR;
+
+    /* no fill */
+    if(nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
+
+    /* Define chunking for the variable:
+    * the raw data is to be partitioned into 100x100 element chunks.
+    */
+    chunk_size[0] = CH_NX;
+    chunk_size[1] = CH_NY;
+    if(nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunk_size)) ERR;
+
+#ifndef PLAIN
+    /*
+     * Set parameters for SZIP compression; check the description of
+     * the H5Pset_szip function in the HDF5 Reference Manual for more
+     * information.
+     */
+    szip_params[0] = H5_SZIP_NN_OPTION_MASK;
+    szip_params[1] = H5_SZIP_MAX_PIXELS_PER_BLOCK;
+    { int stat = nc_def_var_filter(ncid, varid, HDF5_FILTER_SZIP, 2, szip_params);
+       if(stat) {
+         fprintf(stderr,"XXX: %d %s\b",stat,nc_strerror(stat));
+         ERR;
+       }
+    }
+#endif
+
+    if(nc_enddef(ncid)) ERR;
+
+    initialize();
+
+    /* Write the array to the file */
+    if(nc_put_var_float(ncid, varid, &buf[0][0])) ERR;
+
+#ifdef USECLOSE
+    /* Close and re-open the file */
+    if(nc_close(ncid)) ERR;
+    if(nc_open("testszip.nc", NC_NETCDF4, &ncid)) ERR;
+    if(nc_inq_varid(ncid, "datasetF32", &varid)) ERR;
+#endif
+
+    /*
+    * Read the array.  This is similar to writing data,
+    * except the data flows in the opposite direction.
+    * Note: Decompression should be automatic.
+    */
+
+    memset(buf_r,0,sizeof(buf_r));
+    if(nc_get_var_float(ncid, varid, &buf_r[0][0])) ERR;
+
+    /* Do comparison */
+    errcnt = compare();
+
+    if(nc_close(ncid)) ERR;
+
+    if(errcnt) ERR;
+
+    SUMMARIZE_ERR;
+    FINAL_RESULTS;
+
+    return (errcnt==0?0:1);
+}
+
+static int
+compare()
+{
+    int i,j;
+    int errs = 0;
+    
+    /* Do comparison */
+    for (i=0; i < NX; i++) {
+	for (j=0; j < NY; j++) {
+            if(buf[i][j] != buf_r[i][j]) {
+		errs++;
+	        printf("mismatch: [%d][%d]: write = %f read=%f\n",
+		        i,j,buf[i][j],buf_r[i][j]);
+	}
+     }
+   }
+   return errs;
+}
+
+static void
+initialize(void)
+{
+   int i, j;
+   /* Initialize data buffer with some bogus data. */
+   for(i=0; i < NX; i++) {
+     for(j=0; j < NY; j++) {
+       buf[i][j] = (float)(i + j);
+     }
+   }
+}
+
diff --git a/nc_test4/test_wrapper.in b/nc_test4/test_wrapper.in
new file mode 100644
index 0000000..f4d40c8
--- /dev/null
+++ b/nc_test4/test_wrapper.in
@@ -0,0 +1,35 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/*
+This is a round-about way of getting the output from
+a shell script test. Apparently, LOG_DRIVER
+only works for executables and not for shell scripts.
+So, use this executable to indirectly invoke a shell script
+test so that its output appears in e.g. travis log.
+If I could figure out the shell equivalent of LOG_DRIVER,
+then this would not be necessary.
+*/
+
+
+#define CMD "./tst_filter.sh"
+#define TOPSRCDIR "@abs_top_srcdir@"
+#define TOPBUILDDIR "@abs_top_builddir@"
+
+int
+main(int argc, char** argv)
+{
+    int stat;
+    char path[4096];
+    
+    fprintf(stderr,"test_wrapper: TOPSRCDIR=%s TOPBUILDDIR=%s\n",TOPSRCDIR,TOPBUILDDIR);
+    strcpy(path,TOPSRCDIR);
+    strcat(path,"/nc_test4/");
+    strcat(path,CMD);
+    fprintf(stderr,"test_wrapper: path=%s\n",path);
+    stat = system(path);
+    return WEXITSTATUS(stat);
+}
diff --git a/nc_test4/tst_atts1.c b/nc_test4/tst_atts1.c
index 12a5cc8..34841a4 100644
--- a/nc_test4/tst_atts1.c
+++ b/nc_test4/tst_atts1.c
@@ -4,7 +4,7 @@
 
    Test attributes.
 
-   $Id$
+   @author Ed Hartnett
 */
 
 #include <nc_tests.h>
@@ -12,7 +12,7 @@
 #include "netcdf.h"
 #include <signal.h>
 
-#define FILE_NAME "tst_atts.nc"
+#define FILE_NAME "tst_atts1.nc"
 #define FILE_NAME2 "tst_atts_2.nc"
 #define VAR1_NAME "Horace_Rumpole"
 #define VAR2_NAME "Claude_Erskine-Brown"
diff --git a/ncdump/tst_bug324.c b/nc_test4/tst_bug324.c
similarity index 98%
rename from ncdump/tst_bug324.c
rename to nc_test4/tst_bug324.c
index 2ce5b27..f165d44 100644
--- a/ncdump/tst_bug324.c
+++ b/nc_test4/tst_bug324.c
@@ -63,7 +63,7 @@ main(int argc, char **argv)
     /* Check file can be opened and read correctly */
     {
 	int format;
-	int ndims, nvars, ngatts, xdimid, nunlim;
+	int ndims, nvars, ngatts, xdimid;
 	nc_type lat_type, h_type;
 	int lat_rank, lat_natts, h_rank, h_natts;
 	if (nc_open(FILENAME, NC_NOWRITE, &ncid)) ERR;
diff --git a/nc_test4/tst_camrun.c b/nc_test4/tst_camrun.c
index 3038aa7..2ce9cbb 100644
--- a/nc_test4/tst_camrun.c
+++ b/nc_test4/tst_camrun.c
@@ -662,7 +662,6 @@
 #   define RANK_wat_a2 4
 #   define RANK_wat_a3 4
 
-#ifdef EXTRA_TESTS
 #define MEGABYTE 1048576
 void
 get_mem_used2(int *mem_used)
@@ -691,7 +690,6 @@ get_mem_used2(int *mem_used)
       *mem_used = -1;
   fclose(pf);
 }
-#endif
 
 int
 main()
@@ -2005,17 +2003,13 @@ main()
    int wat_a1_dims[RANK_wat_a1];
    int wat_a2_dims[RANK_wat_a2];
    int wat_a3_dims[RANK_wat_a3];
-#ifdef EXTRA_TESTS
    int memused;
-#endif /* EXTRA_TESTS */
 
    printf("\n*** Testing CAM output file in netCDF-4.\n");
    printf("*** creating file...");
 
-#ifdef EXTRA_TESTS
    get_mem_used2(&memused);
    printf("data memory %d MB\n", memused);
-#endif /* EXTRA_TESTS */
 
    if (nc_set_chunk_cache(0, 1009, .75)) ERR;
 
@@ -7389,26 +7383,20 @@ main()
    if (nc_put_att_text(ncid, wat_a3_id, "cell_methods", 10, "time: mean")) ERR;
 
 
-#ifdef EXTRA_TESTS
    get_mem_used2(&memused);
    printf("before enddef data memory %d MB\n", memused);
-#endif
 
    /* leave define mode */
    if (nc_enddef (ncid)) ERR;
 
-#ifdef EXTRA_TESTS
    get_mem_used2(&memused);
    printf("before close data memory %d MB\n", memused);
-#endif
 
    /* assign variable data */
    if (nc_close(ncid)) ERR;
 
-#ifdef EXTRA_TESTS
    get_mem_used2(&memused);
    printf("after close data memory %d MB\n", memused);
-#endif
 
    SUMMARIZE_ERR;
    FINAL_RESULTS;
diff --git a/nc_test4/tst_chunk_hdf4.c b/nc_test4/tst_chunk_hdf4.c
index 104e44b..f9edb22 100644
--- a/nc_test4/tst_chunk_hdf4.c
+++ b/nc_test4/tst_chunk_hdf4.c
@@ -3,6 +3,8 @@
    COPYRIGHT file for conditions of use.
 
    Test that NetCDF-4 can read HDF4 files.
+   
+   Dennis Heimbigner, Ward Fisher, Ed Hartnett
 */
 #include <config.h>
 #include <nc_tests.h>
@@ -32,9 +34,8 @@ main(int argc, char **argv)
    int d;
    int storage;
    size_t chunksizes[NC_MAX_VAR_DIMS];
-   const char* srcdir = ".";
 
-   printf("\n*** Testing HDF4/NetCDF-4 chunking API: chunked...\n");
+   printf("\n*** Testing HDF4/NetCDF-4 chunking API: chunked...");
    {
 
       /* Open with netCDF */
@@ -51,20 +52,21 @@ main(int argc, char **argv)
       if(nc_inq_var_chunking(ncid,varid,&storage,chunksizes)) ERR;
 
       if(storage == NC_CONTIGUOUS) {
-	fprintf(stderr,"nc_inq_var_chunking did not return CHUNKED\n");
-	ERR;
+         fprintf(stderr,"nc_inq_var_chunking did not return CHUNKED\n");
+         ERR;
       }
 
       for(d=0;d<rank;d++) {
-	if(EXPECTED_CHUNKSIZES[d] != chunksizes[d]) {
-	    fprintf(stderr,"chunk size mismatch: [%d] %ld :: %ld\n",d,chunksizes[d],EXPECTED_CHUNKSIZES[d]);
-	    ERR;
-	}
+         if(EXPECTED_CHUNKSIZES[d] != chunksizes[d]) {
+            fprintf(stderr,"chunk size mismatch: [%d] %ld :: %ld\n",d,chunksizes[d],EXPECTED_CHUNKSIZES[d]);
+            ERR;
+         }
       }
       if (nc_close(ncid)) ERR;
    }
+   SUMMARIZE_ERR;
 
-   printf("\n*** Testing HDF4/NetCDF-4 chunking API: contiguous...\n");
+   printf("*** Testing HDF4/NetCDF-4 chunking API: contiguous...");
    {
       /* Open with netCDF */
       if (nc_open(CONTIGFILE, NC_NOWRITE, &ncid)) ERR;
@@ -80,13 +82,23 @@ main(int argc, char **argv)
       if(nc_inq_var_chunking(ncid,varid,&storage,chunksizes)) ERR;
 
       if(storage != NC_CONTIGUOUS) {
-	fprintf(stderr,"nc_inq_var_chunking did not return CONTIGUOUS\n");
-	ERR;
+         fprintf(stderr,"nc_inq_var_chunking did not return CONTIGUOUS\n");
+         ERR;
       }
 
       if (nc_close(ncid)) ERR;
    }
+   SUMMARIZE_ERR;
+   printf("*** Testing HDF4/NetCDF-4 chunking API: contiguous...");
+   {
+      /* Open with netCDF */
+      if (nc_open(CONTIGFILE, 0, &ncid)) ERR;
 
+      if (nc_inq_varid(ncid, CONTIGVAR, &varid)) ERR;
+      if (nc_def_var_deflate(ncid, varid, 0, 1, 4) != NC_EPERM) ERR;
+
+      if (nc_close(ncid)) ERR;
+   }
    SUMMARIZE_ERR;
    FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_chunks.c b/nc_test4/tst_chunks.c
index 160d92c..2ae73bf 100644
--- a/nc_test4/tst_chunks.c
+++ b/nc_test4/tst_chunks.c
@@ -287,5 +287,46 @@ main(int argc, char **argv)
       if (nc_abort(ncid)) ERR;
    }
    SUMMARIZE_ERR;
+   printf("**** testing different chunksizes on an unlimited dimension with existing data...");
+   {
+#define D_UNLIM "unlimited_dim"
+#define V_UNLIM_ONE "unlimited_var_one"
+#define V_UNLIM_TWO "unlimited_var_two"
+    int ncid;
+    int unlim_dimid;
+    int first_unlim_varid;
+    int second_unlim_varid;
+    size_t first_chunks[1];
+    size_t second_chunks[1];
+    size_t start[1], count[1];
+    unsigned short first_data[2] = {0, 1}, second_data[3] = {2, 3, 4};
+
+    /* Create a netcdf4 file with 1 dimension. */
+    if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+    if (nc_def_dim(ncid, D_UNLIM, NC_UNLIMITED, &unlim_dimid)) ERR;
+
+    /* Add one var with one chunksize */
+    if (nc_def_var(ncid, V_UNLIM_ONE, NC_USHORT, NDIMS1, &unlim_dimid, &first_unlim_varid)) ERR;
+    first_chunks[0] = 2;
+    if (nc_def_var_chunking(ncid, first_unlim_varid, NC_CHUNKED, first_chunks)) ERR;
+
+    /* Add a record to the first variable. */
+    start[0] = 0;
+    count[0] = 1;
+    if (nc_put_vara(ncid, first_unlim_varid, start, count, first_data)) ERR;
+
+    /* Add second var with second chunksize */
+    if (nc_def_var(ncid, V_UNLIM_TWO, NC_USHORT, NDIMS1, &unlim_dimid, &second_unlim_varid)) ERR;
+    second_chunks[0] = 3;
+    if (nc_def_var_chunking(ncid, second_unlim_varid, NC_CHUNKED, second_chunks)) ERR;
+
+    /* Add a record to the second variable. */
+    start[0] = 0;
+    count[0] = 2;
+    if (nc_put_vara(ncid, second_unlim_varid, start, count, second_data)) ERR;
+
+    if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
    FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_compounds.c b/nc_test4/tst_compounds.c
index 79ce911..d1601d6 100644
--- a/nc_test4/tst_compounds.c
+++ b/nc_test4/tst_compounds.c
@@ -4,7 +4,7 @@
 
    Test netcdf-4 compound type feature.
 
-   $Id: tst_compounds.c,v 1.45 2010/05/25 13:53:03 ed Exp $
+   Ed Hartnett
 */
 
 #include <config.h>
@@ -56,6 +56,12 @@ main(int argc, char **argv)
 			     NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR;
       if (nc_insert_compound(ncid, typeid, DATES_WITH_ALIENS,
 			     NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR;
+
+      /* This won't work due to bad typeid. */
+      if (nc_def_var(ncid, SERVICE_RECORD, typeid + TEST_VAL_42, 0, NULL,
+                     &varid) != NC_EBADTYPE) ERR;
+
+      /* Define the variable. */
       if (nc_def_var(ncid, SERVICE_RECORD, typeid, 0, NULL, &varid)) ERR;
       if (nc_put_var(ncid, varid, &data)) ERR;
       if (nc_close(ncid)) ERR;
diff --git a/nc_test4/tst_converts.c b/nc_test4/tst_converts.c
index 183da06..b6cb74b 100644
--- a/nc_test4/tst_converts.c
+++ b/nc_test4/tst_converts.c
@@ -22,25 +22,59 @@
 #define VAR2_NAME "var2"
 
 /* This is handy for print statements. */
-static char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4",
-			      "netCDF-4 classic model"};
+static char *format_name[MAX_NUM_FORMATS] = {"classic", "64-bit offset", "netCDF-4",
+                                             "netCDF-4 classic model", "CDF5"};
 
 int check_file(int format, unsigned char *uchar_out);
 int create_file(int format, unsigned char *uchar_out);
 
+/* Determine how many formats are available, and what they are. */
+void
+determine_test_formats(int *num_formats, int *format)
+{
+   int ind = 0;
+   int num;
+
+   /* Check inputs. */
+   assert(num_formats && format);
+
+   /* We always have classic and 64-bit offset */
+   num = 2;
+   format[ind++] = NC_FORMAT_CLASSIC;
+   format[ind++] = NC_FORMAT_64BIT_OFFSET;
+
+   /* Do we have netCDF-4 and netCDF-4 classic? */
+#ifdef USE_NETCDF4
+   num += 2;
+   format[ind++] = NC_FORMAT_NETCDF4_CLASSIC;
+   format[ind++] = NC_FORMAT_NETCDF4;
+#endif /* USE_NETCDF4 */
+
+   /* Do we have CDF5? */
+#ifdef ENABLE_CDF5
+   num++;
+   format[ind++] = NC_FORMAT_CDF5;
+#endif /* ENABLE_CDF5 */
+
+   *num_formats = num;
+}
+
 int
 main(int argc, char **argv)
 {
    unsigned char uchar_out[DIM1_LEN] = {0, 128, 255};
-   int format;
+   int format[MAX_NUM_FORMATS];
+   int num_formats;
+   int f = 0;
 
    printf("\n*** Testing netcdf data conversion.\n");
+   determine_test_formats(&num_formats, format);
 
-   for (format = 1; format < 5; format++)
+   for (f = 0; f < num_formats; f++)
    {
-      printf("*** Testing conversion in netCDF %s files... ", format_name[format]);
-      create_file(format, uchar_out);
-      check_file(format, uchar_out);
+      printf("*** Testing conversion in netCDF %s files... ", format_name[f]);
+      create_file(format[f], uchar_out);
+      check_file(format[f], uchar_out);
       SUMMARIZE_ERR;
    }
 
@@ -72,7 +106,7 @@ create_file(int format, unsigned char *uchar_out)
    retval = nc_put_var_uchar(ncid, varid, uchar_out);
    if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
    {
-     if (retval != NC_ERANGE) ERR;
+      if (retval != NC_ERANGE) ERR;
    }
    else if (retval != NC_NOERR) ERR;
 
@@ -83,7 +117,6 @@ create_file(int format, unsigned char *uchar_out)
 int
 check_file(int format, unsigned char *uchar_out)
 {
-
    int ncid;
    int ndims, natts;
    int dimids_var[1], var_type;
@@ -116,19 +149,35 @@ check_file(int format, unsigned char *uchar_out)
    else if (res) ERR;
 
    for (i=0; i<DIM1_LEN; i++)
+#ifdef ERANGE_FILL
+      if (uchar_in[i] != uchar_out[i] && uchar_in[i] != NC_FILL_UBYTE) ERR;
+#else
       if (uchar_in[i] != uchar_out[i]) ERR;
+#endif
 
    if (nc_get_var_schar(ncid, 0, char_in)) ERR;
    for (i=0; i<DIM1_LEN; i++)
+#ifdef ERANGE_FILL
+      if (char_in[i] != (signed char)uchar_out[i] && char_in[i] != NC_FILL_BYTE) ERR;
+#else
       if (char_in[i] != (signed char)uchar_out[i]) ERR;
+#endif
 
    if (nc_get_var_short(ncid, 0, short_in)) ERR;
    for (i=0; i<DIM1_LEN; i++)
+#ifdef ERANGE_FILL
+      if (short_in[i] != (signed char)uchar_out[i] && short_in[i] != NC_FILL_BYTE) ERR;
+#else
       if (short_in[i] != (signed char)uchar_out[i]) ERR;
+#endif
 
    if (nc_get_var_int(ncid, 0, int_in)) ERR;
    for (i=0; i<DIM1_LEN; i++)
+#ifdef ERANGE_FILL
+      if (int_in[i] != (signed char)uchar_out[i] && int_in[i] != NC_FILL_BYTE) ERR;
+#else
       if (int_in[i] != (signed char)uchar_out[i]) ERR;
+#endif
 
    if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC)
    {
diff --git a/nc_test4/tst_create_files.c b/nc_test4/tst_create_files.c
index 2d0b5fc..cc6bf39 100644
--- a/nc_test4/tst_create_files.c
+++ b/nc_test4/tst_create_files.c
@@ -23,7 +23,6 @@ main(int argc, char **argv)
 {
     int nc_argc = argc;
     int nc_argv = argv;
-    nc_initialize();
 
     printf("\n*** Create some files for testing benchmarks.\n");
 
@@ -301,6 +300,5 @@ main(int argc, char **argv)
     }
     SUMMARIZE_ERR;
 
-    nc_finalize();
     FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_dims3.c b/nc_test4/tst_dims3.c
index e1ae65a..8b1f51a 100644
--- a/nc_test4/tst_dims3.c
+++ b/nc_test4/tst_dims3.c
@@ -109,8 +109,8 @@ nc_set_log_level(0);
    printf("*** testing defining dimensions and coord variables in different orders in root group...");
    {
        int ncid, grpid, grp2id;
-       int time_dimid, lev_dimid, vrt_dimid, g2lev_dimid, g2vrt_dimid;
-       int time_dimid_in, lev_dimid_in, vrt_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
+       int time_dimid, lev_dimid, g2lev_dimid, g2vrt_dimid;
+       int time_dimid_in, lev_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
        int time_varid, lev_varid, gvar2_varid, g2lev_varid, g2vrt_varid;
        int var2_dims[VAR2_RANK];
       /* Create test for fix of bug that resulted in two dimensions
@@ -156,8 +156,8 @@ nc_set_log_level(0);
    printf("*** testing defining dimensions and coord variables in different orders in subgroup...");
    {
        int ncid, grpid, grp2id;
-       int time_dimid, lev_dimid, vrt_dimid, g2lev_dimid, g2vrt_dimid;
-       int time_dimid_in, lev_dimid_in, vrt_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
+       int time_dimid, lev_dimid, g2lev_dimid, g2vrt_dimid;
+       int time_dimid_in, lev_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
        int time_varid, lev_varid, gvar2_varid, g2lev_varid, g2vrt_varid;
        int var2_dims[VAR2_RANK];
       /* Create test for fix of bug inside a subgroup that results in two dimensions
diff --git a/nc_test4/tst_empty_vlen_unlim.c b/nc_test4/tst_empty_vlen_unlim.c
index 6c2f0a5..af1627e 100644
--- a/nc_test4/tst_empty_vlen_unlim.c
+++ b/nc_test4/tst_empty_vlen_unlim.c
@@ -82,6 +82,7 @@ int main() {
 
     printf("\t* Puting data in secondary variable:\tnc_put_vara().\n");
     if (nc_put_vara(ncid,varid2,startp2,countp2,data2)) ERR;
+    free(data2);
 
     /***********/
     /* Actually unnecessary to recreate the issue. */
@@ -112,18 +113,17 @@ int main() {
     data[2].p = dat2;
     data[2].len = VLEN2;
 
-    //printf("\t* Puting data in VLEN variable:\tnc_put_vara().\n");
-    //stat = nc_put_vara(ncid,varid,&startp,&countp,data);
-    //stat = nc_put_var(ncid,varid,&data);
-    //if(stat) ERR;
-
-
+    printf("\t* Puting data in VLEN variable:\tnc_put_vara().\n");
+    stat = nc_put_vara(ncid,varid,startp,countp,data);
+    if(stat) ERR;
 
     /* Close File. */
     printf("\t* Closing file:\tnc_close().\n");
     if ((stat = nc_close(ncid))) ERR;
 
-
+    free(dat0);
+    free(dat1);
+    free(dat2);
   }
 
   printf("Testing access to unset entries in VLEN variable, unlimit dimension\n");
@@ -174,6 +174,7 @@ int main() {
 
     printf("\t* Puting data in secondary variable:\tnc_put_vara().\n");
     if (nc_put_vara(ncid,varid2,startp2,countp2,data2)) ERR;
+    free(data2);
 
     /***********/
     /* Actually unnecessary to recreate the issue. */
@@ -204,21 +205,18 @@ int main() {
     data[2].p = dat2;
     data[2].len = VLEN2;
 
-    //printf("\t* Puting data in VLEN variable:\tnc_put_vara().\n");
-    //stat = nc_put_vara(ncid,varid,&startp,&countp,data);
-    //stat = nc_put_var(ncid,varid,&data);
-    //if(stat) ERR;
-
-
+    printf("\t* Puting data in VLEN variable:\tnc_put_vara().\n");
+    stat = nc_put_vara(ncid,varid,startp,countp,data);
+    if(stat) ERR;
 
     /* Close File. */
     printf("\t* Closing file:\tnc_close().\n");
     if ((stat = nc_close(ncid))) ERR;
-
-
+    free(dat0);
+    free(dat1);
+    free(dat2);
   }
 
-
   SUMMARIZE_ERR;
   FINAL_RESULTS;
 
diff --git a/nc_test4/tst_enums.c b/nc_test4/tst_enums.c
index 873800f..34c2021 100644
--- a/nc_test4/tst_enums.c
+++ b/nc_test4/tst_enums.c
@@ -284,6 +284,7 @@ main(int argc, char **argv)
    SUMMARIZE_ERR;
    printf("*** testing enum interuptus...");
    {
+      unsigned char ubyte_value = 42;
 #define GEEKY_NAME "Galadriel"
 
       /* Create a file. */
@@ -304,8 +305,12 @@ main(int argc, char **argv)
       /* Close the file. */
       if (nc_close(ncid) != NC_EINVAL) ERR;
 
+      if (nc_redef(ncid)) ERR;
+      if (nc_insert_enum(ncid, typeid, "name", &ubyte_value)) ERR;
+      if (nc_close(ncid)) ERR;      
    }
 
    SUMMARIZE_ERR;
    FINAL_RESULTS;
 }
+
diff --git a/nc_test4/tst_files.c b/nc_test4/tst_files.c
index 1fe342c..2d60c24 100644
--- a/nc_test4/tst_files.c
+++ b/nc_test4/tst_files.c
@@ -2,12 +2,11 @@
    Copyright 2005 University Corporation for Atmospheric Research/Unidata
    See COPYRIGHT file for conditions of use.
 
-   Test internal netcdf-4 file code.
-   $Id: tst_files.c,v 1.42 2010/05/18 12:30:05 ed Exp $
+   Test netcdf-4 file code.
+   Ed Hartnett
 */
 
 #include <config.h>
-#include "netcdf.h"
 #include <nc_tests.h>
 #include "err_macros.h"
 
@@ -53,10 +52,14 @@ main(int argc, char **argv)
       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
       if (nc_close(ncid)) ERR;
 
+      /* This will fail. */
       if (nc_open(FILE_NAME, NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
 
+      /* These will all fail due to incorrect mode flag combinations. */
       if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_NETCDF4, &ncid) != NC_EINVAL) ERR;
       if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
+      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CDF5, &ncid) != NC_EINVAL) ERR;
+      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CDF5, &ncid) != NC_EINVAL) ERR;
       if (nc_create(FILE_NAME, NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
    }
    SUMMARIZE_ERR;
@@ -147,7 +150,7 @@ main(int argc, char **argv)
       if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
       if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
       if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_BYTE ||
-	  dimids_var[0] != dimids[0] || natts != 0) ERR;
+          dimids_var[0] != dimids[0] || natts != 0) ERR;
       if (nc_close(ncid)) ERR;
 
       /* Recreate the file. */
@@ -206,7 +209,7 @@ main(int argc, char **argv)
       if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
       if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
       if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
-	  dimids_var[0] != dimids[0] || natts != 0) ERR;
+          dimids_var[0] != dimids[0] || natts != 0) ERR;
       if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
@@ -244,10 +247,10 @@ main(int argc, char **argv)
       if (dim_len != DIM2_LEN || strcmp(dim_name, DIM2_NAME)) ERR;
       if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
       if (ndims != 2 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
-	  dimids_var[0] != dimids[0] || natts != 0) ERR;
+          dimids_var[0] != dimids[0] || natts != 0) ERR;
       if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
       if (ndims != 2 || strcmp(var_name, VAR2_NAME) || var_type != NC_UINT ||
-	  dimids_var[1] != dimids[1] || natts != 0) ERR;
+          dimids_var[1] != dimids[1] || natts != 0) ERR;
       if (nc_get_att_float(ncid, NC_GLOBAL, ATT1_NAME, &float_in)) ERR;
       if (float_in != float_out) ERR;
       if (nc_get_att_int(ncid, NC_GLOBAL, ATT2_NAME, &int_in)) ERR;
@@ -262,12 +265,22 @@ main(int argc, char **argv)
    printf("*** testing redef for netCDF 64-bit offset...");
    test_redef(NC_FORMAT_64BIT_OFFSET);
    SUMMARIZE_ERR;
+
+#ifdef USE_NETCDF4
    printf("*** testing redef for netCDF-4 ...");
    test_redef(NC_FORMAT_NETCDF4);
    SUMMARIZE_ERR;
    printf("*** testing redef for netCDF-4, with strict netCDF-3 rules...");
    test_redef(NC_FORMAT_NETCDF4_CLASSIC);
    SUMMARIZE_ERR;
+#endif /* USE_NETCDF4 */
+
+#ifdef ENABLE_CDF5
+   printf("*** testing redef for CDF5...");
+   test_redef(NC_FORMAT_CDF5);
+   SUMMARIZE_ERR;
+#endif /* ENABLE_CDF5 */
+
    printf("*** testing different formats...");
    {
       int ncid;
@@ -285,11 +298,14 @@ main(int argc, char **argv)
       if (format != NC_FORMAT_64BIT_OFFSET) ERR;
       if (nc_close(ncid)) ERR;
 
+      
+#ifdef USE_NETCDF4
       /* Create a netcdf-4 file. */
       if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
       if (nc_inq_format(ncid, &format)) ERR;
       if (format != NC_FORMAT_NETCDF4) ERR;
       if (nc_close(ncid)) ERR;
+#endif /* USE_NETCDF4 */
    }
    SUMMARIZE_ERR;
    printf("*** testing CLASSIC_MODEL flag with classic formats...");
@@ -310,6 +326,7 @@ main(int argc, char **argv)
       if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
+#ifdef USE_NETCDF4
    printf("*** testing multiple open files...");
    {
 #define VAR_NAME "Captain_Kirk"
@@ -329,32 +346,34 @@ main(int argc, char **argv)
       /* Create a bunch of files. */
       for (f = 0; f < NUM_FILES; f++)
       {
-	 sprintf(file_name, "tst_files2_%d.nc", f);
-	 if (nc_create(file_name, NC_NETCDF4, &ncid[f])) ERR;
-	 if (nc_def_dim(ncid[f], D1_NAME, TEXT_LEN + 1, &dimid)) ERR;
-	 if (nc_def_var(ncid[f], VAR_NAME, NC_CHAR, NDIMS, &dimid, &varid)) ERR;
-	 if (f % 2 == 0)
-	    if (nc_def_var_chunking(ncid[f], varid, 0, chunks)) ERR;
-
-	 /* Write one time to the coordinate variable. */
-	 count[0] = TEXT_LEN + 1;
-	 if (nc_put_vara_text(ncid[f], varid, index, count, ttext)) ERR;
+         sprintf(file_name, "tst_files2_%d.nc", f);
+         if (nc_create(file_name, NC_NETCDF4, &ncid[f])) ERR;
+         if (nc_def_dim(ncid[f], D1_NAME, TEXT_LEN + 1, &dimid)) ERR;
+         if (nc_def_var(ncid[f], VAR_NAME, NC_CHAR, NDIMS, &dimid, &varid)) ERR;
+         if (f % 2 == 0)
+            if (nc_def_var_chunking(ncid[f], varid, 0, chunks)) ERR;
+
+         /* Write one time to the coordinate variable. */
+         count[0] = TEXT_LEN + 1;
+         if (nc_put_vara_text(ncid[f], varid, index, count, ttext)) ERR;
       }
 
       /* Read something from each file. */
       for (f = 0; f < NUM_FILES; f++)
       {
-	 if (nc_get_vara_text(ncid[f], varid, index, count, (char *)ttext_in)) ERR;
-	 if (strcmp(ttext_in, ttext)) ERR;
+         if (nc_get_vara_text(ncid[f], varid, index, count, (char *)ttext_in)) ERR;
+         if (strcmp(ttext_in, ttext)) ERR;
       }
 
       /* Close all open files. */
       for (f = 0; f < NUM_FILES; f++)
-	 if (nc_close(ncid[f])) ERR;
+         if (nc_close(ncid[f])) ERR;
    }
    SUMMARIZE_ERR;
+#endif /* USE_NETCDF4 */
    FINAL_RESULTS;
 }
+
 #define REDEF_ATT1_NAME "CANTERBURY"
 #define REDEF_ATT2_NAME "ELY"
 #define REDEF_ATT3_NAME "KING_HENRY_V"
@@ -407,14 +426,14 @@ test_redef(int format)
 
    /* Change chunk cache. */
    if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS,
-			  NEW_CACHE_PREEMPTION)) ERR;
+                          NEW_CACHE_PREEMPTION)) ERR;
 
    /* Create a file with two dims, two vars, and two atts. */
    if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR;
 
    /* Retrieve the chunk cache settings, just for fun. */
    if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in,
-			  &cache_preemption_in)) ERR;
+                          &cache_preemption_in)) ERR;
    if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS ||
        cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;
 
@@ -422,7 +441,7 @@ test_redef(int format)
     * name. */
    if (format != NC_FORMAT_NETCDF4)
       if (nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN,
-			    &dimids[1]) != NC_EBADNAME) ERR;
+                     &dimids[1]) != NC_EBADNAME) ERR;
 
    if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR;
    if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR;
@@ -459,15 +478,15 @@ test_redef(int format)
 
    /* This will fail. */
    ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS,
-			  dimids, &varid);
+                    dimids, &varid);
    if(format == NC_FORMAT_NETCDF4) {
-	if(ret != NC_EPERM) {
-	    ERR;
-	}
+      if(ret != NC_EPERM) {
+         ERR;
+      }
    } else {
-	if(ret != NC_ENOTINDEFINE) {
-	    ERR;
-	}
+      if(ret != NC_ENOTINDEFINE) {
+         ERR;
+      }
    }
    /* This will fail. */
    if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR;
diff --git a/nc_test4/tst_files4.c b/nc_test4/tst_files4.c
index 55fb289..a83523a 100644
--- a/nc_test4/tst_files4.c
+++ b/nc_test4/tst_files4.c
@@ -105,7 +105,6 @@ main() {/* create data.nc */
        if (nc_close(ncid)) ERR;
     }
     SUMMARIZE_ERR;
-#ifdef EXTRA_TESTS
     printf("*** testing opening of many files...");
     {
        int i, ncid;
@@ -121,6 +120,5 @@ main() {/* create data.nc */
        /*printf("last ncid: %d\n", ncid);*/
     }
     SUMMARIZE_ERR;
-#endif
     FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_files5.c b/nc_test4/tst_files5.c
index dbfff6f..e6dd57f 100644
--- a/nc_test4/tst_files5.c
+++ b/nc_test4/tst_files5.c
@@ -9,7 +9,7 @@
 #include "err_macros.h"
 #include "netcdf.h"
 
-#define FILE_NAME "tst_files.nc"
+#define FILE_NAME "tst_files5.nc"
 
 int
 main(int argc, char **argv)
diff --git a/nc_test4/tst_fill_attr_vanish.c b/nc_test4/tst_fill_attr_vanish.c
index 511d41e..189d20b 100644
--- a/nc_test4/tst_fill_attr_vanish.c
+++ b/nc_test4/tst_fill_attr_vanish.c
@@ -34,20 +34,11 @@
 int main()
 {
   int ncid, dimids[RANK_P], time_id, p_id, test_id, status;
-  int ndims, dimids_in[RANK_P];
-
   int test_data[1] = {1};
   size_t test_start[1] = {0}, test_count[1] = {1};
   int test_fill_val[] = {5};
-
-
   double data[1] = {3.14159};
   size_t start[1] = {0}, count[1] = {1};
-  float ddata[1][4][3];
-  static float P_data[LEN];
-  size_t cor[RANK_P] = {0, 1, 0};
-  size_t edg[RANK_P] = {1, 1, LEN};
-  float pfills[] = {3};
 
   printf("\n*** Testing for a netCDF-4 fill-value bug.\n");
   printf("*** Creating a file with no _FillValue defined. ***\n");
diff --git a/nc_test4/tst_fills2.c b/nc_test4/tst_fills2.c
index 0ae26cd..323e5d0 100644
--- a/nc_test4/tst_fills2.c
+++ b/nc_test4/tst_fills2.c
@@ -283,7 +283,7 @@ main(int argc, char **argv)
       for (i = 0; i < DATA_START2; i++)
 	 if (strcmp(data_in[i], missing_val[0])) ERR;
       if (strcmp(data_in[DATA_START2], data_out[0])) ERR;
-      if (nc_free_string(DATA_START + 1, data_in)) ERR;
+      if (nc_free_string(DATA_START2 + 1, data_in)) ERR;
 
       /* Close everything up. */
       if (nc_close(ncid)) ERR;
diff --git a/nc_test4/tst_filter.sh b/nc_test4/tst_filter.sh
new file mode 100755
index 0000000..2accb83
--- /dev/null
+++ b/nc_test4/tst_filter.sh
@@ -0,0 +1,146 @@
+#!/bin/bash
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../test_common.sh
+
+# Which test cases to exercise
+API=1
+NG=1
+NCP=1
+UNK=1
+NGC=1
+MISC=1
+
+# Load the findplugins function
+. ${builddir}/findplugin.sh
+echo "findplugin.sh loaded"
+
+# Function to remove selected -s attributes from file;
+# These attributes might be platform dependent
+sclean() {
+cat $1 \
+  | sed -e '/var:_Endianness/d' \
+  | sed -e '/_NCProperties/d' \
+  | sed -e '/_SuperblockVersion/d' \
+  | sed -e '/_IsNetcdf4/d' \
+  | cat > $2
+}
+
+# Function to extract _Filter attribute from a file
+# These attributes might be platform dependent
+getfilterattr() {
+sed -e '/var:_Filter/p' -ed <$1 >$2
+}
+
+trimleft() {
+sed -e 's/[ 	]*\([^ 	].*\)/\1/' <$1 >$2
+}
+
+# Locate the plugin path and the library names; argument order is critical
+# Find bzip2 and capture
+findplugin bzip2
+BZIP2PATH="${HDF5_PLUGIN_PATH}/${HDF5_PLUGIN_LIB}"
+# Find misc and capture
+findplugin misc
+MISCPATH="${HDF5_PLUGIN_PATH}/${HDF5_PLUGIN_LIB}"
+
+echo "final HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}"
+export HDF5_PLUGIN_PATH
+
+# Verify
+if ! test -f ${BZIP2PATH} ; then echo "Unable to locate ${BZIP2PATH}"; exit 1; fi
+if ! test -f ${MISCPATH} ; then echo "Unable to locate ${MISCPATH}"; exit 1; fi
+
+# Execute the specified tests
+
+if test "x$API" = x1 ; then
+echo "*** Testing dynamic filters using API"
+rm -f ./bzip2.nc ./bzip2.dump ./tmp
+${execdir}/test_filter
+${NCDUMP} -s bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp ./bzip2.dump
+diff -b -w ${srcdir}/bzip2.cdl ./bzip2.dump
+echo "*** Pass: API dynamic filter"
+fi
+
+if test "x$MISC" = x1 ; then
+echo
+echo "*** Testing dynamic filters parameter passing"
+rm -f ./testmisc.nc tmp tmp2
+${execdir}/test_filter_misc
+# Verify the parameters via ncdump
+${NCDUMP} -s testmisc.nc > ./tmp
+# Extract the parameters
+getfilterattr ./tmp ./tmp2
+rm -f ./tmp
+trimleft ./tmp2 ./tmp
+rm -f ./tmp2
+cat >./tmp2 <<EOF
+var:_Filter = "32768,1,239,23,65511,27,77,93,1145389056,3287505826,1097305129,1,2147483648,4294967295,4294967295" ;
+EOF
+diff -b -w ./tmp ./tmp2
+echo "*** Pass: parameter passing"
+fi
+
+if test "x$NG" = x1 ; then
+echo "*** Testing dynamic filters using ncgen"
+rm -f ./bzip2.nc ./bzip2.dump ./tmp
+${NCGEN} -lb -4 -o bzip2.nc ${srcdir}/bzip2.cdl
+${NCDUMP} -s bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp ./bzip2.dump
+diff -b -w ${srcdir}/bzip2.cdl ./bzip2.dump
+echo "*** Pass: ncgen dynamic filter"
+fi
+
+if test "x$NCP" = x1 ; then
+echo "*** Testing dynamic filters using nccopy"
+rm -f ./unfiltered.nc ./filtered.nc ./filtered.dump ./tmp
+${NCGEN} -4 -lb -o unfiltered.nc ${srcdir}/unfiltered.cdl
+${NCCOPY} -F "/g/var,307,9,4" unfiltered.nc filtered.nc
+${NCDUMP} -s filtered.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp ./filtered.dump
+diff -b -w ${srcdir}/filtered.cdl ./filtered.dump
+echo "*** Pass: nccopy dynamic filter"
+fi
+
+if test "x$UNK" = x1 ; then
+echo "*** Testing access to filter info when filter dll is not available"
+rm -f bzip2.nc ./tmp
+# build bzip2.nc
+${NCGEN} -lb -4 -o bzip2.nc ${srcdir}/bzip2.cdl
+# dump and clean bzip2.nc header only when filter is avail
+${NCDUMP} -hs bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp bzip2.dump
+# Now hide the filter code
+mv ${BZIP2PATH} ${BZIP2PATH}.save
+# dump and clean bzip2.nc header only when filter is not avail
+rm -f ./tmp
+${NCDUMP} -hs bzip2.nc > ./tmp
+# Remove irrelevant -s output
+sclean ./tmp bzip2x.dump
+# Restore the filter code
+mv ${BZIP2PATH}.save ${BZIP2PATH}
+diff -b -w ./bzip2.dump ./bzip2x.dump
+echo "*** Pass: ncgen dynamic filter"
+fi
+
+if test "x$NGC" = x1 ; then
+rm -f ./test_bzip2.c
+echo "*** Testing dynamic filters using ncgen with -lc"
+${NCGEN} -lc -4 ${srcdir}/bzip2.cdl > test_bzip2.c
+diff -b -w ${srcdir}/ref_bzip2.c ./test_bzip2.c
+echo "*** Pass: ncgen dynamic filter"
+fi
+
+#cleanup
+rm -f ./bzip*.nc ./unfiltered.nc ./filtered.nc ./tmp ./tmp2 *.dump bzip*hdr.*
+rm -fr ./test_bzip2.c
+rm -fr ./testmisc.nc
+
+echo "*** Pass: all selected tests passed"
+
+exit 0
diff --git a/nc_test4/tst_filterparser.c b/nc_test4/tst_filterparser.c
new file mode 100644
index 0000000..16226ac
--- /dev/null
+++ b/nc_test4/tst_filterparser.c
@@ -0,0 +1,194 @@
+/*
+  Copyright 2008, UCAR/Unidata
+  See COPYRIGHT file for copying and redistribution conditions.
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "netcdf.h"
+#include "ncfilter.h"
+
+#define PARAMS_ID 32768
+
+#if defined  _MSC_VER || defined __APPLE__
+#define DBLVAL 12345678.12345678
+#else
+#define DBLVAL 12345678.12345678d
+#endif
+
+#define MAXPARAMS 32
+#define NPARAMS 16 /* # of unsigned ints in params */
+
+static unsigned int baseline[NPARAMS];
+	
+/* Expected contents of baseline:
+id = 32768
+params = 4294967279, 23, 4294967271, 27, 77, 93, 1145389056, 3287505826, 1097305129, 1, 2147483648, 4294967295, 4294967295
+*/
+
+static const char* spec = 
+"32768, -17b, 23ub, -25S, 27US, 77, 93U, 789f, 12345678.12345678d, -9223372036854775807L, 18446744073709551615UL, 2147483647, -2147483648, 4294967295";
+
+
+/* Test support for the conversions */
+/* Not sure if this kind of casting via union is legal C99 */
+static union {
+    unsigned int ui;
+    float f;
+} uf;
+
+static union {
+    unsigned int ui[2];
+    double d;
+} ud;
+
+static union {
+    unsigned int ui[2];
+    unsigned long long ull;
+    long long ll;
+} ul;
+
+static int nerrs = 0;
+
+static void
+mismatch(size_t i, unsigned int *params, const char* tag)
+{
+    fprintf(stderr,"mismatch: %s [%d] baseline=%ud params=%u\n",tag,(int)i,baseline[i],params[i]);
+    fflush(stderr);
+    nerrs++;
+}
+
+static void
+mismatch2(size_t i, unsigned int *params, const char* tag)
+{
+    fprintf(stderr,"mismatch2: %s [%d-%d] baseline=%ud,%ud params=%u,%u\n",
+	tag,(int)i,i+1,baseline[i],baseline[i+1],params[i],params[i+1]);
+    fflush(stderr);
+    nerrs++;
+}
+
+static void
+insert(int index, void* src, size_t size)
+{
+    void* dst = &baseline[index];
+    memcpy(dst,src,size);
+}
+
+static void
+buildbaseline(void)
+{
+    unsigned int val4;
+    unsigned long long val8;
+    float float4;
+    double float8;
+
+    val4 = ((unsigned int)-17) & 0xff;
+    insert(0,&val4,sizeof(val4)); /* 0 signed int*/
+    val4 = (unsigned int)23;
+    insert(1,&val4,sizeof(val4)); /* 1 unsigned int*/
+    val4 = ((unsigned int)-25) & 0xffff;
+    insert(2,&val4,sizeof(val4)); /* 3 signed int*/
+    val4 = (unsigned int)27;
+    insert(3,&val4,sizeof(val4)); /* 4 unsigned int*/
+    val4 = (unsigned int)77;
+    insert(4,&val4,sizeof(val4)); /* 4 signed int*/
+    val4 = (unsigned int)93;
+    insert(5,&val4,sizeof(val4)); /* 5 unsigned int*/
+    float4 = 789.0f;
+    insert(6,&float4,sizeof(float4)); /* 6 float */
+    float8 = DBLVAL;
+    insert(7,&float8,sizeof(float8)); /* 7 double */
+    val8 = -9223372036854775807L;
+    insert(9,&val8,sizeof(val8)); /* 9 signed long long */
+    val8 = 18446744073709551615UL;
+    insert(11,&val8,sizeof(val8)); /* 11 unsigned long long */
+    val4 = 2147483647;
+    insert(13,&val4,sizeof(val4)); /* 13 signed int */
+    val4 = -2147483648;
+    insert(14,&val4,sizeof(val4)); /* 14 signed int */
+    val4 = 4294967295;
+    insert(15,&val4,sizeof(val4)); /* 15 unsigned int */
+}
+
+/**************************************************/
+int
+main(int argc, char **argv)
+{
+    int stat = 0;
+    unsigned int id = 0;
+    size_t i,nparams = 0;
+    unsigned int* params = NULL;
+
+    printf("\nTesting filter parser.\n");
+
+    buildbaseline(); /* Build our comparison vector */
+
+    stat = NC_parsefilterspec(spec,&id,&nparams,&params);
+    if(stat) {
+	fprintf(stderr,"NC_parsefilterspec failed\n");
+	exit(1);
+    }
+    if(id != PARAMS_ID)
+        fprintf(stderr,"mismatch: id: expected=%u actual=%u\n",PARAMS_ID,id);
+    for(i=0;i<nparams;i++) {
+	if(baseline[i] != params[i])
+	    mismatch(i,params,"N.A.");
+    }
+    /* Now some specialized tests */
+    uf.ui = params[6];
+    if(uf.f != (float)789.0)
+	mismatch(6,params,"uf.f");
+    ud.ui[0] = params[7];
+    ud.ui[1] = params[8];
+#ifdef WORD_BIGENDIAN
+    byteswap8((unsigned char*)&ud.d);
+#endif
+    if(ud.d != DBLVAL)
+	mismatch2(7,params,"ud.d");
+    ul.ui[0] = params[9];
+    ul.ui[1] = params[10];
+#ifdef WORD_BIGENDIAN
+    byteswap8((unsigned char*)&ul.ll);
+#endif
+    if(ul.ll != -9223372036854775807LL)
+	mismatch2(9,params,"ul.ll");
+    ul.ui[0] = params[11];
+    ul.ui[1] = params[12];
+#ifdef WORD_BIGENDIAN
+    byteswap8((unsigned char*)&ul.ull);
+#endif
+    if(ul.ull != 18446744073709551615ULL)
+	mismatch2(11,params,"ul.ull");
+
+    if (params)
+       free(params);
+
+    if (!nerrs)
+       printf("SUCCESS!!\n");
+
+    return (nerrs > 0 ? 1 : 0);
+}
+
+#ifdef WORD_BIGENDIAN
+/* Byte swap an 8-byte integer in place */
+static void
+byteswap8(unsigned char* mem)
+{
+    unsigned char c;
+    c = mem[0];
+    mem[0] = mem[7];
+    mem[7] = c;
+    c = mem[1];
+    mem[1] = mem[6];
+    mem[6] = c;
+    c = mem[2];
+    mem[2] = mem[5];
+    mem[5] = c;
+    c = mem[3];
+    mem[3] = mem[4];
+    mem[4] = c;
+}
+#endif
diff --git a/nc_test4/tst_formatx_hdf4.sh b/nc_test4/tst_formatx_hdf4.sh
index e954d3e..f008fe3 100755
--- a/nc_test4/tst_formatx_hdf4.sh
+++ b/nc_test4/tst_formatx_hdf4.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 # This shell script tests the output several previous tests.
-# $Id: tst_output.sh,v 1.17 2010/05/14 16:21:15 ed Exp $
+# Ed Hartnett
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 . ../test_common.sh
@@ -13,16 +13,19 @@ echo ""
 echo "*** Testing extended file format output."
 set -e
 
+echo "Creating HDF4 file"
+${execdir}/tst_interops2
+
 echo "Test extended format output for a HDF4 file"
-rm -f tmp
-${NCDUMP} -K $FILE >tmp
-if ! fgrep 'HDF4 mode=00001000' <tmp ; then
-TMP=`cat tmp`
+rm -f tmp_tst_formatx_hdf4
+${NCDUMP} -K $FILE >tmp_tst_formatx_hdf4
+if ! fgrep 'HDF4 mode=00001000' <tmp_tst_formatx_hdf4 ; then
+TMP=`cat tmp_tst_formatx_hdf4`
 echo "*** Fail: extended format for an HDF4 file: result=" $TMP
 ECODE=1
 fi
 
-rm -f tmp
+rm -f tmp_tst_formatx_hdf4
 
 exit $ECODE
 
diff --git a/nc_test4/tst_grps.c b/nc_test4/tst_grps.c
index 2cadc03..a404214 100644
--- a/nc_test4/tst_grps.c
+++ b/nc_test4/tst_grps.c
@@ -3,7 +3,8 @@
    See COPYRIGHT file for conditions of use.
 
    Test netcdf-4 group code.
-   $Id: tst_grps.c,v 1.37 2010/04/07 15:21:28 ed Exp $
+
+   Ed Hartnett
 */
 
 #include <nc_tests.h>
@@ -11,13 +12,17 @@
 #include "netcdf.h"
 
 #define FILE_NAME "tst_grps.nc"
+#define FILE_NAME_CLASSIC "tst_grps_classic.nc"
+#define FILE_NAME_CLASSIC_MODEL "tst_grps_classic_model.nc"
 #define DIM1_NAME "kingdom"
 #define DIM1_LEN 3
 #define DIM2_NAME "year"
 #define DIM2_LEN 5
 #define VAR1_NAME "Number_of_Beheadings_in_Family"
 #define DYNASTY "Tudor"
+#define HENRY_IV "Henry_IV"
 #define HENRY_VII "Henry_VII"
+#define HENRY_VIII "Henry_VIII"
 #define MARGARET "Margaret"
 #define JAMES_V_OF_SCOTLAND "James_V_of_Scotland"
 #define MARY_I_OF_SCOTLAND "Mary_I_of_Scotland"
@@ -31,15 +36,21 @@ main(int argc, char **argv)
    printf("\n*** Testing netcdf-4 group functions.\n");
    printf("*** testing simple group create...");
    {
-      int ncid;
+      int ncid, ncid2;
       char name_in[NC_MAX_NAME + 1];
       int henry_vii_id;
+      int henry_viii_id;
       int grpid_in[MAX_SIBLING_GROUPS], varids_in[MAX_SIBLING_GROUPS];
       int dimids_in[MAX_SIBLING_GROUPS], nvars_in, ndims_in, ncid_in;
       int parent_ncid;
       char name_out[NC_MAX_NAME + 1];
       int num_grps;
 
+      /* Create a netCDF classic file. Groups will not be allowed. */
+      if (nc_create(FILE_NAME_CLASSIC, 0, &ncid2)) ERR;
+      if (nc_def_grp(ncid2, name_out, &henry_vii_id) != NC_ENOTNC4) ERR;
+      if (nc_close(ncid2)) ERR;
+
       /* Create a file with one group, a group to contain data about
        * Henry VII. */
       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
@@ -47,7 +58,16 @@ main(int argc, char **argv)
       /* This should also work as simple "is this the root group" test */
       if (nc_inq_grp_parent(ncid, NULL) != NC_ENOGRP) ERR;
       strcpy(name_out, HENRY_VII);
+
+      /* These will not work. */
+      if (nc_def_grp(ncid + TEST_VAL_42, name_out, &henry_vii_id) != NC_EBADID) ERR;
+      if (nc_def_grp(ncid, NULL, &henry_vii_id) != NC_EINVAL) ERR;
+      if (nc_def_grp(ncid, BAD_NAME, &henry_vii_id) != NC_EBADNAME) ERR;
+
+      /* Define the group. */
       if (nc_def_grp(ncid, name_out, &henry_vii_id)) ERR;
+
+      /* Check it out. */
       if (nc_inq_grp_parent(henry_vii_id, &parent_ncid)) ERR;
       if (parent_ncid != ncid) ERR;
       if (nc_inq_ncid(ncid, HENRY_VII, &ncid_in)) ERR;
@@ -69,10 +89,77 @@ main(int argc, char **argv)
       if (strcmp(name_in, HENRY_VII)) ERR;
       if (nc_inq_varids(grpid_in[0], &nvars_in, varids_in)) ERR;
       if (nvars_in != 0) ERR;
-      if (nc_inq_varids(grpid_in[0], &ndims_in, dimids_in)) ERR;
-      if (ndims_in != 0) ERR;
+      if (nc_inq_varids(grpid_in[0], NULL, varids_in)) ERR;
+      if (nc_inq_varids(grpid_in[0], &nvars_in, NULL)) ERR;
+      if (nc_inq_varids(grpid_in[0], NULL, NULL)) ERR;
+      
       if (nc_inq_ncid(ncid, HENRY_VII, &ncid_in)) ERR;
       if (ncid_in != grpid_in[0]) ERR;
+
+      /* These should fail - file is read-only. */
+      if (nc_def_grp(ncid, HENRY_VIII, &henry_viii_id) != NC_EPERM) ERR;
+      if (nc_rename_grp(grpid_in[0], HENRY_VIII) != NC_EPERM) ERR;
+
+      /* Close the file. */
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
+   printf("*** testing simple group rename...");
+   {
+      int ncid, ncid2;
+      int grpid_in;
+      char name_in[NC_MAX_NAME + 1];
+      int henry_vii_id;
+
+      /* Create a classic model file. No groups will be allowed. */
+      if (nc_create(FILE_NAME_CLASSIC_MODEL, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid2)) ERR;
+      if (nc_def_grp(ncid2, HENRY_VII, &henry_vii_id) != NC_ESTRICTNC3) ERR;
+      if (nc_def_var(ncid2, HENRY_IV, NC_INT, 0, NULL, NULL));
+      if (nc_close(ncid2)) ERR;
+
+      /* Create a file with one group, a group to contain data about
+       * Henry VII. */
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_var(ncid, HENRY_IV, NC_INT, 0, NULL, NULL));      
+
+      /* Turn off define mode. It will automatically be turned back on
+       * when nc_def_grp is called. */
+      if (nc_enddef(ncid)) ERR; 
+      if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
+
+      /* Check it out. */
+      if (nc_inq_grpname(henry_vii_id, name_in)) ERR;
+      if (strcmp(name_in, HENRY_VII)) ERR;
+
+      /* These will not work. */
+      if (nc_rename_grp(henry_vii_id, BAD_NAME) != NC_EBADNAME) ERR;
+      if (nc_rename_grp(henry_vii_id, HENRY_IV) != NC_ENAMEINUSE) ERR;
+      if (nc_rename_grp(ncid, HENRY_IV) != NC_EBADGRPID) ERR;
+
+      /* Rename the group. */
+      if (nc_rename_grp(henry_vii_id, HENRY_VIII)) ERR;
+
+      /* Check it out. */
+      if (nc_inq_grpname(henry_vii_id, name_in)) ERR;
+      if (strcmp(name_in, HENRY_VIII)) ERR;
+
+      /* Close the file. */
+      if (nc_close(ncid)) ERR;
+
+      /* Re-open the file. */
+      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
+      
+      /* Check it out. */
+      if (nc_inq_grps(ncid, NULL, &grpid_in)) ERR;
+      if (nc_inq_grpname(grpid_in, name_in)) ERR;
+      if (strcmp(name_in, HENRY_VIII)) ERR;
+
+      /* Rename it. */
+      if (nc_rename_grp(grpid_in, HENRY_VII)) ERR;
+      if (nc_inq_grpname(grpid_in, name_in)) ERR;
+      if (strcmp(name_in, HENRY_VII)) ERR;
+
+      /* Close the file. */
       if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
@@ -121,6 +208,9 @@ main(int argc, char **argv)
       if (nc_def_var(henry_vii_id, VAR_NAME2, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid2)) ERR;
       if (nc_def_var(henry_vii_id, VAR_NAME3, NC_INT64, NDIMS_IN_VAR, &dimid2, &varid3)) ERR;
 
+      /* These won't work. */
+      if (nc_inq_ncid(ncid + TEST_VAL_42, HENRY_VII, &grpid_in) != NC_EBADID) ERR;
+
       /* Check it out. Find the group by name. */
       if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;
 
@@ -220,15 +310,26 @@ main(int argc, char **argv)
 
    printf("*** testing simple nested group creates...");
    {
+      char root_name[] = "/";
       int ncid, grp_ncid;
       int henry_vii_id, margaret_id, james_v_of_scotland_id, mary_i_of_scotland_id;
-      int james_i_of_england_id;
       char name_in[NC_MAX_NAME + 1];
       char full_name[NC_MAX_NAME * 10], full_name_in[NC_MAX_NAME * 10];
+      char full_name_in1[NC_MAX_NAME * 10];
+      char wrong_name[NC_MAX_NAME * 10];
       int grpid_in[MAX_SIBLING_GROUPS];
       int grp_in;
+      int grp_in2;
       int num_grps;
-      size_t len;
+      size_t len, len1;
+
+      /* This name is wrong. */
+      strcpy(wrong_name, "/");
+      strcat(wrong_name, HENRY_VII);
+      strcpy(wrong_name, "/");
+      strcat(wrong_name, MARGARET);
+      strcpy(wrong_name, "/");
+      strcat(wrong_name, MARGARET);
 
       /* Create a file with some nested groups in it, suitable
        * to storing information about the Tudor dynasty of England. */
@@ -237,16 +338,37 @@ main(int argc, char **argv)
       if (nc_def_grp(henry_vii_id, MARGARET, &margaret_id)) ERR;
       if (nc_def_grp(margaret_id, JAMES_V_OF_SCOTLAND, &james_v_of_scotland_id)) ERR;
       if (nc_def_grp(james_v_of_scotland_id, MARY_I_OF_SCOTLAND, &mary_i_of_scotland_id)) ERR;
-      if (nc_def_grp(mary_i_of_scotland_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &james_i_of_england_id)) ERR;
+      /* nc_def_grp will accept NULL as ID pointer. Group will be
+       * created, but ID not returned. */
+      if (nc_def_grp(mary_i_of_scotland_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, NULL)) ERR;
 
       strcpy(full_name, "/");
       if (nc_inq_grpname_full(ncid, &len, full_name_in)) ERR;
       if (len != 1 || strcmp(full_name_in, full_name)) ERR;
       if (nc_inq_grpname_len(ncid, &len)) ERR;
       if (len != 1) ERR;
+
+      /* These won't work. */
+      if (nc_inq_grp_full_ncid(ncid + TEST_VAL_42, full_name, &grp_in) != NC_EBADID) ERR;
+      if (nc_inq_grp_full_ncid(ncid, NULL, &grp_in) != NC_EINVAL) ERR;
+      
+      /* Get the ncid from the full name. */
       if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
       if (grp_in != ncid) ERR;
 
+      /* Works (pretty pointlessly) with NULL for ID pointer. */
+      if (nc_inq_grp_full_ncid(ncid, full_name, NULL)) ERR;
+
+      /* Get the root group ID from '/'. */
+      if (nc_inq_grp_full_ncid(ncid, root_name, &grp_in2)) ERR;
+      if (grp_in2 != ncid) ERR;
+
+      /* But the root group does not exist within another group. */
+      if (nc_inq_grp_full_ncid(mary_i_of_scotland_id, root_name, &grp_in2) != NC_ENOGRP) ERR;
+
+      /* This name is wrong. */
+      if (nc_inq_grp_full_ncid(ncid, wrong_name, &grp_in2) != NC_ENOGRP) ERR;
+
       if (nc_inq_grp_ncid(ncid, HENRY_VII, NULL)) ERR;
       if (nc_inq_grp_ncid(ncid, HENRY_VII, &grp_ncid)) ERR;
       if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
@@ -254,6 +376,7 @@ main(int argc, char **argv)
       if (nc_inq_grps(ncid, NULL, grpid_in)) ERR;
       if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
       if (strcmp(name_in, HENRY_VII)) ERR;
+      if (nc_inq_grpname(grpid_in[0], NULL)) ERR;      
       if (grpid_in[0] != grp_ncid) ERR;
       strcat(full_name, HENRY_VII);
       if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in)) ERR;
@@ -261,6 +384,9 @@ main(int argc, char **argv)
       if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
       if (grp_in != grpid_in[0]) ERR;
 
+      /* Also works with NULL last param. */
+      if (nc_inq_grp_full_ncid(ncid, full_name, NULL)) ERR;
+
       if (nc_inq_grp_ncid(grpid_in[0], MARGARET, &grp_ncid)) ERR;
       if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
       if (num_grps != 1) ERR;
@@ -312,6 +438,11 @@ main(int argc, char **argv)
       if (len != strlen(full_name) || strcmp(full_name_in, full_name)) ERR;
       if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
       if (grp_in != grpid_in[0]) ERR;
+      if (nc_inq_grpname_full(grpid_in[0], NULL, NULL)) ERR;
+      if (nc_inq_grpname_full(grpid_in[0], &len1, NULL)) ERR;
+      if (len1 != strlen(full_name)) ERR;
+      if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in1)) ERR;
+      if (strcmp(full_name_in1, full_name)) ERR;      
 
       if (nc_close(ncid)) ERR;
 
diff --git a/nc_test4/tst_grps2.c b/nc_test4/tst_grps2.c
index 297fb1f..55d10ad 100644
--- a/nc_test4/tst_grps2.c
+++ b/nc_test4/tst_grps2.c
@@ -4,14 +4,14 @@
 
    Test netcdf-4 group code some more.
 
-   $Id$
+   @author Ed Hartnett
 */
 
 #include <nc_tests.h>
 #include "err_macros.h"
 #include "netcdf.h"
 
-#define FILE_NAME "tst_grps.nc"
+#define FILE_NAME "tst_grps2.nc"
 #define DIM1_NAME "kingdom"
 #define DIM1_LEN 3
 #define DIM2_NAME "year"
diff --git a/nc_test4/tst_h5_endians.c b/nc_test4/tst_h5_endians.c
index 3b167f0..3d9d839 100644
--- a/nc_test4/tst_h5_endians.c
+++ b/nc_test4/tst_h5_endians.c
@@ -38,7 +38,7 @@ int main() {
   int be_dbl_varid;
   int ed;
   int failures = 0;
-  int retval = 0;
+  int retval;
 
   printf("* Checking that endianness is properly read from file.\n");
   printf("** Generating test files.\n");
@@ -48,36 +48,51 @@ int main() {
   {
 
     printf("*** Creating a file via netcdf API: %s.\n",FILE_NAME_NC);
-    retval = nc_create(FILE_NAME_NC, NC_NETCDF4 | NC_CLOBBER, &ncid);
+    if ((retval = nc_create(FILE_NAME_NC, NC_NETCDF4 | NC_CLOBBER, &ncid)))
+	return retval;
 
-    retval = nc_def_dim(ncid, DIM_NAME, NDIM, &dimid);
+    if ((retval = nc_def_dim(ncid, DIM_NAME, NDIM, &dimid)))
+	return retval;
 
     /* Little-Endian Float */
-    retval = nc_def_var(ncid, LE_FLOAT_VARNAME, NC_FLOAT, 1, &dimid, &le_float_varid);
-    retval = nc_def_var_endian(ncid, le_float_varid, NC_ENDIAN_LITTLE);
+    if ((retval = nc_def_var(ncid, LE_FLOAT_VARNAME, NC_FLOAT, 1, &dimid, &le_float_varid)))
+	return retval;
+    if ((retval = nc_def_var_endian(ncid, le_float_varid, NC_ENDIAN_LITTLE)))
+	return retval;
 
     /* Big-Endian Float */
-    retval = nc_def_var(ncid, BE_FLOAT_VARNAME, NC_FLOAT, 1, &dimid, &be_float_varid);
-    retval = nc_def_var_endian(ncid, be_float_varid, NC_ENDIAN_BIG);
+    if ((retval = nc_def_var(ncid, BE_FLOAT_VARNAME, NC_FLOAT, 1, &dimid, &be_float_varid)))
+	return retval;
+    if ((retval = nc_def_var_endian(ncid, be_float_varid, NC_ENDIAN_BIG)))
+	return retval;
 
     /* Little-Endian Int */
-    retval = nc_def_var(ncid, LE_INT_VARNAME, NC_INT, 1, &dimid, &le_int_varid);
-    retval = nc_def_var_endian(ncid, le_int_varid, NC_ENDIAN_LITTLE);
+    if ((retval = nc_def_var(ncid, LE_INT_VARNAME, NC_INT, 1, &dimid, &le_int_varid)))
+	return retval;
+    if ((retval = nc_def_var_endian(ncid, le_int_varid, NC_ENDIAN_LITTLE)))
+	return retval;
 
     /* Big-Endian Int */
-    retval = nc_def_var(ncid, BE_INT_VARNAME, NC_INT, 1, &dimid, &be_int_varid);
-    retval = nc_def_var_endian(ncid, be_int_varid, NC_ENDIAN_BIG);
+    if ((retval = nc_def_var(ncid, BE_INT_VARNAME, NC_INT, 1, &dimid, &be_int_varid)))
+	return retval;
+    if ((retval = nc_def_var_endian(ncid, be_int_varid, NC_ENDIAN_BIG)))
+	return retval;
 
     /* Little-Endian Double */
-    retval = nc_def_var(ncid, LE_DBL_VARNAME, NC_DOUBLE, 1, &dimid, &le_dbl_varid);
-    retval = nc_def_var_endian(ncid, le_dbl_varid, NC_ENDIAN_LITTLE);
+    if ((retval = nc_def_var(ncid, LE_DBL_VARNAME, NC_DOUBLE, 1, &dimid, &le_dbl_varid)))
+	return retval;
+    if ((retval = nc_def_var_endian(ncid, le_dbl_varid, NC_ENDIAN_LITTLE)))
+	return retval;
 
     /* Big-Endian Double */
-    retval = nc_def_var(ncid, BE_DBL_VARNAME, NC_DOUBLE, 1, &dimid, &be_dbl_varid);
-    retval = nc_def_var_endian(ncid, be_dbl_varid, NC_ENDIAN_BIG);
+    if ((retval = nc_def_var(ncid, BE_DBL_VARNAME, NC_DOUBLE, 1, &dimid, &be_dbl_varid)))
+	return retval;
+    if ((retval = nc_def_var_endian(ncid, be_dbl_varid, NC_ENDIAN_BIG)))
+	return retval;
 
 
-    retval = nc_close(ncid);
+    if ((retval = nc_close(ncid)))
+	return retval;
   }
 
   /*
@@ -95,40 +110,54 @@ int main() {
     be_dbl_varid = 0;
 
     printf("*** %s\n",FILE_NAME_NC);
-    retval = nc_open(FILE_NAME_NC, NC_NETCDF4 | NC_NOWRITE, &ncid);
-
-    retval = nc_inq_varid(ncid,LE_FLOAT_VARNAME,&le_float_varid);
-    retval = nc_inq_varid(ncid,BE_FLOAT_VARNAME,&be_float_varid);
-    retval = nc_inq_varid(ncid,LE_INT_VARNAME,&le_int_varid);
-    retval = nc_inq_varid(ncid,BE_INT_VARNAME,&be_int_varid);
-    retval = nc_inq_varid(ncid,LE_DBL_VARNAME,&le_dbl_varid);
-    retval = nc_inq_varid(ncid,BE_DBL_VARNAME,&be_dbl_varid);
+    if ((retval = nc_open(FILE_NAME_NC, NC_NETCDF4 | NC_NOWRITE, &ncid)))
+	return retval;
+
+    if ((retval = nc_inq_varid(ncid,LE_FLOAT_VARNAME,&le_float_varid)))
+	return retval;
+    if ((retval = nc_inq_varid(ncid,BE_FLOAT_VARNAME,&be_float_varid)))
+	return retval;
+    if ((retval = nc_inq_varid(ncid,LE_INT_VARNAME,&le_int_varid)))
+	return retval;
+    if ((retval = nc_inq_varid(ncid,BE_INT_VARNAME,&be_int_varid)))
+	return retval;
+    if ((retval = nc_inq_varid(ncid,LE_DBL_VARNAME,&le_dbl_varid)))
+	return retval;
+    if ((retval = nc_inq_varid(ncid,BE_DBL_VARNAME,&be_dbl_varid)))
+	return retval;
 
     printf("\tLittle-Endian Float...\t");
-    retval = nc_inq_var_endian(ncid,le_float_varid,&ed);
+    if ((retval = nc_inq_var_endian(ncid,le_float_varid,&ed)))
+	return retval;
     if(ed == NC_ENDIAN_LITTLE) printf("passed\n"); else {printf("failed\n"); failures++;}
 
     printf("\tBig-Endian Float...\t");
-    retval = nc_inq_var_endian(ncid,be_float_varid,&ed);
+    if ((retval = nc_inq_var_endian(ncid,be_float_varid,&ed)))
+	return retval;
     if(ed == NC_ENDIAN_BIG) printf("passed\n"); else {printf("failed\n"); failures++;}
 
     printf("\tLittle-Endian Int...\t");
-    retval = nc_inq_var_endian(ncid,le_int_varid,&ed);
+    if ((retval = nc_inq_var_endian(ncid,le_int_varid,&ed)))
+	return retval;
     if(ed == NC_ENDIAN_LITTLE) printf("passed\n"); else {printf("failed\n"); failures++;}
 
     printf("\tBig-Endian Int...\t");
-    retval = nc_inq_var_endian(ncid,be_int_varid,&ed);
+    if ((retval = nc_inq_var_endian(ncid,be_int_varid,&ed)))
+	return retval;
     if(ed == NC_ENDIAN_BIG) printf("passed\n"); else {printf("failed\n"); failures++;}
 
     printf("\tLittle-Endian Double...\t");
-    retval = nc_inq_var_endian(ncid,le_dbl_varid,&ed);
+    if ((retval = nc_inq_var_endian(ncid,le_dbl_varid,&ed)))
+	return retval;
     if(ed == NC_ENDIAN_LITTLE) printf("passed\n"); else {printf("failed\n"); failures++;}
 
     printf("\tBig-Endian Double...\t");
-    retval = nc_inq_var_endian(ncid,be_dbl_varid,&ed);
+    if ((retval = nc_inq_var_endian(ncid,be_dbl_varid,&ed)))
+	return retval;
     if(ed == NC_ENDIAN_BIG) printf("passed\n"); else {printf("failed\n"); failures++;}
 
-    retval = nc_close(ncid);
+    if ((retval = nc_close(ncid)))
+	return retval;
   }
 
   printf("** Failures Returned: [%d]\n",failures);
diff --git a/nc_test4/tst_h_atts2.c b/nc_test4/tst_h_atts2.c
deleted file mode 100644
index 7c40520..0000000
--- a/nc_test4/tst_h_atts2.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* This is part of the netCDF package.
-   Copyright 2005 University Corporation for Atmospheric Research/Unidata
-   See COPYRIGHT file for conditions of use.
-
-   Test HDF5 file code. These are not intended to be exhaustive tests,
-   but they use HDF5 the same way that netCDF-4 does, so if these
-   tests don't work, than netCDF-4 won't work either.
-
-   This file deals with HDF5 attributes, but more so.
-
-   $Id: tst_h_atts2.c,v 1.18 2009/07/03 13:07:14 ed Exp $
-*/
-#include <nc_tests.h>
-#include "err_macros.h"
-#include <hdf5.h>
-
-#define FILE_NAME "tst_h_atts2.h5"
-#define REF_FILE_NAME "tst_xplatform2_3.nc"
-#define MAX_LEN 80
-#define NUM_ATTS 1
-#define ATT_NAME "King_John"
-#define NUM_OBJ 3
-
-int
-main()
-{
-   printf("\n*** Checking HDF5 attribute functions some more.\n");
-#ifdef EXTRA_TESTS
-   printf("*** Opening tst_xplatform2_3.nc...");
-   {
-      hid_t fileid, grpid, attid;
-      hid_t file_typeid1[NUM_OBJ], native_typeid1[NUM_OBJ];
-      hid_t file_typeid2, native_typeid2;
-      hsize_t num_obj, i;
-      H5O_info_t obj_info;
-      char obj_name[NC_MAX_NAME + 1];
-
-      /* Open one of the netCDF test files. */
-      if ((fileid = H5Fopen(REF_FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
-      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
-
-      /* How many objects in this group? */
-      if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
-      if (num_obj != NUM_OBJ) ERR;
-
-      /* For each object in the group... */
-      for (i = 0; i < num_obj; i++)
-      {
-	 /* Get the name. */
-	 if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC,
-				i, &obj_info, H5P_DEFAULT) < 0) ERR_RET;
-	 if (H5Lget_name_by_idx(grpid, ".", H5_INDEX_NAME, H5_ITER_INC, i,
-				obj_name, NC_MAX_NAME + 1, H5P_DEFAULT) < 0) ERR_RET;
-	 printf(" reading type %s ", obj_name);
-	 if (obj_info.type != H5O_TYPE_NAMED_DATATYPE) ERR_RET;
-
-	 /* Get the typeid. */
-	 if ((file_typeid1[i] = H5Topen2(grpid, obj_name, H5P_DEFAULT)) < 0) ERR_RET;
-	 if ((native_typeid1[i] = H5Tget_native_type(file_typeid1[i], H5T_DIR_DEFAULT)) < 0) ERR_RET;
-      }
-
-      /* There is one att: open it by index. */
-      if ((attid = H5Aopen_idx(grpid, 0)) < 0) ERR;
-
-      /* Get file and native typeids. */
-      if ((file_typeid2 = H5Aget_type(attid)) < 0) ERR;
-      if ((native_typeid2 = H5Tget_native_type(file_typeid2, H5T_DIR_DEFAULT)) < 0) ERR;
-
-      /* Close the attribute. */
-      if (H5Aclose(attid) < 0) ERR;
-
-      /* Close the typeids. */
-      if (H5Tclose(file_typeid2) < 0) ERR_RET;
-      if (H5Tclose(native_typeid2) < 0) ERR_RET;
-      for (i = 0; i < NUM_OBJ; i++)
-      {
-	 if (H5Tclose(file_typeid1[i]) < 0) ERR_RET;
-	 if (H5Tclose(native_typeid1[i]) < 0) ERR_RET;
-      }
-
-      /* Close the group and file. */
-      if (H5Gclose(grpid) < 0 ||
-	  H5Fclose(fileid) < 0) ERR;
-   }
-
-   SUMMARIZE_ERR;
-   printf("*** Opening tst_xplatform2_3.nc again...");
-   {
-      hid_t fileid, grpid, attid, file_typeid, native_typeid;
-      hid_t file_typeid2, native_typeid2;
-#if 0
-      hsize_t num_obj;
-#endif
-
-      /* Open one of the netCDF test files. */
-      if ((fileid = H5Fopen(REF_FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
-      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
-
-      /* There is one att: open it by index. */
-      if ((attid = H5Aopen_idx(grpid, 0)) < 0) ERR;
-
-      /* Get file and native typeids. */
-      if ((file_typeid = H5Aget_type(attid)) < 0) ERR;
-      if ((native_typeid = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0) ERR;
-
-      /* Now getting another copy of the native typeid will fail! WTF? */
-      if ((file_typeid2 = H5Aget_type(attid)) < 0) ERR;
-      if ((native_typeid2 = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0) ERR;
-
-      /* Close the attribute. */
-      if (H5Aclose(attid) < 0) ERR;
-
-      /* Close the typeids. */
-      if (H5Tclose(file_typeid) < 0) ERR;
-      if (H5Tclose(native_typeid) < 0) ERR;
-      if (H5Tclose(file_typeid2) < 0) ERR;
-      if (H5Tclose(native_typeid2) < 0) ERR;
-
-      /* Close the group and file. */
-      if (H5Gclose(grpid) < 0 ||
-	  H5Fclose(fileid) < 0) ERR;
-   }
-
-   SUMMARIZE_ERR;
-#endif
-   FINAL_RESULTS;
-}
diff --git a/nc_test4/tst_h_files3.c b/nc_test4/tst_h_files3.c
deleted file mode 100644
index 1131884..0000000
--- a/nc_test4/tst_h_files3.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* This is part of the netCDF package.
-   Copyright 2005 University Corporation for Atmospheric Research/Unidata
-   See COPYRIGHT file for conditions of use.
-
-   Test netcdf-4 variables.
-   $Id: tst_h_files3.c,v 1.2 2010/02/05 17:06:28 ed Exp $
-*/
-
-#include <nc_tests.h>
-#include "err_macros.h"
-#include "netcdf.h"
-#include <unistd.h>
-#include <time.h>
-#include <sys/time.h> /* Extra high precision time info. */
-#include <hdf5.h>
-#include <H5DSpublic.h>
-
-#define MAX_LEN 30
-#define TMP_FILE_NAME "tst_files2_tmp.out"
-#define FILE_NAME "tst_files2_1.nc"
-#define MILLION 1000000
-
-void *last_sbrk;
-
-void
-get_mem_used2(int *mem_used)
-{
-   char buf[30];
-   FILE *pf;
-
-   snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
-   pf = fopen(buf, "r");
-   if (pf) {
-      unsigned size; /*       total program size */
-      unsigned resident;/*   resident set size */
-      unsigned share;/*      shared pages */
-      unsigned text;/*       text (code) */
-      unsigned lib;/*        library */
-      unsigned data;/*       data/stack */
-      /*unsigned dt;          dirty pages (unused in Linux 2.6)*/
-      fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share,
-	     &text, &lib, &data);
-      *mem_used = data;
-   }
-   else
-      *mem_used = -1;
-  fclose(pf);
-}
-
-int
-main(int argc, char **argv)
-{
-
-   printf("\n*** Testing netcdf-4 file functions, some more.\n");
-   last_sbrk = sbrk(0);
-/*    printf("Test for memory consumption of simple HDF5 file read...\n"); */
-/*    { */
-/* #define NUM_TRIES 200000 */
-/* #define CHUNK_CACHE_NELEMS_1 1009 */
-/* #define CHUNK_CACHE_SIZE_1 1000000 */
-/* #define CHUNK_CACHE_PREEMPTION_1 .75 */
-/* #define MAX_OBJ 2       */
-/* #define FILE_NAME2 "ref_tst_kirk.nc" */
-/*       int mem_used, mem_used1, mem_used2; */
-/*       hid_t fapl_id, fileid, grpid, datasetid; */
-/*       int try; */
-/*       int num_scales; */
-
-/*       printf("\t\t\tbef_open\taft_open\taft_close\tused_open\tused_closed\n"); */
-/*       for (try = 0; try < NUM_TRIES; try++) */
-/*       { */
-/* 	 char obj_name2[] = "Captain_Kirk"; */
-/* 	 get_mem_used2(&mem_used); */
-
-/* 	 /\* Reopen the file. *\/ */
-/*  	 if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; */
-/* 	 if ((fileid = H5Fopen(FILE_NAME2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR; */
-/* 	 if ((grpid = H5Gopen(fileid, "/")) < 0) ERR; */
-
-/* 	 if ((datasetid = H5Dopen2(grpid, obj_name2, H5P_DEFAULT)) < 0) ERR; */
-/* 	 num_scales = H5DSget_num_scales(datasetid, 0); */
-
-/* 	 get_mem_used2(&mem_used1); */
-
-/* 	 /\* Close everything. *\/ */
-/* 	 if (H5Dclose(datasetid)) ERR_RET; */
-/* 	 if (H5Pclose(fapl_id)) ERR_RET; */
-/* 	 if (H5Gclose(grpid) < 0) ERR_RET; */
-/* 	 if (H5Fclose(fileid) < 0) ERR_RET; */
-
-/* 	 get_mem_used2(&mem_used2); */
-
-/* 	 if (mem_used2 - mem_used) */
-/* 	 { */
-/* 	    printf("try %d - \t\t%d\t\t%d\t\t%d\t\t%d\t\t%d \n", try,  */
-/* 		   mem_used, mem_used1, mem_used2, mem_used1 - mem_used,  */
-/* 		   mem_used2 - mem_used); */
-/* 	    /\*if (try > 1) */
-/* 	      ERR_RET;*\/ */
-/* 	 } */
-/*       } */
-/*    } */
-/*    SUMMARIZE_ERR; */
-/*    printf("Test for memory consumption of HDF5 file read...\n"); */
-/*    { */
-/* #define NUM_TRIES 2000 */
-/* #define CHUNK_CACHE_NELEMS_1 1009 */
-/* #define CHUNK_CACHE_SIZE_1 1000000 */
-/* #define CHUNK_CACHE_PREEMPTION_1 .75 */
-/* #define MAX_OBJ 2       */
-/* #define FILE_NAME2 "ref_tst_kirk.nc" */
-/*       hsize_t num_obj, i; */
-/*       int mem_used, mem_used1, mem_used2; */
-/*       hid_t fapl_id, fileid, grpid, datasetid[MAX_OBJ]; */
-/*       hid_t access_pid, spaceid; */
-/*       char obj_name[NC_MAX_NAME + 1]; */
-/*       int try; */
-/*       H5O_info_t obj_info; */
-/*       H5_index_t idx_field = H5_INDEX_CRT_ORDER; */
-/*       ssize_t size; */
-/*       int ndims; */
-/*       hsize_t dims[NC_MAX_DIMS], max_dims[NC_MAX_DIMS]; */
-/*       int is_scale = 0; */
-
-/*       get_mem_used2(&mem_used); */
-/*       mem_used1 = mem_used; */
-/*       mem_used2 = mem_used; */
-/*       printf("start: memuse= %d\t%d\t%d \n",mem_used, mem_used1,   */
-/* 	     mem_used2); */
-
-/* /\*      if (H5Eset_auto(NULL, NULL) < 0) ERR;*\/ */
-
-/*       printf("bef_open\taft_open\taft_close\tused_open\tused_closed\n"); */
-/*       for (try = 0; try < NUM_TRIES; try++) */
-/*       { */
-/* 	 get_mem_used2(&mem_used); */
-
-/* 	 /\* Reopen the file. *\/ */
-/* 	 if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; */
-/* 	 if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) ERR; */
-/* 	 if (H5Pset_cache(fapl_id, 0, CHUNK_CACHE_NELEMS_1, CHUNK_CACHE_SIZE_1, */
-/* 			  CHUNK_CACHE_PREEMPTION_1) < 0) ERR; */
-/* 	 if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST,  */
-/* 				  H5F_LIBVER_LATEST) < 0) ERR; */
-/* 	 if ((fileid = H5Fopen(FILE_NAME2, H5F_ACC_RDONLY, fapl_id)) < 0) ERR; */
-/* 	 if ((grpid = H5Gopen(fileid, "/")) < 0) ERR; */
-
-/* 	 if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR; */
-/* 	 if (num_obj > MAX_OBJ) ERR; */
-/* 	 for (i = 0; i < num_obj; i++) */
-/* 	 { */
-/* 	    if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, */
-/* 				   i, &obj_info, H5P_DEFAULT) < 0) ERR; */
-/* 	    if ((size = H5Lget_name_by_idx(grpid, ".", idx_field, H5_ITER_INC, i, */
-/* 					   NULL, 0, H5P_DEFAULT)) < 0) ERR; */
-/* 	    if (H5Lget_name_by_idx(grpid, ".", idx_field, H5_ITER_INC, i, */
-/* 				   obj_name, size+1, H5P_DEFAULT) < 0) ERR; */
-/* 	    if ((datasetid[i] = H5Dopen2(grpid, obj_name, H5P_DEFAULT)) < 0) ERR; */
-/* 	    if ((access_pid = H5Dget_access_plist(datasetid[i])) < 0) ERR; */
-/* 	    if ((spaceid = H5Dget_space(datasetid[i])) < 0) ERR; */
-/* 	    if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR; */
-/* 	    if (H5Sget_simple_extent_dims(spaceid, dims, max_dims) < 0) ERR; */
-/* 	    if ((is_scale = H5DSis_scale(datasetid[i])) < 0) ERR; */
-/* 	    if (is_scale) */
-/* 	    { */
-/* 	       char dimscale_name_att[NC_MAX_NAME + 1]; */
-/* 	       int natts, a; */
-/* 	       hid_t attid = 0; */
-/* 	       char att_name[NC_MAX_HDF5_NAME + 1]; */
-
-/* 	       if ((natts = H5Aget_num_attrs(datasetid[i])) < 0) ERR; */
-/* 	       for (a = 0; a < natts; a++) */
-/* 	       { */
-/* 		  if ((attid = H5Aopen_idx(datasetid[i], (unsigned int)a)) < 0) ERR; */
-/* 		  if (H5Aget_name(attid, NC_MAX_HDF5_NAME, att_name) < 0) ERR; */
-/* 		  if (H5Aclose(attid) < 0) ERR; */
-/* 	       } */
-/* 	       if (H5DSget_scale_name(datasetid[i], dimscale_name_att, NC_MAX_NAME) < 0) ERR; */
-/* 	    } */
-/* 	    else */
-/* 	    { */
-/* 	       int num_scales; */
-/* 	       size_t chunk_cache_size, chunk_cache_nelems; */
-/* 	       double rdcc_w0; */
-/* 	       hid_t propid; */
-
-/* 	       num_scales = H5DSget_num_scales(datasetid[i], 0); */
-/* 	       if ((H5Pget_chunk_cache(access_pid, &chunk_cache_nelems, */
-/* 				       &chunk_cache_size, &rdcc_w0)) < 0) ERR; */
-/* 	       if ((propid = H5Dget_create_plist(datasetid[i])) < 0) ERR; */
-
-/* 	       if (H5Pclose(propid)) ERR; */
-
-/* 	    } */
-
-/* 	    if (H5Pclose(access_pid)) ERR; */
-/* 	    if (H5Sclose(spaceid)) ERR; */
-/* 	 } */
-
-/* 	 get_mem_used2(&mem_used1); */
-
-/* 	 /\* Close everything. *\/ */
-/* 	 for (i = 0; i < num_obj; i++) */
-/* 	    if (H5Dclose(datasetid[i])) ERR; */
-/* 	 if (H5Pclose(fapl_id)) ERR; */
-/* 	 if (H5Gclose(grpid) < 0) ERR; */
-/* 	 if (H5Fclose(fileid) < 0) ERR; */
-
-/* 	 get_mem_used2(&mem_used2); */
-
-/* 	 if (mem_used2 - mem_used) */
-/* 	 { */
-/* 	    printf("try %d - %d\t\t%d\t\t%d\t\t%d\t\t%d \n", try,  */
-/* 		   mem_used, mem_used1, mem_used2, mem_used1 - mem_used,  */
-/* 		   mem_used2 - mem_used); */
-/* 	    if (try > 1) */
-/* 	       ERR_RET; */
-/* 	 } */
-/*       } */
-/*    } */
-/*    SUMMARIZE_ERR; */
-   FINAL_RESULTS;
-}
diff --git a/nc_test4/tst_h_scalar.c b/nc_test4/tst_h_scalar.c
index 8853f2a..fbd40ca 100644
--- a/nc_test4/tst_h_scalar.c
+++ b/nc_test4/tst_h_scalar.c
@@ -185,7 +185,6 @@ main()
         hid_t dcplid;
 	hid_t scalar_spaceid;
         hid_t vlstr_typeid, fixstr_typeid;
-	hid_t attid;
 
         /* Create scalar dataspace */
 	if ((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;
@@ -265,7 +264,6 @@ main()
     printf("*** Checking accessing file through netCDF-4 API...");
     {
 	int ncid, varid;
-        size_t len;
         nc_type type;
         int ndims;
         char *vlstr;
diff --git a/nc_test4/tst_h_strbug.c b/nc_test4/tst_h_strbug.c
index a9e450f..b819604 100644
--- a/nc_test4/tst_h_strbug.c
+++ b/nc_test4/tst_h_strbug.c
@@ -32,14 +32,12 @@ main()
     char fsdata[]   = "fixed-length string";
     char *v1ddata[DIM1] = {"strings","of","variable","length"};
     int i;
-    char ch;
 
     printf("\n*** Creating file for checking fix to bugs in accessing strings from HDF5 non-netcdf-4 file.\n");
     {
 	hid_t fileid, scalar_spaceid, vstypeid, fstypeid, vsattid, fsattid, vsdsetid, fsdsetid;
-	hid_t class;
 	size_t type_size = FSTR_LEN;
-	hid_t v1dattid, v1ddsetid;
+	hid_t v1ddsetid;
 	hid_t v1dspaceid;
 	hsize_t dims[1] = {DIM1};
 
@@ -128,7 +126,7 @@ main()
 
     printf("*** Checking reading variable-length HDF5 string att through netCDF-4 API...");
     {
-	int ncid, varid, ndims;
+	int ncid;
 	nc_type type;
 	size_t len;
 	char *data_in;
@@ -145,7 +143,7 @@ main()
 
     printf("*** Checking reading fixed-length HDF5 string att through netCDF-4 API...");
     {
-	int ncid, varid, ndims;
+	int ncid;
 	nc_type type;
 	size_t len;
 	char *data_in;
diff --git a/nc_test4/tst_h_vl2.c b/nc_test4/tst_h_vl2.c
index f0471ca..9d4d77e 100644
--- a/nc_test4/tst_h_vl2.c
+++ b/nc_test4/tst_h_vl2.c
@@ -4,13 +4,13 @@
 
    This program excersizes HDF5 variable length array code.
 
-   $Id: tst_h_vl2.c,v 1.5 2010/06/01 15:34:52 ed Exp $
+   @author Ed Hartnett
 */
 #include <nc_tests.h>
 #include <hdf5.h>
 #include <nc_logging.h>
 
-#define FILE_NAME "tst_vl.nc"
+#define FILE_NAME "tst_h_vl.nc"
 int
 main()
 {
diff --git a/nc_test4/tst_hdf5_file_compat.c b/nc_test4/tst_hdf5_file_compat.c
index 51a3ae6..4813d9d 100644
--- a/nc_test4/tst_hdf5_file_compat.c
+++ b/nc_test4/tst_hdf5_file_compat.c
@@ -33,7 +33,6 @@
 
 int main(int argc, char **argv) {
 
-  int res = 0;
   int ncid = 0;
 
   printf("\n*** Testing libhdf5 file compatibility (open files generated by hdf5 1.10).\n");
diff --git a/nc_test4/tst_interops.c b/nc_test4/tst_interops.c
index 0050bf7..086336e 100644
--- a/nc_test4/tst_interops.c
+++ b/nc_test4/tst_interops.c
@@ -390,11 +390,7 @@ main(int argc, char **argv)
       /* Open the file with HDF5 while netcdf still has it open. */
       if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
       /* Turn this off for*/
-#ifdef EXTRA_TESTS
       if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) ERR;
-#else
-      if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
-#endif
       if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, fapl_id)) < 0) ERR;
       if (H5Pclose(fapl_id) < 0) ERR;
       if (H5Fclose(fileid) < 0) ERR;
diff --git a/nc_test4/tst_interops2.c b/nc_test4/tst_interops2.c
index 412878c..d83fdb9 100644
--- a/nc_test4/tst_interops2.c
+++ b/nc_test4/tst_interops2.c
@@ -3,6 +3,7 @@
    COPYRIGHT file for conditions of use.
 
    Test that NetCDF-4 can read HDF4 files.
+   Ed Hartnett
 */
 #include <config.h>
 #include <nc_tests.h>
@@ -10,6 +11,7 @@
 #include <hdf5.h>
 #include <H5DSpublic.h>
 #include <mfhdf.h>
+#include <netcdf_f.h>
 
 #define FILE_NAME "tst_interops2.h4"
 
@@ -56,6 +58,15 @@ main(int argc, char **argv)
       if (nc_inq_dim(ncid, 1, NULL, &len_in)) ERR;
       if (len_in != LON_LEN) ERR;
 
+      /* THese won't work. */
+      if (nc_redef(ncid) != NC_EPERM) ERR;
+      if (nc_def_var(ncid, "wow", NC_INT, 0, NULL, NULL) != NC_EPERM) ERR;
+      if (nc_def_var_chunking(ncid, 0, NC_CONTIGUOUS, NULL) != NC_EPERM) ERR;
+
+      /* Expected this to return NC_EPERM, but instead it returns
+       * success. See github issue #744. */
+      if (nc_def_var_chunking_ints(ncid, 0, NC_CONTIGUOUS, NULL)) ERR;
+      
       /* Read the data through a vara function from the netCDF API. */
       if (nc_get_vara(ncid, 0, nstart, ncount, data_in)) ERR;
       for (i = 0; i < LAT_LEN; i++)
diff --git a/nc_test4/tst_interops3.c b/nc_test4/tst_interops3.c
index b1a0c8f..4603e88 100644
--- a/nc_test4/tst_interops3.c
+++ b/nc_test4/tst_interops3.c
@@ -4,6 +4,8 @@
 
    Test that NetCDF-4 can read a bunch of HDF4 files pulled in from
    the FTP site.
+
+   @author Ed Hartnett
 */
 
 #include <config.h>
@@ -11,7 +13,55 @@
 #include "err_macros.h"
 #include <mfhdf.h>
 
-#define FILE_NAME "tst_interops2.h4"
+#define FILE_NAME "tst_interops3.h4"
+
+/* Function to test nc_inq_format(). */
+int
+check_inq_format(int ncid, int expected_format, int expected_extended_format, int expected_mode)
+{
+   int format;
+   int extended_format;
+   int mode;
+   
+   if (nc_inq_format(ncid + 66000, NULL) != NC_EBADID) ERR;
+   if (nc_inq_format(ncid, NULL)) ERR;
+   if (nc_inq_format(ncid, &format)) ERR;
+   if (format != expected_format) {
+      printf("format %d expected_format %d\n", format, expected_format);      
+      ERR;
+   }
+   if (nc_inq_format_extended(ncid + 66000, &extended_format, &mode) != NC_EBADID) ERR;
+   {
+      int mode;
+      if (nc_inq_format_extended(ncid, NULL, &mode)) ERR;
+      if (mode != expected_mode) {
+         printf("expected_mode %x mode %x\n", expected_mode, mode);
+         //ERR;
+      }
+   }
+   {
+      int extended_format;
+      if (nc_inq_format_extended(ncid, &extended_format, NULL)) ERR;
+      if (extended_format != expected_extended_format) ERR;
+   }
+
+   if (nc_inq_format_extended(ncid, &extended_format, &mode)) ERR;
+   if (mode != expected_mode) ERR;
+   if (extended_format != expected_extended_format) ERR;
+
+   /* Nothing to do with inq_format, but let's check the base_pe
+    * functions. */
+   if (expected_format == NC_FORMAT_CLASSIC || expected_format == NC_FORMAT_64BIT_OFFSET ||
+       expected_format == NC_FORMAT_CDF5) {
+      if (nc_set_base_pe(ncid, 0)) ERR;
+      if (nc_inq_base_pe(ncid, NULL)) ERR;
+   } else {
+      if (nc_set_base_pe(ncid, 0) != NC_ENOTNC3) ERR;
+      if (nc_inq_base_pe(ncid, NULL) != NC_ENOTNC3) ERR;
+   }
+
+   return 0;
+}
 
 int
 main(int argc, char **argv)
@@ -28,12 +78,15 @@ main(int argc, char **argv)
 							   "MYD29.A2002185.0000.005.2007160150627.hdf",
 							   "MYD29.A2009152.0000.005.2009153124331.hdf"};
       size_t len_in;
+      int expected_mode = NC_NETCDF4;
+      int expected_extended_format = NC_FORMATX_NC_HDF4;
       int f;
 
       for (f = 0; f < NUM_SAMPLE_FILES; f++)
       {
 	 if (nc_open(file_name[f], NC_NOWRITE, &ncid)) ERR;
 	 if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR;
+         if (check_inq_format(ncid, NC_FORMAT_NETCDF4, expected_extended_format, expected_mode)) ERR;
 	 if (nc_close(ncid)) ERR;
       }
    }
diff --git a/nc_test4/tst_interops5.c b/nc_test4/tst_interops5.c
index 3869106..44c3274 100644
--- a/nc_test4/tst_interops5.c
+++ b/nc_test4/tst_interops5.c
@@ -194,14 +194,10 @@ main(int argc, char **argv)
       hid_t fileid, grpid, spaceid, datasetid;
       int data_out[DIM1_LEN], data_in[DIM1_LEN];
       hsize_t dims[1] = {DIM1_LEN};
-      H5Z_filter_t filter;
-      int num_filters;
       hid_t propid;
-      unsigned int flags, cd_values[NUM_CD_ELEM], filter_config;
-      size_t cd_nelems = NUM_CD_ELEM;
-      size_t namelen = MAX_NAME;
-      char name[MAX_NAME + 1], name_in[MAX_NAME + 1];
+      char name_in[MAX_NAME + 1];
       int ncid, ndims_in, nvars_in, ngatts_in, unlimdimid_in, ngrps_in;
+      int nc_grpid;
       int dimid_in[1], natts_in;
 
       nc_type xtype_in;
@@ -236,19 +232,19 @@ main(int argc, char **argv)
       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
       if (nc_inq(ncid, &ndims_in, &nvars_in, &ngatts_in, &unlimdimid_in)) ERR;
       if (ndims_in != 0 || nvars_in != 0 || ngatts_in != 0 || unlimdimid_in != -1) ERR;
-      if (nc_inq_grps(ncid, &ngrps_in, &grpid)) ERR;
+      if (nc_inq_grps(ncid, &ngrps_in, &nc_grpid)) ERR;
       if (ngrps_in != 1) ERR;
-      if (nc_inq(grpid, &ndims_in, &nvars_in, &ngatts_in, &unlimdimid_in)) ERR;
+      if (nc_inq(nc_grpid, &ndims_in, &nvars_in, &ngatts_in, &unlimdimid_in)) ERR;
       if (ndims_in != 1 || nvars_in != 1 || ngatts_in != 0 || unlimdimid_in != -1) ERR;
 
       /* Check the variable. */
-      if (nc_inq_var(grpid, 0, name_in, &xtype_in, &ndims_in, dimid_in,
+      if (nc_inq_var(nc_grpid, 0, name_in, &xtype_in, &ndims_in, dimid_in,
       		     &natts_in)) ERR;
       if (strcmp(name_in, BATTLE_RECORD) || xtype_in != NC_INT || ndims_in != 1 ||
       	  dimid_in[0] != 0 || natts_in != 0) ERR;
 
       /* Check the data. */
-      if (nc_get_var(grpid, 0, data_in)) ERR;
+      if (nc_get_var(nc_grpid, 0, data_in)) ERR;
       for (i = 0; i < DIM1_LEN; i++)
 	 if (data_in[i] != data_out[i]) ERR;
 
diff --git a/nc_test4/tst_large.c b/nc_test4/tst_large.c
index 0a069c1..5afac59 100644
--- a/nc_test4/tst_large.c
+++ b/nc_test4/tst_large.c
@@ -2,8 +2,9 @@
    Copyright 2005 University Corporation for Atmospheric Research/Unidata
    See COPYRIGHT file for conditions of use.
 
-   Test netcdf-4 variables.
-   $Id: tst_large.c,v 1.5 2009/05/18 10:26:24 ed Exp $
+   Test netcdf-4 large file fill values.
+
+   Ed Hartnett.
 */
 
 #include <nc_tests.h>
@@ -12,11 +13,9 @@
 #include "ncdispatch.h"
 
 #define FILE_NAME "tst_large.nc"
-#define NUMDIMS 2		/* rank of each variable in tests */
+#define NUMDIMS 2               /* rank of each variable in tests */
 #define DIM1 2048
-#define DIM2 2097153		/* DIM1*DIM2*sizeof(char)   > 2**32 */
-
-
+#define DIM2 2097153            /* DIM1*DIM2*sizeof(char)   > 2**32 */
 
 int
 main(int argc, char **argv)
@@ -34,7 +33,7 @@ main(int argc, char **argv)
 
       /* Create phony data. */
       for (j = 0; j < DIM2; j++)
-	 vals[j] = 9 * (j + 11); /* note vals[j] is 99 when j==0 */
+         vals[j] = 9 * (j + 11); /* note vals[j] is 99 when j==0 */
 
       /* Create file with 2 dims and one var. */
       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
@@ -49,16 +48,13 @@ main(int argc, char **argv)
       if (nc_close(ncid)) ERR;
 
       /* Reopen and read a value. */
-/*       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; */
-/*       if (nc_inq_varid(ncid, "var", &varid)) ERR; */
-/*       if (nc_get_var1_schar(ncid, varid, index, &char_val_in)) ERR; */
-/*       if (char_val_in != 99)	/\* see above, the value written when start[0]==0, j==0 *\/ */
-/* 	 ERR; */
-/*       if (nc_close(ncid)) ERR; */
+      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
+      if (nc_inq_varid(ncid, "var", &varid)) ERR;
+      if (nc_get_var1_schar(ncid, varid, index, &char_val_in)) ERR;
+      if (char_val_in != 99)    /* see above, the value written when start[0]==0, j==0 */
+         ERR;
+      if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
-
-   nc_finalize();
-
    FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_large2.c b/nc_test4/tst_large2.c
index dd22b53..48cbe3e 100644
--- a/nc_test4/tst_large2.c
+++ b/nc_test4/tst_large2.c
@@ -40,7 +40,7 @@ int main(int argc, char **argv)
 	 {"64-bit offset", "netCDF-4"};
       int i, j, f;
 
-      printf("sizes: int - %d, size_t - %d, and int * - %d\n",
+      printf("sizes: int - %ld, size_t - %ld, and int * - %ld\n",
 	     sizeof(int), sizeof(size_t), sizeof(int *));
 
       /* Allocate room for one slab of data. */
@@ -83,7 +83,7 @@ int main(int argc, char **argv)
 	       {
 		  if (data[j + LON_LEN * i] != (start[0] + i + j) % 19)
 		  {
-		     printf("error on start[0]: %d i: %d j: %d expected %d got %g\n",
+		     printf("error on start[0]: %ld i: %ld j: %ld expected %d got %g\n",
 			    start[0], i, j, (start[0] + i + j), data[j + LON_LEN * i]);
 		     ERR_RET;
 		  }
@@ -96,7 +96,5 @@ int main(int argc, char **argv)
    }
    SUMMARIZE_ERR;
 
-   nc_finalize();
-
    FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_large3.c b/nc_test4/tst_large3.c
index 05fff4d..4f43a6a 100644
--- a/nc_test4/tst_large3.c
+++ b/nc_test4/tst_large3.c
@@ -6,7 +6,7 @@
  features. It turns off fill mode to quickly create an 8 gb file, and
  write one value is written, nothing is read.
 
- $Id$
+ @author Ed Hartnett
 */
 #include <config.h>
 #include <nc_tests.h>
@@ -32,7 +32,7 @@
 #define QTR_CLASSIC_MAX (MAX_CLASSIC_BYTES/4)
 
 /* We will create this file. */
-#define FILE_NAME "tst_large.nc"
+#define FILE_NAME "tst_large3.nc"
 
 int
 main(int argc, char **argv)
@@ -96,8 +96,6 @@ main(int argc, char **argv)
 
     SUMMARIZE_ERR;
 
-    nc_finalize();
-
     FINAL_RESULTS;
 }
 
diff --git a/nc_test4/tst_large5.c b/nc_test4/tst_large5.c
index 32cd7cb..0b5c401 100644
--- a/nc_test4/tst_large5.c
+++ b/nc_test4/tst_large5.c
@@ -140,7 +140,5 @@ main(int argc, char **argv)
    }
    SUMMARIZE_ERR;
 
-   nc_finalize();
-
    FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_rehash.c b/nc_test4/tst_rehash.c
index 8fb5c4e..460dee9 100644
--- a/nc_test4/tst_rehash.c
+++ b/nc_test4/tst_rehash.c
@@ -16,16 +16,19 @@ int main()
 {
   int  status;
   int  id;
-  int  rh_id, varid, v1, v2, v3, v4;
+  int  v1, v2, v3, v4;
   int  dimids[2];
 
 
   nc_create(FILENAME, NC_CLOBBER, &id);
   nc_redef(id);
 
-  status = nc_def_dim(id, "dim1", 10, &dimids[0]);
-  status = nc_def_var(id, "dim1", NC_FLOAT, 1, dimids, &v1);
-  status = nc_def_var(id, "var1", NC_FLOAT, 1, dimids, &v2);
+  if ((status = nc_def_dim(id, "dim1", 10, &dimids[0])))
+      return status;
+  if ((status = nc_def_var(id, "dim1", NC_FLOAT, 1, dimids, &v1)))
+      return status;
+  if ((status = nc_def_var(id, "var1", NC_FLOAT, 1, dimids, &v2)))
+      return status;
 
   nc_close(id);
 
@@ -35,7 +38,8 @@ int main()
   nc_rename_var(id, v1,"dim_new1");
   nc_rename_dim(id, dimids[0], "dim_new1");
 
-  status = nc_def_dim(id, "dim2", 20, &dimids[1]);
+  if ((status = nc_def_dim(id, "dim2", 20, &dimids[1])))
+      return status;
   nc_def_var(id, "dim2", NC_FLOAT, 1, &dimids[1], &v3);
   nc_def_var(id, "var2", NC_FLOAT, 2, dimids,    &v4);
 
diff --git a/nc_test4/tst_rename.c b/nc_test4/tst_rename.c
index 178ddbb..87ba17e 100644
--- a/nc_test4/tst_rename.c
+++ b/nc_test4/tst_rename.c
@@ -1,167 +1,398 @@
 /*
- * Demonstrate netcdf-4 rename bug.
+ * Test renames of vars and dims. It's a surprisingly tricky business.
+ *
+ * Quincey Koziol, Ed Hartnett
  */
 
-#include <netcdf.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* On error, prints line number and file of test program. */
-#define ERR do {                                     \
-fflush(stdout);                                      \
-fprintf(stderr, "Unexpected result, %s, line: %d\n", \
-	__FILE__, __LINE__);                         \
-return 2;                                            \
-} while (0)
-
-#define FILE_NAME3 "tst_rnfix3.nc"
-#define FILE_NAME4 "tst_rnfix4.nc"
-#define ODIM_NAME "lat"		/* name for coord dim */
-#define NDIM_NAME "tal"		/* new name for coord dim */
-#define OVAR_NAME "lat"		/* name for coord var */
-#define NVAR_NAME "tal"		/* new name for coord var */
-#define OVAR2_NAME "rh"		/* name for non-coord var that uses coord dim */
-#define VAR_RANK 1		/* all vars in this test are of same rank */
-#define DIM_LEN 2		/* all dims in this test are of same len */
+#include "nc_tests.h"
+#include "err_macros.h"
+
+#define FILE_NAME3 "tst_rename_fix3.nc"
+#define FILE_NAME4 "tst_rename_fix4.nc"
+#define ODIM_NAME "lat"         /* name for coord dim */
+#define LAT "lat"
+#define TAL "tal"
+#define TAL1 "tal1"
+#define TAL2 "tal2"
+#define RH "rh"
+#define NDIM_NAME "tal"         /* new name for coord dim */
+#define OVAR_NAME "lat"         /* name for coord var */
+#define NVAR_NAME "tal"         /* new name for coord var */
+#define OVAR2_NAME "rh"         /* name for non-coord var that uses coord dim */
+#define VAR_RANK 1              /* all vars in this test are of same rank */
+#define DIM_LEN 2               /* all dims in this test are of same len */
+
+/* Test data. */
+int lats[DIM_LEN] = {-90, 90};
+float rh[DIM_LEN] = {0.25, 0.75};
 
 /* For renaming tests.  Create small test file of specified format
  * with a coordinate dimension, corresponding coordinate variable, and
- * a non-coordinate variable that uses the coordinate dimension.
- */
+ * a non-coordinate variable that uses the coordinate dimension. */
 int
-create_test_file(
-    char *path,	/* filename */
-    int format	/* NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
-		   NC_FORMAT_NETCDF4, or NC_FORMAT_NETCDF4_CLASSIC */
-    ) 
+create_test_file(char *path, int format)
 {
-    int ncid, dimid, varid, var2id;
-    int dims[VAR_RANK];
-    int lats[DIM_LEN] = {-90, 90};
-    float rh[DIM_LEN] = {0.25, 0.75};
-    switch (format) {
-    case (NC_FORMAT_CLASSIC):
-	if (nc_create(path, 0, &ncid)) ERR;
-	break;
-    case (NC_FORMAT_64BIT_OFFSET):
-	if (nc_create(path, NC_64BIT_OFFSET, &ncid)) ERR;
-	break;
-    case (NC_FORMAT_NETCDF4):
-	if (nc_create(path, NC_NETCDF4, &ncid)) ERR;
-	break;
-    case(NC_FORMAT_NETCDF4_CLASSIC):
-	if (nc_create(path, NC_NETCDF4 | NC_CLASSIC_MODEL, &ncid)) ERR;
-	break;
-    default:
-	ERR;
-	return NC_ENOTNC;
-    }    
-    if (nc_def_dim(ncid, ODIM_NAME, DIM_LEN, &dimid)) ERR;
-    dims[0] = dimid;
-    if (nc_def_var(ncid, OVAR_NAME, NC_INT, VAR_RANK, dims, &varid)) ERR;
-    if (nc_def_var(ncid, OVAR2_NAME, NC_FLOAT, VAR_RANK, dims, &var2id)) ERR;
-    if (nc_enddef(ncid)) ERR;	/* not necessary for netCDF-4 files */
-    if (nc_put_var_int(ncid, varid, lats)) ERR;
-    if (nc_put_var_float(ncid, var2id, rh)) ERR;
-    if (nc_close(ncid)) ERR;
-    return 0;
+   int ncid, varid, var2id;
+   int dims[VAR_RANK];
+
+   if (nc_set_default_format(format, NULL)) ERR;
+   if (nc_create(path, 0, &ncid)) ERR;
+   if (nc_def_dim(ncid, LAT, DIM_LEN, &dims[0])) ERR;
+   if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, dims, &varid)) ERR;
+   if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, dims, &var2id)) ERR;
+   if (nc_enddef(ncid)) ERR;    /* not necessary for netCDF-4 files */
+   if (nc_put_var_int(ncid, varid, lats)) ERR;
+   if (nc_put_var_float(ncid, var2id, rh)) ERR;
+   if (nc_close(ncid)) ERR;
+   return 0;
 }
-      
+
+/* Check the file that was produced by create_test_file(). Only the
+ * names have been changed... */
+int
+check_file(int ncid, char *var0_name, char *var1_name, char *dim_name)
+{
+   int varid;
+   int var2id;
+   int dimid;
+   int lats_in[DIM_LEN];
+   float rh_in[DIM_LEN];
+   int ii;
+
+   /* printf("checking for vars %s and %s, dim %s\n", var0_name, var1_name, */
+   /*        dim_name); */
+   
+   /* Check vars. Ids will change because of rename. */
+   if (nc_inq_varid(ncid, var0_name, &varid)) ERR;
+   if (nc_inq_varid(ncid, var1_name, &var2id)) ERR;
+
+   /* Check dim. */
+   if (nc_inq_dimid(ncid, dim_name, &dimid)) ERR;
+   if (dimid != 0) ERR;
+   
+   /* Check the lats. */
+   if (nc_get_var_int(ncid, varid, lats_in)) ERR;
+   for (ii = 0; ii < DIM_LEN; ii++)
+      if (lats_in[ii] != lats[ii])
+         ERR;
+
+   /* Check the RH. */
+   if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
+   for (ii = 0; ii < DIM_LEN; ii++)
+      if (rh_in[ii] != rh[ii])
+         ERR;
+
+   return 0;
+}
+
+/* Check the file created in Charlie Zender's test. See github
+ * #597. */
+int
+check_charlies_file(char *file, char *dim_name, char *var_name)
+{
+   int ncid;
+   int varid, dimid;
+   
+   if (nc_open(file, 0, &ncid)) ERR;
+   if (nc_inq_varid(ncid, var_name, &varid)) ERR;
+   if (nc_inq_dimid(ncid, dim_name, &dimid)) ERR;
+   if (varid || dimid) ERR;
+   if (nc_close(ncid)) ERR;
+   return NC_NOERR;
+}
+
 int
 main(int argc, char **argv)
 {
 #define NUM_FORMATS 2
-  int formats[NUM_FORMATS] = {NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};
-  char *fmt_names[] = {"netCDF-4", "netCDF-4 classic model"};
-  char *file_names[] = {FILE_NAME3, FILE_NAME4};
-  int format;
+   int formats[NUM_FORMATS] = {NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};
+   char *fmt_names[] = {"netCDF-4", "netCDF-4 classic model"};
+   char *file_names[] = {FILE_NAME3, FILE_NAME4};
+   int format;
 
-  fprintf(stderr,"*** Testing netcdf rename bugs and fixes.\n");
+   fprintf(stderr,"*** Testing netcdf rename bugs and fixes.\n");
+   nc_set_log_level(5);
 
-  for(format = 0; format < NUM_FORMATS; format++)
-    {
+   for (format = 0; format < NUM_FORMATS; format++)
+   /* for (format = 0; format < 1; format++) */
+   {
       int ncid, dimid, varid, var2id;
       int lats[DIM_LEN] = {-90, 90};
       int lats_in[DIM_LEN];
       float rh[DIM_LEN] = {0.25, 0.75};
       float rh_in[DIM_LEN];
       int ii;
-      
-      fprintf(stderr,"*** Test renaming coordinate variable and its dimension for %s...\n",
-	     fmt_names[format]);
-      if (create_test_file(file_names[format], formats[format])) ERR;
-      if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
-      if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
-      if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
-      if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
-      if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
-      if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR;
-      if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR;
-      if (nc_enddef(ncid)) ERR;
-      if (nc_get_var_int(ncid, varid, lats_in)) ERR;
-      for (ii = 0; ii < DIM_LEN; ii++) {
-	if (lats_in[ii] != lats[ii])
-	  fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
+
+      fprintf(stderr,"*** Test Charlie's test for renaming...");
+      {
+#define CHARLIE_TEST_FILE "tst_charlie_rename_coord_dim.nc"
+#define LON "lon"
+#define LONGITUDE "longitude"
+#define DIM1_LEN 4
+#define NDIM1 1
+         int ncid, dimid, varid;
+         float data[DIM1_LEN] = {0, 90.0, 180.0, 270.0};
+
+         /* Create a nice, simple file. This file will contain one
+          * dataset, "lon", which is a dimscale. */
+         if (nc_create(CHARLIE_TEST_FILE, NC_NETCDF4, &ncid)) ERR;
+         if (nc_def_dim(ncid, LON, DIM1_LEN, &dimid)) ERR;
+         if (nc_def_var(ncid, LON, NC_FLOAT, NDIM1, &dimid, &varid)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         if (nc_put_var_float(ncid, varid, data)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         /* Check the file. */
+         if (check_charlies_file(CHARLIE_TEST_FILE, LON, LON)) ERR;
+
+         /* Open the file and rename the dimension. This will cause
+          * lon to stop being a coord var and dimscale, and create a
+          * new dimscale without var dataset "longitude". Dataset
+          * "lon" will point to "longitude" as its dimscale. */
+         if (nc_open(CHARLIE_TEST_FILE, NC_WRITE, &ncid)) ERR;
+         if (nc_redef(ncid)) ERR;
+         if (nc_rename_dim(ncid, 0, LONGITUDE)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         /* Reopen the file to check. */
+         if (check_charlies_file(CHARLIE_TEST_FILE, LONGITUDE, LON)) ERR;
+
+         /* Open the file and rename the variable. This will remove
+          * the dimscale-only dataset "longitude" and rename the
+          * extisting dataset "lon" to "longitude". Variable
+          * "longitude" will become a coordinate var. */
+         /* if (nc_open(CHARLIE_TEST_FILE, NC_WRITE, &ncid)) ERR; */
+         /* if (nc_redef(ncid)) ERR; */
+         /* if (nc_rename_var(ncid, 0, LONGITUDE)) ERR; */
+         /* if (nc_enddef(ncid)) ERR; */
+         /* if (nc_close(ncid)) ERR; */
+
+         /* Reopen the file to check. */
+         /* if (check_charlies_file(CHARLIE_TEST_FILE, LONGITUDE, LONGITUDE)) ERR; */
       }
-      if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
-      for (ii = 0; ii < DIM_LEN; ii++) {
-	if (rh_in[ii] != rh[ii])
-	  fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
+      SUMMARIZE_ERR;
+
+      printf("*** testing renaming before enddef for %s...", fmt_names[format]);
+      {
+         int ncid, varid, var2id;
+         int dimid;
+         
+         if (nc_set_default_format(formats[format], NULL)) ERR;
+         if (nc_create(file_names[format], 0, &ncid)) ERR;
+         if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
+         if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
+         if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
+
+         /* Now rename the dim. */
+         if (nc_rename_dim(ncid, dimid, TAL)) ERR;
+         if (nc_rename_var(ncid, varid, TAL)) ERR;
+         
+         if (nc_enddef(ncid)) ERR;    /* not necessary for netCDF-4 files */
+         if (nc_put_var_int(ncid, varid, lats)) ERR;
+         if (nc_put_var_float(ncid, var2id, rh)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         /* Reopen and check. */
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         if (check_file(ncid, TAL, RH, TAL)) ERR;
+         if (nc_close(ncid)) ERR;
       }
-      if (nc_close(ncid)) ERR;
-
-      fprintf(stderr,"*** Test renaming just coordinate variable for %s...\n",
-	     fmt_names[format]);
-      if (create_test_file(file_names[format], formats[format])) ERR;
-      if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
-      if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
-      if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
-      if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
-      if (nc_redef(ncid)) ERR;  /* omitting this and nc_enddef call eliminates bug */
-      /* if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR; */
-      if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR;
-      if (nc_enddef(ncid)) ERR;
-      if (nc_get_var_int(ncid, varid, lats_in)) ERR;
-      for (ii = 0; ii < DIM_LEN; ii++) {
-	if (lats_in[ii] != lats[ii])
-	  fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
+      SUMMARIZE_ERR;
+
+      printf("*** testing renaming after enddef for %s...", fmt_names[format]);
+      {
+         int ncid, varid, var2id;
+         int dimid;
+         
+         if (nc_set_default_format(formats[format], NULL)) ERR;
+         if (nc_create(file_names[format], 0, &ncid)) ERR;
+         if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
+         if (nc_def_var(ncid, TAL1, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
+         if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         if (nc_redef(ncid)) ERR;
+
+         if (nc_rename_var(ncid, varid, TAL2)) ERR;
+         if (nc_rename_dim(ncid, dimid, TAL)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         
+         if (nc_put_var_int(ncid, varid, lats)) ERR;
+         if (nc_put_var_float(ncid, var2id, rh)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         /* Reopen and check. */
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         if (check_file(ncid, TAL2, RH, TAL)) ERR;
+         if (nc_close(ncid)) ERR;
       }
-      if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
-      for (ii = 0; ii < DIM_LEN; ii++) {
-	if (rh_in[ii] != rh[ii])
-	  fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
+      SUMMARIZE_ERR;
+      printf("*** testing more renaming after enddef for %s...", fmt_names[format]);
+      {
+         int ncid, varid, var2id;
+         int dimid;
+         
+         /* This will create a HDF5 file with two datasets, RH, and
+          * LAT. LAT is a dimscale. RH points to dimscale LAT. Life is
+          * so simple. */
+         if (nc_set_default_format(formats[format], NULL)) ERR;
+         if (nc_create(file_names[format], 0, &ncid)) ERR;
+         if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
+         if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
+         if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         if (nc_redef(ncid)) ERR;
+
+         /* This will cause dataset LAT to be renamed TAL. It will no
+          * longer be a dimscale. Dataset LAT will be created as a
+          * dimscale without a variable. Datasets RH and TAL will
+          * re-point to (new) dimscale LAT. */
+         if (nc_rename_var(ncid, varid, TAL)) ERR;
+         if (nc_enddef(ncid)) ERR;
+
+         if (nc_redef(ncid)) ERR;
+
+         /* This will cause dimscale-only dataset LAT to be
+          * deleted. Existing dataset TAL will become the dimscale
+          * dataset. Dataset RH will re-point to dimscale TAL. */
+         if (nc_rename_dim(ncid, dimid, TAL)) ERR;
+         if (nc_enddef(ncid)) ERR;
+
+         /* Varids have changed, so get them again. */
+         if (nc_inq_varid(ncid, TAL, &varid)) ERR;
+         if (nc_inq_varid(ncid, RH, &var2id)) ERR;
+
+         /* Write some data. */
+         if (nc_put_var_int(ncid, varid, lats)) ERR;
+         if (nc_put_var_float(ncid, var2id, rh)) ERR;
+         if (nc_close(ncid)) ERR;
+
+         /* Reopen and check. */
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         if (check_file(ncid, TAL, RH, TAL)) ERR;
+         if (nc_close(ncid)) ERR;
       }
-      if (nc_close(ncid)) ERR;
+      SUMMARIZE_ERR;
+
+      printf("*** testing renaming after enddef for %s...", fmt_names[format]);
+      {
+         int ncid, varid, var2id;
+         int dimid;
+         
+         if (nc_set_default_format(formats[format], NULL)) ERR;
+         if (nc_create(file_names[format], 0, &ncid)) ERR;
+         if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
+         if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
+         if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
+         if (nc_enddef(ncid)) ERR;    /* not necessary for netCDF-4 files */
+         if (nc_redef(ncid)) ERR;    /* not necessary for netCDF-4 files */
+
+         /* Now rename the dim. */
+         if (nc_rename_dim(ncid, dimid, TAL)) ERR;
+         if (nc_rename_var(ncid, varid, TAL)) ERR;
+         if (nc_enddef(ncid)) ERR;    /* not necessary for netCDF-4 files */
+         
+         if (nc_put_var_int(ncid, varid, lats)) ERR;
+         if (nc_put_var_float(ncid, var2id, rh)) ERR;
+         if (nc_close(ncid)) ERR;
 
+         /* Reopen and check. */
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         /* if (check_file(ncid, LAT, RH, TAL)) ERR; */
+         /* if (check_file(ncid, TAL, RH, TAL)) ERR; */
+         if (nc_close(ncid)) ERR;
+      }
+      SUMMARIZE_ERR;
       
-      fprintf(stderr,"*** Test renaming just coordinate dimension for %s...\n",
-	     fmt_names[format]);
-      if (create_test_file(file_names[format], formats[format])) ERR;
-      if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
-      if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
-      if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
-      if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
-      if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
-      if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR;
-      /* if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR; */
-      if (nc_enddef(ncid)) ERR;
-      if (nc_get_var_int(ncid, varid, lats_in)) ERR;
-      for (ii = 0; ii < DIM_LEN; ii++) {
-	if (lats_in[ii] != lats[ii])
-	  fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
+      printf("*** testing renaming after enddef for %s...", fmt_names[format]);
+      {
+         /* Create a file with datasets LAT, RH. LAT is a dimscale. RH
+          * points to LAT. */
+         if (create_test_file(file_names[format], formats[format])) ERR;
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         if (nc_inq_dimid(ncid, LAT, &dimid)) ERR;
+         if (nc_inq_varid(ncid, LAT, &varid)) ERR;
+         if (nc_inq_varid(ncid, RH, &var2id)) ERR;
+         if (check_file(ncid, LAT, RH, LAT)) ERR;
+         if (nc_redef(ncid)) ERR;
+
+         /* Rename the dim. This creates new dataset TAL. LAT is no
+          * longer a dimscale. RH is repointed to TAL. LAT is pointed
+          * to TAL. */
+         if (nc_rename_dim(ncid, dimid, TAL)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         if (nc_redef(ncid)) ERR;
+
+         /* Rename the var. This will remove dimscale-only dataset
+          * TAL. LAT will become a dimscale. RH will point to LAT. */
+         if (nc_rename_var(ncid, varid, TAL)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         /* if (check_file(ncid, LAT, RH, TAL)) ERR; */
+         if (nc_close(ncid)) ERR;
+
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         /* if (check_file(ncid, LAT, RH, TAL)) ERR; */
+         if (nc_close(ncid)) ERR;
+      }
+      SUMMARIZE_ERR;
+
+      fprintf(stderr,"*** Test renaming just coordinate variable for %s...",
+              fmt_names[format]);
+      {
+         if (create_test_file(file_names[format], formats[format])) ERR;
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
+         if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
+         if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
+         if (nc_redef(ncid)) ERR;  /* omitting this and nc_enddef call eliminates bug */
+         /* if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR; */
+         if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR;
+         if (nc_enddef(ncid)) ERR;
+         if (nc_get_var_int(ncid, varid, lats_in)) ERR;
+         for (ii = 0; ii < DIM_LEN; ii++) {
+            if (lats_in[ii] != lats[ii])
+               fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
+         }
+         if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
+         for (ii = 0; ii < DIM_LEN; ii++) {
+            if (rh_in[ii] != rh[ii])
+               fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
+         }
+         if (nc_close(ncid)) ERR;
       }
-      if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
-      for (ii = 0; ii < DIM_LEN; ii++) {
-	if (rh_in[ii] != rh[ii])
-	  fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
+      SUMMARIZE_ERR;
+
+      fprintf(stderr,"*** Test renaming just coordinate dimension for %s...",
+              fmt_names[format]);
+      {
+         if (create_test_file(file_names[format], formats[format])) ERR;
+         if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
+         if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
+         if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
+         if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
+         if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
+         if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR;
+         /* if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR; */
+         if (nc_enddef(ncid)) ERR;
+         if (nc_get_var_int(ncid, varid, lats_in)) ERR;
+         for (ii = 0; ii < DIM_LEN; ii++) {
+            if (lats_in[ii] != lats[ii])
+               fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
+         }
+         if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
+         for (ii = 0; ii < DIM_LEN; ii++) {
+            if (rh_in[ii] != rh[ii])
+               fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
+         }
+         if (nc_close(ncid)) ERR;
       }
-      if (nc_close(ncid)) ERR;
+      SUMMARIZE_ERR;
 
-      if (formats[format] == NC_FORMAT_NETCDF4) {
-          printf("*** Test renaming attribute in sub-group for %s...\n",
+      if (formats[format] == NC_FORMAT_NETCDF4)
+      {
+         printf("*** Test renaming attribute in sub-group for %s...",
                 fmt_names[format]);
-          {
+         {
 #define DIMNAME "lon"
 #define VARNAME "lon"
 #define G1_VARNAME "lon"
@@ -173,7 +404,7 @@ main(int argc, char **argv)
 #define RANK_g1_lon 1
 
             /* IDs of file, groups, dimensions, variables, attributes */
-            int ncid, g1_grp, lon_dim, lon_var, g1_lon_var, units_att;
+            int ncid, g1_grp, lon_dim, lon_var, g1_lon_var;
             size_t lon_len = 4;
             char *data_in;
 
@@ -199,16 +430,16 @@ main(int argc, char **argv)
             if (nc_enddef (ncid)) ERR;
             /* write variable data */
             {
-              float lon_data[4] = {0, 90, 180, 270};
-              size_t start[] = {0};
-              size_t count[] = {4};
-              if (nc_put_vara(ncid, lon_var, start, count, lon_data)) ERR;
+               float lon_data[4] = {0, 90, 180, 270};
+               size_t start[] = {0};
+               size_t count[] = {4};
+               if (nc_put_vara(ncid, lon_var, start, count, lon_data)) ERR;
             }
             {
-              float g1_lon_data[4] = {0, 90, 180, 270};
-              size_t start[] = {0};
-              size_t count[] = {4};
-              if (nc_put_vara(g1_grp, g1_lon_var, start, count, g1_lon_data)) ERR;
+               float g1_lon_data[4] = {0, 90, 180, 270};
+               size_t start[] = {0};
+               size_t count[] = {4};
+               if (nc_put_vara(g1_grp, g1_lon_var, start, count, g1_lon_data)) ERR;
             }
             if (nc_close(ncid)) ERR;
 
@@ -222,20 +453,18 @@ main(int argc, char **argv)
             /* reopen the file again and see if renamed attribute exists and
                has expected value */
             {
-              nc_type att_type;
-              size_t att_len;
-
-              if (nc_open(file_names[format], NC_NOWRITE, &ncid)) ERR;
-              if (nc_inq_grp_ncid(ncid, GRP_NAME, &g1_grp)) ERR;
-              if (nc_inq_varid(g1_grp, VARNAME, &g1_lon_var)) ERR;
-              if (nc_get_att_text(g1_grp, g1_lon_var, NEW_NAME, data_in)) ERR;
-              if (strncmp(CONTENTS, data_in, strlen(CONTENTS))) ERR;
-              if (nc_close(ncid)) ERR;
+
+               if (nc_open(file_names[format], NC_NOWRITE, &ncid)) ERR;
+               if (nc_inq_grp_ncid(ncid, GRP_NAME, &g1_grp)) ERR;
+               if (nc_inq_varid(g1_grp, VARNAME, &g1_lon_var)) ERR;
+               if (nc_get_att_text(g1_grp, g1_lon_var, NEW_NAME, data_in)) ERR;
+               if (strncmp(CONTENTS, data_in, strlen(CONTENTS))) ERR;
+               if (nc_close(ncid)) ERR;
             }
             free(data_in);
-          }
+         }
+         SUMMARIZE_ERR;
       }
-    }
-
-  return(0);
+   } /* next format */
+   FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_simplerw_coll_r.c b/nc_test4/tst_simplerw_coll_r.c
index 098db49..51d3dbb 100644
--- a/nc_test4/tst_simplerw_coll_r.c
+++ b/nc_test4/tst_simplerw_coll_r.c
@@ -1,28 +1,19 @@
-/*   Copyright 2007-2011, UCAR/Unidata. See COPYRIGHT file for copying
-  and redistribution conditions.
-
-  This is part of the netCDF package.
-
-  This is a benchmarking program for netCDF-4 parallel I/O.
-*/
-
-/* Defining USE_MPE causes the MPE trace library to be used (and you
- * must also relink with -llmpe -lmpe). This causes clog2 output to be
- * written, which can be converted to slog2 (by the program
- * clog2TOslog2) and then used in the analysis program jumpshot. */
-/*#define USE_MPE 1*/
-
-#include <mpi.h>
-#include <stdio.h>
-#include <string.h>
-#include <netcdf.h>
-#include <netcdf_par.h>
-
-#ifdef USE_MPE
-#include <mpe.h>
-#endif /* USE_MPE */
-
-#define FILE_NAME "tst_parallel4_simplerw_coll.nc"
+/* Copyright 2007-2011, UCAR/Unidata. See COPYRIGHT file for copying
+ * and redistribution conditions.
+ *
+ * This is part of the netCDF package.
+ *
+ * This test is for parallel IO and the collective access of metadata
+ * with HDF5.
+ *
+ * Ward Fisher, Ed Hartnett
+ */
+
+#include "config.h"
+#include "nc_tests.h"
+#include "err_macros.h"
+
+#define TEST_NAME "tst_parallel4_simplerw_coll"
 #define NDIMS 3
 #define DIMSIZE 16
 #define NUM_SLABS 16
@@ -30,220 +21,396 @@
 #define DIM2_NAME "x"
 #define DIM3_NAME "y"
 #define VAR_NAME "Bond_James_Bond"
-#define ERR do { \
-fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
-fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
-        __FILE__, __LINE__);                                \
-return 2;                                                   \
-} while (0)
+#define NUM_FILL_TEST_RUNS 3
 
 int
 main(int argc, char **argv)
 {
-    /* MPI stuff. */
-    int mpi_namelen;
-    char mpi_name[MPI_MAX_PROCESSOR_NAME];
-    int mpi_size, mpi_rank;
-    MPI_Comm comm = MPI_COMM_WORLD;
-    MPI_Info info = MPI_INFO_NULL;
-    double start_time = 0, total_time;
-
-    /* Netcdf-4 stuff. */
-    int ncid, varid, dimids[NDIMS];
-    size_t start[NDIMS] = {0, 0, 0};
-    size_t count[NDIMS] = {1, DIMSIZE, DIMSIZE};
-    int data[DIMSIZE * DIMSIZE], data_in[DIMSIZE * DIMSIZE];
-    int j, i, ret;
-
-    char file_name[NC_MAX_NAME + 1];
-    int ndims_in, nvars_in, natts_in, unlimdimid_in;
-
-#ifdef USE_MPE
-    int s_init, e_init, s_define, e_define, s_write, e_write, s_close, e_close;
-#endif /* USE_MPE */
-
-    /* Initialize MPI. */
-    MPI_Init(&argc,&argv);
-    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
-    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
-    MPI_Get_processor_name(mpi_name, &mpi_namelen);
-    /*printf("mpi_name: %s size: %d rank: %d\n", mpi_name, mpi_size, mpi_rank);*/
-//#if 0
-    /* Must be able to evenly divide my slabs between processors. */
-    if (NUM_SLABS % mpi_size != 0)
-    {
-       if (!mpi_rank) printf("NUM_SLABS (%d) is not evenly divisible by mpi_size(%d)\n",
-                             NUM_SLABS, mpi_size);
-       ERR;
-    }
-
-#ifdef USE_MPE
-    MPE_Init_log();
-    s_init = MPE_Log_get_event_number();
-    e_init = MPE_Log_get_event_number();
-    s_define = MPE_Log_get_event_number();
-    e_define = MPE_Log_get_event_number();
-    s_write = MPE_Log_get_event_number();
-    e_write = MPE_Log_get_event_number();
-    s_close = MPE_Log_get_event_number();
-    e_close = MPE_Log_get_event_number();
-    s_open = MPE_Log_get_event_number();
-    e_open = MPE_Log_get_event_number();
-    MPE_Describe_state(s_init, e_init, "Init", "red");
-    MPE_Describe_state(s_define, e_define, "Define", "yellow");
-    MPE_Describe_state(s_write, e_write, "Write", "green");
-    MPE_Describe_state(s_close, e_close, "Close", "purple");
-    MPE_Describe_state(s_open, e_open, "Open", "blue");
-    MPE_Start_log();
-    MPE_Log_event(s_init, 0, "start init");
-#endif /* USE_MPE */
-
-/*     if (!mpi_rank) */
-/*     { */
-/*        printf("\n*** Testing parallel I/O some more.\n"); */
-/*        printf("*** writing a %d x %d x %d file from %d processors...\n",  */
-/*               NUM_SLABS, DIMSIZE, DIMSIZE, mpi_size); */
-/*     } */
-
-    /* We will write the same slab over and over. */
-    for (i = 0; i < DIMSIZE * DIMSIZE; i++)
-       data[i] = mpi_rank;
-
-#ifdef USE_MPE
-    MPE_Log_event(e_init, 0, "end init");
-    MPE_Log_event(s_define, 0, "start define file");
-#endif /* USE_MPE */
-
-    /* Create a parallel netcdf-4 file. */
-    if (nc_create_par(FILE_NAME, NC_NETCDF4|NC_MPIIO, comm, info, &ncid)) ERR;
-
-    /* A global attribute holds the number of processors that created
-     * the file. */
-    if (nc_put_att_int(ncid, NC_GLOBAL, "num_processors", NC_INT, 1, &mpi_size)) ERR;
-
-    /* Create three dimensions. */
-    if (nc_def_dim(ncid, DIM1_NAME, NUM_SLABS, dimids)) ERR;
-    if (nc_def_dim(ncid, DIM2_NAME, DIMSIZE, &dimids[1])) ERR;
-    if (nc_def_dim(ncid, DIM3_NAME, DIMSIZE, &dimids[2])) ERR;
-
-    /* Create one var. */
-    if (nc_def_var(ncid, VAR_NAME, NC_INT, NDIMS, dimids, &varid)) ERR;
-
-    /* Write metadata to file. */
-    if (nc_enddef(ncid)) ERR;
-
-#ifdef USE_MPE
-    MPE_Log_event(e_define, 0, "end define file");
-    if (mpi_rank)
-       sleep(mpi_rank);
-#endif /* USE_MPE */
-
-/*    if (nc_var_par_access(ncid, varid, NC_COLLECTIVE)) ERR;*/
-/*    if (nc_var_par_access(ncid, varid, NC_INDEPENDENT)) ERR;*/
-
-    if (!mpi_rank)
-       start_time = MPI_Wtime();
-
-    /* Write all the slabs this process is responsible for. */
-    for (i = 0; i < NUM_SLABS / mpi_size; i++)
-    {
-       start[0] = NUM_SLABS / mpi_size * mpi_rank + i;
-
-#ifdef USE_MPE
-       MPE_Log_event(s_write, 0, "start write slab");
-#endif /* USE_MPE */
-
-       /* Write one slab of data. */
-       if (nc_put_vara_int(ncid, varid, start, count, data)) ERR;
-
-#ifdef USE_MPE
-       MPE_Log_event(e_write, 0, "end write file");
-#endif /* USE_MPE */
-    }
-
-    if (!mpi_rank)
-    {
-       total_time = MPI_Wtime() - start_time;
-/*       printf("num_proc\ttime(s)\n");*/
-       printf("%d\t%g\t%g\n", mpi_size, total_time, DIMSIZE * DIMSIZE * NUM_SLABS * sizeof(int) / total_time);
-    }
-
-#ifdef USE_MPE
-    MPE_Log_event(s_close, 0, "start close file");
-#endif /* USE_MPE */
-
-    /* Close the netcdf file. */
-    if (nc_close(ncid))	ERR;
-
-//#endif
-#ifdef USE_MPE
-    MPE_Log_event(e_close, 0, "end close file");
-#endif /* USE_MPE */
-
-    /* Reopen the file and check it. */
-    if ((ret = nc_open_par(FILE_NAME, NC_NOWRITE|NC_MPIIO, comm, info, &ncid)))
-    {
-       printf("ret = %d\n", ret);
-       return -1;
-    }
-    if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
-    if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||
-        unlimdimid_in != -1) ERR;
-
-    /* Read all the slabs this process is responsible for. */
-    for (i = 0; i < NUM_SLABS / mpi_size; i++)
-    {
-       start[0] = NUM_SLABS / mpi_size * mpi_rank + i;
-
-#ifdef USE_MPE
-       MPE_Log_event(s_read, 0, "start read slab");
-#endif /* USE_MPE */
-
-      if(mpi_rank == 0) {
-for(j=0; j<3;j++)
-count[j] = 0;
-
-      }
-    if (nc_var_par_access(ncid, varid, NC_COLLECTIVE)) ERR;
-       /* Read one slab of data. */
-       if (nc_get_vara_int(ncid, varid, start, count, data_in)) ERR;
-
-if(mpi_rank != 0) {
-       /* Check data. */
-       for (j = 0; j < DIMSIZE * DIMSIZE; j++)
-	  if (data_in[j] != mpi_rank)
-	  {
-	     ERR;
-	     break;
-	  }
-}
-
-#ifdef USE_MPE
-       MPE_Log_event(e_read, 0, "end read file");
-#endif /* USE_MPE */
-    }
-
-#ifdef USE_MPE
-    MPE_Log_event(s_close, 0, "start close file");
-#endif /* USE_MPE */
-
-    /* Close the netcdf file. */
-    if (nc_close(ncid))	ERR;
-
-#ifdef USE_MPE
-    MPE_Log_event(e_close, 0, "end close file");
-#endif /* USE_MPE */
-
-    /* Delete this large file. */
-   // remove(file_name);
-
-    /* Shut down MPI. */
-    MPI_Finalize();
-
-/*     if (!mpi_rank) */
-/*     { */
-/*        SUMMARIZE_ERR; */
-/*        FINAL_RESULTS; */
-/*     } */
-    return 0;
+   int mpi_namelen;
+   char mpi_name[MPI_MAX_PROCESSOR_NAME];
+   int mpi_size, mpi_rank;
+   MPI_Comm comm = MPI_COMM_WORLD;
+   MPI_Info info = MPI_INFO_NULL;
+   double start_time = 0, total_time;
+   int mpi_size_in;
+#define NUM_TEST_TYPES 11
+   nc_type test_type[NUM_TEST_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE,
+                                        NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64};
+   int tt, fv;
+   int j, i, k, ret;
+
+   /* Initialize MPI. */
+   MPI_Init(&argc,&argv);
+   MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
+   MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+   MPI_Get_processor_name(mpi_name, &mpi_namelen);
+
+   /* Must be able to evenly divide my slabs between processors. */
+   if (NUM_SLABS % mpi_size)
+   {
+      if (!mpi_rank)
+         printf("NUM_SLABS (%d) is not evenly divisible by mpi_size(%d)\n",
+                NUM_SLABS, mpi_size);
+      ERR;
+   }
+
+   if (!mpi_rank)
+      printf("\n*** Testing parallel I/O some more.\n");
+
+   /* Test for different fill value settings. */
+   for (fv = 0; fv < NUM_FILL_TEST_RUNS; fv++)
+   {
+      /* Test for different netCDF types. */
+      for (tt = 0; tt < NUM_TEST_TYPES; tt++)
+      {
+         char file_name[NC_MAX_NAME + 1];
+         int fill_mode_in;
+         void *data, *data_in;
+         void *fill_value, *fill_value_in;
+         size_t type_size;
+         size_t write_start[NDIMS] = {0, 0, 1};
+         size_t write_count[NDIMS] = {1, DIMSIZE, DIMSIZE - 1};
+         size_t read_start[NDIMS] = {0, 0, 0};
+         size_t read_count[NDIMS] = {1, DIMSIZE, DIMSIZE};
+         int ncid, varid, dimids[NDIMS];
+         int ndims_in, nvars_in, natts_in, unlimdimid_in;
+
+         /* Fill values to be expected. */
+         signed char byte_expected_fill_value;
+         unsigned char char_expected_fill_value;
+         short short_expected_fill_value;
+         int int_expected_fill_value;
+         float float_expected_fill_value;
+         double double_expected_fill_value;
+         unsigned char ubyte_expected_fill_value;
+         unsigned short ushort_expected_fill_value;
+         unsigned int uint_expected_fill_value;
+         long long int int64_expected_fill_value;
+         unsigned long long int uint64_expected_fill_value;
+
+         /* Fill values used when writing. */
+         signed char byte_fill_value = -TEST_VAL_42;
+         unsigned char char_fill_value = 'x';
+         short short_fill_value = TEST_VAL_42 * 100;
+         int int_fill_value = TEST_VAL_42 * 1000;
+         float float_fill_value = TEST_VAL_42 * 1000;
+         double double_fill_value = TEST_VAL_42 * 1000;
+         unsigned char ubyte_fill_value = TEST_VAL_42;
+         unsigned short ushort_fill_value = TEST_VAL_42 * 100;
+         unsigned int uint_fill_value = TEST_VAL_42 * 1000;
+         long long int int64_fill_value = TEST_VAL_42 * 1000;
+         unsigned long long int uint64_fill_value = TEST_VAL_42 * 1000;
+
+         /* Fill values read in. */
+         signed char byte_fill_value_in;
+         unsigned char char_fill_value_in;
+         short short_fill_value_in;
+         int int_fill_value_in;
+         float float_fill_value_in;
+         double double_fill_value_in;
+         unsigned char ubyte_fill_value_in;
+         unsigned short ushort_fill_value_in;
+         unsigned int uint_fill_value_in;
+         long long int int64_fill_value_in;
+         unsigned long long int uint64_fill_value_in;
+         
+         /* Data to write and read. */
+         signed char byte_data[DIMSIZE * DIMSIZE], byte_data_in[DIMSIZE * DIMSIZE];
+         unsigned char char_data[DIMSIZE * DIMSIZE], char_data_in[DIMSIZE * DIMSIZE];
+         short short_data[DIMSIZE * DIMSIZE], short_data_in[DIMSIZE * DIMSIZE];
+         int int_data[DIMSIZE * DIMSIZE], int_data_in[DIMSIZE * DIMSIZE];
+         float float_data[DIMSIZE * DIMSIZE], float_data_in[DIMSIZE * DIMSIZE];
+         double double_data[DIMSIZE * DIMSIZE], double_data_in[DIMSIZE * DIMSIZE];
+         unsigned char ubyte_data[DIMSIZE * DIMSIZE], ubyte_data_in[DIMSIZE * DIMSIZE];
+         unsigned short ushort_data[DIMSIZE * DIMSIZE], ushort_data_in[DIMSIZE * DIMSIZE];
+         unsigned int uint_data[DIMSIZE * DIMSIZE], uint_data_in[DIMSIZE * DIMSIZE];
+         long long int int64_data[DIMSIZE * DIMSIZE], int64_data_in[DIMSIZE * DIMSIZE];
+         unsigned long long int uint64_data[DIMSIZE * DIMSIZE], uint64_data_in[DIMSIZE * DIMSIZE];
+         
+         if (!mpi_rank)
+            printf("*** writing a %d x %d x %d file from %d processors for fill value test %d type %d...\n",
+                   NUM_SLABS, DIMSIZE, DIMSIZE, mpi_size, fv, test_type[tt]);
+
+         /* Initialize test data. */
+         switch(test_type[tt])
+         {
+         case NC_BYTE:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               byte_data[i] = mpi_rank;
+            data = byte_data;
+            data_in = byte_data_in;
+            byte_expected_fill_value = fv ? byte_fill_value : NC_FILL_BYTE;
+            fill_value = &byte_expected_fill_value;
+            fill_value_in = &byte_fill_value_in;
+            break;
+         case NC_CHAR:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               char_data[i] = mpi_rank;
+            data = char_data;
+            data_in = char_data_in;
+            char_expected_fill_value = fv ? char_fill_value : NC_FILL_CHAR;
+            fill_value = &char_expected_fill_value;
+            fill_value_in = &char_fill_value_in;
+            break;
+         case NC_SHORT:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               short_data[i] = mpi_rank;
+            data = short_data;
+            data_in = short_data_in;
+            short_expected_fill_value = fv ? short_fill_value : NC_FILL_SHORT;
+            fill_value = &short_expected_fill_value;
+            fill_value_in = &short_fill_value_in;
+            break;
+         case NC_INT:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               int_data[i] = mpi_rank;
+            data = int_data;
+            data_in = int_data_in;
+            int_expected_fill_value = fv ? int_fill_value : NC_FILL_INT;
+            fill_value = &int_expected_fill_value;
+            fill_value_in = &int_fill_value_in;
+            break;
+         case NC_FLOAT:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               float_data[i] = mpi_rank;
+            data = float_data;
+            data_in = float_data_in;
+            float_expected_fill_value = fv ? float_fill_value : NC_FILL_FLOAT;
+            fill_value = &float_expected_fill_value;
+            fill_value_in = &float_fill_value_in;
+            break;
+         case NC_DOUBLE:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               double_data[i] = mpi_rank;
+            data = double_data;
+            data_in = double_data_in;
+            double_expected_fill_value = fv ? double_fill_value : NC_FILL_DOUBLE;
+            fill_value = &double_expected_fill_value;
+            fill_value_in = &double_fill_value_in;
+            break;
+         case NC_UBYTE:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               ubyte_data[i] = mpi_rank;
+            data = ubyte_data;
+            data_in = ubyte_data_in;
+            ubyte_expected_fill_value = fv ? ubyte_fill_value : NC_FILL_UBYTE;
+            fill_value = &ubyte_expected_fill_value;
+            fill_value_in = &ubyte_fill_value_in;
+            break;
+         case NC_USHORT:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               ushort_data[i] = mpi_rank;
+            data = ushort_data;
+            data_in = ushort_data_in;
+            ushort_expected_fill_value = fv ? ushort_fill_value : NC_FILL_USHORT;
+            fill_value = &ushort_expected_fill_value;
+            fill_value_in = &ushort_fill_value_in;
+            break;
+         case NC_UINT:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               uint_data[i] = mpi_rank;
+            data = uint_data;
+            data_in = uint_data_in;
+            uint_expected_fill_value = fv ? uint_fill_value : NC_FILL_UINT;
+            fill_value = &uint_expected_fill_value;
+            fill_value_in = &uint_fill_value_in;
+            break;
+         case NC_INT64:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               int64_data[i] = mpi_rank;
+            data = int64_data;
+            data_in = int64_data_in;
+            int64_expected_fill_value = fv ? int64_fill_value : NC_FILL_INT64;
+            fill_value = &int64_expected_fill_value;
+            fill_value_in = &int64_fill_value_in;
+            break;
+         case NC_UINT64:
+            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
+               uint64_data[i] = mpi_rank;
+            data = uint64_data;
+            data_in = uint64_data_in;
+            uint64_expected_fill_value = fv ? uint64_fill_value : NC_FILL_UINT64;
+            fill_value = &uint64_expected_fill_value;
+            fill_value_in = &uint64_fill_value_in;
+            break;
+         }
+      
+         /* Create a file name. */
+         sprintf(file_name, "%s_type_%d_fv_%d.nc", TEST_NAME, test_type[tt], fv);
+
+         /* Create a parallel netcdf-4 file. */
+         if (nc_create_par(file_name, NC_NETCDF4|NC_MPIIO, comm, info, &ncid)) ERR;
+
+         /* Get the type len. */
+         if (nc_inq_type(ncid, test_type[tt], NULL, &type_size)) ERR;
+
+         /* A global attribute holds the number of processors that created
+          * the file. */
+         if (nc_put_att_int(ncid, NC_GLOBAL, "num_processors", NC_INT, 1, &mpi_size)) ERR;
+
+         /* Create three dimensions. */
+         if (nc_def_dim(ncid, DIM1_NAME, NUM_SLABS, dimids)) ERR;
+         if (nc_def_dim(ncid, DIM2_NAME, DIMSIZE, &dimids[1])) ERR;
+         if (nc_def_dim(ncid, DIM3_NAME, DIMSIZE, &dimids[2])) ERR;
+
+         /* Create one var. */
+         if (nc_def_var(ncid, VAR_NAME, test_type[tt], NDIMS, dimids, &varid)) ERR;
+         if (nc_put_att_int(ncid, varid, "var_num_processors", NC_INT, 1, &mpi_size)) ERR;
+         if (fv == 1)
+         {
+            if (nc_def_var_fill(ncid, varid, NC_FILL, fill_value)) ERR;
+            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, fill_value_in)) ERR;
+            if (fill_mode_in != NC_FILL) ERR;
+            if (memcmp(fill_value_in, fill_value, type_size)) ERR;
+         }
+         else if (fv == 2)
+         {
+            if (nc_def_var_fill(ncid, varid, NC_NOFILL, NULL)) ERR;
+            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, NULL)) ERR;
+            if (!fill_mode_in) ERR; /* nofill will be true */
+         }            
+
+         /* Write metadata to file. */
+         if (nc_enddef(ncid)) ERR;
+
+         /* Change access mode to collective, then back to independent. */
+         if (nc_var_par_access(ncid, varid, NC_COLLECTIVE)) ERR;
+         if (nc_var_par_access(ncid, varid, NC_INDEPENDENT)) ERR;
+
+         if (!mpi_rank)
+            start_time = MPI_Wtime();
+
+         /* Write all the slabs this process is responsible for. */
+         for (i = 0; i < NUM_SLABS / mpi_size; i++)
+         {
+            write_start[0] = NUM_SLABS / mpi_size * mpi_rank + i;
+
+            /* Write one slab of data. Due to start/count settings,
+             * every 16th value will be a fill value. */
+            if (nc_put_vara(ncid, varid, write_start, write_count, data)) ERR;
+         }
+
+         /* On rank 0, keep track of time. */
+         if (!mpi_rank)
+         {
+            total_time = MPI_Wtime() - start_time;
+            printf("%d\t%g\t%g\n", mpi_size, total_time, DIMSIZE * DIMSIZE * NUM_SLABS *
+                   sizeof(int) / total_time);
+         }
+
+         /* Close the netcdf file. */
+         if (nc_close(ncid)) ERR;
+
+         /* Reopen the file and check it. */
+         if ((ret = nc_open_par(file_name, NC_NOWRITE|NC_MPIIO, comm, info, &ncid))) ERR;
+         if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
+         if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||
+             unlimdimid_in != -1) ERR;
+
+         /* Check the attributes. */
+         if (nc_get_att_int(ncid, NC_GLOBAL, "num_processors", &mpi_size_in)) ERR;
+         if (mpi_size_in != mpi_size) ERR;
+         if (nc_get_att_int(ncid, 0, "var_num_processors", &mpi_size_in)) ERR;
+         if (mpi_size_in != mpi_size) ERR;
+         if (fv == 1)
+         {
+            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, fill_value_in)) ERR;
+            if (fill_mode_in != NC_FILL) ERR;
+            if (memcmp(fill_value_in, fill_value, type_size)) ERR;
+         }
+
+         /* Read all the slabs this process is responsible for. */
+         for (i = 0; i < NUM_SLABS / mpi_size; i++)
+         {
+            read_start[0] = NUM_SLABS / mpi_size * mpi_rank + i;
+            /* printf("mpi_rank %d i %d read_start[0] %ld\n", mpi_rank, i, read_start[0]); */
+
+            /* Read one slab of data. */
+            if (nc_get_vara(ncid, varid, read_start, read_count, data_in)) ERR;
+
+            /* Check data.  For the third fill value test, fill is
+             * turned off. So don't bother testing the values where k
+             * is zero. */
+            /* printf("mpi_rank %d fv %d i %d j %d k %d int_data_in[j * k] %d int_expected_fill_value %d " */
+            /*        "expected_value %d\n", mpi_rank, fv, i, j, k, int_data_in[j * k], */
+            /*        int_expected_fill_value, expected_value); */
+            switch (test_type[tt])
+            {
+            case NC_BYTE:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (byte_data_in[j * DIMSIZE + k] != (signed char)(k ? mpi_rank : byte_expected_fill_value)) ERR;
+               break;
+            case NC_SHORT:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (short_data_in[j * DIMSIZE + k] != (short)(k ? mpi_rank : short_expected_fill_value)) ERR;
+               break;
+            case NC_INT:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (int_data_in[j * DIMSIZE + k] != (int)(k ? mpi_rank : int_expected_fill_value)) ERR;
+               break;
+            case NC_FLOAT:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (float_data_in[j * DIMSIZE + k] != (float)(k ? mpi_rank : float_expected_fill_value)) ERR;
+               break;
+            case NC_DOUBLE:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (double_data_in[j * DIMSIZE + k] != (double)(k ? mpi_rank : double_expected_fill_value)) ERR;
+               break;
+            case NC_UBYTE:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (ubyte_data_in[j * DIMSIZE + k] != (unsigned char)(k ? mpi_rank : ubyte_expected_fill_value)) ERR;
+               break;
+            case NC_USHORT:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (ushort_data_in[j * DIMSIZE + k] != (unsigned short)(k ? mpi_rank : ushort_expected_fill_value)) ERR;
+               break;
+            case NC_UINT:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (uint_data_in[j * DIMSIZE + k] != (unsigned int)(k ? mpi_rank : uint_expected_fill_value)) ERR;
+               break;
+            case NC_INT64:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (int64_data_in[j * DIMSIZE + k] != (long long int)(k ? mpi_rank : int64_expected_fill_value)) ERR;
+               break;
+            case NC_UINT64:
+               for (j = 0; j < DIMSIZE; j++)
+                  for (k = 0; k < DIMSIZE; k++)
+                     if (fv < 2 || k)
+                        if (uint64_data_in[j * DIMSIZE + k] != (unsigned long long int)(k ? mpi_rank : uint64_expected_fill_value)) ERR;
+               break;
+            }
+         } /* next slab */
+
+         /* Close the netcdf file. */
+         if (nc_close(ncid))  ERR;
+
+         if (!mpi_rank)
+            SUMMARIZE_ERR;
+      } /* next test type */
+   } /* next fill value test run */
+   
+   /* Shut down MPI. */
+   MPI_Finalize();
+
+   if (!mpi_rank)
+      FINAL_RESULTS;
+   return 0;
 }
diff --git a/nc_test4/tst_szip.sh b/nc_test4/tst_szip.sh
new file mode 100755
index 0000000..dfffdb0
--- /dev/null
+++ b/nc_test4/tst_szip.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../test_common.sh
+
+set -e
+
+rm -f testnc.h5 testszip.nc szip_dump.cdl
+
+echo "*** Test read of known szip file"
+${NCDUMP} ${srcdir}/ref_szip.h5 >szip_dump.cdl
+diff -w ${srcdir}/ref_szip.cdl ./szip_dump.cdl
+
+echo "*** Testing tst_szip "
+${execdir}/test_szip
+echo "***Passed"
+
+echo "*** Testing h5testszip "
+${execdir}/h5testszip
+echo "***Passed"
+
+echo "*** Testing h5testszip on testszip.nc"
+${execdir}/h5testszip ./testszip.nc
+echo "***Passed"
+
+rm -f testnc.h5 testszip.nc
+rm -f szip_dump.cdl
+
+exit
diff --git a/nc_test4/tst_types.c b/nc_test4/tst_types.c
index e57e25d..def4a04 100644
--- a/nc_test4/tst_types.c
+++ b/nc_test4/tst_types.c
@@ -1,335 +1,395 @@
-/* Test program for types. */
-#include <config.h>
-#include <netcdf.h>
-
-/* This macro prints an error message and exits. */
-#define BAIL(e) do { \
-fprintf(stderr, "Error in file %s, line %d.\n%s\n", \
-__FILE__, __LINE__, nc_strerror(e)); \
-return 2; \
-} while (0)
-
-/* This macro keep track of the number of errors and prints an error
- * message. */
-#define ERR do { \
-fprintf(stderr, "Error in file %s, line %d.\n", __FILE__, __LINE__); \
-errors++; \
-} while (0)
- 
+/* This is part of the netCDF package.
+   Copyright 2005 University Corporation for Atmospheric Research/Unidata
+   See COPYRIGHT file for conditions of use.
+
+   Test netcdf-4 types.
+
+   Ed Hartnett
+*/
+
+#include "config.h"
+#include "nc_tests.h"
+#include "err_macros.h"
+
 #define MAX_VARNAME 20
 #define NUM_TYPES 6
 #define NUM_DIMS 1
 #define SIZE 5
 #define STRIDE_SIZE 2
-#define FILENAME "test.nc"
-
-#define CLEAN_INPUT_BUFFERS  \
-   for (i=0; i<SIZE; i++) { \
-      ubyte_data_out[i] = 0; \
-      ushort_data_out[i] = 0; \
-      uint_data_out[i] = 0; \
-      int64_data_out[i] = 0; \
-      uint64_data_out[i] = 0; \
-      bool_data_out[i] = 0; \
+#define FILENAME "tst_types.nc"
+#define FILENAME2 "tst_types2.nc"
+#define FILENAME3 "tst_types3.nc"
+#define FILENAME4 "tst_types4.nc"
+
+#define CLEAN_INPUT_BUFFERS                     \
+   for (i = 0; i < SIZE; i++) {                 \
+      ubyte_data_out[i] = 0;                    \
+      ushort_data_out[i] = 0;                   \
+      uint_data_out[i] = 0;                     \
+      int64_data_out[i] = 0;                    \
+      uint64_data_out[i] = 0;                   \
    }
 
+/* Create the test file for these tests. */
+int
+create_test_file(char *filename, int *varid, int *ncid)
+{
+   int dimid;
+   int type;
+   char varname[MAX_VARNAME];
+
+   /* Open a netcdf-4 file, and one dimension. */
+   if (nc_create(filename, NC_NETCDF4, ncid)) ERR;
+   if (nc_def_dim(*ncid, "dim1", SIZE, &dimid)) ERR;
+
+   /* Create vars of the new types. Take advantage of the fact that
+    * new types are numbered from NC_UBYTE (7) through NC_STRING
+    * (12). */
+   for (type = 0; type < NUM_TYPES; type++)
+   {
+      /* Create a var... */
+      sprintf(varname, "var_%d", type);
+      if (nc_def_var(*ncid, varname, type + NC_UBYTE, 1, &dimid, &varid[type])) ERR;
+   }
+   return 0;
+}
+
 int main(int argc, char *argv[])
 {
    /* IDs, names, and parameters for the var[asm1] functions. */
-   int ncid, varid[NUM_TYPES], attid, dimid;
+   int ncid, varid[NUM_TYPES], dimid;
    char varname[MAX_VARNAME];
-   size_t index1[NUM_DIMS], start[NUM_DIMS], offset[NUM_DIMS];
-   size_t count[NUM_DIMS], imap[NUM_DIMS];
+   size_t index1[NUM_DIMS], start[NUM_DIMS];
+   size_t count[NUM_DIMS];
+   ptrdiff_t imap[NUM_DIMS];
    ptrdiff_t stride[NUM_DIMS];
 
    /* Phoney data we will write. */
    unsigned char ubyte_data_out[] = {0,1,2,3,4};
-   unsigned short ushort_data_out[] = {0,11,22,33,44}; 
-   unsigned int uint_data_out[] = {0,111,222,333,3000000000u;};
-   nc_int64 int64_data_out[] = {0,-111111111,2222222222,-3333333333,444444444};
-   nc_uint64 uint64_data_out[] = {0,111111111,2222222222,33333333,44444444};
-   unsigned char bool_data_out[] = {0,1,0,1,0};
+   unsigned short ushort_data_out[] = {0,11,22,33,44};
+   unsigned int uint_data_out[] = {0,111,222,333,3000000000u};
+   long long int int64_data_out[] = {0,-111111111,2222222222,-3333333333,444444444};
+   unsigned long long int uint64_data_out[] = {0,111111111,2222222222,33333333,44444444};
 
    /* We will read back in the phoney data with these. */
    unsigned char ubyte_data_in[SIZE];
    unsigned short ushort_data_in[SIZE];
    unsigned int uint_data_in[SIZE];
-   nc_int64 int64_data_in[SIZE];
-   nc_uint64 uint64_data_in[SIZE];
-   unsigned char bool_data_in[SIZE];
+   long long int int64_data_in[SIZE];
+   unsigned long long int uint64_data_in[SIZE];
 
    int i;
-   int type, num_errors = 0, res = NC_NOERR;
-   int errors = 0, total_errors = 0;
+   int type;
 
-   /* Uncomment the following line to get verbose feedback. */
-   /*nc_set_log_level(2);*/
-   printf("\n\n*** Testing netCDF-4 new atomic types...\n");
+   printf("\n*** Testing netCDF-4 types...\n");
+   printf("*** testing netCDF-4 new atomic types and equality...");
+   {
+      int ncid1, ncid2;
+      int equal;
+
+      /* Open a netcdf-4 file, and one dimension. */
+      if (nc_create(FILENAME, NC_NETCDF4, &ncid1)) ERR;
+      if (nc_def_dim(ncid1, "dim1", SIZE, &dimid)) ERR;
+
+      /* Open another netcdf-4 file. */
+      if (nc_create(FILENAME2, NC_NETCDF4, &ncid2)) ERR;
+
+      /* Create vars of the new types. Take advantage of the fact that
+       * new types are numbered from NC_UBYTE (7) through NC_STRING
+       * (12). */
+      for (type = 0; type < NUM_TYPES; type++)
+      {
+         /* Create a var... */
+         sprintf(varname, "var_%d", type);
+         if (nc_def_var(ncid1, varname, type + NC_UBYTE, 1, &dimid, &varid[type])) ERR;
+         if (nc_inq_type_equal(ncid1, type + NC_UBYTE, ncid2, type + NC_UBYTE, &equal));
+         if (!equal) ERR;
+      }
+      nc_close(ncid2);
+      nc_close(ncid1);
+   }
+   SUMMARIZE_ERR;
 
-   /* Open a netcdf-4 file, and one dimension. */
-   if ((res = nc_create(FILENAME, NC_NETCDF4, &ncid)))
-      BAIL(res);
-   if ((res = nc_def_dim(ncid, "dim1", SIZE, &dimid)))
-      BAIL(res);
+#define ENUM_TYPE_NAME "enum_type"
+#define ENUM_FIELD1_NAME "enum_field_1"
+#define ENUM_UNEQUAL_TYPE_NAME_3 "enum_type_3"
+#define ENUM_UNEQUAL_TYPE_NAME_4 "enum_type_4"
+#define NUM_CLASSIC_TYPES 6
+#define NUM_ENHANCED_TYPES 12
 
-   /* Create vars of the new types. Take advantage of the fact that
-    * new types are numbered from NC_UBYTE (7) through NC_BOOL (12).*/
-   for(type = 0; type < NUM_TYPES; type++)
+   printf("*** testing user-defined netCDF-4 enum types and equality...");
    {
-      /* Create a var... */
-      sprintf(varname, "var_%d", type);
-      printf("*** creating var %s, type: %d...\t\t", varname, type+NC_UBYTE);
-      if ((res = nc_def_var(ncid, varname, type+NC_UBYTE, 1, &dimid, &varid[type])))
-	 BAIL(res);
-      printf("ok!\n");
+      int ncid1, ncid2, ncid3, ncid4;
+      int typeid1, typeid2, typeid3;
+      int enum_value = TEST_VAL_42;
+      int equal;
+      int classic_type[NUM_CLASSIC_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE};
+      int enhanced_type[NUM_ENHANCED_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE,
+                                               NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64, NC_STRING};
+      int t;
+
+      /* Create a netcdf-4 file. */
+      if (nc_create(FILENAME, NC_NETCDF4, &ncid1)) ERR;
+
+      /* Create an enum type. */
+      if (nc_def_enum(ncid1, NC_INT, ENUM_TYPE_NAME, &typeid1)) ERR;
+      if (nc_insert_enum(ncid1, typeid1, ENUM_FIELD1_NAME, &enum_value)) ERR;
+
+      /* Create another netcdf-4 file. */
+      if (nc_create(FILENAME2, NC_NETCDF4, &ncid2)) ERR;
+
+      /* Create a netcdf-3 classic file. */
+      if (nc_create(FILENAME3, 0, &ncid3)) ERR;
+
+      /* Create a netcdf-4 classic model file. */
+      if (nc_create(FILENAME4, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid4)) ERR;
+
+      /* Create an enum type that will be equal to typeid1. */
+      if (nc_def_enum(ncid2, NC_INT, ENUM_TYPE_NAME, &typeid2)) ERR;
+      if (nc_insert_enum(ncid2, typeid2, ENUM_FIELD1_NAME, &enum_value)) ERR;
+
+      /* These will fail. */
+      if (nc_def_enum(ncid2, NC_INT, ENUM_TYPE_NAME, &typeid3) != NC_ENAMEINUSE) ERR;
+      if (nc_def_enum(ncid2 + TEST_VAL_42, NC_INT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3) != NC_EBADID) ERR;
+      if (nc_def_enum(ncid2, NC_INT, NULL, &typeid3) != NC_EINVAL) ERR;
+      if (nc_def_enum(ncid3, NC_SHORT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3) != NC_ENOTNC4) ERR;
+      /* if (nc_def_enum(ncid4, NC_SHORT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3) != NC_ENOTNC4) ERR; */
+
+      /* Create some enum types that will not be equal to typeid1. */
+      if (nc_def_enum(ncid2, NC_SHORT, ENUM_UNEQUAL_TYPE_NAME_3, &typeid3)) ERR;
+      if (nc_insert_enum(ncid2, typeid3, ENUM_FIELD1_NAME, &enum_value)) ERR;
+
+      /* This will fail because types are not yet committed. */
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2, &equal) != NC_EHDFERR) ERR;
+
+      /* Commit the types to the file. */
+      if (nc_enddef(ncid1)) ERR;
+      if (nc_enddef(ncid2)) ERR;
+
+      /* This succeeds but does nothing. */
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2, NULL)) ERR;
+
+      /* These will fail. */
+      if (nc_inq_type_equal(ncid1, 0, ncid2, typeid2, &equal) != NC_EINVAL) ERR;
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, 0, &equal) != NC_EINVAL) ERR;
+      if (nc_inq_type_equal(ncid1, -TEST_VAL_42, ncid2, typeid2, &equal) != NC_EINVAL) ERR;
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, -TEST_VAL_42, &equal) != NC_EINVAL) ERR;
+      if (nc_inq_type_equal(ncid1 + TEST_VAL_42, typeid1, ncid2, typeid2, &equal) != NC_EBADID) ERR;
+      if (nc_inq_type_equal(ncid1, typeid1 + TEST_VAL_42, ncid2, typeid2, &equal) != NC_EBADTYPE) ERR;
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2 + TEST_VAL_42, typeid2, &equal) != NC_EBADID) ERR;
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2 + TEST_VAL_42, &equal) != NC_EBADTYPE) ERR;
+
+      /* Ensure the two equal types are equal. */
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid2, &equal)) ERR;
+      if (!equal) ERR;
+
+      /* Ensure the two unequal types are not equal. */
+      if (nc_inq_type_equal(ncid1, typeid1, ncid2, typeid3, &equal)) ERR;
+      if (equal) ERR;
+
+      /* Atomic types are not equal to user-defined types, but are
+       * equal to themselves. */
+      for (t = 0; t < NUM_CLASSIC_TYPES; t++)
+      {
+         if (nc_inq_type_equal(ncid1, typeid1, ncid3, classic_type[t], &equal)) ERR;
+         if (equal) ERR;
+         if (nc_inq_type_equal(ncid1, classic_type[t], ncid3, classic_type[t], &equal)) ERR;
+         if (!equal) ERR;
+      }
+      
+      for (t = 0; t < NUM_ENHANCED_TYPES; t++)
+      {
+         if (nc_inq_type_equal(ncid1, typeid1, ncid2, enhanced_type[t], &equal)) ERR;
+         if (equal) ERR;
+         if (nc_inq_type_equal(ncid1, enhanced_type[t], ncid2, enhanced_type[t], &equal)) ERR;
+         if (!equal) ERR;
+      }
+
+      /* Close the files. */
+      nc_close(ncid1);
+      nc_close(ncid2);
+      nc_close(ncid3);
+      nc_close(ncid4);
    }
-   
-   /* Test the varm functions. */
-   printf("*** testing varm functions...\t\t\t");
-/*   CLEAN_INPUT_BUFFERS;
-   errors = 0;
-   start[0] = 0;
-   count[0] = 1;
-   stride[0] = 1;
-   imap[0] = 0;
-
-   if ((res = nc_put_varm_ubyte(ncid, varid[0], start, count, 
-				stride, imap, ubyte_data_out)))
-      BAIL(res);
-   if ((res = nc_get_varm_ubyte(ncid, varid[0], start, count, 
-				stride, imap, ubyte_data_in)))
-      BAIL(res);
-   for (i=0; i<STRIDE_SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_varm_ushort(ncid, varid[1], start, count, 
-				 stride, imap, ushort_data_out)))
-      BAIL(res);
-   if ((res = nc_get_varm_ushort(ncid, varid[1], start, count,
-				 stride, imap, ushort_data_in)))
-      BAIL(res);
-   for (i=0; i<STRIDE_SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_varm_uint(ncid, varid[2], start, 
-			       count, stride, imap, uint_data_out)))
-      BAIL(res);
-   if ((res = nc_get_varm_uint(ncid, varid[2], start, count, 
-			       stride, imap, uint_data_in)))
-      BAIL(res);
-   for (i=0; i<STRIDE_SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_varm_int64(ncid, varid[3], start, count, 
-				stride, imap, int64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_varm_int64(ncid, varid[3], start, count, 
-				stride, imap, int64_data_in)))
-      BAIL(res);
-   for (i=0; i<STRIDE_SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_varm_uint64(ncid, varid[4], start, count, 
-				 stride, imap, uint64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_varm_uint64(ncid, varid[4], start, count,
-				 stride, imap, uint64_data_in)))
-      BAIL(res);
-   for (i=0; i<STRIDE_SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_varm_bool(ncid, varid[5], start, count, 
-			       stride, imap, bool_data_out)))
-      BAIL(res);
-   if ((res = nc_get_varm_bool(ncid, varid[5], start, 
-			       count, stride, imap, bool_data_in)))
-      BAIL(res);
-   for (i=0; i<STRIDE_SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   total_errors += errors;
-   if (errors)
-      printf("*** ERROR!! - %d errors. Sorry!\n");
-   else
-      printf("ok!\n");
-*/
-   /* Test the vars functions. */
-   printf("*** testing vars functions...\t\t\t");
-   CLEAN_INPUT_BUFFERS;
-   errors = 0;
-   start[0] = 0;
-   count[0] = 2;
-   stride[0] = STRIDE_SIZE;
-
-   if ((res = nc_put_vars_uchar(ncid, varid[0], start, count, 
-				stride, ubyte_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vars_uchar(ncid, varid[0], start, count, 
-				stride, ubyte_data_in)))
-      BAIL(res);
-   if (ubyte_data_in[0] != ubyte_data_out[0]) ERR;
-   if (ubyte_data_in[1] != ubyte_data_out[STRIDE_SIZE]) ERR;
-
-   if ((res = nc_put_vars_ushort(ncid, varid[1], start, count, 
-				 stride, ushort_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vars_ushort(ncid, varid[1], start, count,
-				 stride, ushort_data_in)))
-      BAIL(res);
-   for (i=0; i<2; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vars_uint(ncid, varid[2], start, 
-			       count, stride, uint_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vars_uint(ncid, varid[2], start, count, 
-			       stride, uint_data_in)))
-      BAIL(res);
-   for (i=0; i<2; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vars_int64(ncid, varid[3], start, count, 
-				stride, int64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vars_int64(ncid, varid[3], start, count, 
-				stride, int64_data_in)))
-      BAIL(res);
-   for (i=0; i<2; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vars_uint64(ncid, varid[4], start, count, 
-				 stride, uint64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vars_uint64(ncid, varid[4], start, count,
-				 stride, uint64_data_in)))
-      BAIL(res);
-   for (i=0; i<2; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vars_bool(ncid, varid[5], start, count, 
-			       stride, bool_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vars_bool(ncid, varid[5], start, 
-			       count, stride, bool_data_in)))
-      BAIL(res);
-   for (i=0; i<2; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   total_errors += errors;
-   if (errors)
-      printf("*** ERROR!! - %d errors. Sorry!\n");
-   else
-      printf("ok!\n");
+   SUMMARIZE_ERR;
 
    /* Test the vara functions. */
-   printf("*** testing vara functions...\t\t\t");
-   CLEAN_INPUT_BUFFERS;
-   errors = 0;
-   start[0] = 0;
-   count[0] = SIZE;
-
-   if ((res = nc_put_vara_uchar(ncid, varid[0], start, count, ubyte_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vara_uchar(ncid, varid[0], start, count, ubyte_data_in)))
-      BAIL(res);
-   for (i=0; i<SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vara_ushort(ncid, varid[1], start, count, ushort_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vara_ushort(ncid, varid[1], start, count, ushort_data_in)))
-      BAIL(res);
-   for (i=0; i<SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vara_uint(ncid, varid[2], start, count, uint_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vara_uint(ncid, varid[2], start, count, uint_data_in)))
-      BAIL(res);
-   for (i=0; i<SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vara_int64(ncid, varid[3], start, count, int64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vara_int64(ncid, varid[3], start, count, int64_data_in)))
-      BAIL(res);
-   for (i=0; i<SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vara_uint64(ncid, varid[4], start, count, uint64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vara_uint64(ncid, varid[4], start, count, uint64_data_in)))
-      BAIL(res);
-   for (i=0; i<SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   if ((res = nc_put_vara_bool(ncid, varid[5], start, count, bool_data_out)))
-      BAIL(res);
-   if ((res = nc_get_vara_bool(ncid, varid[5], start, count, bool_data_in)))
-      BAIL(res);
-   for (i=0; i<SIZE; i++)
-      if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
-
-   total_errors += errors;
-   if (errors)
-      printf("*** ERROR!! - %d errors. Sorry!\n");
-   else
-      printf("ok!\n");
+   printf("*** testing vara functions with new netCDF-4 atomic types...");
+   {
+      CLEAN_INPUT_BUFFERS;
+      start[0] = 0;
+      count[0] = SIZE;
+
+      /* Open a netcdf-4 file, and one dimension. */
+      if (create_test_file(FILENAME, varid, &ncid)) ERR;
+
+      if (nc_put_vara_uchar(ncid, varid[0], start, count, ubyte_data_out)) ERR;
+      if (nc_get_vara_uchar(ncid, varid[0], start, count, ubyte_data_in)) ERR;
+      for (i = 0; i < SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vara_ushort(ncid, varid[1], start, count, ushort_data_out)) ERR;
+      if (nc_get_vara_ushort(ncid, varid[1], start, count, ushort_data_in)) ERR;
+      for (i = 0; i < SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vara_uint(ncid, varid[2], start, count, uint_data_out)) ERR;
+      if (nc_get_vara_uint(ncid, varid[2], start, count, uint_data_in)) ERR;
+      for (i = 0; i < SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vara_longlong(ncid, varid[3], start, count, int64_data_out)) ERR;
+      if (nc_get_vara_longlong(ncid, varid[3], start, count, int64_data_in)) ERR;
+      for (i = 0; i < SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vara_ulonglong(ncid, varid[4], start, count, uint64_data_out)) ERR;
+      if (nc_get_vara_ulonglong(ncid, varid[4], start, count, uint64_data_in)) ERR;
+      for (i = 0; i < SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      /* Close the test file. */
+      nc_close(ncid);
+   }
+   SUMMARIZE_ERR;
+
+   /* Test the vars functions. */
+   printf("*** testing vars functions with new netCDF-4 atomic types...");
+   {
+      CLEAN_INPUT_BUFFERS;
+      start[0] = 0;
+      count[0] = 2;
+      stride[0] = STRIDE_SIZE;
+
+      /* Open a netcdf-4 file, and one dimension. */
+      if (create_test_file(FILENAME, varid, &ncid)) ERR;
+
+      if (nc_put_vars_uchar(ncid, varid[0], start, count, stride,
+                            ubyte_data_out)) ERR;
+      if (nc_get_vars_uchar(ncid, varid[0], start, count, stride,
+                            ubyte_data_in)) ERR;
+      if (ubyte_data_in[0] != ubyte_data_out[0]) ERR;
+      if (ubyte_data_in[1] != ubyte_data_out[STRIDE_SIZE]) ERR;
+
+      if (nc_put_vars_ushort(ncid, varid[1], start, count, stride,
+                             ushort_data_out)) ERR;
+      if (nc_get_vars_ushort(ncid, varid[1], start, count, stride,
+                             ushort_data_in)) ERR;
+      for (i = 0; i < 2; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vars_uint(ncid, varid[2], start, count, stride,
+                           uint_data_out)) ERR;
+      if (nc_get_vars_uint(ncid, varid[2], start, count, stride,
+                           uint_data_in)) ERR;
+      for (i = 0; i < 2; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vars_longlong(ncid, varid[3], start, count, stride,
+                               int64_data_out)) ERR;
+      if (nc_get_vars_longlong(ncid, varid[3], start, count, stride,
+                               int64_data_in)) ERR;
+      for (i = 0; i < 2; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_vars_ulonglong(ncid, varid[4], start, count, stride,
+                                uint64_data_out)) ERR;
+      if (nc_get_vars_ulonglong(ncid, varid[4], start, count, stride,
+                                uint64_data_in)) ERR;
+      for (i = 0; i < 2; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      /* Close the test file. */
+      nc_close(ncid);
+   }
+   SUMMARIZE_ERR;
 
    /* Test the var1 functions. */
-   printf("*** testing var1 functions...\t\t\t");
-   CLEAN_INPUT_BUFFERS;
-   errors = 0;
-   index1[0] = 0;
-
-   if ((res = nc_put_var1_uchar(ncid, varid[0], index1, uchar_data_out)))
-      BAIL(res);
-   if ((res = nc_get_var1_uchar(ncid, varid[0], index1, uchar_data_in)))
-      BAIL(res);
-   if (uchar_data_in[0] != uchar_data_out[0]) ERR;
-
-   if ((res = nc_put_var1_ushort(ncid, varid[1], index1, ushort_data_out)))
-      BAIL(res);
-   if ((res = nc_get_var1_ushort(ncid, varid[1], index1, ushort_data_in)))
-      BAIL(res);
-   if (ushort_data_in[0] != ushort_data_out[0]) ERR;
-
-   if ((res = nc_put_var1_uint(ncid, varid[2], index1, uint_data_out)))
-      BAIL(res);
-   if ((res = nc_get_var1_uint(ncid, varid[2], index1, uint_data_in)))
-      BAIL(res);
-   if (uint_data_in[0] != uint_data_out[0]) ERR;
-
-   if ((res = nc_put_var1_int64(ncid, varid[3], index1, int64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_var1_int64(ncid, varid[3], index1, int64_data_in)))
-      BAIL(res);
-   if (int64_data_in[0] != int64_data_out[0]) ERR;
-
-   if ((res = nc_put_var1_uint64(ncid, varid[4], index1, uint64_data_out)))
-      BAIL(res);
-   if ((res = nc_get_var1_uint64(ncid, varid[4], index1, uint64_data_in)))
-      BAIL(res);
-   if (uint64_data_in[0] != uint64_data_out[0]) ERR;
-
-   if ((res = nc_put_var1_bool(ncid, varid[5], index1, bool_data_out)))
-      BAIL(res);
-   if ((res = nc_get_var1_bool(ncid, varid[5], index1, bool_data_in)))
-      BAIL(res);
-   if (bool_data_in[0] != bool_data_out[0]) ERR;
-
-   total_errors += errors;
-   if (errors)
-      printf("*** ERROR!! - %d errors. Sorry!\n");
-   else
-      printf("ok!\n");
-
-   if (total_errors)
-      printf(" *** %d total errors\n", errors);
-   else
-      printf(" *** success!\n");
-
-   nc_finalize();
-
-   return 2 ? errors : 0;
+   printf("*** testing var1 functions with new netCDF-4 atomic types...");
+   {
+      CLEAN_INPUT_BUFFERS;
+      index1[0] = 0;
+
+      /* Open a netcdf-4 file, and one dimension. */
+      if (create_test_file(FILENAME, varid, &ncid)) ERR;
+
+      if (nc_put_var1_uchar(ncid, varid[0], index1, ubyte_data_out)) ERR;
+      if (nc_get_var1_uchar(ncid, varid[0], index1, ubyte_data_in)) ERR;
+      if (ubyte_data_in[0] != ubyte_data_out[0]) ERR;
+
+      if (nc_put_var1_ushort(ncid, varid[1], index1, ushort_data_out)) ERR;
+      if (nc_get_var1_ushort(ncid, varid[1], index1, ushort_data_in)) ERR;
+      if (ushort_data_in[0] != ushort_data_out[0]) ERR;
+
+      if (nc_put_var1_uint(ncid, varid[2], index1, uint_data_out)) ERR;
+      if (nc_get_var1_uint(ncid, varid[2], index1, uint_data_in)) ERR;
+      if (uint_data_in[0] != uint_data_out[0]) ERR;
+
+      if (nc_put_var1_longlong(ncid, varid[3], index1, int64_data_out)) ERR;
+      if (nc_get_var1_longlong(ncid, varid[3], index1, int64_data_in)) ERR;
+      if (int64_data_in[0] != int64_data_out[0]) ERR;
+
+      if (nc_put_var1_ulonglong(ncid, varid[4], index1, uint64_data_out)) ERR;
+      if (nc_get_var1_ulonglong(ncid, varid[4], index1, uint64_data_in)) ERR;
+      if (uint64_data_in[0] != uint64_data_out[0]) ERR;
+
+      /* Close the test file. */
+      nc_close(ncid);
+   }
+   SUMMARIZE_ERR;
+
+   /* Test the varm functions. */
+   printf("*** testing varm functions with new netCDF-4 atomic types...");
+   {
+      int ncid, varid[NUM_TYPES];
+      CLEAN_INPUT_BUFFERS;
+      start[0] = 0;
+      count[0] = 1;
+      stride[0] = 1;
+      imap[0] = 0;
+
+      /* Open a netcdf-4 file, and one dimension. */
+      if (create_test_file(FILENAME, varid, &ncid)) ERR;
+
+      if (nc_put_varm_ubyte(ncid, varid[0], start, count, stride, imap,
+                            ubyte_data_out)) ERR;
+      if (nc_get_varm_ubyte(ncid, varid[0], start, count, stride, imap,
+                            ubyte_data_in)) ERR;
+      for (i = 0; i < STRIDE_SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_varm_ushort(ncid, varid[1], start, count, stride, imap,
+                             ushort_data_out)) ERR;
+      if (nc_get_varm_ushort(ncid, varid[1], start, count, stride, imap,
+                             ushort_data_in)) ERR;
+      for (i = 0; i < STRIDE_SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_varm_uint(ncid, varid[2], start, count, stride, imap,
+                           uint_data_out)) ERR;
+      if (nc_get_varm_uint(ncid, varid[2], start, count, stride, imap,
+                           uint_data_in)) ERR;
+      for (i = 0; i < STRIDE_SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_varm_longlong(ncid, varid[3], start, count,
+                               stride, imap, int64_data_out)) ERR;
+      if (nc_get_varm_longlong(ncid, varid[3], start, count,
+                               stride, imap, int64_data_in)) ERR;
+      for (i = 0; i < STRIDE_SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      if (nc_put_varm_ulonglong(ncid, varid[4], start, count,
+                                stride, imap, uint64_data_out)) ERR;
+      if (nc_get_varm_ulonglong(ncid, varid[4], start, count,
+                                stride, imap, uint64_data_in)) ERR;
+      for (i = 0; i < STRIDE_SIZE; i++)
+         if (ubyte_data_in[i] != ubyte_data_out[i]) ERR;
+
+      /* Close the test file. */
+      nc_close(ncid);
+   }
+   SUMMARIZE_ERR;
+
+   FINAL_RESULTS;
 }
diff --git a/nc_test4/tst_vars.c b/nc_test4/tst_vars.c
index d0a0b3d..70883d4 100644
--- a/nc_test4/tst_vars.c
+++ b/nc_test4/tst_vars.c
@@ -3,7 +3,7 @@
    See COPYRIGHT file for conditions of use.
 
    Test netcdf-4 variables.
-   $Id: tst_vars.c,v 1.49 2009/12/30 12:03:48 ed Exp $
+   Ed Hartnett, Ward Fisher
 */
 
 #include "nc_tests.h"
@@ -184,6 +184,12 @@ create_4D_example(char *file_name, int cmode)
    for (rec = 0; rec < NREC; rec++)
    {
       start[0] = rec;
+
+      /* This won't work due to bad id. */
+      if (nc_put_vara_float(ncid + MILLION, pres_varid, start, count,
+                            &pres_out[0][0][0]) != NC_EBADID) ERR;
+      
+      /* Now write the data. */
       if (nc_put_vara_float(ncid, pres_varid, start, count,
 				      &pres_out[0][0][0])) ERR;
       if (nc_put_vara_float(ncid, temp_varid, start, count,
@@ -335,11 +341,33 @@ main(int argc, char **argv)
    printf("*** testing simple variables...");
 
    {
+      int bad_dimids[3] = {1, 2, 5}; /* "Three sir!" */
+      
       /* Create a file with a variable of each type. */
       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
       if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
       if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
       if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
+
+      /* These attempts will fail due to bad paramters. */
+      if (nc_def_var(ncid + MILLION, VAR_BYTE_NAME, NC_BYTE, 2, dimids,
+                     &byte_varid) != NC_EBADID) ERR;
+      if (nc_def_var(ncid + TEST_VAL_42, VAR_BYTE_NAME, NC_BYTE, 2, dimids,
+                     &byte_varid) != NC_EBADID) ERR;
+      if (nc_def_var(ncid, BAD_NAME, NC_BYTE, 2, dimids,
+                     &byte_varid) != NC_EBADNAME) ERR;
+      if (nc_def_var(ncid, VAR_BYTE_NAME, 0, 2, dimids,
+                     &byte_varid) != NC_EBADTYPE) ERR;
+      if (nc_def_var(ncid, VAR_BYTE_NAME, TEST_VAL_42, 2, dimids,
+                     &byte_varid) != NC_EBADTYPE) ERR;
+      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, -2, dimids,
+                     &byte_varid) != NC_EINVAL) ERR;
+      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, NULL,
+                     &byte_varid) != NC_EINVAL) ERR;
+      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 3, bad_dimids,
+                     &byte_varid) != NC_EBADDIM) ERR;
+
+      /* Now create our variables. */
       if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
       if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
       if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
@@ -826,6 +854,10 @@ main(int argc, char **argv)
       /* Open the file and check the same stuff. */
       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
 
+      /* Can't define a var! */
+      if (nc_def_var(ncid, "this_wont_work", NC_INT, NDIMS4, dimids, &varid)
+          != NC_EPERM) ERR;
+
       if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
       if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
 	  unlimdimid != -1) ERR;
@@ -1124,6 +1156,7 @@ main(int argc, char **argv)
    printf("*** testing fill values for 2D unlimited dimension variable...");
    {
 #define D1_NAME "unlimited"
+#define D1_LEN 4
 #define D1_TARGET 3
 #define D2_NAME "fixed"
 #define D2_LEN 3
@@ -1136,7 +1169,7 @@ main(int argc, char **argv)
       size_t index[ND1];
       int varid;
       int no_fill;
-      int data = TARGET_VALUE, data_in[D1_TARGET][D2_LEN], fill_value_in;
+      int data = TARGET_VALUE, data_in[D1_LEN][D2_LEN], fill_value_in;
       int i, j;
 
       /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
diff --git a/nc_test4/tst_vars2.c b/nc_test4/tst_vars2.c
index 4ed3147..91769fe 100644
--- a/nc_test4/tst_vars2.c
+++ b/nc_test4/tst_vars2.c
@@ -3,15 +3,17 @@
     See COPYRIGHT file for conditions of use.
 
    Test netcdf-4 variables.
-   $Id: tst_vars2.c,v 1.35 2010/01/25 21:01:08 ed Exp $
+   Ed Hartnett
 */
 
 #include <nc_tests.h>
 #include "err_macros.h"
 #include "netcdf.h"
+#include "netcdf_f.h"
 
 #define FILE_NAME "tst_vars2.nc"
 #define NUM_DIMS 1
+#define NUM_VARS 3
 #define DIM1_LEN NC_UNLIMITED
 #define DIM1_NAME "Hoplites_Engaged"
 #define VAR_NAME "Battle_of_Marathon"
@@ -24,13 +26,18 @@ main(int argc, char **argv)
 {
    int ncid, dimids[NUM_DIMS];
    int varid;
-   int nvars_in, varids_in[NUM_DIMS];
+   int nvars_in, varids_in[NUM_VARS];
    signed char fill_value = 42, fill_value_in;
    nc_type xtype_in;
    size_t len_in;
    char name_in[NC_MAX_NAME + 1];
    int attnum_in;
    int cnum;
+   char too_long_name[NC_MAX_NAME + 2];
+
+   /* Set up a name that is too long for netCDF. */
+   memset(too_long_name, 'a', NC_MAX_NAME + 1);
+   too_long_name[NC_MAX_NAME + 1] = 0;
 
    printf("\n*** Testing netcdf-4 variable functions, even more.\n");
    for (cnum = 0; cnum < MAX_CNUM; cnum++)
@@ -123,6 +130,9 @@ main(int argc, char **argv)
          /* Open the file and check. */
          if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
 
+         /* This will not work because file was opened read-only. */
+          if (nc_rename_var(ncid, 0, "something_very_new") != NC_EPERM) ERR;
+
          /* Check metadata. */
          if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
          if (nvars_in != 1 || varids_in[0] != 0) ERR;
@@ -330,7 +340,7 @@ main(int argc, char **argv)
          int dimid[NDIMS_1], var_dimids[VAR_DIMS] = {2, 0, 1};
          float fill_value = -9999.0f;
          char long_name[] = PRES_MAX_WIND;
-         int i, attid[NUM_ATTS];
+         int i;
 
          ncid = nccreate(FILE_NAME, NC_NETCDF4);
 
@@ -364,8 +374,7 @@ main(int argc, char **argv)
          /* Now add a fill value. This will acutually cause HDF5 to
           * destroy the dataset and recreate it, recreating also the
           * three attributes that are attached to it. */
-         attid[3] = ncattput(ncid, varid, _FillValue, NC_FLOAT,
-                             1, &fill_value);
+	 ncattput(ncid, varid, _FillValue, NC_FLOAT, 1, &fill_value);
 
          /* Check to ensure the atts have their expected attnums. */
          if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR;
@@ -405,6 +414,17 @@ main(int argc, char **argv)
       if (nc_def_dim(ncid, DIMNAME, 1, &dimid)) ERR;
       if (nc_enddef(ncid)) ERR;
       if (nc_redef(ncid)) ERR;
+
+      /* Check that these netCDF-4 things will fail on this classic
+       * model file. */
+      if (nc_def_var(ncid, DIMNAME, NC_UINT, 1, &dimid, &xvarid) != NC_ESTRICTNC3) ERR;
+      if (nc_def_var(ncid, DIMNAME, NC_INT, NC_MAX_VAR_DIMS + 1, &dimid,
+                     &xvarid) != NC_EMAXDIMS) ERR;
+      if (nc_enddef(ncid)) ERR;
+      if (nc_def_var(ncid, DIMNAME, NC_INT, 1, &dimid, &xvarid) != NC_ENOTINDEFINE) ERR;
+      if (nc_redef(ncid)) ERR;
+
+      /* Define the variable for the test. */
       if (nc_def_var(ncid, DIMNAME, NC_INT, 1, &dimid, &xvarid)) ERR;
       if (nc_put_att_text(ncid, xvarid, UNITS, strlen(units), units)) ERR;
       if (nc_def_var(ncid, VARNAME, NC_INT, 1, &dimid, &varid)) ERR;
@@ -440,6 +460,12 @@ main(int argc, char **argv)
       if (nc_close(ncid)) ERR;
 
       if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
+
+      /* These won't work. */
+      if (nc_rename_var(ncid + TEST_VAL_42, 0, "az") != NC_EBADID) ERR;
+      if (nc_rename_var(ncid + MILLION, 0, "az") != NC_EBADID) ERR;
+
+      /* Rename the var. */
       if (nc_rename_var(ncid, 0, "az")) ERR;
       if (nc_close(ncid)) ERR;
    }
@@ -447,12 +473,13 @@ main(int argc, char **argv)
    SUMMARIZE_ERR;
    printf("**** testing dimension and variable renaming...");
    {
-      /* This test contributed by Jeff Whitaker of NOAA - Thanks Jeff! */
-      int  ncid, lat_dim, time_dim, lon_dim, wind_id;
+      /* This test based on code contributed by Jeff Whitaker of NOAA
+       * - Thanks Jeff! */
+      int  ncid, lat_dim, time_dim, lon_dim, wind_id, temp2_id;
       size_t lat_len = 73, time_len = 10, lon_len = 145;
       int wind_dims[RANK_wind], wind_slobber[1], cdf_goober[1];
 
-      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
 
       /* define dimensions */
       if (nc_def_dim(ncid, "lon", lon_len, &lon_dim)) ERR;
@@ -466,6 +493,7 @@ main(int argc, char **argv)
       /* define variables */
       wind_dims[0] = lon_dim;
       if (nc_def_var(ncid, "temp", NC_FLOAT, RANK_wind, wind_dims, &wind_id)) ERR;
+      if (nc_def_var(ncid, "temp2", NC_FLOAT, RANK_wind, wind_dims, &temp2_id)) ERR;
 
       if (nc_put_att_text(ncid, wind_id, "bar", 3, "foo")) ERR;
       wind_slobber[0] = 3;
@@ -476,109 +504,160 @@ main(int argc, char **argv)
       if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
       if (nc_inq_dimid(ncid, "lon", &lon_dim)) ERR;
 
+      /* THese won't work due to bad params. */
+      if (nc_rename_dim(ncid + MILLION, lon_dim, "longitude") != NC_EBADID) ERR;
+      if (nc_rename_dim(ncid + TEST_VAL_42, lon_dim, "longitude") != NC_EBADID) ERR;
+
       /* rename dimension */
       if (nc_rename_dim(ncid, lon_dim, "longitude")) ERR;
+
+      /* These will fail due to bad params. */
+      if (nc_inq_varid(ncid + MILLION, "temp", &wind_id) != NC_EBADID) ERR;
+      if (nc_inq_varid(ncid + TEST_VAL_42, "temp", &wind_id) != NC_EBADID) ERR;
+      if (nc_inq_varid(ncid, NULL, &wind_id) != NC_EINVAL) ERR;
+      if (nc_inq_varid(ncid, "not_a_real_name", &wind_id) != NC_ENOTVAR) ERR;
+      if (nc_inq_varid(ncid, BAD_NAME, &wind_id) != NC_ENOTVAR) ERR;
+      if (nc_inq_varid(ncid, too_long_name, &wind_id) != NC_EMAXNAME) ERR;
+
+      /* Now get the variable ID. */
       if (nc_inq_varid(ncid, "temp", &wind_id)) ERR;
 
+      /* THis also works, pointlessly. */
+      if (nc_inq_varid(ncid, "temp", NULL)) ERR;
+
+      /* These won't work due to bad paramters. */
+      if (nc_rename_var(ncid + MILLION, wind_id, "wind") != NC_EBADID) ERR;
+      if (nc_rename_var(ncid, wind_id + TEST_VAL_42, "wind") != NC_ENOTVAR) ERR;
+      if (nc_rename_var(ncid, -TEST_VAL_42, "wind") != NC_ENOTVAR) ERR;
+      if (nc_rename_var(ncid, wind_id, BAD_NAME) != NC_EBADNAME) ERR;
+      if (nc_rename_var(ncid, wind_id, too_long_name) != NC_EMAXNAME) ERR;
+      if (nc_rename_var(ncid, wind_id, "temp2") != NC_ENAMEINUSE) ERR;
+      if (nc_rename_var(ncid, wind_id, "windy") != NC_ENOTINDEFINE) ERR;
+
       /* rename variable */
       if (nc_rename_var(ncid, wind_id, "wind")) ERR;
+
+      /* Enter define mode and rename it to something longer. */
+      if (nc_redef(ncid)) ERR;
+      if (nc_rename_var(ncid, wind_id, "windy")) ERR;      
+      if (nc_inq_varid(ncid, "windy", &wind_id)) ERR;
       if (nc_close(ncid)) ERR;
-   }
-   SUMMARIZE_ERR;
 
+      /* Try again without classic. */
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
 
-/*    printf("*** testing 2D array of NC_CHAR..."); */
-/*    { */
-/*       int dimid[NDIMS_1], var_dimids[VAR_DIMS] = {2, 0, 1}; */
-/*       float fill_value = -9999.0f; */
-/*       char long_name[] = PRES_MAX_WIND; */
-/*       int i, attid[NUM_ATTS]; */
+      /* define dimension */
+      if (nc_def_dim(ncid, "lon", lon_len, &lon_dim)) ERR;
+
+      /* define variable */
+      wind_dims[0] = lon_dim;
+      if (nc_def_var(ncid, "temp", NC_FLOAT, RANK_wind, wind_dims, &wind_id)) ERR;
+      if (nc_enddef(ncid)) ERR;
+      if (nc_rename_var(ncid, wind_id, "windy")) ERR;            
+      if (nc_close(ncid)) ERR;
+      
+   }
+   SUMMARIZE_ERR;
 
-/*       ncid = nccreate(FILE_NAME, NC_NETCDF4); */
+#define VAR_DIMS2 2
+   printf("*** testing 2D array of NC_FLOAT with v2 API...");
+   {
+      int dimid[VAR_DIMS2];
+      int ndims, nvars, natts, recdim;
 
-/*       /\* Create dims. *\/ */
-/*       dimid[0] = ncdimdef(ncid, LAT, LAT_LEN); */
-/*       dimid[1] = ncdimdef(ncid, LON, LON_LEN); */
+      ncid = nccreate(FILE_NAME, NC_NETCDF4);
 
-/*       /\* Create var. *\/ */
-/*       varid = ncvardef(ncid, CXX_VAR_NAME, NC_FLOAT, VAR_DIMS, var_dimids); */
-/*       if (varid) ERR; */
+      /* Create dims. */
+      dimid[0] = ncdimdef(ncid, LAT, LAT_LEN);
+      dimid[1] = ncdimdef(ncid, LON, LON_LEN);
 
-/*       ncclose(ncid); */
+      /* Create var. */
+      varid = ncvardef(ncid, CXX_VAR_NAME, NC_FLOAT, VAR_DIMS2, dimid);
+      if (varid != 0) ERR;
 
-/*       /\* Open the file and check. *\/ */
-/*       ncid = ncopen(FILE_NAME, 0); */
-/*       ncclose(ncid); */
-/*    } */
+      ncclose(ncid);
 
-/*    SUMMARIZE_ERR; */
+      /* Open the file and check. */
+      ncid = ncopen(FILE_NAME, 0);
+      ncinquire (ncid, &ndims, &nvars, &natts, &recdim);
+      if (nvars != 1 || ndims != 2 || natts != 0 || recdim != -1) ERR;
+      ncclose(ncid);
+   }
+   SUMMARIZE_ERR;
 
 #define NDIMS 3
 #define NNAMES 4
 #define NLINES 13
-/*    printf("**** testing funny names for netCDF-4..."); */
-/*    { */
-/*       int  ncid, wind_id; */
-/*       size_t len[NDIMS] = {7, 3, 1}; */
-/*       int dimids[NDIMS], dimids_in[NDIMS], ndims_in; */
-/*       char funny_name[NNAMES][NC_MAX_NAME] = {"\a\t", "\f\n", "\r\v", "\b"}; */
-/*       char name_in[NC_MAX_NAME + 1]; */
-/*       char *speech[NLINES] = {"who would fardels bear, ", */
-/* 			      "To grunt and sweat under a weary life, ", */
-/* 			      "But that the dread of something after death, ", */
-/* 			      "The undiscover'd country from whose bourn ", */
-/* 			      "No traveller returns, puzzles the will ", */
-/* 			      "And makes us rather bear those ills we have ", */
-/* 			      "Than fly to others that we know not of? ", */
-/* 			      "Thus conscience does make cowards of us all; ", */
-/* 			      "And thus the native hue of resolution ", */
-/* 			      "Is sicklied o'er with the pale cast of thought, ", */
-/* 			      "And enterprises of great pith and moment ", */
-/* 			      "With this regard their currents turn awry, ", */
-/* 			      "And lose the name of action."}; */
-/*       char *speech_in[NLINES]; */
-/*       int i; */
-/*       unsigned short nlines = NLINES; */
-/*       unsigned int nlines_in; */
-
-/*       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; */
-
-/*       /\* Define dimensions. *\/ */
-/*       for (i = 0; i < NDIMS; i++) */
-/* 	 if (nc_def_dim(ncid, funny_name[i], len[i], &dimids[i])) ERR; */
-
-/*       /\* Write some global atts. *\/ */
-/*       if (nc_put_att_string(ncid, NC_GLOBAL, funny_name[0], NLINES,  */
-/* 			    (const char **)speech)) ERR; */
-/*       if (nc_put_att_ushort(ncid, NC_GLOBAL, funny_name[1], NC_UINT, 1, &nlines)) ERR; */
-
-/*       /\* Define variables. *\/ */
-/*       if (nc_def_var(ncid, funny_name[3], NC_INT64, NDIMS, dimids, &wind_id)) ERR; */
-
-/*       if (nc_close(ncid)) ERR; */
-
-/*       /\* Open the file and check. *\/ */
-/*       if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */
-/*       if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; */
-/*       if (ndims_in != NDIMS) ERR; */
-/*       for (i = 0; i < NDIMS; i++) */
-/*       { */
-/* 	 if (dimids_in[i] != i) ERR; */
-/* 	 if (nc_inq_dimname(ncid, i, name_in)) ERR; */
-/* 	 if (strcmp(name_in, funny_name[i])) ERR; */
-/*       } */
-
-/*       if (nc_get_att_string(ncid, NC_GLOBAL, funny_name[0], (char **)speech_in)) ERR; */
-/*       for (i = 0; i < NLINES; i++) */
-/* 	 if (strcmp(speech_in[i], speech[i])) ERR; */
-/*       if (nc_get_att_uint(ncid, NC_GLOBAL, funny_name[1], &nlines_in)) ERR; */
-/*       if (nlines_in != NLINES) ERR; */
-/*       if (nc_free_string(NLINES, (char **)speech_in)) ERR; */
-/*       if (nc_inq_varname(ncid, 0, name_in)) ERR; */
-/*       if (strcmp(name_in, funny_name[3])) ERR; */
-/*       if (nc_close(ncid)) ERR; */
-/*    } */
-/*    SUMMARIZE_ERR; */
+   printf("**** testing funny names for netCDF-4...");
+   {
+      int  ncid, wind_id;
+      size_t len[NDIMS] = {7, 3, 1};
+      int dimids[NDIMS], dimids_in[NDIMS], ndims_in;
+      char funny_name[NNAMES][NC_MAX_NAME] = {"\a\t", "\f\n", "\r\v", "\b"};
+      char serious_name[NNAMES][NC_MAX_NAME] = {"name1", "name2", "name3", "name4"};
+      char name_in[NC_MAX_NAME + 1];
+      char *speech[NLINES] = {"who would fardels bear, ",
+			      "To grunt and sweat under a weary life, ",
+			      "But that the dread of something after death, ",
+			      "The undiscover'd country from whose bourn ",
+			      "No traveller returns, puzzles the will ",
+			      "And makes us rather bear those ills we have ",
+			      "Than fly to others that we know not of? ",
+			      "Thus conscience does make cowards of us all; ",
+			      "And thus the native hue of resolution ",
+			      "Is sicklied o'er with the pale cast of thought, ",
+			      "And enterprises of great pith and moment ",
+			      "With this regard their currents turn awry, ",
+			      "And lose the name of action."};
+      char *speech_in[NLINES];
+      int i;
+      unsigned short nlines = NLINES;
+      unsigned int nlines_in;
+
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+
+      /* Define dimensions. Funny names are rejected, serious names work. */
+      for (i = 0; i < NDIMS; i++)
+      	 if (nc_def_dim(ncid, funny_name[i], len[i], &dimids[i]) != NC_EBADNAME) ERR;
+      for (i = 0; i < NDIMS; i++)
+      	 if (nc_def_dim(ncid, serious_name[i], len[i], &dimids[i])) ERR;
+
+      /* Write some global atts. Funny names are rejected, serious names work. */
+      if (nc_put_att_string(ncid, NC_GLOBAL, funny_name[0], NLINES,
+			    (const char **)speech) != NC_EBADNAME) ERR;
+      if (nc_put_att_ushort(ncid, NC_GLOBAL, funny_name[1], NC_UINT, 1, &nlines) != NC_EBADNAME) ERR;
+      if (nc_put_att_string(ncid, NC_GLOBAL, serious_name[0], NLINES,
+			    (const char **)speech)) ERR;
+      if (nc_put_att_ushort(ncid, NC_GLOBAL, serious_name[1], NC_UINT, 1, &nlines)) ERR;
+
+      /* Define variables. Funny name fails, seriousness wins the day! */
+      if (nc_def_var(ncid, funny_name[3], NC_INT64, NDIMS, dimids, &wind_id) != NC_EBADNAME) ERR;
+      if (nc_def_var(ncid, serious_name[3], NC_INT64, NDIMS, dimids, &wind_id)) ERR;
+
+      if (nc_close(ncid)) ERR;
+
+      /* Open the file and check. */
+      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
+      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
+      if (ndims_in != NDIMS) ERR;
+      for (i = 0; i < NDIMS; i++)
+      {
+      	 if (dimids_in[i] != i) ERR;
+      	 if (nc_inq_dimname(ncid, i, name_in)) ERR;
+      	 if (strcmp(name_in, serious_name[i])) ERR;
+      }
+
+      if (nc_get_att_string(ncid, NC_GLOBAL, serious_name[0], (char **)speech_in)) ERR;
+      for (i = 0; i < NLINES; i++)
+      	 if (strcmp(speech_in[i], speech[i])) ERR;
+      if (nc_get_att_uint(ncid, NC_GLOBAL, serious_name[1], &nlines_in)) ERR;
+      if (nlines_in != NLINES) ERR;
+      if (nc_free_string(NLINES, (char **)speech_in)) ERR;
+      if (nc_inq_varname(ncid, 0, name_in)) ERR;
+      if (strcmp(name_in, serious_name[3])) ERR;
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
    printf("**** testing endianness...");
 
 #define NDIMS4 1
@@ -587,7 +666,7 @@ main(int argc, char **argv)
 #define DIM4_LEN 10
    {
       int dimids[NDIMS4], dimids_in[NDIMS4];
-      int varid;
+      int varid, varid1;
       int ndims, nvars, natts, unlimdimid;
       nc_type xtype_in;
       char name_in[NC_MAX_NAME + 1];
@@ -614,17 +693,39 @@ main(int argc, char **argv)
       if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
       if (nvars != 1) ERR;
       if (varids_in[0] != 0) ERR;
+
+      /* Test some bad parameter values. */
+      if (nc_inq_var(ncid + MILLION, 0, name_in, &xtype_in, &ndims,
+                     dimids_in, &natts) != NC_EBADID) ERR;
+      if (nc_inq_var(ncid + TEST_VAL_42, 0, name_in, &xtype_in, &ndims,
+                     dimids_in, &natts) != NC_EBADID) ERR;
+      if (nc_inq_var(ncid, -TEST_VAL_42, name_in, &xtype_in, &ndims,
+                     dimids_in, &natts) != NC_ENOTVAR) ERR;
+      if (nc_inq_var(ncid, 1, name_in, &xtype_in, &ndims,
+                     dimids_in, &natts) != NC_ENOTVAR) ERR;
+      if (nc_inq_var(ncid, TEST_VAL_42, name_in, &xtype_in, &ndims,
+                     dimids_in, &natts) != NC_ENOTVAR) ERR;
+
+      /* Now pass correct parameters. */
       if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
                      dimids_in, &natts)) ERR;
       if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT ||
           ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
       if (nc_inq_var_endian(ncid, 0, &endian_in)) ERR;
       if (endian_in != NC_ENDIAN_BIG) ERR;
+
+      /* This also works, uselessly. */
+      if (nc_inq_var(ncid, 0, name_in, NULL, NULL, NULL, NULL)) ERR;
+      
       if (nc_close(ncid)) ERR;
 
       /* Open the file and check the same stuff. */
       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
 
+      /* This won't work. */
+      if (nc_def_var(ncid, "this_wont_work", NC_BYTE, NDIMS4, dimids,
+                     &varid1) != NC_EPERM) ERR;
+
       if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
       if (ndims != NDIMS4 || nvars != 1 || natts != 0 ||
           unlimdimid != -1) ERR;
@@ -650,22 +751,34 @@ main(int argc, char **argv)
 #define NDIMS5 1
 #define DIM5_NAME "D5"
 #define VAR_NAME5 "V5"
+#define VAR_NAME5_1 "V5_1"
+#define VAR_NAME5_2 "V5_2"
 #define DIM5_LEN 1000
 #define CACHE_SIZE 32000000
 #define CACHE_NELEMS 1009
 #define CACHE_PREEMPTION .75
+#define CACHE_SIZE2 64000000
+#define CACHE_NELEMS2 2000
+#define CACHE_PREEMPTION2 .50
 
       int dimids[NDIMS5], dimids_in[NDIMS5];
-      int varid;
+      int varid, varid1, varid2;
       int ndims, nvars, natts, unlimdimid;
       nc_type xtype_in;
       char name_in[NC_MAX_NAME + 1];
       int data[DIM5_LEN], data_in[DIM5_LEN];
       size_t chunksize[NDIMS5] = {5};
+      size_t bad_chunksize[NDIMS5] = {-5};
       size_t chunksize_in[NDIMS5];
+      int chunksize_int[NDIMS5];
+      int chunksize_int_in[NDIMS5];
       int storage_in;
       size_t cache_size_in, cache_nelems_in;
       float cache_preemption_in;
+      int cache_size_int_in, cache_nelems_int_in;
+      int cache_preemption_int_in;
+      int cache_size_int_default, cache_nelems_int_default;
+      int cache_preemption_int_default;
       int i, d;
 
       for (i = 0; i < DIM5_LEN; i++)
@@ -675,8 +788,45 @@ main(int argc, char **argv)
       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
       if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
       if (dimids[0] != 0) ERR;
+
+      /* Define the variable. */
       if (nc_def_var(ncid, VAR_NAME5, NC_INT, NDIMS5, dimids, &varid)) ERR;
+
+      /* These will fail due to bad parameters. */
+      if (nc_def_var_chunking(ncid + MILLION, varid, NC_CHUNKED,
+                              chunksize) != NC_EBADID) ERR;
+      if (nc_def_var_chunking(ncid + TEST_VAL_42, varid, NC_CHUNKED,
+                              chunksize) != NC_EBADID) ERR;
+      if (nc_def_var_chunking(ncid, varid + TEST_VAL_42, NC_CHUNKED,
+                              chunksize) != NC_ENOTVAR) ERR;
+      if (nc_def_var_chunking(ncid, varid + 1, NC_CHUNKED,
+                              chunksize) != NC_ENOTVAR) ERR;
+      if (nc_def_var_chunking(ncid, -1, NC_CHUNKED,
+                              chunksize) != NC_ENOTVAR) ERR;
+      if (nc_def_var_chunking(ncid, varid, NC_CHUNKED, bad_chunksize) !=
+          NC_EBADCHUNK) ERR;
+
+      /* Define the chunking. */
       if (nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunksize)) ERR;
+
+      /* Try to set var cache with bad parameters. They will be
+       * rejected. */
+      if (nc_set_var_chunk_cache(ncid + MILLION, varid, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION) != NC_EBADID) ERR;
+      if (nc_set_var_chunk_cache(ncid + 1, varid, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION) != NC_EBADID) ERR;
+      if (nc_set_var_chunk_cache(ncid, varid + TEST_VAL_42, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION) != NC_ENOTVAR) ERR;
+      if (nc_set_var_chunk_cache(ncid, -TEST_VAL_42, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION) != NC_ENOTVAR) ERR;
+      if (nc_set_var_chunk_cache(ncid, varid + 1, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION) != NC_ENOTVAR) ERR;
+      if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION + TEST_VAL_42) != NC_EINVAL) ERR;
+      if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION - TEST_VAL_42) != NC_EINVAL) ERR;
+
+      /* Set the cache. */
       if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
       if (nc_put_var_int(ncid, varid, data)) ERR;
 
@@ -698,10 +848,80 @@ main(int argc, char **argv)
       for (i = 0; i < DIM5_LEN; i++)
          if (data[i] != data_in[i])
 	    ERR_RET;
+
+      /* These will not work due to bad paramters. */
+      if (nc_inq_var_chunking_ints(ncid + MILLION, 0, &storage_in,
+                                   chunksize_int_in) != NC_EBADID) ERR;
+      if (nc_inq_var_chunking_ints(ncid + TEST_VAL_42, 0, &storage_in,
+                                   chunksize_int_in) != NC_EBADID) ERR;
+      if (nc_inq_var_chunking_ints(ncid, -1, &storage_in,
+                                   chunksize_int_in) != NC_ENOTVAR) ERR;
+      if (nc_inq_var_chunking_ints(ncid, varid + 1, &storage_in,
+                                   chunksize_int_in) != NC_ENOTVAR) ERR;
+      if (nc_inq_var_chunking_ints(ncid, varid + TEST_VAL_42, &storage_in,
+                                   chunksize_int_in) != NC_ENOTVAR) ERR;
+      
+      /* Now check with the fortran versions of the var_chunking. */
+      if (nc_inq_var_chunking_ints(ncid, 0, &storage_in, chunksize_int_in)) ERR;
+      for (d = 0; d < NDIMS5; d++)
+	 if (chunksize_int_in[d] != chunksize[d]) ERR;
+      for (d = 0; d < NDIMS5; d++)
+         chunksize_int[d] = chunksize[d] * 2;
+
+      /* Check that some bad parameter values are rejected properly. */
+      if (nc_def_var_chunking_ints(ncid + MILLION, varid, NC_CHUNKED,
+                                   chunksize_int) != NC_EBADID) ERR;
+      if (nc_def_var_chunking_ints(ncid + TEST_VAL_42, varid, NC_CHUNKED,
+                                   chunksize_int) != NC_EBADID) ERR;
+      if (nc_def_var_chunking_ints(ncid, -1, NC_CHUNKED,
+                                   chunksize_int) != NC_ENOTVAR) ERR;
+      if (nc_def_var_chunking_ints(ncid, varid + 1, NC_CHUNKED,
+                                   chunksize_int) != NC_ENOTVAR) ERR;
+      if (nc_def_var_chunking_ints(ncid, varid + TEST_VAL_42, NC_CHUNKED,
+                                   chunksize_int) != NC_ENOTVAR) ERR;
+      
+      if (nc_def_var_chunking_ints(ncid, varid, NC_CHUNKED, chunksize_int) != NC_ELATEDEF) ERR;
+      if (nc_redef(ncid)) ERR;
+      if (nc_def_var(ncid, VAR_NAME5_1, NC_INT, NDIMS5, dimids, &varid1)) ERR;
+      if (nc_def_var(ncid, VAR_NAME5_2, NC_INT, 0, NULL, &varid2)) ERR;
+      if (nc_def_var_chunking(ncid, varid2, NC_CHUNKED, chunksize)) ERR;
+      if (nc_def_var_chunking_ints(ncid, varid2, NC_CHUNKED, chunksize_int)) ERR;
+      if (nc_def_var_chunking_ints(ncid, varid1, NC_CHUNKED, chunksize_int)) ERR;
+      if (nc_inq_var_chunking_ints(ncid, varid2, NC_CHUNKED, chunksize_int_in)) ERR;      
+      if (nc_inq_var_chunking_ints(ncid, varid1, NULL, chunksize_int_in)) ERR;
+      for (d = 0; d < NDIMS5; d++)
+	 if (chunksize_int_in[d] != chunksize[d] * 2) ERR;
+      if (nc_inq_var_chunking_ints(ncid, varid1, NULL, NULL)) ERR;
+
+      /* Check that some bad parameter values are rejected properly. */
+      if (nc_get_var_chunk_cache(ncid + MILLION, varid, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_EBADID) ERR;
+      if (nc_get_var_chunk_cache(ncid + 1, -TEST_VAL_42, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_EBADID) ERR;
+      if (nc_get_var_chunk_cache(ncid, varid + TEST_VAL_42, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_ENOTVAR) ERR;
+      if (nc_get_var_chunk_cache(ncid, varid2 + 1, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_ENOTVAR) ERR;
+      if (nc_get_var_chunk_cache(ncid, -TEST_VAL_42, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_ENOTVAR) ERR;
+
+      /* Get the var chunk cache settings. */
       if (nc_get_var_chunk_cache(ncid, varid, &cache_size_in, &cache_nelems_in,
 				 &cache_preemption_in)) ERR;
       if (cache_size_in != CACHE_SIZE || cache_nelems_in != CACHE_NELEMS ||
 	  cache_preemption_in != CACHE_PREEMPTION) ERR;
+      /* THis should also work, pointlessly. */
+      if (nc_get_var_chunk_cache(ncid, varid, NULL, NULL, NULL)) ERR;
+
+      /* Check the _int version of this function, used by the F77 API. */
+      if (nc_get_var_chunk_cache_ints(ncid, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in)) ERR;
+      if (cache_size_int_in != CACHE_SIZE / MEGABYTE) ERR;
+      if (cache_nelems_int_in != CACHE_NELEMS) ERR;
+      if (cache_preemption_int_in != (int)(CACHE_PREEMPTION * 100)) ERR;
+      /* THis should also work, pointlessly. */
+      if (nc_get_var_chunk_cache_ints(ncid, varid, NULL, NULL, NULL)) ERR;
+
       if (nc_close(ncid)) ERR;
 
       /* Open the file and check the same stuff. */
@@ -709,11 +929,11 @@ main(int argc, char **argv)
 
       /* Check stuff. */
       if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
-      if (ndims != NDIMS5 || nvars != 1 || natts != 0 ||
+      if (ndims != NDIMS5 || nvars != NUM_VARS || natts != 0 ||
           unlimdimid != -1) ERR;
       if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
-      if (nvars != 1) ERR;
-      if (varids_in[0] != 0) ERR;
+      if (nvars != NUM_VARS) ERR;
+      if (varids_in[0] != 0 || varids_in[1] != 1) ERR;
       if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR;
       if (strcmp(name_in, VAR_NAME5) || xtype_in != NC_INT || ndims != 1 || natts != 0 ||
 	  dimids_in[0] != 0) ERR;
@@ -725,6 +945,139 @@ main(int argc, char **argv)
       for (i = 0; i < DIM5_LEN; i++)
          if (data[i] != data_in[i])
 	    ERR_RET;
+
+      /* Use the _int function to change the var chunk cache settings. */
+      if (nc_set_var_chunk_cache_ints(ncid, varid, CACHE_SIZE2 / MEGABYTE, CACHE_NELEMS2,
+                                      (int)(CACHE_PREEMPTION2 * 100))) ERR;
+
+      /* These will fail due to bad ncid and group ID. */
+      if (nc_get_var_chunk_cache_ints(ncid + MILLION, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in) != NC_EBADID) ERR;
+      if (nc_get_var_chunk_cache_ints(ncid + TEST_VAL_42, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in) != NC_EBADID) ERR;
+
+      /* Now get the settings. */
+      if (nc_get_var_chunk_cache_ints(ncid, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in)) ERR;
+      if (cache_size_int_in != CACHE_SIZE2 / MEGABYTE || cache_nelems_int_in != CACHE_NELEMS2 ||
+          cache_preemption_int_in != (int)(CACHE_PREEMPTION2 * 100)) ERR;
+
+      /* Passing negative values to the _int function causes them to
+       * be ignored and a default setting used. Set all to negative to
+       * get defaults.. */
+      if (nc_set_var_chunk_cache_ints(ncid, varid, -CACHE_SIZE / MEGABYTE, -CACHE_NELEMS2,
+                                      -(int)(CACHE_PREEMPTION2 * 100))) ERR;
+      if (nc_get_var_chunk_cache_ints(ncid, varid, &cache_size_int_default, &cache_nelems_int_default,
+                                      &cache_preemption_int_default)) ERR;
+
+      /* Now set the size only. */
+      if (nc_set_var_chunk_cache_ints(ncid, varid, CACHE_SIZE / MEGABYTE, -CACHE_NELEMS2,
+                                      -(int)(CACHE_PREEMPTION2 * 100))) ERR;
+      if (nc_get_var_chunk_cache_ints(ncid, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in)) ERR;
+      if (cache_size_int_in != CACHE_SIZE / MEGABYTE || cache_nelems_int_in != cache_nelems_int_default ||
+          cache_preemption_int_in != cache_preemption_int_default) ERR;
+      /* Now set the nelems only. */
+      if (nc_set_var_chunk_cache_ints(ncid, varid, -CACHE_SIZE / MEGABYTE, CACHE_NELEMS,
+                                      -(int)(CACHE_PREEMPTION2 * 100))) ERR;
+      if (nc_get_var_chunk_cache_ints(ncid, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in)) ERR;
+      if (cache_size_int_in != cache_size_int_default || cache_nelems_int_in != CACHE_NELEMS ||
+          cache_preemption_int_in != cache_preemption_int_default) ERR;
+      /* Now set the preemption only. */
+      if (nc_set_var_chunk_cache_ints(ncid, varid, -CACHE_SIZE / MEGABYTE, -CACHE_NELEMS,
+                                      (int)(CACHE_PREEMPTION2 * 100))) ERR;
+      if (nc_get_var_chunk_cache_ints(ncid, varid, &cache_size_int_in, &cache_nelems_int_in,
+                                      &cache_preemption_int_in)) ERR;
+      if (cache_size_int_in != cache_size_int_default || cache_nelems_int_in != cache_nelems_int_default ||
+          cache_preemption_int_in != (int)(CACHE_PREEMPTION2 * 100)) ERR;
+      
+      if (nc_close(ncid)) ERR;
+   }
+
+   SUMMARIZE_ERR;
+   printf("**** testing netCDF-4 functions on netCDF-3 files...");
+   {
+      int dimids[NDIMS5], dimids_in[NDIMS5];
+      int varid;
+      int ndims, nvars, natts, unlimdimid;
+      nc_type xtype_in;
+      char name_in[NC_MAX_NAME + 1];
+      int data[DIM5_LEN], data_in[DIM5_LEN];
+      size_t chunksize[NDIMS5] = {5};
+      size_t chunksize_in[NDIMS5];
+      int storage_in;
+      size_t cache_size_in, cache_nelems_in;
+      float cache_preemption_in;
+      int i;
+
+      for (i = 0; i < DIM5_LEN; i++)
+         data[i] = i;
+
+      /* Create a netcdf classic file with one dim and one var. */
+      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
+      if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
+      if (dimids[0] != 0) ERR;
+      if (nc_def_var(ncid, VAR_NAME5, NC_INT, NDIMS5, dimids, &varid)) ERR;
+
+      /* These will return error. */
+      if (nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunksize) != NC_ENOTNC4) ERR;
+      if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS,
+                                 CACHE_PREEMPTION) != NC_ENOTNC4) ERR;
+
+      if (nc_enddef(ncid)) ERR;
+      if (nc_put_var_int(ncid, varid, data)) ERR;
+
+      /* Check stuff. */
+      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
+      if (ndims != NDIMS5 || nvars != 1 || natts != 0 ||
+          unlimdimid != -1) ERR;
+      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
+      if (nvars != 1) ERR;
+      if (varids_in[0] != 0) ERR;
+      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR;
+      if (strcmp(name_in, VAR_NAME5) || xtype_in != NC_INT || ndims != 1 || natts != 0 ||
+	  dimids_in[0] != 0) ERR;
+
+      /* This call fails. */
+      if (nc_get_var_chunk_cache(ncid, varid, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_ENOTNC4) ERR;
+
+      /* This call passes but does nothing. */
+      if (nc_inq_var_chunking(ncid, 0, &storage_in, chunksize_in)) ERR;
+
+      if (nc_get_var_int(ncid, varid, data_in)) ERR;
+      for (i = 0; i < DIM5_LEN; i++)
+         if (data[i] != data_in[i])
+	    ERR_RET;
+
+      if (nc_close(ncid)) ERR;
+
+      /* Open the file and check the same stuff. */
+      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
+
+      /* Check stuff. */
+      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
+      if (ndims != NDIMS5 || nvars != 1 || natts != 0 ||
+          unlimdimid != -1) ERR;
+      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
+      if (nvars != 1) ERR;
+      if (varids_in[0] != 0) ERR;
+      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR;
+      if (strcmp(name_in, VAR_NAME5) || xtype_in != NC_INT || ndims != 1 || natts != 0 ||
+	  dimids_in[0] != 0) ERR;
+
+      /* This call fails. */
+      if (nc_get_var_chunk_cache(ncid, varid, &cache_size_in, &cache_nelems_in,
+				 &cache_preemption_in) != NC_ENOTNC4) ERR;
+
+      /* This call passes but does nothing. */
+      if (nc_inq_var_chunking(ncid, 0, &storage_in, chunksize_in)) ERR;
+      
+      if (nc_get_var_int(ncid, varid, data_in)) ERR;
+      for (i = 0; i < DIM5_LEN; i++)
+         if (data[i] != data_in[i])
+	    ERR_RET;
       if (nc_close(ncid)) ERR;
    }
 
@@ -1032,6 +1385,37 @@ main(int argc, char **argv)
 
    }
    SUMMARIZE_ERR;
+   printf("**** testing error conditions on nc_def_var functions...");
+   {
+      int ncid;
+      int dimids[NDIMS6];
+      int varid;
+      int num_models = 2;
+      int m;
+      int mode = NC_NETCDF4;
+
+      /* Test without and with classic model. */
+      for (m = 0; m < num_models; m++)
+      {
+         if (m)
+            mode |= NC_CLASSIC_MODEL;
+
+         /* Create a netcdf-4 file. */
+         if (nc_create(FILE_NAME, mode, &ncid)) ERR;
+         if (nc_def_dim(ncid, DIM8_NAME, TEST_VAL_42, &dimids[0])) ERR;
+         if (nc_def_var(ncid, VAR_NAME8, NC_INT, NDIMS6, dimids, &varid)) ERR;
+
+         /* Set the var to contiguous. */
+         if (nc_def_var_chunking(ncid, varid, NC_CONTIGUOUS, NULL)) ERR;
+
+         /* Now defalte can't be set. */
+         if (nc_def_var_deflate(ncid, varid, 0, 1, 4)) ERR;
+
+         if (nc_close(ncid)) ERR;
+      }
+
+   }
+   SUMMARIZE_ERR;
 #define NDIMS6 1
 #define DIM8_NAME "num_monkeys"
 #define DIM9_NAME "num_coconuts"
diff --git a/nc_test4/tst_vars3.c b/nc_test4/tst_vars3.c
index f876798..fd200f1 100644
--- a/nc_test4/tst_vars3.c
+++ b/nc_test4/tst_vars3.c
@@ -3,7 +3,7 @@
    See COPYRIGHT file for conditions of use.
 
    Test netcdf-4 variables.
-   $Id: tst_vars3.c,v 1.29 2010/04/30 18:21:52 ed Exp $
+   Ed Hartnett, Russ Rew, Dennis Heimbigner, Ward Fisher
 */
 
 #include <nc_tests.h>
@@ -12,6 +12,7 @@
 
 #define FILE_NAME "tst_vars3.nc"
 #define NDIMS1 1
+#define NDIMS2 2
 #define D_SMALL "small_dim"
 #define D_SMALL_LEN 16
 #define D_MEDIUM "medium_dim"
@@ -263,6 +264,10 @@ main(int argc, char **argv)
       if (nc_inq_var(ncid, 1, NULL, NULL, &ndims, dimids_in, NULL)) ERR;
       if (ndims != 3 || dimids_in[0] != 0 || dimids_in[1] != 2 || dimids_in[2] != 1) ERR;
 
+      /* These will not work due to bad parameters. */
+      if (nc_get_vara(ncid + MILLION, 1, cor, edg, P_data) != NC_EBADID) ERR;
+      if (nc_get_vara(ncid + TEST_VAL_42, 1, cor, edg, P_data) != NC_EBADID) ERR;
+      
       /* Read the record of non-existent data. */
       if (nc_get_vara(ncid, 1, cor, edg, P_data)) ERR;
       for (i = 0; i < LEN; i++)
@@ -378,6 +383,26 @@ main(int argc, char **argv)
       if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
+   printf("**** testing bad inputs to put/get_vara calls...");
+   {
+      int ncid, dimid[NDIMS2], varid;
+      size_t start[NDIMS2] = {0, 0}, count[NDIMS2] = {NX, NY};
+      double double_data[NX * NY];
+
+      /* Create file with two dims, one 2D var. */
+      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
+      if (nc_def_dim(ncid, ZD1_NAME, NX, &dimid[0])) ERR;
+      if (nc_def_dim(ncid, D2_NAME, NY, &dimid[1])) ERR;
+      if (nc_def_var(ncid, ZD1_NAME, NC_DOUBLE, NDIMS2, dimid, &varid)) ERR;
+      if (nc_enddef(ncid)) ERR;
+
+      /* Try to write some data, but fail. */
+      if (nc_put_vara_double(ncid + MILLION, 0, start, count, double_data) != NC_EBADID) ERR;
+      if (nc_put_vara_double(ncid + TEST_VAL_42, 0, start, count, double_data) != NC_EBADID) ERR;
+
+      if (nc_close(ncid)) ERR;
+   }
+   SUMMARIZE_ERR;
 /* #ifdef USE_SZIP */
 /*    printf("**** testing that szip works..."); */
 /*    { */
diff --git a/nc_test4/tst_xplatform2.c b/nc_test4/tst_xplatform2.c
index 5a50be5..6b6e1ab 100644
--- a/nc_test4/tst_xplatform2.c
+++ b/nc_test4/tst_xplatform2.c
@@ -10,6 +10,7 @@
 #include <nc_tests.h>
 #include "err_macros.h"
 #include "netcdf.h"
+#include <hdf5.h>
 
 #define FILE_NAME_1 "tst_xplatform2_1.nc"
 #define REF_FILE_NAME_1 "ref_tst_xplatform2_1.nc"
@@ -209,16 +210,16 @@ check_file_3(int ncid, struct s3 *data_out)
    for (i = 0; i < DIM3_LEN; i++)
       for (j = 0; j < NUM_VL; j++)
       {
-	 if (data_in[i].data[j].len != data_in[i].data[j].len) ERR;
+	 if (data_in[i].data[j].len != data_out[i].data[j].len) ERR;
 	 for (k = 0; k < data_out[i].data[j].len; k++)
 	    if (((struct s1 *)data_in[i].data[j].p)[k].x != ((struct s1 *)data_out[i].data[j].p)[k].x ||
 		((struct s1 *)data_in[i].data[j].p)[k].y != ((struct s1 *)data_out[i].data[j].p)[k].y) ERR;
       }
 
    /* Free our vlens. */
-/*    for (i = 0; i < DIM3_LEN; i++) */
-/*       for (j = 0; j < NUM_VL; j++) */
-/* 	 nc_free_vlen(&(data_in[i].data[j])); */
+   for (i = 0; i < DIM3_LEN; i++)
+      for (j = 0; j < NUM_VL; j++)
+	 nc_free_vlen(&(data_in[i].data[j]));
 
    /* We're done! */
    return NC_NOERR;
@@ -273,16 +274,16 @@ check_file_4(int ncid, struct s3 *data_out)
    for (i = 0; i < DIM3_LEN; i++)
       for (j = 0; j < NUM_VL; j++)
       {
-	 if (data_in[i].data[j].len != data_in[i].data[j].len) ERR;
+	 if (data_in[i].data[j].len != data_out[i].data[j].len) ERR;
 	 for (k = 0; k < data_out[i].data[j].len; k++)
 	    if (((struct s1 *)data_in[i].data[j].p)[k].x != ((struct s1 *)data_out[i].data[j].p)[k].x ||
 		((struct s1 *)data_in[i].data[j].p)[k].y != ((struct s1 *)data_out[i].data[j].p)[k].y) ERR;
       }
 
    /* Free our vlens. */
-/*    for (i = 0; i < DIM3_LEN; i++) */
-/*       for (j = 0; j < NUM_VL; j++) */
-/* 	 nc_free_vlen(&(data_in[i].data[j])); */
+   for (i = 0; i < DIM3_LEN; i++)
+      for (j = 0; j < NUM_VL; j++)
+	 nc_free_vlen(&(data_in[i].data[j]));
 
    /* We're done! */
    return NC_NOERR;
@@ -340,7 +341,6 @@ main(int argc, char **argv)
 	 }
       }
 
-
    printf("*** testing of vlen of compound type...");
    {
       nc_type s1_typeid, vlen_typeid;
@@ -352,9 +352,9 @@ main(int argc, char **argv)
        * different platforms - our old friend struct s1. */
       if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, X_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, Y_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
 
       /* Now make a new type: a vlen of our compound type. */
       if (nc_def_vlen(ncid, VLEN_NAME, s1_typeid, &vlen_typeid)) ERR;
@@ -382,8 +382,8 @@ main(int argc, char **argv)
       strcpy(file_in, "");
       if (getenv("srcdir"))
       {
-	 strcat(file_in, getenv("srcdir"));
-	 strcat(file_in, "/");
+   	 strcat(file_in, getenv("srcdir"));
+   	 strcat(file_in, "/");
       }
       strcat(file_in, REF_FILE_NAME_1);
 
@@ -406,21 +406,21 @@ main(int argc, char **argv)
        * different platforms - our old friend struct s1. */
       if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, X_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, Y_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
 
       /* Now make a compound type that holds an array of the struct s1
        * type. */
       if (nc_def_compound(ncid, sizeof(struct s2), S2_TYPE_NAME, &s2_typeid)) ERR;
       if (nc_insert_array_compound(ncid, s2_typeid, S1_NAME,
-				   NC_COMPOUND_OFFSET(struct s2, data),
-				   s1_typeid, 1, dimsizes)) ERR;
+   				   NC_COMPOUND_OFFSET(struct s2, data),
+   				   s1_typeid, 1, dimsizes)) ERR;
 
 
       /* Write the output data as an attribute. */
       if (nc_put_att(ncid, NC_GLOBAL, S2_ATT_NAME, s2_typeid,
-		     DIM2_LEN, comp_array_of_comp_out)) ERR;
+   		     DIM2_LEN, comp_array_of_comp_out)) ERR;
 
       /* How does it look? */
       if (check_file_2(ncid, comp_array_of_comp_out)) ERR;
@@ -441,8 +441,8 @@ main(int argc, char **argv)
       strcpy(file_in, "");
       if (getenv("srcdir"))
       {
-	 strcat(file_in, getenv("srcdir"));
-	 strcat(file_in, "/");
+   	 strcat(file_in, getenv("srcdir"));
+   	 strcat(file_in, "/");
       }
       strcat(file_in, REF_FILE_NAME_2);
 
@@ -465,9 +465,9 @@ main(int argc, char **argv)
        * different platforms - our old friend struct s1. */
       if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, X_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, Y_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
 
       /* Now make a new type: a vlen of our s1 compound type. */
       if (nc_def_vlen(ncid, VLEN_NAME, s1_typeid, &vlen_typeid)) ERR;
@@ -476,16 +476,16 @@ main(int argc, char **argv)
        * type. */
       if (nc_def_compound(ncid, sizeof(struct s3), S3_TYPE_NAME, &s3_typeid)) ERR;
       if (nc_insert_array_compound(ncid, s3_typeid, VL_NAME,
-				   NC_COMPOUND_OFFSET(struct s3, data),
-				   vlen_typeid, 1, dimsizes)) ERR;
+   				   NC_COMPOUND_OFFSET(struct s3, data),
+   				   vlen_typeid, 1, dimsizes)) ERR;
 
 
       /* Write the output data as an attribute. */
       if (nc_put_att(ncid, NC_GLOBAL, S3_ATT_NAME, s3_typeid,
-		     DIM3_LEN, comp_array_of_vlen_of_comp_out)) ERR;
+   		     DIM3_LEN, comp_array_of_vlen_of_comp_out)) ERR;
 
-      /* How does it look? */
-      if (check_file_3(ncid, comp_array_of_vlen_of_comp_out)) ERR;
+      /* How does it look? Uncomment this line to see memory issue. */
+      /* if (check_file_3(ncid, comp_array_of_vlen_of_comp_out)) ERR; */
 
       /* We're done - wasn't that easy? */
       if (nc_close(ncid)) ERR;
@@ -496,15 +496,6 @@ main(int argc, char **argv)
       if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
-/*    printf("*** testing Solaris-written compound containing array of vlen of compound type..."); */
-/*    { */
-/*       /\* Check out the same file, generated on buddy and included with */
-/*        * the distribution. *\/ */
-/*       if (nc_open(REF_FILE_NAME_3, NC_NOWRITE, &ncid)) ERR; */
-/*       if (check_file_3(ncid, comp_array_of_vlen_of_comp_out)) ERR; */
-/*       if (nc_close(ncid)) ERR; */
-/*    } */
-/*    SUMMARIZE_ERR; */
    printf("*** testing compound variable containing array of vlen of compound type...");
    {
       nc_type vlen_typeid, s3_typeid, s1_typeid;
@@ -518,9 +509,9 @@ main(int argc, char **argv)
        * different platforms - our old friend struct s1. */
       if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, X_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
       if (nc_insert_compound(ncid, s1_typeid, Y_NAME,
-			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
+   			     NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
 
       /* Now make a new type: a vlen of our s1 compound type. */
       if (nc_def_vlen(ncid, VLEN_NAME, s1_typeid, &vlen_typeid)) ERR;
@@ -529,8 +520,8 @@ main(int argc, char **argv)
        * type. */
       if (nc_def_compound(ncid, sizeof(struct s3), S3_TYPE_NAME, &s3_typeid)) ERR;
       if (nc_insert_array_compound(ncid, s3_typeid, VL_NAME,
-				   NC_COMPOUND_OFFSET(struct s3, data),
-				   vlen_typeid, 1, dimsizes)) ERR;
+   				   NC_COMPOUND_OFFSET(struct s3, data),
+   				   vlen_typeid, 1, dimsizes)) ERR;
 
       /* Create a dimension and a var of s3 type, then write the
        * data. */
@@ -562,5 +553,102 @@ main(int argc, char **argv)
    free(comp_array_of_vlen_of_comp_out);
    free(vlen_of_comp_out);
 
+   /* Now run the tests formerly in tst_h_atts2.c. */
+#define REF_FILE_NAME "tst_xplatform2_3.nc"
+#define NUM_OBJ 3
+   
+   printf("\n*** Checking HDF5 attribute functions some more.\n");
+   printf("*** Opening tst_xplatform2_3.nc...");
+   {
+      hid_t fileid, grpid, attid;
+      hid_t file_typeid1[NUM_OBJ], native_typeid1[NUM_OBJ];
+      hid_t file_typeid2, native_typeid2;
+      hsize_t num_obj, i;
+      H5O_info_t obj_info;
+      char obj_name[NC_MAX_NAME + 1];
+
+      /* Open one of the netCDF test files. */
+      if ((fileid = H5Fopen(REF_FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
+      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
+
+      /* How many objects in this group? */
+      if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
+      if (num_obj != NUM_OBJ) ERR;
+
+      /* For each object in the group... */
+      for (i = 0; i < num_obj; i++)
+      {
+	 /* Get the name. */
+	 if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC,
+				i, &obj_info, H5P_DEFAULT) < 0) ERR_RET;
+	 if (H5Lget_name_by_idx(grpid, ".", H5_INDEX_NAME, H5_ITER_INC, i,
+				obj_name, NC_MAX_NAME + 1, H5P_DEFAULT) < 0) ERR_RET;
+	 printf(" reading type %s ", obj_name);
+	 if (obj_info.type != H5O_TYPE_NAMED_DATATYPE) ERR_RET;
+
+	 /* Get the typeid. */
+	 if ((file_typeid1[i] = H5Topen2(grpid, obj_name, H5P_DEFAULT)) < 0) ERR_RET;
+	 if ((native_typeid1[i] = H5Tget_native_type(file_typeid1[i], H5T_DIR_DEFAULT)) < 0) ERR_RET;
+      }
+
+      /* There is one att: open it by index. */
+      if ((attid = H5Aopen_idx(grpid, 0)) < 0) ERR;
+
+      /* Get file and native typeids. */
+      if ((file_typeid2 = H5Aget_type(attid)) < 0) ERR;
+      if ((native_typeid2 = H5Tget_native_type(file_typeid2, H5T_DIR_DEFAULT)) < 0) ERR;
+
+      /* Close the attribute. */
+      if (H5Aclose(attid) < 0) ERR;
+
+      /* Close the typeids. */
+      if (H5Tclose(file_typeid2) < 0) ERR_RET;
+      if (H5Tclose(native_typeid2) < 0) ERR_RET;
+      for (i = 0; i < NUM_OBJ; i++)
+      {
+	 if (H5Tclose(file_typeid1[i]) < 0) ERR_RET;
+	 if (H5Tclose(native_typeid1[i]) < 0) ERR_RET;
+      }
+
+      /* Close the group and file. */
+      if (H5Gclose(grpid) < 0 ||
+	  H5Fclose(fileid) < 0) ERR;
+   }
+
+   SUMMARIZE_ERR;
+   printf("*** Opening tst_xplatform2_3.nc again...");
+   {
+      hid_t fileid, grpid, attid, file_typeid, native_typeid;
+      hid_t file_typeid2, native_typeid2;
+
+      /* Open one of the netCDF test files. */
+      if ((fileid = H5Fopen(REF_FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
+      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
+
+      /* There is one att: open it by index. */
+      if ((attid = H5Aopen_idx(grpid, 0)) < 0) ERR;
+
+      /* Get file and native typeids. */
+      if ((file_typeid = H5Aget_type(attid)) < 0) ERR;
+      if ((native_typeid = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0) ERR;
+
+      /* Now getting another copy of the native typeid will fail! WTF? */
+      if ((file_typeid2 = H5Aget_type(attid)) < 0) ERR;
+      if ((native_typeid2 = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0) ERR;
+
+      /* Close the attribute. */
+      if (H5Aclose(attid) < 0) ERR;
+
+      /* Close the typeids. */
+      if (H5Tclose(file_typeid) < 0) ERR;
+      if (H5Tclose(native_typeid) < 0) ERR;
+      if (H5Tclose(file_typeid2) < 0) ERR;
+      if (H5Tclose(native_typeid2) < 0) ERR;
+
+      /* Close the group and file. */
+      if (H5Gclose(grpid) < 0 ||
+	  H5Fclose(fileid) < 0) ERR;
+   }
+   SUMMARIZE_ERR;
    FINAL_RESULTS;
 }
diff --git a/nc_test4/unfiltered.cdl b/nc_test4/unfiltered.cdl
new file mode 100644
index 0000000..0fe71ca
--- /dev/null
+++ b/nc_test4/unfiltered.cdl
@@ -0,0 +1,87 @@
+netcdf unfiltered {
+dimensions:
+	dim0 = 4 ;
+	dim1 = 4 ;
+	dim2 = 4 ;
+	dim3 = 4 ;
+
+// global attributes:
+		:_Format = "netCDF-4" ;
+
+group: g {
+  variables:
+  	float var(dim0, dim1, dim2, dim3) ;
+  		var:_Storage = "chunked" ;
+  		var:_ChunkSizes = 4, 4, 4, 4 ;
+  		var:_Endianness = "little" ;
+
+  // group attributes:
+  data:
+
+   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,
+  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, 241, 242, 243,
+  244, 245, 246, 247,
+  248, 249, 250, 251,
+  252, 253, 254, 255 ;
+  } // group g
+}
diff --git a/ncdap_test/Makefile.am b/ncdap_test/Makefile.am
index a8c7adf..90b6537 100644
--- a/ncdap_test/Makefile.am
+++ b/ncdap_test/Makefile.am
@@ -3,14 +3,15 @@
 
 # This file builds and runs DAP tests.
 
-# This will not work until we get a new remotetest server set up 
-
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 include $(top_srcdir)/lib_flags.am
 
 #LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
 #TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
 
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
+
 LDADD = ${top_builddir}/liblib/libnetcdf.la
 AM_CPPFLAGS += -I$(top_srcdir)/liblib
 AM_CPPFLAGS += -DTOPSRCDIR=${abs_top_srcdir}
@@ -27,7 +28,9 @@ test_vara_SOURCES = test_vara.c t_srcdir.h
 if ENABLE_DAP
 check_PROGRAMS += t_dap3a test_cvt3 test_vara
 TESTS += t_dap3a test_cvt3 test_vara
+if BUILD_UTILITIES
 TESTS += tst_ncdap3.sh
+endif
 
 # remote tests are optional
 # because the server may be down or inaccessible
@@ -37,10 +40,10 @@ check_PROGRAMS += findtestserver
 findtestserver_SOURCES = findtestserver.c
 
 if BUILD_UTILITIES
-TESTS += tst_ber.sh tst_remote3.sh tst_formatx.sh
+TESTS += tst_ber.sh tst_remote3.sh tst_formatx.sh testurl.sh
 endif
 
-TESTS += test_partvar testurl.sh
+TESTS += test_partvar
 
 if ENABLE_DAP_LONG_TESTS
  TESTS += tst_longremote3.sh
@@ -83,6 +86,8 @@ EXTRA_DIST = tst_ncdap3.sh  \
 	     t_ncf330.c tst_ber.sh
 
 CLEANFILES = test_varm3 test_cvt3 results/*.dmp results/*.das results/*.dds datadds* t_dap3a test_nstride_cached *.exe
+# This should only be left behind if using parallel io
+CLEANFILES += tmp_*
 
 # This rule are used if someone wants to rebuild t_dap3a.c
 # Otherwise never invoked, but records how to do it.
@@ -102,5 +107,6 @@ clean-local: clean-local-check
 
 clean-local-check:
 	-rm -rf results
-	-rm .dodsrc
+	-rm -f .dodsrc
+
 
diff --git a/ncdap_test/Makefile.in b/ncdap_test/Makefile.in
index 8394551..a33be60 100644
--- a/ncdap_test/Makefile.in
+++ b/ncdap_test/Makefile.in
@@ -18,8 +18,6 @@
 
 # This file builds and runs DAP tests.
 
-# This will not work until we get a new remotetest server set up 
-
 # This is part of the netCDF package.
 # Copyright 2005 University Corporation for Atmospheric Research/Unidata
 # See COPYRIGHT file for conditions of use.
@@ -103,15 +101,13 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
 check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
-TESTS = $(am__EXEEXT_3) $(am__append_6) $(am__EXEEXT_4) \
-	$(am__append_8) $(am__EXEEXT_5) $(am__append_10)
+TESTS = $(am__EXEEXT_1) $(am__append_4) $(am__append_6) \
+	$(am__EXEEXT_3) $(am__append_8) $(am__EXEEXT_4) \
+	$(am__append_10)
+ at ENABLE_DAP_TRUE@am__append_2 = t_dap3a test_cvt3 test_vara
 @ENABLE_DAP_TRUE at am__append_3 = t_dap3a test_cvt3 test_vara
- at ENABLE_DAP_TRUE@am__append_4 = t_dap3a test_cvt3 test_vara \
- at ENABLE_DAP_TRUE@	tst_ncdap3.sh
+ at BUILD_UTILITIES_TRUE@@ENABLE_DAP_TRUE at am__append_4 = tst_ncdap3.sh
 
 # remote tests are optional
 # because the server may be down or inaccessible
@@ -122,8 +118,8 @@ TESTS = $(am__EXEEXT_3) $(am__append_6) $(am__EXEEXT_4) \
 @ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE@	t_misc \
 @ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE@	test_varm3 \
 @ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE@	t_ncf330
- at BUILD_UTILITIES_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__append_6 = tst_ber.sh tst_remote3.sh tst_formatx.sh
- at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__append_7 = test_partvar testurl.sh
+ at BUILD_UTILITIES_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__append_6 = tst_ber.sh tst_remote3.sh tst_formatx.sh testurl.sh
+ at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__append_7 = test_partvar
 @ENABLE_DAP_LONG_TESTS_TRUE@@ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__append_8 = tst_longremote3.sh
 #TESTS += t_ncf330
 @ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__append_9 =  \
@@ -465,15 +461,11 @@ am__set_TESTS_bases = \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
 RECHECK_LOGS = $(TEST_LOGS)
- at ENABLE_DAP_TRUE@am__EXEEXT_3 = t_dap3a$(EXEEXT) test_cvt3$(EXEEXT) \
- at ENABLE_DAP_TRUE@	test_vara$(EXEEXT) tst_ncdap3.sh
- at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__EXEEXT_4 = test_partvar$(EXEEXT) \
- at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE@	testurl.sh
- at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__EXEEXT_5 = test_varm3$(EXEEXT) \
+ at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__EXEEXT_3 = test_partvar$(EXEEXT)
+ at ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE at am__EXEEXT_4 = test_varm3$(EXEEXT) \
 @ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE@	test_nstride_cached$(EXEEXT) \
 @ENABLE_DAP_REMOTE_TESTS_TRUE@@ENABLE_DAP_TRUE@	t_misc$(EXEEXT)
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
 am__set_b = \
@@ -488,10 +480,9 @@ am__set_b = \
   esac
 am__test_logs1 = $(TESTS:=.log)
 am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
 	$(top_srcdir)/lib_flags.am $(top_srcdir)/test-driver
@@ -525,13 +516,12 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) \
 	-I$(top_srcdir)/liblib -DTOPSRCDIR=${abs_top_srcdir} \
 	-DTOPBINDIR=${abs_top_bindir}
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -554,12 +544,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -585,6 +577,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -599,6 +592,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -702,12 +696,15 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 
 #LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
 #TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
+
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
 LDADD = ${top_builddir}/liblib/libnetcdf.la
 t_dap3a_SOURCES = t_dap3a.c t_srcdir.h
 test_cvt3_SOURCES = test_cvt.c t_srcdir.h
@@ -727,7 +724,9 @@ EXTRA_DIST = tst_ncdap3.sh  \
 	     t_dap.c CMakeLists.txt tst_formatx.sh testauth.sh testurl.sh \
 	     t_ncf330.c tst_ber.sh
 
-CLEANFILES = test_varm3 test_cvt3 results/*.dmp results/*.das results/*.dds datadds* t_dap3a test_nstride_cached *.exe
+# This should only be left behind if using parallel io
+CLEANFILES = test_varm3 test_cvt3 results/*.dmp results/*.das \
+	results/*.dds datadds* t_dap3a test_nstride_cached *.exe tmp_*
 
 # One last thing
 BUILT_SOURCES = .dodsrc
@@ -735,7 +734,7 @@ all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+.SUFFIXES: .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -1119,34 +1118,6 @@ test_vara.log: test_vara$(EXEEXT)
 	--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_ncdap3.sh.log: tst_ncdap3.sh
-	@p='tst_ncdap3.sh'; \
-	b='tst_ncdap3.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_ber.sh.log: tst_ber.sh
-	@p='tst_ber.sh'; \
-	b='tst_ber.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_remote3.sh.log: tst_remote3.sh
-	@p='tst_remote3.sh'; \
-	b='tst_remote3.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_formatx.sh.log: tst_formatx.sh
-	@p='tst_formatx.sh'; \
-	b='tst_formatx.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)
 test_partvar.log: test_partvar$(EXEEXT)
 	@p='test_partvar$(EXEEXT)'; \
 	b='test_partvar'; \
@@ -1154,20 +1125,6 @@ test_partvar.log: test_partvar$(EXEEXT)
 	--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)
-testurl.sh.log: testurl.sh
-	@p='testurl.sh'; \
-	b='testurl.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_longremote3.sh.log: tst_longremote3.sh
-	@p='tst_longremote3.sh'; \
-	b='tst_longremote3.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)
 test_varm3.log: test_varm3$(EXEEXT)
 	@p='test_varm3$(EXEEXT)'; \
 	b='test_varm3'; \
@@ -1189,33 +1146,19 @@ t_misc.log: t_misc$(EXEEXT)
 	--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)
-testbasicauth.sh.log: testbasicauth.sh
-	@p='testbasicauth.sh'; \
-	b='testbasicauth.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)
-testcontainerauth.sh.log: testcontainerauth.sh
-	@p='testcontainerauth.sh'; \
-	b='testcontainerauth.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
@@ -1424,7 +1367,7 @@ clean-local: clean-local-check
 
 clean-local-check:
 	-rm -rf results
-	-rm .dodsrc
+	-rm -f .dodsrc
 
 # 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/ncdap_test/expected3/Makefile.in b/ncdap_test/expected3/Makefile.in
index 7e1050c..9426cfc 100644
--- a/ncdap_test/expected3/Makefile.in
+++ b/ncdap_test/expected3/Makefile.in
@@ -137,7 +137,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -160,12 +159,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -191,6 +192,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -205,6 +207,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/ncdap_test/expectremote3/Makefile.in b/ncdap_test/expectremote3/Makefile.in
index fc52ae8..d02d60e 100644
--- a/ncdap_test/expectremote3/Makefile.in
+++ b/ncdap_test/expectremote3/Makefile.in
@@ -137,7 +137,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -160,12 +159,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -191,6 +192,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -205,6 +207,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/ncdap_test/t_dap.c b/ncdap_test/t_dap.c
index ba3bdac..a73bb6b 100644
--- a/ncdap_test/t_dap.c
+++ b/ncdap_test/t_dap.c
@@ -110,7 +110,7 @@ int main()
 {
     int ncid, varid;
     int ncstat = NC_NOERR;
-    char* url;
+    char url[8192];
     const char* topsrcdir;
     size_t len;
 #ifndef USE_NETCDF4
@@ -123,20 +123,15 @@ int main()
     
     topsrcdir = gettopsrcdir();
 
-    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
-#ifdef DEBUG
-    len += strlen("[log][show=fetch]");
-#endif
-    url = (char*)malloc(len);
     url[0] = '\0';
 
 #ifdef DEBUG
-    strcat(url,"[log][show=fetch]");
+    strlcat(url,"[log][show=fetch]",sizeof(url));
 #endif
 
-    strcat(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
+    strlcat(url,"file://",sizeof(url));
+    strlcat(url,topsrcdir,sizeof(url));
+    strlcat(url,"/ncdap_test/testdata3/test.02",sizeof(url));
 
     printf("*** Test: var conversions on URL: %s\n",url);
 
diff --git a/ncdap_test/t_dap3a.c b/ncdap_test/t_dap3a.c
index 1ee3744..535579a 100644
--- a/ncdap_test/t_dap3a.c
+++ b/ncdap_test/t_dap3a.c
@@ -111,9 +111,8 @@ int main()
 {
     int ncid, varid;
     int ncstat = NC_NOERR;
-    char* url;
+    char url[8102];
     const char* topsrcdir;
-    size_t len;
 #ifndef USE_NETCDF4
     int i,j;
 #endif
@@ -124,20 +123,15 @@ int main()
     
     topsrcdir = gettopsrcdir();
 
-    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
-#ifdef DEBUG
-    len += strlen("[log][show=fetch]");
-#endif
-    url = (char*)malloc(len);
     url[0] = '\0';
 
 #ifdef DEBUG
-    strcat(url,"[log][show=fetch]");
+    strlcat(url,"[log][show=fetch]",sizeof(url));
 #endif
 
-    strcat(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
+    strlcat(url,"file://",sizeof(url));
+    strlcat(url,topsrcdir,sizeof(url));
+    strlcat(url,"/ncdap_test/testdata3/test.02",sizeof(url));
 
     printf("*** Test: var conversions on URL: %s\n",url);
 
diff --git a/ncdap_test/t_dap3c.c b/ncdap_test/t_dap3c.c
index 3ce713e..313437b 100644
--- a/ncdap_test/t_dap3c.c
+++ b/ncdap_test/t_dap3c.c
@@ -27,9 +27,9 @@ main()
 
     topsrcdir = gettopsrcdir();
 
-    strcpy(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
+    strncpy(url,"file://",sizeof(url));
+    strlcat(url,topsrcdir,sizeof(url));
+    strlcat(url,"/ncdap_test/testdata3/test.02",sizeof(url));
 
     if ((retval = nc_open(url, 0, &ncid)))
        ERR(retval);
diff --git a/ncdap_test/t_dap4.c b/ncdap_test/t_dap4.c
deleted file mode 100644
index 8144d2e..0000000
--- a/ncdap_test/t_dap4.c
+++ /dev/null
@@ -1,466 +0,0 @@
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "netcdf.h"
-#include "t_srcdir.h"
-
-#undef GENERATE
-
-#undef DEBUG
-
-/* Test (some) internal/external type conversions
-   using following DAP dataset (test.02).
-	Dataset {
-	    Byte b[DIMSIZE];
-	    Int32 i32[DIMSIZE];
-	    UInt32 ui32[DIMSIZE];
-	    Int16 i16[DIMSIZE];
-	    UInt16 ui16[DIMSIZE];
-	    Float32 f32[DIMSIZE];
-	    Float64 f64[DIMSIZE];
-	    String s[DIMSIZE];
-	    Url u[DIMSIZE];
-	} OneDimensionalSimpleArrays;
-*/
-
-#define NDIMS 1
-#define DIMSIZE 25
-#define STRLEN 64
-
-#ifndef USE_NETCDF4
-#define	NC_UBYTE 	7	/* unsigned 1 byte int */
-#define	NC_USHORT 	8	/* unsigned 2-byte int */
-#define	NC_UINT 	9	/* unsigned 4-byte int */
-#define	NC_INT64 	10	/* signed 8-byte int */
-#define	NC_UINT64 	11	/* unsigned 8-byte int */
-#define	NC_STRING 	12	/* string */
-#endif
-
-
-#define CHECK(expr) check(expr,__FILE__,__LINE__);
-
-#define COMMA (i==0?"":",")
-
-#define COMPARE(t1,t2,v1,v2) compare(t1,t2,(void*)v1,(void*)v2,#v2,__FILE__,__LINE__)
-
-static int failure = 0;
-
-static void compare(nc_type,nc_type,void*,void*,char*,char*,int);
-
-static void
-report(const int i, const char* var, const int line)
-{
-    fprintf(stdout,"%s mismatch: [%d] file: %s line: %d\n",var,i,__FILE__,line);
-    failure = 1;
-}
-
-static void
-check(int ncstat, char* file, int line)
-{
-    if(ncstat == NC_NOERR) return;
-    fprintf(stderr,"*** FAIL: %d (%s) at %s:%d\n",
-	    ncstat,nc_strerror(ncstat),file,line);
-    exit(1);
-}
-
-/* return 1 if |f1-f2| > 0.05 */
-static int
-fdiff(double f1, double f2)
-{
-    double delta = (f1 - f2);
-    if(delta < 0) delta = - delta;
-    if(delta > 0.05) {
-	fprintf(stdout,"fdiff: %1.3f %1.3f delta=%1.3f\n",f1,f2,delta);
-    }
-    return (delta > 0.05?1:0);
-}
-
-static char ch_data[DIMSIZE];
-static signed char int8_data[DIMSIZE];
-static unsigned char uint8_data[DIMSIZE];
-static int int8toint32_data[DIMSIZE];
-static float int82float32_data[DIMSIZE];
-static short int16_data[DIMSIZE];
-static int int16toint32_data[DIMSIZE];
-static float int162float32_data[DIMSIZE];
-static int int32_data[DIMSIZE];
-static float int32tofloat32_data[DIMSIZE];
-static long int32toilong_data[DIMSIZE];
-static float float32_data[DIMSIZE];
-static double float64_data[DIMSIZE];
-#ifndef USE_NETCDF4
-static char string3_data[DIMSIZE][STRLEN];
-#endif
-
-static char ch[DIMSIZE];
-static signed char int8[DIMSIZE];
-static unsigned char uint8[DIMSIZE];
-static short int16[DIMSIZE];
-static int int32[DIMSIZE];
-static float float32[DIMSIZE];
-static double float64[DIMSIZE];
-static long  ilong[DIMSIZE];
-#ifndef USE_NETCDF4
-static char string3[DIMSIZE][STRLEN];
-#endif
-
-int main()
-{
-    int ncid, varid;
-    int ncstat = NC_NOERR;
-    char* url;
-    const char* topsrcdir;
-    size_t len;
-#ifndef USE_NETCDF4
-    int i,j;
-#endif
-
-    /* location of our target url: use file:// to avoid remote
-	server downtime issues
-     */
-    
-    topsrcdir = gettopsrcdir();
-
-    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
-#ifdef DEBUG
-    len += strlen("[log][show=fetch]");
-#endif
-    url = (char*)malloc(len);
-    url[0] = '\0';
-
-#ifdef DEBUG
-    strcat(url,"[log][show=fetch]");
-#endif
-
-    strcat(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
-
-    printf("*** Test: var conversions on URL: %s\n",url);
-
-    /* open file, get varid */
-    CHECK(nc_open(url, NC_NOWRITE, &ncid));
-    
-    /* extract the string case for netcdf-3*/
-#ifndef USE_NETCDF4
-    CHECK(nc_inq_varid(ncid, "s", &varid));
-    CHECK(nc_get_var_text(ncid,varid,(char*)string3));
-#ifdef GENERATE
-    printf("static %s string3_data[DIMSIZE][STRLEN]={","char");
-    for(i=0;i<DIMSIZE;i++) {
-	int j;
-	/* Do simple escape */
-	for(j=0;j<STRLEN;j++) {
-	    if(string3[i][j] > 0
-	       && string3[i][j] != '\n'
-	       && string3[i][j] != '\r'
-	       && string3[i][j] != '\t'
-	       &&(string3[i][j] < ' ' || string3[i][j] >= '\177'))
-		string3[i][j] = '?';
-	}
-	printf("%s\"%s\"",COMMA,string3[i]);
-    }
-    printf("};\n");
-#else
- 	fprintf(stdout,"*** testing: %s\n","string3");
-	for(i=0;i<DIMSIZE;i++) {
-   	    for(j=0;j<STRLEN;j++) {
-	        if(string3[i][j] != string3_data[i][j]) {report(i,"string3",__LINE__); break;}
-	    }
-	}
-#endif
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_text(ncid,varid,ch));
-#ifdef GENERATE
-    printf("static %s ch_data[DIMSIZE]={","char");
-    for(i=0;i<DIMSIZE;i++) printf("%s'\\%03hho'",COMMA,ch[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_CHAR,NC_CHAR,ch,ch_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_schar(ncid,varid,int8));
-#ifdef GENERATE
-    printf("static %s int8_data[DIMSIZE]={","signed char");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hhd",COMMA,int8[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_BYTE,NC_BYTE,int8,int8_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_uchar(ncid,varid,uint8));
-#ifdef GENERATE
-    printf("static %s uint8_data[DIMSIZE]={","unsigned char");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hhu",COMMA,uint8[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_UBYTE,NC_UBYTE,uint8,uint8_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32));
-#ifdef GENERATE
-    printf("static %s int8toint32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_BYTE,NC_INT,int32,int8toint32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s int82float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_FLOAT,NC_FLOAT,float32,int82float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_short(ncid,varid,int16));
-#ifdef GENERATE
-    printf("static %s int16_data[DIMSIZE]={","short");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hd",COMMA,int16[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_SHORT,int16,int16_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32));
-#ifdef GENERATE
-    printf("static %s int16toint32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_INT,int32,int16toint32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s int162float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_FLOAT,float32,int162float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32));
-#ifdef GENERATE
-    printf("static %s int32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_INT,int32,int32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s int32tofloat32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_FLOAT,float32,int32tofloat32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_long(ncid,varid,ilong));
-#ifdef GENERATE
-    printf("static %s int32toilong_data[DIMSIZE]={","long");
-    for(i=0;i<DIMSIZE;i++) printf("%s%ld",COMMA,ilong[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_NAT,ilong,int32toilong_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "f32", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_FLOAT,NC_FLOAT,float32,float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "f64", &varid));
-    CHECK(nc_get_var_double(ncid,varid,float64));
-#ifdef GENERATE
-    printf("static %s float64_data[DIMSIZE]={","double");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float64[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_DOUBLE,NC_DOUBLE,float64,float64_data);
-#endif
-
-    if(failure) {
-        printf("ncstat=%d %s",ncstat,nc_strerror(ncstat));
-        exit(1);
-    }
-    return 0;
-}
-
-static char ch_data[DIMSIZE]={'\000','\001','\002','\003','\004','\005','\006','\007','\010','\011','\012','\013','\014','\015','\016','\017','\020','\021','\022','\023','\024','\025','\026','\027','\030'};
-static signed char int8_data[DIMSIZE]={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};
-static unsigned char uint8_data[DIMSIZE]={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};
-static int int8toint32_data[DIMSIZE]={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};
-static float int82float32_data[DIMSIZE]={0.000,1.000,2.000,3.000,4.000,5.000,6.000,7.000,8.000,9.000,10.000,11.000,12.000,13.000,14.000,15.000,16.000,17.000,18.000,19.000,20.000,21.000,22.000,23.000,24.000};
-static short int16_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
-static int int16toint32_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
-static float int162float32_data[DIMSIZE]={0.000,256.000,512.000,768.000,1024.000,1280.000,1536.000,1792.000,2048.000,2304.000,2560.000,2816.000,3072.000,3328.000,3584.000,3840.000,4096.000,4352.000,4608.000,4864.000,5120.000,5376.000,5632.000,5888.000,6144.000};
-static int int32_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
-static float int32tofloat32_data[DIMSIZE]={0.000,2048.000,4096.000,6144.000,8192.000,10240.000,12288.000,14336.000,16384.000,18432.000,20480.000,22528.000,24576.000,26624.000,28672.000,30720.000,32768.000,34816.000,36864.000,38912.000,40960.000,43008.000,45056.000,47104.000,49152.000};
-static long int32toilong_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
-static float float32_data[DIMSIZE]={0.000,0.010,0.020,0.030,0.040,0.050,0.060,0.070,0.080,0.090,0.100,0.110,0.120,0.130,0.140,0.149,0.159,0.169,0.179,0.189,0.199,0.208,0.218,0.228,0.238};
-static double float64_data[DIMSIZE]={1.000,1.000,1.000,1.000,0.999,0.999,0.998,0.998,0.997,0.996,0.995,0.994,0.993,0.992,0.990,0.989,0.987,0.986,0.984,0.982,0.980,0.978,0.976,0.974,0.971};
-
-#ifndef USE_NETCDF4
-static char string3_data[DIMSIZE][STRLEN]={"This is a data test string (pass 0).","This is a data test string (pass 1).","This is a data test string (pass 2).","This is a data test string (pass 3).","This is a data test string (pass 4).","This is a data test string (pass 5).","This is a data test string (pass 6).","This is a data test string (pass 7).","This is a data test string (pass 8).","This is a data test string (pass 9).","This is a data test string (pass 10).","This is a data tes [...]
-#endif
-
-static void
-compare(nc_type t1, nc_type t2, void* v0, void* vdata0, char* tag,
-	char* file, int line)
-{
-    int i;
-    fprintf(stdout,"*** testing: %s\n",tag); \
-
-#ifdef DEBUG
-#define test \
-    printf("v ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)v[i]);} \
-    printf("\n"); \
-    printf("vdata ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)vdata[i]);} \
-    printf("\n"); \
-    for(i=0;i<DIMSIZE;i++) {\
-        if(v[i] != vdata[i]) {report(i,tag,line); break;}\
-    }
-#define ftest \
-    printf("v ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %g",v[i]);} \
-    printf("\n"); \
-    printf("vdata ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %g",vdata[i]);} \
-    printf("\n"); \
-    for(i=0;i<DIMSIZE;i++) {\
-        if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
-    }
-#else
-#define test for(i=0;i<DIMSIZE;i++) {\
-        if(v[i] != vdata[i]) {report(i,tag,line); break;}\
-    }
-#define ftest for(i=0;i<DIMSIZE;i++) {\
-        if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
-    }
-#endif
-
-#define setup(T) T* v = (T*)v0; T* vdata = (T*)vdata0;
-
-#define CASE(nc1,nc2) (nc1*256+nc2)
-    switch(CASE(t1,t2)) {
-
-    default: {
-	printf("unexpected compare:  %d %d\n",(int)t1,(int)t2);
-	abort();
-    }    
-
-case CASE(NC_CHAR,NC_CHAR): {
-    setup(char);
-    test;
-} break;
-case CASE(NC_BYTE,NC_BYTE): {
-    setup(signed char);
-    test;
-} break;
-case CASE(NC_SHORT,NC_SHORT): {
-    setup(short);
-    test;
-} break;
-case CASE(NC_INT,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_FLOAT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-case CASE(NC_DOUBLE,NC_DOUBLE): {
-    setup(double);
-    ftest;
-} break;
-
-
-/* Mixed comparisons */
-case CASE(NC_BYTE,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_SHORT,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_SHORT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-case CASE(NC_INT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-
-/* This is an get_var_long case */
-case CASE(NC_INT,NC_NAT): {
-    setup(long);
-    test;
-} break;
-
-case CASE(NC_UBYTE,NC_UBYTE): {
-    setup(unsigned char);
-    test;
-} break;
-case CASE(NC_USHORT,NC_USHORT): {
-    setup(unsigned short);
-    test;
-} break;
-case CASE(NC_UINT,NC_UINT): {
-    setup(unsigned int);
-    test;
-} break;
-
-/* Mixed cases */
-case CASE(NC_INT,NC_INT64): {
-    setup(long long);
-    test;
-} break;
-
-case CASE(NC_INT,NC_UINT64): {
-    setup(unsigned long long);
-    test;
-} break;
-
-case CASE(NC_STRING,NC_STRING):{
-    setup(char*);
-    for(i=0;i<DIMSIZE;i++) {
-	if(strcmp(v[i],vdata[i])!=0) {report(i,tag,line); break;}
-    }
-} break;
-
-case CASE(NC_CHAR,NC_STRING):{
-    setup(char*);
-    if(memcmp((void*)v[0],(void*)vdata,DIMSIZE+1)!=0)
-        {report(0,tag,line);}
-} break;
-
-    } /*switch*/
-}
-
diff --git a/ncdap_test/t_dap4a.c b/ncdap_test/t_dap4a.c
deleted file mode 100644
index 6c78bdb..0000000
--- a/ncdap_test/t_dap4a.c
+++ /dev/null
@@ -1,937 +0,0 @@
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "netcdf.h"
-#include "t_srcdir.h"
-
-#undef GENERATE
-
-#undef DEBUG
-
-/* Test (some) internal/external type conversions
-   using following DAP dataset (test.02).
-	Dataset {
-	    Byte b[DIMSIZE];
-	    Int32 i32[DIMSIZE];
-	    UInt32 ui32[DIMSIZE];
-	    Int16 i16[DIMSIZE];
-	    UInt16 ui16[DIMSIZE];
-	    Float32 f32[DIMSIZE];
-	    Float64 f64[DIMSIZE];
-	    String s[DIMSIZE];
-	    Url u[DIMSIZE];
-	} OneDimensionalSimpleArrays;
-*/
-
-#define NDIMS 1
-#define DIMSIZE 25
-#define STRLEN 64
-
-#ifndef USE_NETCDF4
-#define	NC_UBYTE 	7	/* unsigned 1 byte int */
-#define	NC_USHORT 	8	/* unsigned 2-byte int */
-#define	NC_UINT 	9	/* unsigned 4-byte int */
-#define	NC_INT64 	10	/* signed 8-byte int */
-#define	NC_UINT64 	11	/* unsigned 8-byte int */
-#define	NC_STRING 	12	/* string */
-#endif
-
-
-#define CHECK(expr) check(expr,__FILE__,__LINE__);
-
-#define COMMA (i==0?"":",")
-
-#define COMPARE(t1,t2,v1,v2) compare(t1,t2,(void*)v1,(void*)v2,#v2,__FILE__,__LINE__)
-
-static int failure = 0;
-
-static void compare(nc_type,nc_type,void*,void*,char*,char*,int);
-
-static void
-report(const int i, const char* var, const int line)
-{
-    fprintf(stdout,"%s mismatch: [%d] file: %s line: %d\n",var,i,__FILE__,line);
-    failure = 1;
-}
-
-static void
-check(int ncstat, char* file, int line)
-{
-    if(ncstat == NC_NOERR) return;
-    fprintf(stderr,"*** FAIL: %d (%s) at %s:%d\n",
-	    ncstat,nc_strerror(ncstat),file,line);
-    exit(1);
-}
-
-/* return 1 if |f1-f2| > 0.05 */
-static int
-fdiff(double f1, double f2)
-{
-    double delta = (f1 - f2);
-    if(delta < 0) delta = - delta;
-    if(delta > 0.05) {
-	fprintf(stdout,"fdiff: %1.3f %1.3f delta=%1.3f\n",f1,f2,delta);
-    }
-    return (delta > 0.05?1:0);
-}
-
-static char ch_data[DIMSIZE];
-static signed char int8_data[DIMSIZE];
-static unsigned char uint8_data[DIMSIZE];
-static int int8toint32_data[DIMSIZE];
-static float int82float32_data[DIMSIZE];
-static short int16_data[DIMSIZE];
-static int int16toint32_data[DIMSIZE];
-static float int162float32_data[DIMSIZE];
-static int int32_data[DIMSIZE];
-static float int32tofloat32_data[DIMSIZE];
-static long int32toilong_data[DIMSIZE];
-static float float32_data[DIMSIZE];
-static double float64_data[DIMSIZE];
-#ifndef USE_NETCDF4
-static char string3_data[DIMSIZE][STRLEN];
-#endif
-
-static char ch[DIMSIZE];
-static signed char int8[DIMSIZE];
-static unsigned char uint8[DIMSIZE];
-static short int16[DIMSIZE];
-static int int32[DIMSIZE];
-static float float32[DIMSIZE];
-static double float64[DIMSIZE];
-static long  ilong[DIMSIZE];
-#ifndef USE_NETCDF4
-static char string3[DIMSIZE][STRLEN];
-#endif
-
-int main()
-{
-    int ncid, varid;
-    int ncstat = NC_NOERR;
-    char* url;
-    const char* topsrcdir;
-    size_t len;
-#ifndef USE_NETCDF4
-    int i,j;
-#endif
-
-    /* location of our target url: use file:// to avoid remote
-	server downtime issues
-     */
-    
-    /* Assume that TESTS_ENVIRONMENT was set */
-    topsrcdir = gettopsrcdir();
-
-    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
-#ifdef DEBUG
-    len += strlen("[log][show=fetch]");
-#endif
-    url = (char*)malloc(len);
-    url[0] = '\0';
-
-#ifdef DEBUG
-    strcat(url,"[log][show=fetch]");
-#endif
-
-    strcat(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
-
-    printf("*** Test: var conversions on URL: %s\n",url);
-
-    /* open file, get varid */
-    CHECK(nc_open(url, NC_NOWRITE, &ncid));
-    
-    /* extract the string case for netcdf-3*/
-#ifndef USE_NETCDF4
-    CHECK(nc_inq_varid(ncid, "s", &varid));
-    CHECK(nc_get_var_text(ncid,varid,(char*)string3));
-#ifdef GENERATE
-    printf("static %s string3_data[DIMSIZE][STRLEN]={","char");
-    for(i=0;i<DIMSIZE;i++) {
-	int j;
-	/* Do simple escape */
-	for(j=0;j<STRLEN;j++) {
-	    if(string3[i][j] > 0
-	       && string3[i][j] != '\n'
-	       && string3[i][j] != '\r'
-	       && string3[i][j] != '\t'
-	       &&(string3[i][j] < ' ' || string3[i][j] >= '\177'))
-		string3[i][j] = '?';
-	}
-	printf("%s\"%s\"",COMMA,string3[i]);
-    }
-    printf("};\n");
-#else
- 	fprintf(stdout,"*** testing: %s\n","string3");
-	for(i=0;i<DIMSIZE;i++) {
-   	    for(j=0;j<STRLEN;j++) {
-	        if(string3[i][j] != string3_data[i][j]) {report(i,"string3",__LINE__); break;}
-	    }
-	}
-#endif
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_text(ncid,varid,ch));
-#ifdef GENERATE
-    printf("static %s ch_data[DIMSIZE]={","char");
-    for(i=0;i<DIMSIZE;i++) printf("%s'\\%03hho'",COMMA,ch[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_CHAR,NC_CHAR,ch,ch_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_schar(ncid,varid,int8));
-#ifdef GENERATE
-    printf("static %s int8_data[DIMSIZE]={","signed char");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hhd",COMMA,int8[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_BYTE,NC_BYTE,int8,int8_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_uchar(ncid,varid,uint8));
-#ifdef GENERATE
-    printf("static %s uint8_data[DIMSIZE]={","unsigned char");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hhu",COMMA,uint8[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_UBYTE,NC_UBYTE,uint8,uint8_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32));
-#ifdef GENERATE
-    printf("static %s int8toint32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_BYTE,NC_INT,int32,int8toint32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s int82float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_FLOAT,NC_FLOAT,float32,int82float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_short(ncid,varid,int16));
-#ifdef GENERATE
-    printf("static %s int16_data[DIMSIZE]={","short");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hd",COMMA,int16[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_SHORT,int16,int16_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32));
-#ifdef GENERATE
-    printf("static %s int16toint32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_INT,int32,int16toint32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s int162float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_FLOAT,float32,int162float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32));
-#ifdef GENERATE
-    printf("static %s int32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_INT,int32,int32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s int32tofloat32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_FLOAT,float32,int32tofloat32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_long(ncid,varid,ilong));
-#ifdef GENERATE
-    printf("static %s int32toilong_data[DIMSIZE]={","long");
-    for(i=0;i<DIMSIZE;i++) printf("%s%ld",COMMA,ilong[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_NAT,ilong,int32toilong_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "f32", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32));
-#ifdef GENERATE
-    printf("static %s float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_FLOAT,NC_FLOAT,float32,float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "f64", &varid));
-    CHECK(nc_get_var_double(ncid,varid,float64));
-#ifdef GENERATE
-    printf("static %s float64_data[DIMSIZE]={","double");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float64[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_DOUBLE,NC_DOUBLE,float64,float64_data);
-#endif
-
-    if(failure) {
-        printf("ncstat=%d %s",ncstat,nc_strerror(ncstat));
-        exit(1);
-    }
-    return 0;
-}
-
-static char ch_data[DIMSIZE]={'\000','\001','\002','\003','\004','\005','\006','\007','\010','\011','\012','\013','\014','\015','\016','\017','\020','\021','\022','\023','\024','\025','\026','\027','\030'};
-static signed char int8_data[DIMSIZE]={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};
-static unsigned char uint8_data[DIMSIZE]={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};
-static int int8toint32_data[DIMSIZE]={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};
-static float int82float32_data[DIMSIZE]={0.000,1.000,2.000,3.000,4.000,5.000,6.000,7.000,8.000,9.000,10.000,11.000,12.000,13.000,14.000,15.000,16.000,17.000,18.000,19.000,20.000,21.000,22.000,23.000,24.000};
-static short int16_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
-static int int16toint32_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
-static float int162float32_data[DIMSIZE]={0.000,256.000,512.000,768.000,1024.000,1280.000,1536.000,1792.000,2048.000,2304.000,2560.000,2816.000,3072.000,3328.000,3584.000,3840.000,4096.000,4352.000,4608.000,4864.000,5120.000,5376.000,5632.000,5888.000,6144.000};
-static int int32_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
-static float int32tofloat32_data[DIMSIZE]={0.000,2048.000,4096.000,6144.000,8192.000,10240.000,12288.000,14336.000,16384.000,18432.000,20480.000,22528.000,24576.000,26624.000,28672.000,30720.000,32768.000,34816.000,36864.000,38912.000,40960.000,43008.000,45056.000,47104.000,49152.000};
-static long int32toilong_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
-static float float32_data[DIMSIZE]={0.000,0.010,0.020,0.030,0.040,0.050,0.060,0.070,0.080,0.090,0.100,0.110,0.120,0.130,0.140,0.149,0.159,0.169,0.179,0.189,0.199,0.208,0.218,0.228,0.238};
-static double float64_data[DIMSIZE]={1.000,1.000,1.000,1.000,0.999,0.999,0.998,0.998,0.997,0.996,0.995,0.994,0.993,0.992,0.990,0.989,0.987,0.986,0.984,0.982,0.980,0.978,0.976,0.974,0.971};
-
-#ifndef USE_NETCDF4
-static char string3_data[DIMSIZE][STRLEN]={"This is a data test string (pass 0).","This is a data test string (pass 1).","This is a data test string (pass 2).","This is a data test string (pass 3).","This is a data test string (pass 4).","This is a data test string (pass 5).","This is a data test string (pass 6).","This is a data test string (pass 7).","This is a data test string (pass 8).","This is a data test string (pass 9).","This is a data test string (pass 10).","This is a data tes [...]
-#endif
-
-static void
-compare(nc_type t1, nc_type t2, void* v0, void* vdata0, char* tag,
-	char* file, int line)
-{
-    int i;
-    fprintf(stdout,"*** testing: %s\n",tag); \
-
-#ifdef DEBUG
-#define test \
-    printf("v ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)v[i]);} \
-    printf("\n"); \
-    printf("vdata ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)vdata[i]);} \
-    printf("\n"); \
-    for(i=0;i<DIMSIZE;i++) {\
-        if(v[i] != vdata[i]) {report(i,tag,line); break;}\
-    }
-#define ftest \
-    printf("v ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %g",v[i]);} \
-    printf("\n"); \
-    printf("vdata ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %g",vdata[i]);} \
-    printf("\n"); \
-    for(i=0;i<DIMSIZE;i++) {\
-        if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
-    }
-#else
-#define test for(i=0;i<DIMSIZE;i++) {\
-        if(v[i] != vdata[i]) {report(i,tag,line); break;}\
-    }
-#define ftest for(i=0;i<DIMSIZE;i++) {\
-        if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
-    }
-#endif
-
-#define setup(T) T* v = (T*)v0; T* vdata = (T*)vdata0;
-
-#define CASE(nc1,nc2) (nc1*256+nc2)
-    switch(CASE(t1,t2)) {
-
-    default: {
-	printf("unexpected compare:  %d %d\n",(int)t1,(int)t2);
-	abort();
-    }    
-
-case CASE(NC_CHAR,NC_CHAR): {
-    setup(char);
-    test;
-} break;
-case CASE(NC_BYTE,NC_BYTE): {
-    setup(signed char);
-    test;
-} break;
-case CASE(NC_SHORT,NC_SHORT): {
-    setup(short);
-    test;
-} break;
-case CASE(NC_INT,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_FLOAT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-case CASE(NC_DOUBLE,NC_DOUBLE): {
-    setup(double);
-    ftest;
-} break;
-
-
-/* Mixed comparisons */
-case CASE(NC_BYTE,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_SHORT,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_SHORT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-case CASE(NC_INT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-
-/* This is an get_var_long case */
-case CASE(NC_INT,NC_NAT): {
-    setup(long);
-    test;
-} break;
-
-case CASE(NC_UBYTE,NC_UBYTE): {
-    setup(unsigned char);
-    test;
-} break;
-case CASE(NC_USHORT,NC_USHORT): {
-    setup(unsigned short);
-    test;
-} break;
-case CASE(NC_UINT,NC_UINT): {
-    setup(unsigned int);
-    test;
-} break;
-
-/* Mixed cases */
-case CASE(NC_INT,NC_INT64): {
-    setup(long long);
-    test;
-} break;
-
-case CASE(NC_INT,NC_UINT64): {
-    setup(unsigned long long);
-    test;
-} break;
-
-case CASE(NC_STRING,NC_STRING):{
-    setup(char*);
-    for(i=0;i<DIMSIZE;i++) {
-	if(strcmp(v[i],vdata[i])!=0) {report(i,tag,line); break;}
-    }
-} break;
-
-case CASE(NC_CHAR,NC_STRING):{
-    setup(char*);
-    if(memcmp((void*)v[0],(void*)vdata,DIMSIZE+1)!=0)
-        {report(0,tag,line);}
-} break;
-
-    } /*switch*/
-}
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "netcdf.h"
-
-
-#undef GENERATE
-
-#undef DEBUG
-
-/* Test (some) internal/external type conversions
-   using following DAP dataset (test.02).
-	Dataset {
-	    Byte b[DIMSIZE];
-	    Int32 i32[DIMSIZE];
-	    UInt32 ui32[DIMSIZE];
-	    Int16 i16[DIMSIZE];
-	    UInt16 ui16[DIMSIZE];
-	    Float32 f32[DIMSIZE];
-	    Float64 f64[DIMSIZE];
-	    String s[DIMSIZE];
-	    Url u[DIMSIZE];
-	} OneDimensionalSimpleArrays;
-*/
-
-#define NDIMS 1
-#define DIMSIZE 25
-#define STRLEN 64
-
-#ifndef USE_NETCDF4
-#define	NC_UBYTE 	7	/* unsigned 1 byte int */
-#define	NC_USHORT 	8	/* unsigned 2-byte int */
-#define	NC_UINT 	9	/* unsigned 4-byte int */
-#define	NC_INT64 	10	/* signed 8-byte int */
-#define	NC_UINT64 	11	/* unsigned 8-byte int */
-#define	NC_STRING 	12	/* string */
-#endif
-
-
-#define CHECK(expr) check(expr,__FILE__,__LINE__);
-
-#define COMMA (i==0?"":",")
-
-#define COMPARE(t1,t2,v1,v2) compare(t1,t2,(void*)v1,(void*)v2,#v2,__FILE__,__LINE__)
-
-static int failure = 0;
-
-static void compare(nc_type,nc_type,void*,void*,char*,char*,int);
-
-static void
-report(const int i, const char* var, const int line)
-{
-    fprintf(stdout,"%s mismatch: [%d] file: %s line: %d\n",var,i,__FILE__,line);
-    failure = 1;
-}
-
-static void
-check(int ncstat, char* file, int line)
-{
-    if(ncstat == NC_NOERR) return;
-    fprintf(stderr,"*** FAIL: %d (%s) at %s:%d\n",
-	    ncstat,nc_strerror(ncstat),file,line);
-    exit(1);
-}
-
-/* return 1 if |f1-f2| > 0.05 */
-static int
-fdiff(double f1, double f2)
-{
-    double delta = (f1 - f2);
-    if(delta < 0) delta = - delta;
-    if(delta > 0.05) {
-	fprintf(stdout,"fdiff: %1.3f %1.3f delta=%1.3f\n",f1,f2,delta);
-    }
-    return (delta > 0.05?1:0);
-}
-
-static char ch_data[DIMSIZE];
-static signed char int8_data[DIMSIZE];
-static unsigned char uint8_data[DIMSIZE];
-static int int8toint32_data[DIMSIZE];
-static float int82float32_data[DIMSIZE];
-static short int16_data[DIMSIZE];
-static int int16toint32_data[DIMSIZE];
-static float int162float32_data[DIMSIZE];
-static int int32_data[DIMSIZE];
-static float int32tofloat32_data[DIMSIZE];
-static long int32toilong_data[DIMSIZE];
-static float float32_data[DIMSIZE];
-static double float64_data[DIMSIZE];
-#ifndef USE_NETCDF4
-static char string3_data[DIMSIZE][STRLEN];
-#endif
-
-static char ch[DIMSIZE];
-static signed char int8v[DIMSIZE];
-static unsigned char uint8v[DIMSIZE];
-static short int16v[DIMSIZE];
-static int int32v[DIMSIZE];
-static float float32v[DIMSIZE];
-static double float64v[DIMSIZE];
-static long  ilong[DIMSIZE];
-#ifndef USE_NETCDF4
-static char string3[DIMSIZE][STRLEN];
-#endif
-
-int main()
-{
-    int ncid, varid;
-    int ncstat = NC_NOERR;
-    char* url;
-    char* topsrcdir;
-    size_t len;
-#ifndef USE_NETCDF4
-    int i,j;
-#endif
-
-    /* location of our target url: use file:// to avoid remote
-	server downtime issues
-     */
-    
-    /* 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);
-    }    
-    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
-#ifdef DEBUG
-    len += strlen("[log][show=fetch]");
-#endif
-    url = (char*)malloc(len);
-    url[0] = '\0';
-
-#ifdef DEBUG
-    strcat(url,"[log][show=fetch]");
-#endif
-
-    strcat(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
-
-    printf("*** Test: var conversions on URL: %s\n",url);
-
-    /* open file, get varid */
-    CHECK(nc_open(url, NC_NOWRITE, &ncid));
-    
-    /* extract the string case for netcdf-3*/
-#ifndef USE_NETCDF4
-    CHECK(nc_inq_varid(ncid, "s", &varid));
-    CHECK(nc_get_var_text(ncid,varid,(char*)string3));
-#ifdef GENERATE
-    printf("static %s string3_data[DIMSIZE][STRLEN]={","char");
-    for(i=0;i<DIMSIZE;i++) {
-	int j;
-	/* Do simple escape */
-	for(j=0;j<STRLEN;j++) {
-	    if(string3[i][j] > 0
-	       && string3[i][j] != '\n'
-	       && string3[i][j] != '\r'
-	       && string3[i][j] != '\t'
-	       &&(string3[i][j] < ' ' || string3[i][j] >= '\177'))
-		string3[i][j] = '?';
-	}
-	printf("%s\"%s\"",COMMA,string3[i]);
-    }
-    printf("};\n");
-#else
- 	fprintf(stdout,"*** testing: %s\n","string3");
-	for(i=0;i<DIMSIZE;i++) {
-   	    for(j=0;j<STRLEN;j++) {
-	        if(string3[i][j] != string3_data[i][j]) {report(i,"string3",__LINE__); break;}
-	    }
-	}
-#endif
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_text(ncid,varid,ch));
-#ifdef GENERATE
-    printf("static %s ch_data[DIMSIZE]={","char");
-    for(i=0;i<DIMSIZE;i++) printf("%s'\\%03hho'",COMMA,ch[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_CHAR,NC_CHAR,ch,ch_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_schar(ncid,varid,int8v));
-#ifdef GENERATE
-    printf("static %s int8_data[DIMSIZE]={","signed char");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hhd",COMMA,int8v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_BYTE,NC_BYTE,int8v,int8_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_uchar(ncid,varid,uint8v));
-#ifdef GENERATE
-    printf("static %s uint8_data[DIMSIZE]={","unsigned char");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hhu",COMMA,uint8v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_UBYTE,NC_UBYTE,uint8v,uint8_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32v));
-#ifdef GENERATE
-    printf("static %s int8toint32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_BYTE,NC_INT,int32v,int8toint32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "b", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32v));
-#ifdef GENERATE
-    printf("static %s int82float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_FLOAT,NC_FLOAT,float32v,int82float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_short(ncid,varid,int16v));
-#ifdef GENERATE
-    printf("static %s int16_data[DIMSIZE]={","short");
-    for(i=0;i<DIMSIZE;i++) printf("%s%hd",COMMA,int16v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_SHORT,int16v,int16_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32v));
-#ifdef GENERATE
-    printf("static %s int16toint32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_INT,int32v,int16toint32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i16", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32v));
-#ifdef GENERATE
-    printf("static %s int162float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_SHORT,NC_FLOAT,float32v,int162float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_int(ncid,varid,int32v));
-#ifdef GENERATE
-    printf("static %s int32_data[DIMSIZE]={","int");
-    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_INT,int32v,int32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32v));
-#ifdef GENERATE
-    printf("static %s int32tofloat32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_FLOAT,float32v,int32tofloat32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "i32", &varid));
-    CHECK(nc_get_var_long(ncid,varid,ilong));
-#ifdef GENERATE
-    printf("static %s int32toilong_data[DIMSIZE]={","long");
-    for(i=0;i<DIMSIZE;i++) printf("%s%ld",COMMA,ilong[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_INT,NC_NAT,ilong,int32toilong_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "f32", &varid));
-    CHECK(nc_get_var_float(ncid,varid,float32v));
-#ifdef GENERATE
-    printf("static %s float32_data[DIMSIZE]={","float");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_FLOAT,NC_FLOAT,float32v,float32_data);
-#endif
-
-    CHECK(nc_inq_varid(ncid, "f64", &varid));
-    CHECK(nc_get_var_double(ncid,varid,float64v));
-#ifdef GENERATE
-    printf("static %s float64_data[DIMSIZE]={","double");
-    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float64v[i]);
-    printf("};\n");
-#else
-    COMPARE(NC_DOUBLE,NC_DOUBLE,float64v,float64_data);
-#endif
-
-    if(failure) {
-        printf("ncstat=%d %s",ncstat,nc_strerror(ncstat));
-        exit(1);
-    }
-    return 0;
-}
-
-static char ch_data[DIMSIZE]={'\000','\001','\002','\003','\004','\005','\006','\007','\010','\011','\012','\013','\014','\015','\016','\017','\020','\021','\022','\023','\024','\025','\026','\027','\030'};
-static signed char int8_data[DIMSIZE]={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};
-static unsigned char uint8_data[DIMSIZE]={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};
-static int int8toint32_data[DIMSIZE]={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};
-static float int82float32_data[DIMSIZE]={0.000,1.000,2.000,3.000,4.000,5.000,6.000,7.000,8.000,9.000,10.000,11.000,12.000,13.000,14.000,15.000,16.000,17.000,18.000,19.000,20.000,21.000,22.000,23.000,24.000};
-static short int16_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
-static int int16toint32_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
-static float int162float32_data[DIMSIZE]={0.000,256.000,512.000,768.000,1024.000,1280.000,1536.000,1792.000,2048.000,2304.000,2560.000,2816.000,3072.000,3328.000,3584.000,3840.000,4096.000,4352.000,4608.000,4864.000,5120.000,5376.000,5632.000,5888.000,6144.000};
-static int int32_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
-static float int32tofloat32_data[DIMSIZE]={0.000,2048.000,4096.000,6144.000,8192.000,10240.000,12288.000,14336.000,16384.000,18432.000,20480.000,22528.000,24576.000,26624.000,28672.000,30720.000,32768.000,34816.000,36864.000,38912.000,40960.000,43008.000,45056.000,47104.000,49152.000};
-static long int32toilong_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
-static float float32_data[DIMSIZE]={0.000,0.010,0.020,0.030,0.040,0.050,0.060,0.070,0.080,0.090,0.100,0.110,0.120,0.130,0.140,0.149,0.159,0.169,0.179,0.189,0.199,0.208,0.218,0.228,0.238};
-static double float64_data[DIMSIZE]={1.000,1.000,1.000,1.000,0.999,0.999,0.998,0.998,0.997,0.996,0.995,0.994,0.993,0.992,0.990,0.989,0.987,0.986,0.984,0.982,0.980,0.978,0.976,0.974,0.971};
-
-#ifndef USE_NETCDF4
-static char string3_data[DIMSIZE][STRLEN]={"This is a data test string (pass 0).","This is a data test string (pass 1).","This is a data test string (pass 2).","This is a data test string (pass 3).","This is a data test string (pass 4).","This is a data test string (pass 5).","This is a data test string (pass 6).","This is a data test string (pass 7).","This is a data test string (pass 8).","This is a data test string (pass 9).","This is a data test string (pass 10).","This is a data tes [...]
-#endif
-
-static void
-compare(nc_type t1, nc_type t2, void* v0, void* vdata0, char* tag,
-	char* file, int line)
-{
-    int i;
-    fprintf(stdout,"*** testing: %s\n",tag); \
-
-#ifdef DEBUG
-#define test \
-    printf("v ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)v[i]);} \
-    printf("\n"); \
-    printf("vdata ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)vdata[i]);} \
-    printf("\n"); \
-    for(i=0;i<DIMSIZE;i++) {\
-        if(v[i] != vdata[i]) {report(i,tag,line); break;}\
-    }
-#define ftest \
-    printf("v ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %g",v[i]);} \
-    printf("\n"); \
-    printf("vdata ="); \
-    for(i=0;i<DIMSIZE;i++) {printf(" %g",vdata[i]);} \
-    printf("\n"); \
-    for(i=0;i<DIMSIZE;i++) {\
-        if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
-    }
-#else
-#define test for(i=0;i<DIMSIZE;i++) {\
-        if(v[i] != vdata[i]) {report(i,tag,line); break;}\
-    }
-#define ftest for(i=0;i<DIMSIZE;i++) {\
-        if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
-    }
-#endif
-
-#define setup(T) T* v = (T*)v0; T* vdata = (T*)vdata0;
-
-#define CASE(nc1,nc2) (nc1*256+nc2)
-    switch(CASE(t1,t2)) {
-
-    default: {
-	printf("unexpected compare:  %d %d\n",(int)t1,(int)t2);
-	abort();
-    }    
-
-case CASE(NC_CHAR,NC_CHAR): {
-    setup(char);
-    test;
-} break;
-case CASE(NC_BYTE,NC_BYTE): {
-    setup(signed char);
-    test;
-} break;
-case CASE(NC_SHORT,NC_SHORT): {
-    setup(short);
-    test;
-} break;
-case CASE(NC_INT,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_FLOAT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-case CASE(NC_DOUBLE,NC_DOUBLE): {
-    setup(double);
-    ftest;
-} break;
-
-
-/* Mixed comparisons */
-case CASE(NC_BYTE,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_SHORT,NC_INT): {
-    setup(int);
-    test;
-} break;
-case CASE(NC_SHORT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-case CASE(NC_INT,NC_FLOAT): {
-    setup(float);
-    ftest;
-} break;
-
-/* This is an get_var_long case */
-case CASE(NC_INT,NC_NAT): {
-    setup(long);
-    test;
-} break;
-
-case CASE(NC_UBYTE,NC_UBYTE): {
-    setup(unsigned char);
-    test;
-} break;
-case CASE(NC_USHORT,NC_USHORT): {
-    setup(unsigned short);
-    test;
-} break;
-case CASE(NC_UINT,NC_UINT): {
-    setup(unsigned int);
-    test;
-} break;
-
-/* Mixed cases */
-case CASE(NC_INT,NC_INT64): {
-    setup(long long);
-    test;
-} break;
-
-case CASE(NC_INT,NC_UINT64): {
-    setup(unsigned long long);
-    test;
-} break;
-
-case CASE(NC_STRING,NC_STRING):{
-    setup(char*);
-    for(i=0;i<DIMSIZE;i++) {
-	if(strcmp(v[i],vdata[i])!=0) {report(i,tag,line); break;}
-    }
-} break;
-
-case CASE(NC_CHAR,NC_STRING):{
-    setup(char*);
-    if(memcmp((void*)v[0],(void*)vdata,DIMSIZE+1)!=0)
-        {report(0,tag,line);}
-} break;
-
-    } /*switch*/
-}
-
diff --git a/ncdap_test/t_dap4c.c b/ncdap_test/t_dap4c.c
deleted file mode 100644
index 80dad48..0000000
--- a/ncdap_test/t_dap4c.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "config.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "netcdf.h"
-#include "t_srcdir.h"
-
-#define VAR "i32"
-
-#define ERRCODE 2
-#define ERR(e) {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);}
-
-#undef DEBUG
-
-int
-main()
-{
-    int ncid, varid;
-    int retval;
-    int i32[100];
-    size_t start[1];
-    size_t count[1];
-    int ok = 1;    
-
-    const char* topsrcdir;
-    char url[4096];
-
-    topsrcdir = gettopsrcdir();
-
-    strcpy(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
-
-    if ((retval = nc_open(url, 0, &ncid)))
-       ERR(retval);
-    if ((retval = nc_inq_varid(ncid, VAR, &varid)))
-       ERR(retval);
-
-    start[0] = 0;
-    count[0] = 26;
-    if ((retval = nc_get_vara_int(ncid, varid, start, count, i32)))
-    if(retval != NC_EINVALCOORDS) {
-	printf("nc_get_vara_int did not return NC_EINVALCOORDS");
-	ok = 0;
-    }
-
-    nc_close(ncid);
-
-    printf(ok?"*** PASS\n":"*** FAIL\n");
-    return 0;
-}
diff --git a/ncdap_test/test_cvt.c b/ncdap_test/test_cvt.c
index 2e9500a..f9bb03f 100644
--- a/ncdap_test/test_cvt.c
+++ b/ncdap_test/test_cvt.c
@@ -110,9 +110,8 @@ int main()
 {
     int ncid, varid;
     int ncstat = NC_NOERR;
-    char* url;
+    char url[8192];
     const char* topsrcdir;
-    size_t len;
 #ifndef USE_NETCDF4
     int i,j;
 #endif
@@ -123,20 +122,15 @@ int main()
     
     topsrcdir = gettopsrcdir();
 
-    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
-#ifdef DEBUG
-    len += strlen("[log][show=fetch]");
-#endif
-    url = (char*)malloc(len);
     url[0] = '\0';
 
 #ifdef DEBUG
-    strcat(url,"[log][show=fetch]");
+    strlcat(url,"[log][show=fetch]",sizeof(url));
 #endif
 
-    strcat(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.02");
+    strlcat(url,"file://",sizeof(url));
+    strlcat(url,topsrcdir,sizeof(url));
+    strlcat(url,"/ncdap_test/testdata3/test.02",sizeof(url));
 
     printf("*** Test: var conversions on URL: %s\n",url);
 
diff --git a/ncdap_test/test_nstride_cached.c b/ncdap_test/test_nstride_cached.c
index 47fe01f..72c6376 100644
--- a/ncdap_test/test_nstride_cached.c
+++ b/ncdap_test/test_nstride_cached.c
@@ -101,7 +101,6 @@ main()
 	exit(0);
     }
 
-    strcpy(url,URL);
     snprintf(url,sizeof(url),URL,svc);
 
     for (idim=0; idim<5; idim++) {
diff --git a/ncdap_test/test_partvar.c b/ncdap_test/test_partvar.c
index 7ccb4bd..c2af1d8 100644
--- a/ncdap_test/test_partvar.c
+++ b/ncdap_test/test_partvar.c
@@ -106,9 +106,9 @@ main()
 	fprintf(stderr,"Cannot locate test server\n");
 	exit(0);
     }
-    strcpy(url,PARAMS);
-    strcat(url,svc);
-    strcat(url,DTSTEST);
+    strncpy(url,PARAMS,sizeof(url));
+    strlcat(url,svc,sizeof(url));
+    strlcat(url,DTSTEST,sizeof(url));
 
     printf("test_partvar: url=%s\n",url);
 
diff --git a/ncdap_test/test_partvar2.c b/ncdap_test/test_partvar2.c
index 4ddfccb..3d22518 100644
--- a/ncdap_test/test_partvar2.c
+++ b/ncdap_test/test_partvar2.c
@@ -95,9 +95,9 @@ main()
 	fprintf(stderr,"Cannot locate test server\n");
 	exit(1);
     }
-    strcpy(url,PARAMS);
-    strcat(url,svc);
-    strcat(url,DTSTEST);
+    strncpy(url,PARAMS,sizeo(url));
+    strlcat(url,svc,sizeof(url));
+    strlcat(url,DTSTEST,sizeof(url));
 
     printf("test_partvar: url=%s\n",url);
 
diff --git a/ncdap_test/test_vara.c b/ncdap_test/test_vara.c
index e3ae045..b819a29 100644
--- a/ncdap_test/test_vara.c
+++ b/ncdap_test/test_vara.c
@@ -1,3 +1,4 @@
+#include "config.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -81,9 +82,9 @@ main()
 
     topsrcdir = gettopsrcdir();
 
-    strcpy(url,"file://");
-    strcat(url,topsrcdir);
-    strcat(url,"/ncdap_test/testdata3/test.06");
+    strncpy(url,"file://",sizeof(url));
+    strlcat(url,topsrcdir,sizeof(url));
+    strlcat(url,"/ncdap_test/testdata3/test.06",sizeof(url));
 
     printf("test_vara: url=%s\n",url);
 
diff --git a/ncdap_test/test_varm3.c b/ncdap_test/test_varm3.c
index 30c5782..37e0ee6 100644
--- a/ncdap_test/test_varm3.c
+++ b/ncdap_test/test_varm3.c
@@ -99,8 +99,8 @@ main()
         fprintf(stderr,"Cannot locate test server\n");
 	exit(0);
     }
-    strcpy(url,svc);
-    strcat(url,TESTPATH);
+    strncpy(url,svc,sizeof(url));
+    strlcat(url,TESTPATH,sizeof(url));
 
     printf("*** Test: varm on URL: %s\n",url);
 
diff --git a/ncdap_test/testdata3/Makefile.in b/ncdap_test/testdata3/Makefile.in
index 272b825..69e4bbc 100644
--- a/ncdap_test/testdata3/Makefile.in
+++ b/ncdap_test/testdata3/Makefile.in
@@ -137,7 +137,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -160,12 +159,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -191,6 +192,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -205,6 +207,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/ncdap_test/testurl.sh b/ncdap_test/testurl.sh
index 4f10caf..4dfc9e1 100755
--- a/ncdap_test/testurl.sh
+++ b/ncdap_test/testurl.sh
@@ -32,7 +32,7 @@ BOTHP="[log][show=fetch]"
 BOTHS="noprefetch&fetch=disk"
 
 locreset () {
-    rm -f ./tmp ./errtmp
+    rm -f ./tmp_testurl ./errtmp_testurl
 }
 
 buildurl () {
@@ -58,8 +58,8 @@ echo "***Testing url prefix parameters"
 buildurl $PREFIX ""
 # Invoke ncdump to extract the URL
 echo "command: ${NCDUMP} -h $url"
-${NCDUMP} -h "$url" >./tmp 2> ./errtmp
-if test "x${SHOW}" = x1 ; then cat ./tmp ; fi
+${NCDUMP} -h "$url" >./tmp_testurl 2> ./errtmp_testurl
+if test "x${SHOW}" = x1 ; then cat ./tmp_testurl ; fi
 fi
 
 locreset
@@ -68,8 +68,8 @@ echo "***Testing url suffix parameters"
 buildurl "" $SUFFIX
 # Invoke ncdump to extract the URL
 echo "command: ${NCDUMP} -h $url"
-${NCDUMP} -h "$url" >./tmp  2> ./errtmp
-if test "x${SHOW}" = x1 ; then cat ./tmp ; fi
+${NCDUMP} -h "$url" >./tmp_testurl  2> ./errtmp_testurl
+if test "x${SHOW}" = x1 ; then cat ./tmp_testurl ; fi
 fi
 
 locreset
@@ -78,8 +78,8 @@ echo "***Testing url prefix+suffix parameters"
 buildurl $BOTHP $BOTHS
 # Invoke ncdump to extract the URL
 echo "command: ${NCDUMP} -h $url"
-${NCDUMP} -h "$url" >./tmp 2> ./errtmp
-if test "x${SHOW}" = x1 ; then cat ./tmp ; fi
+${NCDUMP} -h "$url" >./tmp_testurl 2> ./errtmp_testurl
+if test "x${SHOW}" = x1 ; then cat ./tmp_testurl ; fi
 fi
 
 locreset
diff --git a/ncdap_test/tst_ber.sh b/ncdap_test/tst_ber.sh
index fe1d3ab..760b198 100755
--- a/ncdap_test/tst_ber.sh
+++ b/ncdap_test/tst_ber.sh
@@ -1,6 +1,5 @@
 #!/bin/sh
 
-export SETX=1
 #export NCPATHDEBUG=1
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi
@@ -11,9 +10,9 @@ EXPECTED="${srcdir}/expected3"
 
 URL='[log][cache]file://'
 URL="${URL}${srcdir}/testdata3/$F"
-rm -f ./tmp
-${NCDUMP} "${URL}" | sed 's/\\r//g' > ./tmp
-diff -w ${EXPECTED}/$F.dmp ./tmp
+rm -f ./tmp_tst_ber
+${NCDUMP} "${URL}" | sed 's/\\r//g' > ./tmp_tst_ber
+diff -w ${EXPECTED}/$F.dmp ./tmp_tst_ber
 #cleanup
-rm -f ./tmp
+rm -f ./tmp_tst_ber
 exit
diff --git a/ncdap_test/tst_formatx.sh b/ncdap_test/tst_formatx.sh
index a87594f..5d9a8a4 100755
--- a/ncdap_test/tst_formatx.sh
+++ b/ncdap_test/tst_formatx.sh
@@ -19,13 +19,13 @@ URL="$DTS/test.03"
 
 ECODE=0
 echo "Test extended format output for a DAP2  file"
-rm -f tmp
-${NCDUMP} -K "${URL}" >tmp
-if ! grep 'DAP2 mode=00000000' <tmp ; then
+rm -f tmp_tst_formatx
+${NCDUMP} -K "${URL}" >tmp_tst_formatx
+if ! grep 'DAP2 mode=00000000' <tmp_tst_formatx ; then
 echo "*** Fail: extended format for a DAP2 file"
 ECODE=1
 fi
 
-rm tmp
+rm tmp_tst_formatx
 
 exit $ECODE
diff --git a/ncdap_test/tst_ncdap.sh b/ncdap_test/tst_ncdap.sh
index bf12df1..13f0ca4 100755
--- a/ncdap_test/tst_ncdap.sh
+++ b/ncdap_test/tst_ncdap.sh
@@ -44,7 +44,7 @@ remote*)
     ;;
 esac
 
-RESULTSDIR="./results"
+RESULTSDIR="./results_tst_ncdap"
 #
 if test "x$leakcheck" = "x1" ; then
 VALGRIND="valgrind -q --error-exitcode=2 --leak-check=full"
@@ -109,7 +109,7 @@ echo "pwd=" `pwd`
 
 totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
-
+rm -fr ${RESULTSDIR}
 echo "*** PASSED: ${okcount}/${totalcount} ; ${xfailcount} expected failures ; ${failcount} unexpected failures"
 
 #failcount=0
diff --git a/ncdap_test/tst_remote.sh b/ncdap_test/tst_remote.sh
index 23042ff..64789b1 100755
--- a/ncdap_test/tst_remote.sh
+++ b/ncdap_test/tst_remote.sh
@@ -187,7 +187,7 @@ PARAMS="${PARAMS}[netcdf3]"
 XFAILTESTS="$XFAILTESTS3"
 SVCFAILTESTS="$SVCFAILTESTS3"
 
-RESULTSDIR="./results"
+RESULTSDIR="./results_tst_remote"
 # Locate some tools
 if test "x$leakcheck" = x1 ; then
 VALGRIND="valgrind -q --error-exitcode=2 --leak-check=full"
@@ -325,6 +325,7 @@ cd ..
 
 done
 
+rm -fr ${RESULTSDIR}
 totalcount=`expr $passcount + $failcount + $xfailcount + $svcfailcount`
 okcount=`expr $passcount + $xfailcount + $svcfailcount`
 
diff --git a/ncdap_test/tst_special.sh b/ncdap_test/tst_special.sh
index fd15c54..4451ad0 100755
--- a/ncdap_test/tst_special.sh
+++ b/ncdap_test/tst_special.sh
@@ -62,7 +62,7 @@ d055.nc;http://ilikai.soest.hawaii.edu/cgi-bin/nph-dods/fast/d055.nc \
 # Temporarily suppress
 XFAILTESTS="qscat_high_wind totalAagg  world-unfilter-monthly.nc duacs_global_nrt_msla_merged_h_lr 500m"
 
-RESULTSDIR="./results"
+RESULTSDIR="./results_tst_special"
 # Locate some tools
 if test "x$leakcheck" = x1 ; then
 VALGRIND="valgrind -q --error-exitcode=2 --leak-check=full"
@@ -134,6 +134,7 @@ done
 cd ..
 done
 
+rm -fr ${RESULTSDIR}
 totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
 
diff --git a/ncdap_test/tst_tds.sh b/ncdap_test/tst_tds.sh
index b098b53..de8ff1d 100755
--- a/ncdap_test/tst_tds.sh
+++ b/ncdap_test/tst_tds.sh
@@ -84,7 +84,7 @@ TESTSET="${TDSTESTS1}"
 # Temporarily suppress
 XFAILTESTS="tst-Surface-METAR.nc"
 
-RESULTSDIR="./results"
+RESULTSDIR="./results_tst_tds"
 expected3="${srcdir}/expecttds3"
 
 # Locate some tools
@@ -157,6 +157,7 @@ for t in ${TESTSET} ; do
 done
 cd ..
 
+rm -fr ${RESULTSDIR}
 totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
 
diff --git a/ncdump/CMakeLists.txt b/ncdump/CMakeLists.txt
index 4f0aa12..89174b1 100644
--- a/ncdump/CMakeLists.txt
+++ b/ncdump/CMakeLists.txt
@@ -3,22 +3,6 @@ IF(BUILD_SHARED_LIBS AND WIN32)
   remove_definitions(-DDLL_NETCDF)
 ENDIF()
 
-# These generate some files used in ncdump testing
-# Specifically, they generate ctest0.nc ctest0_64.nc
-# Before, these .nc files were placed in the same place as the
-# .c file: namely build/ncdump.
-# This complicates the shell tests that use it.
-ADD_CUSTOM_COMMAND(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CONFIG_TYPE}/ctest.c
-  COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/ref_ctest.c"
-  "${CMAKE_CURRENT_BINARY_DIR}/ctest.c"
-  )
-ADD_CUSTOM_COMMAND(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ctest64.c
-  COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/ref_ctest64.c"
-  "${CMAKE_CURRENT_BINARY_DIR}/ctest64.c"
-  )
-
 SET(ncdump_FILES ncdump.c vardata.c dumplib.c indent.c nctime0.c utils.c nciter.c)
 SET(nccopy_FILES nccopy.c nciter.c chunkspec.c utils.c dimmap.c)
 
@@ -108,7 +92,7 @@ IF(ENABLE_TESTS)
         ${CMAKE_CURRENT_BINARY_DIR})
 
   ENDIF(USE_NETCDF4)
-ENDIF()
+ENDIF(MSVC)
 
   # Base tests
   # The tests are set up as a combination of shell scripts and executables that
@@ -118,19 +102,27 @@ ENDIF()
   ## Start adding tests in the appropriate order
   add_sh_test(ncdump run_tests)
   add_sh_test(ncdump tst_64bit)
-  add_bin_test(ncdump ctest)
-  add_bin_test(ncdump ctest64)
+  add_bin_test_no_prefix(ref_ctest)
+  add_bin_test_no_prefix(ref_ctest64)
   add_sh_test(ncdump tst_output)
   add_sh_test(ncdump tst_lengths)
   add_sh_test(ncdump tst_calendars)
-  add_bin_test(ncdump tst_utf8)
+  build_bin_test_no_prefix(tst_utf8)
   add_sh_test(ncdump run_utf8_tests)
   IF(USE_NETCDF4)
     add_sh_test(ncdump run_utf8_nc4_tests)
     add_sh_test(ncdump tst_fileinfo)
+    add_sh_test(ncdump tst_hdf5_offset)
   ENDIF(USE_NETCDF4)
 
+  add_sh_test(ncdump tst_null_byte_padding)
+  IF(USE_STRICT_NULL_BYTE_HEADER_PADDING)
+    SET_TESTS_PROPERTIES(ncdump_tst_null_byte_padding PROPERTIES WILL_FAIL TRUE)
+  ENDIF(USE_STRICT_NULL_BYTE_HEADER_PADDING)
+
   add_sh_test(ncdump tst_nccopy3)
+  SET_TESTS_PROPERTIES(ncdump_tst_nccopy3 PROPERTIES RUN_SERIAL TRUE)
+
   add_sh_test(ncdump tst_nccopy3_subset)
   add_sh_test(ncdump tst_charfill)
 
@@ -154,23 +146,22 @@ ENDIF()
   ENDIF(BUILD_DISKLESS)
 
   IF(USE_NETCDF4)
-    add_bin_test(ncdump tst_create_files)
-    add_bin_test(ncdump tst_group_data)
-    add_bin_test(ncdump tst_enum_data)
-    add_bin_test(ncdump tst_opaque_data)
-    add_bin_test(ncdump tst_string_data)
-    add_bin_test(ncdump tst_vlen_data)
-    add_bin_test(ncdump tst_comp)
-    add_bin_test(ncdump tst_comp2)
-    add_bin_test(ncdump tst_nans)
-    add_bin_test(ncdump tst_h_scalar)
-    add_bin_test(ncdump tst_bug324)
+    build_bin_test_no_prefix(tst_create_files)
+    build_bin_test_no_prefix(tst_group_data)
+    build_bin_test_no_prefix(tst_enum_data)
+    build_bin_test_no_prefix(tst_opaque_data)
+    build_bin_test_no_prefix(tst_string_data)
+    build_bin_test_no_prefix(tst_vlen_data)
+    build_bin_test_no_prefix(tst_comp)
+    build_bin_test_no_prefix(tst_comp2)
+    build_bin_test_no_prefix(tst_nans)
+    build_bin_test_no_prefix(tst_h_scalar)
     add_sh_test(ncdump tst_formatx4)
     # Add this test by hand, as it is also called from a script.
     # Editing the script would break autotools compatibility.
-    add_bin_test_no_prefix(tst_special_atts)
-    add_bin_test_no_prefix(tst_compress)
-    add_bin_test_no_prefix(tst_chunking)
+    build_bin_test_no_prefix(tst_special_atts)
+    build_bin_test_no_prefix(tst_compress)
+    build_bin_test_no_prefix(tst_chunking)
 
 
     ###
@@ -178,25 +169,29 @@ ENDIF()
     # It passes, but technically fails because the scientific
     # formatting omits a 0.
     ###
-    IF(EXTRA_TESTS AND NOT MSVC)
+    IF(EXTRA_TESTS)
       add_sh_test(ncdump run_back_comp_tests)
-    ENDIF()
+      IF(MSVC)
+        SET_TESTS_PROPERTIES(ncdump_run_back_comp_tests PROPERTIES WILL_FAIL TRUE)
+      ENDIF(MSVC)
+    ENDIF(EXTRA_TESTS)
 
     # Known failure on MSVC; the number of 0's padding
     # is different, but the result is actually correct.
-    #IF(NOT MSVC)
-    add_sh_test(ncdump tst_netcdf4)
-    add_bin_test(ncdump tst_h_rdc0)
-    #ENDIF()
+    IF(HAVE_BASH)
+      add_sh_test(ncdump tst_netcdf4)
+      build_bin_test_no_prefix(tst_h_rdc0)
+    ENDIF()
 
-    add_bin_test(ncdump tst_unicode)
+    build_bin_test_no_prefix(tst_unicode)
 
-    add_bin_test(ncdump tst_fillbug)
+    build_bin_test_no_prefix(tst_fillbug)
     add_sh_test(ncdump_sh tst_fillbug)
 
-    IF(NOT MSVC)
-      add_sh_test(ncdump tst_netcdf4_4)
-    ENDIF()
+    add_sh_test(ncdump tst_netcdf4_4)
+    IF(MSVC)
+      SET_TESTS_PROPERTIES(ncdump_tst_netcdf4_4 PROPERTIES WILL_FAIL TRUE)
+    ENDIF(MSVC)
 
     ###
     # Some test reordering was required to ensure these tests
@@ -205,28 +200,25 @@ ENDIF()
     add_sh_test(ncdump run_ncgen_tests)
     IF(USE_NETCDF4)
       add_sh_test(ncdump run_ncgen_nc4_tests)
-    ENDIF()
-
-    IF(NOT MSVC)
-      add_sh_test(ncdump tst_nccopy4)
-    ENDIF()
+    ENDIF(USE_NETCDF4)
 
     add_sh_test(ncdump tst_grp_spec)
     add_sh_test(ncdump tst_mud)
     add_sh_test(ncdump_shell tst_h_scalar)
 
-  ENDIF()
+    add_sh_test(ncdump tst_nccopy4)
+    SET_TESTS_PROPERTIES(ncdump_tst_nccopy4 PROPERTIES RUN_SERIAL TRUE)
 
-  add_sh_test(ncdump tst_ncgen4_classic)
-  IF(USE_NETCDF4)
-    add_sh_test(ncdump tst_ncgen4)
-  ENDIF()
+    IF(USE_NETCDF4)
+      add_sh_test(ncdump tst_ncgen4)
+    ENDIF(USE_NETCDF4)
 
   add_sh_test(ncdump tst_inttags)
   IF(USE_NETCDF4)
     add_sh_test(ncdump tst_inttags4)
-  ENDIF()
+  ENDIF(USE_NETCDF4)
 
+ENDIF()
 
 ENDIF()
 
@@ -245,8 +237,10 @@ INSTALL(TARGETS ncdump RUNTIME DESTINATION bin COMPONENT utilities)
 INSTALL(TARGETS nccopy RUNTIME DESTINATION bin COMPONENT utilities)
 SET(MAN_FILES nccopy.1 ncdump.1)
 
+# Note, te L512.bin file is file containing exactly 512 bytes each of value 0.
+# It is used for creating hdf5 files with varying offsets for testing.
 
-FILE(GLOB COPY_FILES ${CMAKE_BINARY_DIR}/ncgen/*.nc ${CMAKE_BINARY_DIR}/nc_test4/*.nc ${CMAKE_CURRENT_SOURCE_DIR}/*.ncml ${CMAKE_CURRENT_SOURCE_DIR}/*.nc ${CMAKE_CURRENT_SOURCE_DIR}/*.cdl ${CMAKE_CURRENT_SOURCE_DIR}/*.sh ${CMAKE_CURRENT_SOURCE_DIR}/*.1)
+FILE(GLOB COPY_FILES ${CMAKE_BINARY_DIR}/ncgen/*.nc ${CMAKE_BINARY_DIR}/nc_test4/*.nc ${CMAKE_CURRENT_SOURCE_DIR}/*.ncml ${CMAKE_CURRENT_SOURCE_DIR}/*.nc ${CMAKE_CURRENT_SOURCE_DIR}/*.cdl ${CMAKE_CURRENT_SOURCE_DIR}/*.sh ${CMAKE_CURRENT_SOURCE_DIR}/*.1 ${CMAKE_CURRENT_SOURCE_DIR}/L512.bin)
 FILE(COPY ${COPY_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/ FILE_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE)
 
 ADD_SUBDIRECTORY(cdl)
diff --git a/ncdump/L512.bin b/ncdump/L512.bin
new file mode 100644
index 0000000..e797e19
--- /dev/null
+++ b/ncdump/L512.bin
@@ -0,0 +1 @@
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             [...]
\ No newline at end of file
diff --git a/ncdump/Makefile.am b/ncdump/Makefile.am
index 33671bc..c827568 100644
--- a/ncdump/Makefile.am
+++ b/ncdump/Makefile.am
@@ -2,26 +2,29 @@
 # Copyright 2005, see the COPYRIGHT file for more information.
 # This file builds and runs the ncdump program.
 
-# $Id: Makefile.am,v 1.147 2010/05/29 00:50:39 dmh Exp $
+# Ed Hartnett, Dennis Heimbigner, Ward Fisher
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 include $(top_srcdir)/lib_flags.am
 LDADD = ${top_builddir}/liblib/libnetcdf.la
 
-TESTS_ENVIRONMENT=CC=${CC}
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
+XFAIL_TESTS=""
 
 # This is the program we're building, and it's sources.
 bin_PROGRAMS = ncdump
-ncdump_SOURCES = ncdump.c vardata.c dumplib.c indent.c nctime0.c	\
-ncdump.h vardata.h dumplib.h indent.h isnan.h nctime0.h cdl.h \
-utils.h utils.c nciter.h nciter.c nccomps.h
+ncdump_SOURCES = ncdump.c vardata.c dumplib.c indent.c nctime0.c        \
+ncdump.h vardata.h dumplib.h indent.h isnan.h nctime0.h cdl.h utils.h   \
+utils.c nciter.h nciter.c nccomps.h
 
 # Another utility program that copies any netCDF file using only the
 # netCDF API
 bin_PROGRAMS += nccopy
-nccopy_SOURCES = nccopy.c nciter.c nciter.h chunkspec.h chunkspec.c \
+nccopy_SOURCES = nccopy.c nciter.c nciter.h chunkspec.h chunkspec.c     \
 utils.h utils.c dimmap.h dimmap.c
 
+# A simple netcdf-4 metadata -> xml printer. Do not install.
 if USE_NETCDF4
 noinst_PROGRAMS = nc4print
 nc4print_SOURCES = nc4print.c
@@ -30,31 +33,60 @@ endif
 # Conditionally build the ocprint program, but do not install
 if ENABLE_DAP
 bin_PROGRAMS += ocprint
-ocprint_SOURCES=ocprint.c
+ocprint_SOURCES = ocprint.c
 endif
 
 # This is the man page.
 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 tst_dimsizes nctrunc
-
-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_nccopy3_subset.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
-tst_dimsizes.sh run_ncgen_tests.sh
-
-if USE_NETCDF4
-check_PROGRAMS += tst_fileinfo
-TESTS += tst_fileinfo.sh run_ncgen_nc4_tests.sh
+# C programs needed by shell scritps for classic tests.
+check_PROGRAMS = rewrite-scalar ref_ctest ref_ctest64 ncdump tst_utf8   \
+bom tst_dimsizes nctrunc
+
+# Tests for classic and 64-bit offset files.
+TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ref_ctest	\
+ref_ctest64 tst_output.sh tst_lengths.sh tst_calendars.sh	\
+run_utf8_tests.sh tst_nccopy3.sh tst_nccopy3_subset.sh		\
+tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh		\
+tst_dimsizes.sh run_ncgen_tests.sh tst_ncgen4_classic.sh
+
+# The tst_nccopy3.sh test uses output from a bunch of other
+# tests. This records the dependency so parallel builds work.
+tst_nccopy3.log: tst_calendars.log run_utf8_tests.log tst_output.log	\
+tst_64bit.log run_tests.log tst_lengths.log
+
+TESTS += tst_null_byte_padding.sh
+if USE_STRICT_NULL_BYTE_HEADER_PADDING
+XFAIL_TESTS += tst_null_byte_padding.sh
 endif
 
 if LARGE_FILE_TESTS
 TESTS += tst_iter.sh
 endif
 
+if USE_NETCDF4
+# NetCDF-4 has some extra C programs to build. These will be run by
+# the shell script tests.
+check_PROGRAMS += tst_fileinfo tst_create_files tst_h_rdc0	\
+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_unicode tst_fillbug tst_compress tst_chunking tst_h_scalar
+
+# Tests for netCDF-4 behavior.
+TESTS += tst_fileinfo.sh tst_hdf5_offset.sh tst_inttags4.sh		\
+tst_netcdf4.sh tst_fillbug.sh tst_netcdf4_4.sh tst_nccopy4.sh		\
+tst_grp_spec.sh tst_mud.sh tst_h_scalar.sh tst_formatx4.sh		\
+run_utf8_nc4_tests.sh run_back_comp_tests.sh run_ncgen_nc4_tests.sh	\
+tst_ncgen4.sh
+
+# The tst_nccopy4.sh test script depends on the output of a bunch of
+# other tests. Record dependencies so parallel builds work.
+tst_nccopy4.log: run_ncgen_tests.log tst_output.log tst_ncgen4.log	\
+tst_fillbug.log tst_netcdf4_4.log tst_h_scalar.log
+endif #!USE_NETCDF4
+
+# Add diskless checks if needed.
 if BUILD_DISKLESS
 TESTS += tst_inmemory_nc3.sh
 if USE_NETCDF4
@@ -62,90 +94,10 @@ TESTS += tst_inmemory_nc4.sh
 endif
 endif
 
-if USE_NETCDF4
-TESTS += tst_inttags4.sh
-endif
-
-if USE_NETCDF4
-# NetCDF-4 has some extra tests.
-check_PROGRAMS += tst_create_files tst_h_rdc0 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_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	\
-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             \
-tst_grp_spec.sh tst_mud.sh tst_h_scalar tst_h_scalar.sh tst_formatx4.sh \
-tst_bug324 run_utf8_nc4_tests.sh
-
-if EXTRA_TESTS
-TESTS += run_back_comp_tests.sh
-endif # EXTRA_TESTS
-
-tst_h_rdc0_CPPFLAGS = -I${top_srcdir}/nc_test ${AM_CPPFLAGS}
-
-endif #!USE_NETCDF4
-#endif #!BUILD_DLL
-
-# Can't run ncgen to generate ctest.c and ctest64.c on cross-compiles.
-BUILT_SOURCES = ctest.c ctest64.c
-if EXTRA_TESTS
-ctest.c:
-	$(top_builddir)/ncgen/ncgen -lc -o ctest0.nc $(top_srcdir)/ncgen/c0.cdl > $(top_builddir)/ncdump/ctest.c
-
-ctest64.c:
-	$(top_builddir)/ncgen/ncgen -k2 -lc -o ctest0_64.nc $(top_srcdir)/ncgen/c0.cdl > $(srcdir)/ctest64.c
-else
-ctest.c:
-	cp $(top_srcdir)/ncdump/ref_ctest.c $(top_builddir)/ncdump/ctest.c
-
-ctest64.c:
-	cp $(top_srcdir)/ncdump/ref_ctest64.c $(top_builddir)/ncdump/ctest64.c
-endif
-
-#if !BUILD_DLL
-TESTS += tst_ncgen4_classic.sh
-if USE_NETCDF4
-TESTS += tst_ncgen4.sh
-endif
-#endif
-
 endif BUILD_TESTSETS
 
-CLEANFILES = test0.nc test1_ncdump.cdl test1_ncdump.nc test2_ncdump.cdl \
-test1.cdl test0_ncdump.nc ctest1.cdl \
-test1_cdf5.nc test1_cdf5.cdl test0_cdf5.nc test2_cdf5.nc test2_cdf5.cdl \
-test0_offset.nc test1_offset.nc test1_offset.cdl test2_offset.nc test2_offset.cdl \
-ctest0.nc ctest0_64.nc c1.cdl c1_4.cdl ctest1_64.cdl c0.nc c0_4.nc small.nc	\
-small2.nc c0tmp.nc c1.ncml utf8.cdl utf8_64.cdl utf8.nc utf8_64.nc	\
-tmp.cdl tst_vlen_data.nc tst_utf8.nc tst_special_atts.nc		\
-tst_unicode.nc tst_solar_2.nc tst_string_data.nc tst_calendars.nc	\
-tst_nans.nc tst_opaque_data.nc tst_solar_cmp.nc tst_enum_data.nc	\
-tst_solar_1.nc tst_mslp_64.nc tst_mslp.nc tst_bug321.nc tst_comp2.nc tst_ncml.nc	\
-tst_fillbug.nc tst_group_data.nc tst_small.nc tst_comp.nc		\
-tst_unicode.cdl tst_group_data.cdl tst_compounds2.cdl tst_comp.cdl	\
-tst_enum_data.cdl tst_small.cdl tst_times.cdl tst_solar_2.cdl		\
-tst_string_data.cdl tst_fillbug.cdl tst_opaque_data.cdl			\
-tst_compounds4.cdl tst_utf8.cdl tst_compounds3.cdl			\
-tst_special_atts.cdl tst_nans.cdl tst_format_att_64.cdl			\
-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                                    \
-inttags.nc inttags4.nc tst_inttags.cdl tst_inttags4.cdl                 \
-tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc    \
-nc4_fileinfo.nc hdf5_fileinfo.hdf \
-ref_hdf5_compat1.nc ref_hdf5_compat2.nc ref_hdf5_compat3.nc \
-ref_tst_compounds.nc ref_tst_dims.nc ref_tst_interops4.nc \
-ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc nccopy3_subset_out.nc
-
 # These files all have to be included with the distribution.
-EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
+EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl		\
 ref_ctest1_nc4.cdl ref_ctest1_nc4c.cdl ref_tst_solar_1.cdl		\
 ref_tst_solar_2.cdl tst_netcdf4.sh tst_netcdf4_4.sh ref_tst_small.cdl	\
 tst_lengths.sh tst_ncml.cdl ref1.ncml ref_tst_group_data.cdl		\
@@ -156,39 +108,55 @@ ref_tst_utf8.cdl ref_tst_fillbug.cdl tst_fillbug.sh tst_calendars.cdl	\
 tst_calendars.sh ref_times.cdl ref_tst_special_atts.cdl			\
 ref_tst_noncoord.cdl ref_tst_compounds2.nc ref_tst_compounds2.cdl	\
 ref_tst_compounds3.nc ref_tst_compounds3.cdl ref_tst_compounds4.nc	\
-ref_tst_compounds4.cdl ref_tst_group_data_v23.cdl tst_mslp.cdl tst_bug321.cdl \
-ref_tst_format_att.cdl ref_tst_format_att_64.cdl tst_nccopy3.sh		\
-tst_nccopy4.sh ref_nc_test_netcdf4_4_0.nc run_back_comp_tests.sh	\
-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                                                  \
-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                      \
-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_fileinfo.sh run_ncgen_tests.sh  \
-test_360_day_1900.nc test_365_day_1900.nc test_366_day_1900.nc          \
-ref_test_360_day_1900.cdl ref_test_365_day_1900.cdl ref_test_366_day_1900.cdl \
-run_ncgen_nc4_tests.sh tst_nccopy3_subset.sh ref_nccopy3_subset.nc
+ref_tst_compounds4.cdl ref_tst_group_data_v23.cdl tst_mslp.cdl		\
+tst_bug321.cdl ref_tst_format_att.cdl ref_tst_format_att_64.cdl		\
+tst_nccopy3.sh tst_nccopy4.sh ref_nc_test_netcdf4_4_0.nc		\
+run_back_comp_tests.sh 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		\
+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			\
+ref_tst_nc4_utf8_4.cdl tst_inttags.sh tst_inttags4.sh CMakeLists.txt	\
+XGetopt.c tst_bom.sh tst_inmemory_nc3.sh tst_dimsizes.sh		\
+tst_inmemory_nc4.sh tst_fileinfo.sh run_ncgen_tests.sh			\
+ref_test_360_day_1900.nc ref_test_365_day_1900.nc			\
+ref_test_366_day_1900.nc ref_test_360_day_1900.cdl			\
+ref_test_365_day_1900.cdl ref_test_366_day_1900.cdl			\
+tst_hdf5_offset.sh run_ncgen_nc4_tests.sh tst_nccopy3_subset.sh		\
+ref_nccopy3_subset.nc ref_test_corrupt_magic.nc tst_ncgen_shared.sh	\
+tst_ncgen4.sh tst_ncgen4_classic.sh tst_ncgen4_diff.sh			\
+tst_ncgen4_cycle.sh tst_null_byte_padding.sh				\
+ref_null_byte_padding_test.nc
+
+# The L512.bin file is file containing exactly 512 bytes each of value 0.
+# It is used for creating hdf5 files with varying offsets for testing.
+EXTRA_DIST += L512.bin
 
 # CDL files and Expected results
-SUBDIRS=cdl expected
-EXTRA_DIST += 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
-
-CLEANFILES += results/*.nc results/*.dmp results/*.dmp2 tmp*.cdl \
-	c5.nc compound_datasize_test.nc compound_datasize_test2.nc \
-	ncf199.nc ref_camrun.c tst_c0.cdl tst_c0_4.cdl tst_c0_4c.cdl \
-	tst_c0_64.cdl tst_compound_datasize_test.cdl \
-	tst_compound_datasize_test2.cdl tst_gattenum.nc \
-	tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl \
-	tst_usuffix.nc tst_bug324.nc nccopy3_subset_out.nc
-
-DISTCLEANFILES = results
-
-clean-local:
-	-rm -rf results
+SUBDIRS = cdl expected
+
+CLEANFILES = tst_*.nc tmp*.nc test*.nc iter.* tmp*.cdl			\
+tst_output_*.cdl tst_output_*.c tst_utf8_*.cdl tst_tst8.cdl		\
+tst_netcdf4_*.cdl test1_ncdump.cdl test2_ncdump.cdl test1.cdl		\
+ctest1.cdl test1_cdf5.cdl test2_cdf5.cdl test1_offset.cdl		\
+test2_offset.cdl ctest0.nc ctest0_64.nc c1.cdl c1_4.cdl ctest1_64.cdl	\
+c0.nc c0_4.nc small.nc small2.nc c0tmp.nc c1.ncml utf8.cdl		\
+utf8_64.cdl utf8.nc utf8_64.nc nc4_utf8.cdl nc4_utf8.nc			\
+tst_unicode.cdl tst_group_data.cdl tst_compounds2.cdl tst_comp.cdl	\
+tst_enum_data.cdl tst_small.cdl tst_times.cdl tst_solar_2.cdl		\
+tst_string_data.cdl tst_fillbug.cdl tst_opaque_data.cdl			\
+tst_compounds4.cdl tst_utf8.cdl tst_compounds3.cdl			\
+tst_special_atts.cdl tst_nans.cdl tst_format_att_64.cdl			\
+tst_vlen_data.cdl tst_solar_1.cdl tst_format_att.cdl			\
+tst_nc_test_netcdf4_4_0.cdl tst_mud4.cdl tst_mud4-bc.cdl		\
+tst_ncf213.cdl tst_h_scalar.cdl tst_mud4_chars.cdl inttags.nc		\
+inttags4.nc tst_inttags.cdl tst_inttags4.cdl nc4_fileinfo.nc		\
+hdf5_fileinfo.hdf nccopy3_subset_out.nc c5.nc				\
+compound_datasize_test.nc compound_datasize_test2.nc ncf199.nc		\
+tst_c0.cdl tst_c0_4.cdl tst_c0_4c.cdl tst_c0_64.cdl			\
+tst_compound_datasize_test.cdl tst_compound_datasize_test2.cdl		\
+tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl ctest.c		\
+ctest64.c nccopy3_subset_out.nc camrun.c
diff --git a/ncdump/Makefile.in b/ncdump/Makefile.in
index 13abe63..2e50b8a 100644
--- a/ncdump/Makefile.in
+++ b/ncdump/Makefile.in
@@ -17,7 +17,7 @@
 # Copyright 2005, see the COPYRIGHT file for more information.
 # This file builds and runs the ncdump program.
 
-# $Id: Makefile.am,v 1.147 2010/05/29 00:50:39 dmh Exp $
+# Ed Hartnett, Dennis Heimbigner, Ward Fisher
 
 # This is part of the netCDF package.
 # Copyright 2005 University Corporation for Atmospheric Research/Unidata
@@ -103,75 +103,50 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
 bin_PROGRAMS = ncdump$(EXEEXT) nccopy$(EXEEXT) $(am__EXEEXT_1)
 @USE_NETCDF4_TRUE at noinst_PROGRAMS = nc4print$(EXEEXT)
 
 # Conditionally build the ocprint program, but do not install
- at ENABLE_DAP_TRUE@am__append_3 = ocprint
+ at ENABLE_DAP_TRUE@am__append_2 = ocprint
 @BUILD_TESTSETS_TRUE at check_PROGRAMS = rewrite-scalar$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@	ctest$(EXEEXT) ctest64$(EXEEXT) \
+ at BUILD_TESTSETS_TRUE@	ref_ctest$(EXEEXT) ref_ctest64$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@	ncdump$(EXEEXT) tst_utf8$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@	bom$(EXEEXT) tst_dimsizes$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@	nctrunc$(EXEEXT) $(am__EXEEXT_2)
 @BUILD_TESTSETS_TRUE at TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh \
- at BUILD_TESTSETS_TRUE@	ctest$(EXEEXT) ctest64$(EXEEXT) \
+ at BUILD_TESTSETS_TRUE@	ref_ctest$(EXEEXT) ref_ctest64$(EXEEXT) \
 @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_nccopy3_subset.sh tst_charfill.sh \
- at BUILD_TESTSETS_TRUE@	tst_iter.sh tst_formatx3.sh tst_bom.sh \
+ at BUILD_TESTSETS_TRUE@	tst_calendars.sh run_utf8_tests.sh \
+ at BUILD_TESTSETS_TRUE@	tst_nccopy3.sh tst_nccopy3_subset.sh \
+ at BUILD_TESTSETS_TRUE@	tst_charfill.sh tst_iter.sh \
+ at BUILD_TESTSETS_TRUE@	tst_formatx3.sh tst_bom.sh \
 @BUILD_TESTSETS_TRUE@	tst_dimsizes.sh run_ncgen_tests.sh \
- at BUILD_TESTSETS_TRUE@	$(am__append_5) $(am__append_6) \
- at BUILD_TESTSETS_TRUE@	$(am__append_7) $(am__append_8) \
- at BUILD_TESTSETS_TRUE@	$(am__EXEEXT_3) $(am__append_10) \
- at BUILD_TESTSETS_TRUE@	tst_ncgen4_classic.sh $(am__append_11)
-
-# NetCDF-4 has some extra tests.
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_4 = tst_fileinfo \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_create_files \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_rdc0 \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_group_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_enum_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_opaque_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_string_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_vlen_data tst_comp \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_comp2 tst_nans \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_special_atts \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_unicode tst_fillbug \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_compress \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_chunking \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_scalar tst_bug324
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_5 = tst_fileinfo.sh run_ncgen_nc4_tests.sh
- at BUILD_TESTSETS_TRUE@@LARGE_FILE_TESTS_TRUE at am__append_6 = tst_iter.sh
+ at BUILD_TESTSETS_TRUE@	tst_ncgen4_classic.sh \
+ at BUILD_TESTSETS_TRUE@	tst_null_byte_padding.sh $(am__append_4) \
+ at BUILD_TESTSETS_TRUE@	$(am__append_6) $(am__append_7) \
+ at BUILD_TESTSETS_TRUE@	$(am__append_8)
+ at BUILD_TESTSETS_TRUE@@USE_STRICT_NULL_BYTE_HEADER_PADDING_TRUE at am__append_3 = tst_null_byte_padding.sh
+ at BUILD_TESTSETS_TRUE@@LARGE_FILE_TESTS_TRUE at am__append_4 = tst_iter.sh
+
+# NetCDF-4 has some extra C programs to build. These will be run by
+# the shell script tests.
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_5 = tst_fileinfo tst_create_files tst_h_rdc0	\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_group_data tst_enum_data tst_opaque_data tst_string_data	\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_vlen_data tst_comp tst_comp2 tst_nans tst_special_atts	\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_unicode tst_fillbug tst_compress tst_chunking tst_h_scalar
+
+
+# Tests for netCDF-4 behavior.
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_6 = tst_fileinfo.sh tst_hdf5_offset.sh tst_inttags4.sh		\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_netcdf4.sh tst_fillbug.sh tst_netcdf4_4.sh tst_nccopy4.sh		\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_grp_spec.sh tst_mud.sh tst_h_scalar.sh tst_formatx4.sh		\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at run_utf8_nc4_tests.sh run_back_comp_tests.sh run_ncgen_nc4_tests.sh	\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_ncgen4.sh
+
+
+# Add diskless checks if needed.
 @BUILD_DISKLESS_TRUE@@BUILD_TESTSETS_TRUE at am__append_7 = tst_inmemory_nc3.sh
 @BUILD_DISKLESS_TRUE@@BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_8 = tst_inmemory_nc4.sh
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_9 = tst_inttags4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_create_files \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_group_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_enum_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_opaque_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_string_data \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_vlen_data tst_comp \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_comp2 tst_nans \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_special_atts \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_netcdf4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_rdc0 tst_unicode \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_fillbug \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_fillbug.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_netcdf4_4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_compress \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_nccopy4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_grp_spec.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_mud.sh tst_h_scalar \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_scalar.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_formatx4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_bug324 \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	run_utf8_nc4_tests.sh
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_TRUE@@USE_NETCDF4_TRUE at am__append_10 = run_back_comp_tests.sh
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at am__append_11 = tst_ncgen4.sh
 subdir = ncdump
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -204,8 +179,7 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_fillbug$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_compress$(EXEEXT) \
 @BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_chunking$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_scalar$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_bug324$(EXEEXT)
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_scalar$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
 bom_SOURCES = bom.c
 bom_OBJECTS = bom.$(OBJEXT)
@@ -215,14 +189,6 @@ AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-ctest_SOURCES = ctest.c
-ctest_OBJECTS = ctest.$(OBJEXT)
-ctest_LDADD = $(LDADD)
-ctest_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
-ctest64_SOURCES = ctest64.c
-ctest64_OBJECTS = ctest64.$(OBJEXT)
-ctest64_LDADD = $(LDADD)
-ctest64_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 am__nc4print_SOURCES_DIST = nc4print.c
 @USE_NETCDF4_TRUE at am_nc4print_OBJECTS = nc4print.$(OBJEXT)
 nc4print_OBJECTS = $(am_nc4print_OBJECTS)
@@ -248,14 +214,18 @@ am__ocprint_SOURCES_DIST = ocprint.c
 ocprint_OBJECTS = $(am_ocprint_OBJECTS)
 ocprint_LDADD = $(LDADD)
 ocprint_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
+ref_ctest_SOURCES = ref_ctest.c
+ref_ctest_OBJECTS = ref_ctest.$(OBJEXT)
+ref_ctest_LDADD = $(LDADD)
+ref_ctest_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
+ref_ctest64_SOURCES = ref_ctest64.c
+ref_ctest64_OBJECTS = ref_ctest64.$(OBJEXT)
+ref_ctest64_LDADD = $(LDADD)
+ref_ctest64_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 rewrite_scalar_SOURCES = rewrite-scalar.c
 rewrite_scalar_OBJECTS = rewrite-scalar.$(OBJEXT)
 rewrite_scalar_LDADD = $(LDADD)
 rewrite_scalar_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
-tst_bug324_SOURCES = tst_bug324.c
-tst_bug324_OBJECTS = tst_bug324.$(OBJEXT)
-tst_bug324_LDADD = $(LDADD)
-tst_bug324_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_chunking_SOURCES = tst_chunking.c
 tst_chunking_OBJECTS = tst_chunking.$(OBJEXT)
 tst_chunking_LDADD = $(LDADD)
@@ -297,7 +267,7 @@ tst_group_data_OBJECTS = tst_group_data.$(OBJEXT)
 tst_group_data_LDADD = $(LDADD)
 tst_group_data_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_h_rdc0_SOURCES = tst_h_rdc0.c
-tst_h_rdc0_OBJECTS = tst_h_rdc0-tst_h_rdc0.$(OBJEXT)
+tst_h_rdc0_OBJECTS = tst_h_rdc0.$(OBJEXT)
 tst_h_rdc0_LDADD = $(LDADD)
 tst_h_rdc0_DEPENDENCIES = ${top_builddir}/liblib/libnetcdf.la
 tst_h_scalar_SOURCES = tst_h_scalar.c
@@ -366,22 +336,22 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = bom.c ctest.c ctest64.c $(nc4print_SOURCES) \
-	$(nccopy_SOURCES) $(ncdump_SOURCES) nctrunc.c \
-	$(ocprint_SOURCES) rewrite-scalar.c tst_bug324.c \
-	tst_chunking.c tst_comp.c tst_comp2.c tst_compress.c \
-	tst_create_files.c tst_dimsizes.c tst_enum_data.c \
-	tst_fileinfo.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 $(am__nc4print_SOURCES_DIST) \
-	$(nccopy_SOURCES) $(ncdump_SOURCES) nctrunc.c \
-	$(am__ocprint_SOURCES_DIST) rewrite-scalar.c tst_bug324.c \
-	tst_chunking.c tst_comp.c tst_comp2.c tst_compress.c \
-	tst_create_files.c tst_dimsizes.c tst_enum_data.c \
-	tst_fileinfo.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
+SOURCES = bom.c $(nc4print_SOURCES) $(nccopy_SOURCES) \
+	$(ncdump_SOURCES) nctrunc.c $(ocprint_SOURCES) ref_ctest.c \
+	ref_ctest64.c rewrite-scalar.c tst_chunking.c tst_comp.c \
+	tst_comp2.c tst_compress.c tst_create_files.c tst_dimsizes.c \
+	tst_enum_data.c tst_fileinfo.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 $(am__nc4print_SOURCES_DIST) $(nccopy_SOURCES) \
+	$(ncdump_SOURCES) nctrunc.c $(am__ocprint_SOURCES_DIST) \
+	ref_ctest.c ref_ctest64.c rewrite-scalar.c tst_chunking.c \
+	tst_comp.c tst_comp2.c tst_compress.c tst_create_files.c \
+	tst_dimsizes.c tst_enum_data.c tst_fileinfo.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 \
@@ -608,34 +578,7 @@ 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_3 = tst_inttags4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_create_files$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_group_data$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_enum_data$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_opaque_data$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_string_data$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_vlen_data$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_comp$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_comp2$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_nans$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_special_atts$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_netcdf4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_rdc0$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_unicode$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_fillbug$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_fillbug.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_netcdf4_4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_compress$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_nccopy4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_grp_spec.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_mud.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_scalar$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_h_scalar.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_formatx4.sh \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	tst_bug324$(EXEEXT) \
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE@	run_utf8_nc4_tests.sh
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
 am__set_b = \
@@ -650,10 +593,9 @@ am__set_b = \
   esac
 am__test_logs1 = $(TESTS:=.log)
 am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
 	$(top_srcdir)/lib_flags.am $(top_srcdir)/test-driver
@@ -687,11 +629,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -714,12 +655,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -745,6 +688,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -759,6 +703,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -862,16 +807,19 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 LDADD = ${top_builddir}/liblib/libnetcdf.la
-TESTS_ENVIRONMENT = CC=${CC}
-ncdump_SOURCES = ncdump.c vardata.c dumplib.c indent.c nctime0.c	\
-ncdump.h vardata.h dumplib.h indent.h isnan.h nctime0.h cdl.h \
-utils.h utils.c nciter.h nciter.c nccomps.h
 
-nccopy_SOURCES = nccopy.c nciter.c nciter.h chunkspec.h chunkspec.c \
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
+XFAIL_TESTS = "" $(am__append_3)
+ncdump_SOURCES = ncdump.c vardata.c dumplib.c indent.c nctime0.c        \
+ncdump.h vardata.h dumplib.h indent.h isnan.h nctime0.h cdl.h utils.h   \
+utils.c nciter.h nciter.c nccomps.h
+
+nccopy_SOURCES = nccopy.c nciter.c nciter.h chunkspec.h chunkspec.c     \
 utils.h utils.c dimmap.h dimmap.c
 
 @USE_NETCDF4_TRUE at nc4print_SOURCES = nc4print.c
@@ -879,54 +827,11 @@ utils.h utils.c dimmap.h dimmap.c
 
 # This is the man page.
 man_MANS = ncdump.1 nccopy.1
- at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_h_rdc0_CPPFLAGS = -I${top_srcdir}/nc_test ${AM_CPPFLAGS}
-
-#endif #!BUILD_DLL
-
-# Can't run ncgen to generate ctest.c and ctest64.c on cross-compiles.
- at BUILD_TESTSETS_TRUE@BUILT_SOURCES = ctest.c ctest64.c
-#endif
-CLEANFILES = test0.nc test1_ncdump.cdl test1_ncdump.nc \
-	test2_ncdump.cdl test1.cdl test0_ncdump.nc ctest1.cdl \
-	test1_cdf5.nc test1_cdf5.cdl test0_cdf5.nc test2_cdf5.nc \
-	test2_cdf5.cdl test0_offset.nc test1_offset.nc \
-	test1_offset.cdl test2_offset.nc test2_offset.cdl ctest0.nc \
-	ctest0_64.nc c1.cdl c1_4.cdl ctest1_64.cdl c0.nc c0_4.nc \
-	small.nc small2.nc c0tmp.nc c1.ncml utf8.cdl utf8_64.cdl \
-	utf8.nc utf8_64.nc tmp.cdl tst_vlen_data.nc tst_utf8.nc \
-	tst_special_atts.nc tst_unicode.nc tst_solar_2.nc \
-	tst_string_data.nc tst_calendars.nc tst_nans.nc \
-	tst_opaque_data.nc tst_solar_cmp.nc tst_enum_data.nc \
-	tst_solar_1.nc tst_mslp_64.nc tst_mslp.nc tst_bug321.nc \
-	tst_comp2.nc tst_ncml.nc tst_fillbug.nc tst_group_data.nc \
-	tst_small.nc tst_comp.nc tst_unicode.cdl tst_group_data.cdl \
-	tst_compounds2.cdl tst_comp.cdl tst_enum_data.cdl \
-	tst_small.cdl tst_times.cdl tst_solar_2.cdl \
-	tst_string_data.cdl tst_fillbug.cdl tst_opaque_data.cdl \
-	tst_compounds4.cdl tst_utf8.cdl tst_compounds3.cdl \
-	tst_special_atts.cdl tst_nans.cdl tst_format_att_64.cdl \
-	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 inttags.nc inttags4.nc \
-	tst_inttags.cdl tst_inttags4.cdl tst_dimsize_classic.nc \
-	tst_dimsize_64offset.nc tst_dimsize_64data.nc nc4_fileinfo.nc \
-	hdf5_fileinfo.hdf ref_hdf5_compat1.nc ref_hdf5_compat2.nc \
-	ref_hdf5_compat3.nc ref_tst_compounds.nc ref_tst_dims.nc \
-	ref_tst_interops4.nc ref_tst_xplatform2_1.nc \
-	ref_tst_xplatform2_2.nc nccopy3_subset_out.nc results/*.nc \
-	results/*.dmp results/*.dmp2 tmp*.cdl c5.nc \
-	compound_datasize_test.nc compound_datasize_test2.nc ncf199.nc \
-	ref_camrun.c tst_c0.cdl tst_c0_4.cdl tst_c0_4c.cdl \
-	tst_c0_64.cdl tst_compound_datasize_test.cdl \
-	tst_compound_datasize_test2.cdl tst_gattenum.nc tst_ncf199.cdl \
-	tst_tst_gattenum.cdl tst_tst_usuffix.cdl tst_usuffix.nc \
-	tst_bug324.nc nccopy3_subset_out.nc
 
 # These files all have to be included with the distribution.
+
+# The L512.bin file is file containing exactly 512 bytes each of value 0.
+# It is used for creating hdf5 files with varying offsets for testing.
 EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
 	ref_ctest1_nc4.cdl ref_ctest1_nc4c.cdl ref_tst_solar_1.cdl \
 	ref_tst_solar_2.cdl tst_netcdf4.sh tst_netcdf4_4.sh \
@@ -952,25 +857,49 @@ EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.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 \
-	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_fileinfo.sh run_ncgen_tests.sh \
-	test_360_day_1900.nc test_365_day_1900.nc test_366_day_1900.nc \
+	ref_tst_nc4_utf8_4.cdl tst_inttags.sh tst_inttags4.sh \
+	CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh \
+	tst_dimsizes.sh tst_inmemory_nc4.sh tst_fileinfo.sh \
+	run_ncgen_tests.sh ref_test_360_day_1900.nc \
+	ref_test_365_day_1900.nc ref_test_366_day_1900.nc \
 	ref_test_360_day_1900.cdl ref_test_365_day_1900.cdl \
-	ref_test_366_day_1900.cdl run_ncgen_nc4_tests.sh \
-	tst_nccopy3_subset.sh ref_nccopy3_subset.nc \
+	ref_test_366_day_1900.cdl tst_hdf5_offset.sh \
+	run_ncgen_nc4_tests.sh tst_nccopy3_subset.sh \
+	ref_nccopy3_subset.nc ref_test_corrupt_magic.nc \
 	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
+	tst_ncgen4_diff.sh tst_ncgen4_cycle.sh \
+	tst_null_byte_padding.sh ref_null_byte_padding_test.nc \
+	L512.bin
 
 # CDL files and Expected results
 SUBDIRS = cdl expected
-DISTCLEANFILES = results
-all: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+CLEANFILES = tst_*.nc tmp*.nc test*.nc iter.* tmp*.cdl			\
+tst_output_*.cdl tst_output_*.c tst_utf8_*.cdl tst_tst8.cdl		\
+tst_netcdf4_*.cdl test1_ncdump.cdl test2_ncdump.cdl test1.cdl		\
+ctest1.cdl test1_cdf5.cdl test2_cdf5.cdl test1_offset.cdl		\
+test2_offset.cdl ctest0.nc ctest0_64.nc c1.cdl c1_4.cdl ctest1_64.cdl	\
+c0.nc c0_4.nc small.nc small2.nc c0tmp.nc c1.ncml utf8.cdl		\
+utf8_64.cdl utf8.nc utf8_64.nc nc4_utf8.cdl nc4_utf8.nc			\
+tst_unicode.cdl tst_group_data.cdl tst_compounds2.cdl tst_comp.cdl	\
+tst_enum_data.cdl tst_small.cdl tst_times.cdl tst_solar_2.cdl		\
+tst_string_data.cdl tst_fillbug.cdl tst_opaque_data.cdl			\
+tst_compounds4.cdl tst_utf8.cdl tst_compounds3.cdl			\
+tst_special_atts.cdl tst_nans.cdl tst_format_att_64.cdl			\
+tst_vlen_data.cdl tst_solar_1.cdl tst_format_att.cdl			\
+tst_nc_test_netcdf4_4_0.cdl tst_mud4.cdl tst_mud4-bc.cdl		\
+tst_ncf213.cdl tst_h_scalar.cdl tst_mud4_chars.cdl inttags.nc		\
+inttags4.nc tst_inttags.cdl tst_inttags4.cdl nc4_fileinfo.nc		\
+hdf5_fileinfo.hdf nccopy3_subset_out.nc c5.nc				\
+compound_datasize_test.nc compound_datasize_test2.nc ncf199.nc		\
+tst_c0.cdl tst_c0_4.cdl tst_c0_4c.cdl tst_c0_64.cdl			\
+tst_compound_datasize_test.cdl tst_compound_datasize_test2.cdl		\
+tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl ctest.c		\
+ctest64.c nccopy3_subset_out.nc camrun.c
+
+all: all-recursive
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+.SUFFIXES: .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -1073,14 +1002,6 @@ bom$(EXEEXT): $(bom_OBJECTS) $(bom_DEPENDENCIES) $(EXTRA_bom_DEPENDENCIES)
 	@rm -f bom$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(bom_OBJECTS) $(bom_LDADD) $(LIBS)
 
-ctest$(EXEEXT): $(ctest_OBJECTS) $(ctest_DEPENDENCIES) $(EXTRA_ctest_DEPENDENCIES) 
-	@rm -f ctest$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(ctest_OBJECTS) $(ctest_LDADD) $(LIBS)
-
-ctest64$(EXEEXT): $(ctest64_OBJECTS) $(ctest64_DEPENDENCIES) $(EXTRA_ctest64_DEPENDENCIES) 
-	@rm -f ctest64$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(ctest64_OBJECTS) $(ctest64_LDADD) $(LIBS)
-
 nc4print$(EXEEXT): $(nc4print_OBJECTS) $(nc4print_DEPENDENCIES) $(EXTRA_nc4print_DEPENDENCIES) 
 	@rm -f nc4print$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(nc4print_OBJECTS) $(nc4print_LDADD) $(LIBS)
@@ -1101,14 +1022,18 @@ ocprint$(EXEEXT): $(ocprint_OBJECTS) $(ocprint_DEPENDENCIES) $(EXTRA_ocprint_DEP
 	@rm -f ocprint$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(ocprint_OBJECTS) $(ocprint_LDADD) $(LIBS)
 
+ref_ctest$(EXEEXT): $(ref_ctest_OBJECTS) $(ref_ctest_DEPENDENCIES) $(EXTRA_ref_ctest_DEPENDENCIES) 
+	@rm -f ref_ctest$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(ref_ctest_OBJECTS) $(ref_ctest_LDADD) $(LIBS)
+
+ref_ctest64$(EXEEXT): $(ref_ctest64_OBJECTS) $(ref_ctest64_DEPENDENCIES) $(EXTRA_ref_ctest64_DEPENDENCIES) 
+	@rm -f ref_ctest64$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(ref_ctest64_OBJECTS) $(ref_ctest64_LDADD) $(LIBS)
+
 rewrite-scalar$(EXEEXT): $(rewrite_scalar_OBJECTS) $(rewrite_scalar_DEPENDENCIES) $(EXTRA_rewrite_scalar_DEPENDENCIES) 
 	@rm -f rewrite-scalar$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(rewrite_scalar_OBJECTS) $(rewrite_scalar_LDADD) $(LIBS)
 
-tst_bug324$(EXEEXT): $(tst_bug324_OBJECTS) $(tst_bug324_DEPENDENCIES) $(EXTRA_tst_bug324_DEPENDENCIES) 
-	@rm -f tst_bug324$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(tst_bug324_OBJECTS) $(tst_bug324_LDADD) $(LIBS)
-
 tst_chunking$(EXEEXT): $(tst_chunking_OBJECTS) $(tst_chunking_DEPENDENCIES) $(EXTRA_tst_chunking_DEPENDENCIES) 
 	@rm -f tst_chunking$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tst_chunking_OBJECTS) $(tst_chunking_LDADD) $(LIBS)
@@ -1193,8 +1118,6 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bom.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/chunkspec.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ctest.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ctest64.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dimmap.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dumplib.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/indent.Po at am__quote@
@@ -1205,8 +1128,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nctime0.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nctrunc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocprint.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ref_ctest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ref_ctest64.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rewrite-scalar.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_bug324.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_chunking.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_comp.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_comp2.Po at am__quote@
@@ -1217,7 +1141,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_fileinfo.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@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_rdc0.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_h_scalar.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_nans.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tst_opaque_data.Po at am__quote@
@@ -1253,20 +1177,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
-tst_h_rdc0-tst_h_rdc0.o: tst_h_rdc0.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tst_h_rdc0_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tst_h_rdc0-tst_h_rdc0.o -MD -MP -MF $(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Tpo -c -o tst_h_rdc0-tst_h_rdc0.o `test -f 'tst_h_rdc0.c' || echo '$(srcdir)/'`tst_h_rdc0.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Tpo $(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tst_h_rdc0.c' object='tst_h_rdc0-tst_h_rdc0.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tst_h_rdc0_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tst_h_rdc0-tst_h_rdc0.o `test -f 'tst_h_rdc0.c' || echo '$(srcdir)/'`tst_h_rdc0.c
-
-tst_h_rdc0-tst_h_rdc0.obj: tst_h_rdc0.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tst_h_rdc0_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tst_h_rdc0-tst_h_rdc0.obj -MD -MP -MF $(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Tpo -c -o tst_h_rdc0-tst_h_rdc0.obj `if test -f 'tst_h_rdc0.c'; then $(CYGPATH_W) 'tst_h_rdc0.c'; else $(CYGPATH_W) '$(srcdir)/tst_h_rdc0.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Tpo $(DEPDIR)/tst_h_rdc0-tst_h_rdc0.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tst_h_rdc0.c' object='tst_h_rdc0-tst_h_rdc0.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tst_h_rdc0_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tst_h_rdc0-tst_h_rdc0.obj `if test -f 'tst_h_rdc0.c'; then $(CYGPATH_W) 'tst_h_rdc0.c'; else $(CYGPATH_W) '$(srcdir)/tst_h_rdc0.c'; fi`
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -1556,376 +1466,33 @@ 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'; \
-	$(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_64bit.sh.log: tst_64bit.sh
-	@p='tst_64bit.sh'; \
-	b='tst_64bit.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)
-ctest.log: ctest$(EXEEXT)
-	@p='ctest$(EXEEXT)'; \
-	b='ctest'; \
-	$(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)
-ctest64.log: ctest64$(EXEEXT)
-	@p='ctest64$(EXEEXT)'; \
-	b='ctest64'; \
-	$(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_output.sh.log: tst_output.sh
-	@p='tst_output.sh'; \
-	b='tst_output.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_lengths.sh.log: tst_lengths.sh
-	@p='tst_lengths.sh'; \
-	b='tst_lengths.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_calendars.sh.log: tst_calendars.sh
-	@p='tst_calendars.sh'; \
-	b='tst_calendars.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_utf8.log: tst_utf8$(EXEEXT)
-	@p='tst_utf8$(EXEEXT)'; \
-	b='tst_utf8'; \
-	$(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_utf8_tests.sh.log: run_utf8_tests.sh
-	@p='run_utf8_tests.sh'; \
-	b='run_utf8_tests.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_nccopy3.sh.log: tst_nccopy3.sh
-	@p='tst_nccopy3.sh'; \
-	b='tst_nccopy3.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_nccopy3_subset.sh.log: tst_nccopy3_subset.sh
-	@p='tst_nccopy3_subset.sh'; \
-	b='tst_nccopy3_subset.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_charfill.sh.log: tst_charfill.sh
-	@p='tst_charfill.sh'; \
-	b='tst_charfill.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_iter.sh.log: tst_iter.sh
-	@p='tst_iter.sh'; \
-	b='tst_iter.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_formatx3.sh.log: tst_formatx3.sh
-	@p='tst_formatx3.sh'; \
-	b='tst_formatx3.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_bom.sh.log: tst_bom.sh
-	@p='tst_bom.sh'; \
-	b='tst_bom.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_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)
-run_ncgen_tests.sh.log: run_ncgen_tests.sh
-	@p='run_ncgen_tests.sh'; \
-	b='run_ncgen_tests.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_fileinfo.sh.log: tst_fileinfo.sh
-	@p='tst_fileinfo.sh'; \
-	b='tst_fileinfo.sh'; \
+ref_ctest.log: ref_ctest$(EXEEXT)
+	@p='ref_ctest$(EXEEXT)'; \
+	b='ref_ctest'; \
 	$(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_ncgen_nc4_tests.sh.log: run_ncgen_nc4_tests.sh
-	@p='run_ncgen_nc4_tests.sh'; \
-	b='run_ncgen_nc4_tests.sh'; \
+ref_ctest64.log: ref_ctest64$(EXEEXT)
+	@p='ref_ctest64$(EXEEXT)'; \
+	b='ref_ctest64'; \
 	$(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'; \
-	$(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_nc4.sh.log: tst_inmemory_nc4.sh
-	@p='tst_inmemory_nc4.sh'; \
-	b='tst_inmemory_nc4.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_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'; \
-	$(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_group_data.log: tst_group_data$(EXEEXT)
-	@p='tst_group_data$(EXEEXT)'; \
-	b='tst_group_data'; \
-	$(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_enum_data.log: tst_enum_data$(EXEEXT)
-	@p='tst_enum_data$(EXEEXT)'; \
-	b='tst_enum_data'; \
-	$(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_opaque_data.log: tst_opaque_data$(EXEEXT)
-	@p='tst_opaque_data$(EXEEXT)'; \
-	b='tst_opaque_data'; \
-	$(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_string_data.log: tst_string_data$(EXEEXT)
-	@p='tst_string_data$(EXEEXT)'; \
-	b='tst_string_data'; \
-	$(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_vlen_data.log: tst_vlen_data$(EXEEXT)
-	@p='tst_vlen_data$(EXEEXT)'; \
-	b='tst_vlen_data'; \
-	$(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_comp.log: tst_comp$(EXEEXT)
-	@p='tst_comp$(EXEEXT)'; \
-	b='tst_comp'; \
-	$(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_comp2.log: tst_comp2$(EXEEXT)
-	@p='tst_comp2$(EXEEXT)'; \
-	b='tst_comp2'; \
-	$(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_nans.log: tst_nans$(EXEEXT)
-	@p='tst_nans$(EXEEXT)'; \
-	b='tst_nans'; \
-	$(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_special_atts.log: tst_special_atts$(EXEEXT)
-	@p='tst_special_atts$(EXEEXT)'; \
-	b='tst_special_atts'; \
-	$(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_netcdf4.sh.log: tst_netcdf4.sh
-	@p='tst_netcdf4.sh'; \
-	b='tst_netcdf4.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_h_rdc0.log: tst_h_rdc0$(EXEEXT)
-	@p='tst_h_rdc0$(EXEEXT)'; \
-	b='tst_h_rdc0'; \
-	$(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_unicode.log: tst_unicode$(EXEEXT)
-	@p='tst_unicode$(EXEEXT)'; \
-	b='tst_unicode'; \
-	$(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_fillbug.log: tst_fillbug$(EXEEXT)
-	@p='tst_fillbug$(EXEEXT)'; \
-	b='tst_fillbug'; \
-	$(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_fillbug.sh.log: tst_fillbug.sh
-	@p='tst_fillbug.sh'; \
-	b='tst_fillbug.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_netcdf4_4.sh.log: tst_netcdf4_4.sh
-	@p='tst_netcdf4_4.sh'; \
-	b='tst_netcdf4_4.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_compress.log: tst_compress$(EXEEXT)
-	@p='tst_compress$(EXEEXT)'; \
-	b='tst_compress'; \
-	$(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_nccopy4.sh.log: tst_nccopy4.sh
-	@p='tst_nccopy4.sh'; \
-	b='tst_nccopy4.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_grp_spec.sh.log: tst_grp_spec.sh
-	@p='tst_grp_spec.sh'; \
-	b='tst_grp_spec.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_mud.sh.log: tst_mud.sh
-	@p='tst_mud.sh'; \
-	b='tst_mud.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_h_scalar.log: tst_h_scalar$(EXEEXT)
-	@p='tst_h_scalar$(EXEEXT)'; \
-	b='tst_h_scalar'; \
-	$(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_h_scalar.sh.log: tst_h_scalar.sh
-	@p='tst_h_scalar.sh'; \
-	b='tst_h_scalar.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_formatx4.sh.log: tst_formatx4.sh
-	@p='tst_formatx4.sh'; \
-	b='tst_formatx4.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_bug324.log: tst_bug324$(EXEEXT)
-	@p='tst_bug324$(EXEEXT)'; \
-	b='tst_bug324'; \
-	$(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_utf8_nc4_tests.sh.log: run_utf8_nc4_tests.sh
-	@p='run_utf8_nc4_tests.sh'; \
-	b='run_utf8_nc4_tests.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_back_comp_tests.sh.log: run_back_comp_tests.sh
-	@p='run_back_comp_tests.sh'; \
-	b='run_back_comp_tests.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_ncgen4_classic.sh.log: tst_ncgen4_classic.sh
-	@p='tst_ncgen4_classic.sh'; \
-	b='tst_ncgen4_classic.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_ncgen4.sh.log: tst_ncgen4.sh
-	@p='tst_ncgen4.sh'; \
-	b='tst_ncgen4.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
@@ -1986,16 +1553,14 @@ distdir: $(DISTFILES)
 check-am: all-am
 	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
 	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) check-recursive
+check: check-recursive
 all-am: Makefile $(PROGRAMS) $(MANS)
 installdirs: installdirs-recursive
 installdirs-am:
 	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
-install: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) install-recursive
+install: install-recursive
 install-exec: install-exec-recursive
 install-data: install-data-recursive
 uninstall: uninstall-recursive
@@ -2025,16 +1590,14 @@ clean-generic:
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
 clean: clean-recursive
 
 clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
-	clean-libtool clean-local clean-noinstPROGRAMS mostlyclean-am
+	clean-libtool clean-noinstPROGRAMS mostlyclean-am
 
 distclean: distclean-recursive
 	-rm -rf ./$(DEPDIR)
@@ -2104,12 +1667,11 @@ uninstall-am: uninstall-binPROGRAMS uninstall-man
 
 uninstall-man: uninstall-man1
 
-.MAKE: $(am__recursive_targets) all check check-am install install-am \
-	install-strip
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
 
 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
 	check-TESTS check-am clean clean-binPROGRAMS \
-	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
+	clean-checkPROGRAMS clean-generic clean-libtool \
 	clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
 	distclean-compile distclean-generic distclean-libtool \
 	distclean-tags distdir dvi dvi-am html html-am info info-am \
@@ -2127,19 +1689,16 @@ uninstall-man: uninstall-man1
 
 .PRECIOUS: Makefile
 
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_TRUE at ctest.c:
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_TRUE@	$(top_builddir)/ncgen/ncgen -lc -o ctest0.nc $(top_srcdir)/ncgen/c0.cdl > $(top_builddir)/ncdump/ctest.c
-
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_TRUE at ctest64.c:
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_TRUE@	$(top_builddir)/ncgen/ncgen -k2 -lc -o ctest0_64.nc $(top_srcdir)/ncgen/c0.cdl > $(srcdir)/ctest64.c
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_FALSE at ctest.c:
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_FALSE@	cp $(top_srcdir)/ncdump/ref_ctest.c $(top_builddir)/ncdump/ctest.c
 
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_FALSE at ctest64.c:
- at BUILD_TESTSETS_TRUE@@EXTRA_TESTS_FALSE@	cp $(top_srcdir)/ncdump/ref_ctest64.c $(top_builddir)/ncdump/ctest64.c
+# The tst_nccopy3.sh test uses output from a bunch of other
+# tests. This records the dependency so parallel builds work.
+ at BUILD_TESTSETS_TRUE@tst_nccopy3.log: tst_calendars.log run_utf8_tests.log tst_output.log	\
+ at BUILD_TESTSETS_TRUE@tst_64bit.log run_tests.log tst_lengths.log
 
-clean-local:
-	-rm -rf results
+# The tst_nccopy4.sh test script depends on the output of a bunch of
+# other tests. Record dependencies so parallel builds work.
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_nccopy4.log: run_ncgen_tests.log tst_output.log tst_ncgen4.log	\
+ at BUILD_TESTSETS_TRUE@@USE_NETCDF4_TRUE at tst_fillbug.log tst_netcdf4_4.log tst_h_scalar.log
 
 # 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/ncdump/bom.c b/ncdump/bom.c
index b8f3ede..eb24690 100644
--- a/ncdump/bom.c
+++ b/ncdump/bom.c
@@ -11,9 +11,9 @@
 /* BOM Sequences */
 static char* U8   = "\xEF\xBB\xBF";    /* UTF-8 */
 static char* BE32 = "\x00\x00\xFE\xFF"; /* UTF-32; big-endian */
-static char* LE32 = "\xFF\xFE";       /* UTF-32; little-endian */
+/* static char* LE32 = "\xFF\xFE";       /\* UTF-32; little-endian *\/ */
 static char* BE16 = "\xFE\xFF";       /* UTF-16; big-endian */
-static char* LE16 = "\xFF\xFE";       /* UTF-16; little-endian */
+/* static char* LE16 = "\xFF\xFE";       /\* UTF-16; little-endian *\/ */
 
 int
 main(int argc, char** argv)
diff --git a/ncdump/cdl.h b/ncdump/cdl.h
index 44b8671..afa12de 100644
--- a/ncdump/cdl.h
+++ b/ncdump/cdl.h
@@ -18,5 +18,6 @@
 #define NC_ATT_STORAGE     "_Storage"
 #define NC_ATT_NOFILL      "_NoFill"
 #define NC_ATT_NETCDF4     "_NetCDF4"
+#define NC_ATT_FILTER      "_Filter"
 
 #endif	/*_CDL_H_ */
diff --git a/ncdump/cdl/Makefile.in b/ncdump/cdl/Makefile.in
index 920e925..98c5a67 100644
--- a/ncdump/cdl/Makefile.in
+++ b/ncdump/cdl/Makefile.in
@@ -137,7 +137,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -160,12 +159,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -191,6 +192,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -205,6 +207,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/ncdump/ctest.c b/ncdump/ctest.c
deleted file mode 100644
index d9b487c..0000000
--- a/ncdump/ctest.c
+++ /dev/null
@@ -1,1472 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <netcdf.h>
-
-
-void
-check_err(const int stat, const int line, const char *file) {
-    if (stat != NC_NOERR) {
-        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
-        fflush(stderr);
-        exit(1);
-    }
-}
-
-int
-main() {/* create ctest0.nc */
-
-    int  stat;  /* return status */
-    int  ncid;  /* netCDF id */
-
-    /* dimension ids */
-    int Dr_dim;
-    int D1_dim;
-    int D2_dim;
-    int D3_dim;
-    int dim_MINUS_name_MINUS_dashes_dim;
-    int dim_PERIOD_name_PERIOD_dots_dim;
-    int dim_PLUS_name_PLUS_plusses_dim;
-    int dim_ATSIGN_name_ATSIGN_ats_dim;
-
-    /* dimension lengths */
-    size_t Dr_len = NC_UNLIMITED;
-    size_t D1_len = 1;
-    size_t D2_len = 2;
-    size_t D3_len = 3;
-    size_t dim_MINUS_name_MINUS_dashes_len = 4;
-    size_t dim_PERIOD_name_PERIOD_dots_len = 5;
-    size_t dim_PLUS_name_PLUS_plusses_len = 6;
-    size_t dim_ATSIGN_name_ATSIGN_ats_len = 7;
-
-    /* variable ids */
-    int c_id;
-    int b_id;
-    int s_id;
-    int i_id;
-    int f_id;
-    int d_id;
-    int cr_id;
-    int br_id;
-    int sr_id;
-    int ir_id;
-    int fr_id;
-    int dr_id;
-    int c1_id;
-    int b1_id;
-    int s1_id;
-    int i1_id;
-    int f1_id;
-    int d1_id;
-    int c2_id;
-    int b2_id;
-    int s2_id;
-    int i2_id;
-    int f2_id;
-    int d2_id;
-    int c3_id;
-    int b3_id;
-    int s3_id;
-    int i3_id;
-    int f3_id;
-    int d3_id;
-    int cr1_id;
-    int br2_id;
-    int sr3_id;
-    int f11_id;
-    int d12_id;
-    int c13_id;
-    int s21_id;
-    int i22_id;
-    int f23_id;
-    int c31_id;
-    int b32_id;
-    int s33_id;
-    int sr11_id;
-    int ir12_id;
-    int fr13_id;
-    int cr21_id;
-    int br22_id;
-    int sr23_id;
-    int fr31_id;
-    int dr32_id;
-    int cr33_id;
-    int c111_id;
-    int b112_id;
-    int s113_id;
-    int f121_id;
-    int d122_id;
-    int c123_id;
-    int s131_id;
-    int i132_id;
-    int f133_id;
-    int f211_id;
-    int d212_id;
-    int c213_id;
-    int s221_id;
-    int i222_id;
-    int f223_id;
-    int c231_id;
-    int b232_id;
-    int s233_id;
-    int s311_id;
-    int i312_id;
-    int f313_id;
-    int var_MINUS_name_MINUS_dashes_id;
-    int var_PERIOD_name_PERIOD_dots_id;
-    int var_PLUS_name_PLUS_plusses_id;
-    int var_ATSIGN_name_ATSIGN_ats_id;
-
-    /* rank (number of dimensions) for each variable */
-#   define RANK_c 0
-#   define RANK_b 0
-#   define RANK_s 0
-#   define RANK_i 0
-#   define RANK_f 0
-#   define RANK_d 0
-#   define RANK_cr 1
-#   define RANK_br 1
-#   define RANK_sr 1
-#   define RANK_ir 1
-#   define RANK_fr 1
-#   define RANK_dr 1
-#   define RANK_c1 1
-#   define RANK_b1 1
-#   define RANK_s1 1
-#   define RANK_i1 1
-#   define RANK_f1 1
-#   define RANK_d1 1
-#   define RANK_c2 1
-#   define RANK_b2 1
-#   define RANK_s2 1
-#   define RANK_i2 1
-#   define RANK_f2 1
-#   define RANK_d2 1
-#   define RANK_c3 1
-#   define RANK_b3 1
-#   define RANK_s3 1
-#   define RANK_i3 1
-#   define RANK_f3 1
-#   define RANK_d3 1
-#   define RANK_cr1 2
-#   define RANK_br2 2
-#   define RANK_sr3 2
-#   define RANK_f11 2
-#   define RANK_d12 2
-#   define RANK_c13 2
-#   define RANK_s21 2
-#   define RANK_i22 2
-#   define RANK_f23 2
-#   define RANK_c31 2
-#   define RANK_b32 2
-#   define RANK_s33 2
-#   define RANK_sr11 3
-#   define RANK_ir12 3
-#   define RANK_fr13 3
-#   define RANK_cr21 3
-#   define RANK_br22 3
-#   define RANK_sr23 3
-#   define RANK_fr31 3
-#   define RANK_dr32 3
-#   define RANK_cr33 3
-#   define RANK_c111 3
-#   define RANK_b112 3
-#   define RANK_s113 3
-#   define RANK_f121 3
-#   define RANK_d122 3
-#   define RANK_c123 3
-#   define RANK_s131 3
-#   define RANK_i132 3
-#   define RANK_f133 3
-#   define RANK_f211 3
-#   define RANK_d212 3
-#   define RANK_c213 3
-#   define RANK_s221 3
-#   define RANK_i222 3
-#   define RANK_f223 3
-#   define RANK_c231 3
-#   define RANK_b232 3
-#   define RANK_s233 3
-#   define RANK_s311 3
-#   define RANK_i312 3
-#   define RANK_f313 3
-#   define RANK_var_MINUS_name_MINUS_dashes 0
-#   define RANK_var_PERIOD_name_PERIOD_dots 0
-#   define RANK_var_PLUS_name_PLUS_plusses 0
-#   define RANK_var_ATSIGN_name_ATSIGN_ats 0
-
-    /* variable shapes */
-    int cr_dims[RANK_cr];
-    int br_dims[RANK_br];
-    int sr_dims[RANK_sr];
-    int ir_dims[RANK_ir];
-    int fr_dims[RANK_fr];
-    int dr_dims[RANK_dr];
-    int c1_dims[RANK_c1];
-    int b1_dims[RANK_b1];
-    int s1_dims[RANK_s1];
-    int i1_dims[RANK_i1];
-    int f1_dims[RANK_f1];
-    int d1_dims[RANK_d1];
-    int c2_dims[RANK_c2];
-    int b2_dims[RANK_b2];
-    int s2_dims[RANK_s2];
-    int i2_dims[RANK_i2];
-    int f2_dims[RANK_f2];
-    int d2_dims[RANK_d2];
-    int c3_dims[RANK_c3];
-    int b3_dims[RANK_b3];
-    int s3_dims[RANK_s3];
-    int i3_dims[RANK_i3];
-    int f3_dims[RANK_f3];
-    int d3_dims[RANK_d3];
-    int cr1_dims[RANK_cr1];
-    int br2_dims[RANK_br2];
-    int sr3_dims[RANK_sr3];
-    int f11_dims[RANK_f11];
-    int d12_dims[RANK_d12];
-    int c13_dims[RANK_c13];
-    int s21_dims[RANK_s21];
-    int i22_dims[RANK_i22];
-    int f23_dims[RANK_f23];
-    int c31_dims[RANK_c31];
-    int b32_dims[RANK_b32];
-    int s33_dims[RANK_s33];
-    int sr11_dims[RANK_sr11];
-    int ir12_dims[RANK_ir12];
-    int fr13_dims[RANK_fr13];
-    int cr21_dims[RANK_cr21];
-    int br22_dims[RANK_br22];
-    int sr23_dims[RANK_sr23];
-    int fr31_dims[RANK_fr31];
-    int dr32_dims[RANK_dr32];
-    int cr33_dims[RANK_cr33];
-    int c111_dims[RANK_c111];
-    int b112_dims[RANK_b112];
-    int s113_dims[RANK_s113];
-    int f121_dims[RANK_f121];
-    int d122_dims[RANK_d122];
-    int c123_dims[RANK_c123];
-    int s131_dims[RANK_s131];
-    int i132_dims[RANK_i132];
-    int f133_dims[RANK_f133];
-    int f211_dims[RANK_f211];
-    int d212_dims[RANK_d212];
-    int c213_dims[RANK_c213];
-    int s221_dims[RANK_s221];
-    int i222_dims[RANK_i222];
-    int f223_dims[RANK_f223];
-    int c231_dims[RANK_c231];
-    int b232_dims[RANK_b232];
-    int s233_dims[RANK_s233];
-    int s311_dims[RANK_s311];
-    int i312_dims[RANK_i312];
-    int f313_dims[RANK_f313];
-
-    /* enter define mode */
-    stat = nc_create("ctest0.nc", NC_CLOBBER, &ncid);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* define dimensions */
-    stat = nc_def_dim(ncid, "Dr", Dr_len, &Dr_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "D1", D1_len, &D1_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "D2", D2_len, &D2_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "D3", D3_len, &D3_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim-name-dashes", dim_MINUS_name_MINUS_dashes_len, &dim_MINUS_name_MINUS_dashes_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim.name.dots", dim_PERIOD_name_PERIOD_dots_len, &dim_PERIOD_name_PERIOD_dots_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim+name+plusses", dim_PLUS_name_PLUS_plusses_len, &dim_PLUS_name_PLUS_plusses_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim at name@ats", dim_ATSIGN_name_ATSIGN_ats_len, &dim_ATSIGN_name_ATSIGN_ats_dim);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* define variables */
-
-    stat = nc_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    br_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    ir_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    fr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    dr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr1_dims[0] = Dr_dim;
-    cr1_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    br2_dims[0] = Dr_dim;
-    br2_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr3_dims[0] = Dr_dim;
-    sr3_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f11_dims[0] = D1_dim;
-    f11_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d12_dims[0] = D1_dim;
-    d12_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c13_dims[0] = D1_dim;
-    c13_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s21_dims[0] = D2_dim;
-    s21_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i22_dims[0] = D2_dim;
-    i22_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f23_dims[0] = D2_dim;
-    f23_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c31_dims[0] = D3_dim;
-    c31_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b32_dims[0] = D3_dim;
-    b32_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s33_dims[0] = D3_dim;
-    s33_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr11_dims[0] = Dr_dim;
-    sr11_dims[1] = D1_dim;
-    sr11_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    ir12_dims[0] = Dr_dim;
-    ir12_dims[1] = D1_dim;
-    ir12_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    fr13_dims[0] = Dr_dim;
-    fr13_dims[1] = D1_dim;
-    fr13_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr21_dims[0] = Dr_dim;
-    cr21_dims[1] = D2_dim;
-    cr21_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    br22_dims[0] = Dr_dim;
-    br22_dims[1] = D2_dim;
-    br22_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr23_dims[0] = Dr_dim;
-    sr23_dims[1] = D2_dim;
-    sr23_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    fr31_dims[0] = Dr_dim;
-    fr31_dims[1] = D3_dim;
-    fr31_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    dr32_dims[0] = Dr_dim;
-    dr32_dims[1] = D3_dim;
-    dr32_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr33_dims[0] = Dr_dim;
-    cr33_dims[1] = D3_dim;
-    cr33_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c111_dims[0] = D1_dim;
-    c111_dims[1] = D1_dim;
-    c111_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b112_dims[0] = D1_dim;
-    b112_dims[1] = D1_dim;
-    b112_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s113_dims[0] = D1_dim;
-    s113_dims[1] = D1_dim;
-    s113_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f121_dims[0] = D1_dim;
-    f121_dims[1] = D2_dim;
-    f121_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d122_dims[0] = D1_dim;
-    d122_dims[1] = D2_dim;
-    d122_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c123_dims[0] = D1_dim;
-    c123_dims[1] = D2_dim;
-    c123_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s131_dims[0] = D1_dim;
-    s131_dims[1] = D3_dim;
-    s131_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i132_dims[0] = D1_dim;
-    i132_dims[1] = D3_dim;
-    i132_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f133_dims[0] = D1_dim;
-    f133_dims[1] = D3_dim;
-    f133_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f211_dims[0] = D2_dim;
-    f211_dims[1] = D1_dim;
-    f211_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d212_dims[0] = D2_dim;
-    d212_dims[1] = D1_dim;
-    d212_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c213_dims[0] = D2_dim;
-    c213_dims[1] = D1_dim;
-    c213_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s221_dims[0] = D2_dim;
-    s221_dims[1] = D2_dim;
-    s221_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i222_dims[0] = D2_dim;
-    i222_dims[1] = D2_dim;
-    i222_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f223_dims[0] = D2_dim;
-    f223_dims[1] = D2_dim;
-    f223_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c231_dims[0] = D2_dim;
-    c231_dims[1] = D3_dim;
-    c231_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b232_dims[0] = D2_dim;
-    b232_dims[1] = D3_dim;
-    b232_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s233_dims[0] = D2_dim;
-    s233_dims[1] = D3_dim;
-    s233_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s311_dims[0] = D3_dim;
-    s311_dims[1] = D1_dim;
-    s311_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i312_dims[0] = D3_dim;
-    i312_dims[1] = D1_dim;
-    i312_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f313_dims[0] = D3_dim;
-    f313_dims[1] = D1_dim;
-    f313_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var-name-dashes", NC_DOUBLE, RANK_var_MINUS_name_MINUS_dashes, 0, &var_MINUS_name_MINUS_dashes_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var.name.dots", NC_DOUBLE, RANK_var_PERIOD_name_PERIOD_dots, 0, &var_PERIOD_name_PERIOD_dots_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var+name+plusses", NC_DOUBLE, RANK_var_PLUS_name_PLUS_plusses, 0, &var_PLUS_name_PLUS_plusses_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var at name@ats", NC_DOUBLE, RANK_var_ATSIGN_name_ATSIGN_ats, 0, &var_ATSIGN_name_ATSIGN_ats_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* assign global attributes */
-
-    {
-    stat = nc_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const signed char c0_Gb_att[2] = {-128, 127} ;
-    stat = nc_put_att_schar(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, c0_Gb_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const short c0_Gs_att[3] = {-32768, 0, 32767} ;
-    stat = nc_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, c0_Gs_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gi_att[3] = {-2147483647, 0, 2147483647} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 3, c0_Gi_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const float c0_Gf_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
-    stat = nc_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 3, c0_Gf_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const double c0_Gd_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
-    stat = nc_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 3, c0_Gd_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_MINUS_name_MINUS_dashes_att[1] = {-1} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt-name-dashes", NC_INT, 1, c0_Gatt_MINUS_name_MINUS_dashes_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_DOT_name_DOT_dots_att[1] = {-2} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt.name.dots", NC_INT, 1, c0_Gatt_DOT_name_DOT_dots_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_PLUS_name_PLUS_plusses_att[1] = {-3} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt+name+plusses", NC_INT, 1, c0_Gatt_PLUS_name_PLUS_plusses_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_ATSIGN_name_ATSIGN_ats_att[1] = {-4} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt at name@ats", NC_INT, 1, c0_Gatt_ATSIGN_name_ATSIGN_ats_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    /* assign per-variable attributes */
-
-    {
-    static const int c0_att_MINUS_name_MINUS_dashes_att[1] = {4} ;
-    stat = nc_put_att_int(ncid, c_id, "att-name-dashes", NC_INT, 1, c0_att_MINUS_name_MINUS_dashes_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_att_DOT_name_DOT_dots_att[1] = {5} ;
-    stat = nc_put_att_int(ncid, c_id, "att.name.dots", NC_INT, 1, c0_att_DOT_name_DOT_dots_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_att_PLUS_name_PLUS_plusses_att[1] = {6} ;
-    stat = nc_put_att_int(ncid, c_id, "att+name+plusses", NC_INT, 1, c0_att_PLUS_name_PLUS_plusses_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_att_ATSIGN_name_ATSIGN_ats_att[1] = {7} ;
-    stat = nc_put_att_int(ncid, c_id, "att at name@ats", NC_INT, 1, c0_att_ATSIGN_name_ATSIGN_ats_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    stat = nc_put_att_text(ncid, b_id, "c", 1, "");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const signed char c0_b_att[4] = {0, 127, -128, -1} ;
-    stat = nc_put_att_schar(ncid, s_id, "b", NC_BYTE, 4, c0_b_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const short c0_s_att[3] = {-32768, 0, 32767} ;
-    stat = nc_put_att_short(ncid, s_id, "s", NC_SHORT, 3, c0_s_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_i_att[3] = {-2147483647, 0, 2147483647} ;
-    stat = nc_put_att_int(ncid, i_id, "i", NC_INT, 3, c0_i_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const float c0_f_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
-    stat = nc_put_att_float(ncid, i_id, "f", NC_FLOAT, 3, c0_f_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const double c0_d_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
-    stat = nc_put_att_double(ncid, i_id, "d", NC_DOUBLE, 3, c0_d_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    stat = nc_put_att_text(ncid, f_id, "c", 1, "x");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    stat = nc_put_att_text(ncid, d_id, "c", 8, "abcd\tZ$&");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    /* leave define mode */
-    stat = nc_enddef (ncid);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* assign variable data */
-
-    {
-    size_t count = 0;
-    static char c_data[1] = {'2'};
-    stat = nc_put_var1(ncid, c_id, &count, c_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static signed char b_data[1] = {-2};
-    stat = nc_put_var1(ncid, b_id, &count, b_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static short s_data[1] = {-5};
-    stat = nc_put_var1(ncid, s_id, &count, s_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static int i_data[1] = {-20};
-    stat = nc_put_var1(ncid, i_id, &count, i_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static float f_data[1] = {((float)-9)};
-    stat = nc_put_var1(ncid, f_id, &count, f_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double d_data[1] = {((double)-10)};
-    stat = nc_put_var1(ncid, d_id, &count, d_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr_data = "ab" ;
-    size_t cr_startset[1] = {0} ;
-    size_t cr_countset[1] = {2};
-    stat = nc_put_vara(ncid, cr_id, cr_startset, cr_countset, cr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char br_data[2] = {-128, 127} ;
-    size_t br_startset[1] = {0} ;
-    size_t br_countset[1] = {2};
-    stat = nc_put_vara(ncid, br_id, br_startset, br_countset, br_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr_data[2] = {-32768, 32767} ;
-    size_t sr_startset[1] = {0} ;
-    size_t sr_countset[1] = {2};
-    stat = nc_put_vara(ncid, sr_id, sr_startset, sr_countset, sr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int ir_data[2] = {-2147483646, 2147483647} ;
-    size_t ir_startset[1] = {0} ;
-    size_t ir_countset[1] = {2};
-    stat = nc_put_vara(ncid, ir_id, ir_startset, ir_countset, ir_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float fr_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
-    size_t fr_startset[1] = {0} ;
-    size_t fr_countset[1] = {2};
-    stat = nc_put_vara(ncid, fr_id, fr_startset, fr_countset, fr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double dr_data[2] = {((double)-1e+308), ((double)1e+308)} ;
-    size_t dr_startset[1] = {0} ;
-    size_t dr_countset[1] = {2};
-    stat = nc_put_vara(ncid, dr_id, dr_startset, dr_countset, dr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c1_data = "\000" ;
-    size_t c1_startset[1] = {0} ;
-    size_t c1_countset[1] = {1};
-    stat = nc_put_vara(ncid, c1_id, c1_startset, c1_countset, c1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b1_data[1] = {-128} ;
-    size_t b1_startset[1] = {0} ;
-    size_t b1_countset[1] = {1};
-    stat = nc_put_vara(ncid, b1_id, b1_startset, b1_countset, b1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s1_data[1] = {-32768} ;
-    size_t s1_startset[1] = {0} ;
-    size_t s1_countset[1] = {1};
-    stat = nc_put_vara(ncid, s1_id, s1_startset, s1_countset, s1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i1_data[1] = {-2147483646} ;
-    size_t i1_startset[1] = {0} ;
-    size_t i1_countset[1] = {1};
-    stat = nc_put_vara(ncid, i1_id, i1_startset, i1_countset, i1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f1_data[1] = {((float)-9.9999996e+35)} ;
-    size_t f1_startset[1] = {0} ;
-    size_t f1_countset[1] = {1};
-    stat = nc_put_vara(ncid, f1_id, f1_startset, f1_countset, f1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d1_data[1] = {((double)-1e+308)} ;
-    size_t d1_startset[1] = {0} ;
-    size_t d1_countset[1] = {1};
-    stat = nc_put_vara(ncid, d1_id, d1_startset, d1_countset, d1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c2_data = "ab" ;
-    size_t c2_startset[1] = {0} ;
-    size_t c2_countset[1] = {2};
-    stat = nc_put_vara(ncid, c2_id, c2_startset, c2_countset, c2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b2_data[2] = {-128, 127} ;
-    size_t b2_startset[1] = {0} ;
-    size_t b2_countset[1] = {2};
-    stat = nc_put_vara(ncid, b2_id, b2_startset, b2_countset, b2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s2_data[2] = {-32768, 32767} ;
-    size_t s2_startset[1] = {0} ;
-    size_t s2_countset[1] = {2};
-    stat = nc_put_vara(ncid, s2_id, s2_startset, s2_countset, s2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i2_data[2] = {-2147483646, 2147483647} ;
-    size_t i2_startset[1] = {0} ;
-    size_t i2_countset[1] = {2};
-    stat = nc_put_vara(ncid, i2_id, i2_startset, i2_countset, i2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f2_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
-    size_t f2_startset[1] = {0} ;
-    size_t f2_countset[1] = {2};
-    stat = nc_put_vara(ncid, f2_id, f2_startset, f2_countset, f2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d2_data[2] = {((double)-1e+308), ((double)1e+308)} ;
-    size_t d2_startset[1] = {0} ;
-    size_t d2_countset[1] = {2};
-    stat = nc_put_vara(ncid, d2_id, d2_startset, d2_countset, d2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c3_data = "\001\177." ;
-    size_t c3_startset[1] = {0} ;
-    size_t c3_countset[1] = {3};
-    stat = nc_put_vara(ncid, c3_id, c3_startset, c3_countset, c3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b3_data[3] = {-128, 127, -1} ;
-    size_t b3_startset[1] = {0} ;
-    size_t b3_countset[1] = {3};
-    stat = nc_put_vara(ncid, b3_id, b3_startset, b3_countset, b3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s3_data[3] = {-32768, 0, 32767} ;
-    size_t s3_startset[1] = {0} ;
-    size_t s3_countset[1] = {3};
-    stat = nc_put_vara(ncid, s3_id, s3_startset, s3_countset, s3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i3_data[3] = {-2147483646, 0, 2147483647} ;
-    size_t i3_startset[1] = {0} ;
-    size_t i3_countset[1] = {3};
-    stat = nc_put_vara(ncid, i3_id, i3_startset, i3_countset, i3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f3_data[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
-    size_t f3_startset[1] = {0} ;
-    size_t f3_countset[1] = {3};
-    stat = nc_put_vara(ncid, f3_id, f3_startset, f3_countset, f3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d3_data[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
-    size_t d3_startset[1] = {0} ;
-    size_t d3_countset[1] = {3};
-    stat = nc_put_vara(ncid, d3_id, d3_startset, d3_countset, d3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr1_data = "xy" ;
-    size_t cr1_startset[2] = {0, 0} ;
-    size_t cr1_countset[2] = {2, 1};
-    stat = nc_put_vara(ncid, cr1_id, cr1_startset, cr1_countset, cr1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char br2_data[4] = {-24, -26, -20, -22} ;
-    size_t br2_startset[2] = {0, 0} ;
-    size_t br2_countset[2] = {2, 2};
-    stat = nc_put_vara(ncid, br2_id, br2_startset, br2_countset, br2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr3_data[6] = {-375, -380, -385, -350, -355, -360} ;
-    size_t sr3_startset[2] = {0, 0} ;
-    size_t sr3_countset[2] = {2, 3};
-    stat = nc_put_vara(ncid, sr3_id, sr3_startset, sr3_countset, sr3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f11_data[1] = {((float)-2187)} ;
-    size_t f11_startset[2] = {0, 0} ;
-    size_t f11_countset[2] = {1, 1};
-    stat = nc_put_vara(ncid, f11_id, f11_startset, f11_countset, f11_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d12_data[2] = {((double)-3000), ((double)-3010)} ;
-    size_t d12_startset[2] = {0, 0} ;
-    size_t d12_countset[2] = {1, 2};
-    stat = nc_put_vara(ncid, d12_id, d12_startset, d12_countset, d12_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c13_data = "\tb\177" ;
-    size_t c13_startset[2] = {0, 0} ;
-    size_t c13_countset[2] = {1, 3};
-    stat = nc_put_vara(ncid, c13_id, c13_startset, c13_countset, c13_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s21_data[2] = {-375, -350} ;
-    size_t s21_startset[2] = {0, 0} ;
-    size_t s21_countset[2] = {2, 1};
-    stat = nc_put_vara(ncid, s21_id, s21_startset, s21_countset, s21_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i22_data[4] = {-24000, -24020, -23600, -23620} ;
-    size_t i22_startset[2] = {0, 0} ;
-    size_t i22_countset[2] = {2, 2};
-    stat = nc_put_vara(ncid, i22_id, i22_startset, i22_countset, i22_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f23_data[6] = {((float)-2187), ((float)-2196), ((float)-2205), ((float)-2106), ((float)-2115), ((float)-2124)} ;
-    size_t f23_startset[2] = {0, 0} ;
-    size_t f23_countset[2] = {2, 3};
-    stat = nc_put_vara(ncid, f23_id, f23_startset, f23_countset, f23_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c31_data = "+- " ;
-    size_t c31_startset[2] = {0, 0} ;
-    size_t c31_countset[2] = {3, 1};
-    stat = nc_put_vara(ncid, c31_id, c31_startset, c31_countset, c31_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b32_data[6] = {-24, -26, -20, -22, -16, -18} ;
-    size_t b32_startset[2] = {0, 0} ;
-    size_t b32_countset[2] = {3, 2};
-    stat = nc_put_vara(ncid, b32_id, b32_startset, b32_countset, b32_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s33_data[9] = {-375, -380, -385, -350, -355, -360, -325, -330, -335} ;
-    size_t s33_startset[2] = {0, 0} ;
-    size_t s33_countset[2] = {3, 3};
-    stat = nc_put_vara(ncid, s33_id, s33_startset, s33_countset, s33_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr11_data[2] = {2500, 2375} ;
-    size_t sr11_startset[3] = {0, 0, 0} ;
-    size_t sr11_countset[3] = {2, 1, 1};
-    stat = nc_put_vara(ncid, sr11_id, sr11_startset, sr11_countset, sr11_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int ir12_data[4] = {640000, 639980, 632000, 631980} ;
-    size_t ir12_startset[3] = {0, 0, 0} ;
-    size_t ir12_countset[3] = {2, 1, 2};
-    stat = nc_put_vara(ncid, ir12_id, ir12_startset, ir12_countset, ir12_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float fr13_data[6] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497)} ;
-    size_t fr13_startset[3] = {0, 0, 0} ;
-    size_t fr13_countset[3] = {2, 1, 3};
-    stat = nc_put_vara(ncid, fr13_id, fr13_startset, fr13_countset, fr13_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr21_data = "@DHL" ;
-    size_t cr21_startset[3] = {0, 0, 0} ;
-    size_t cr21_countset[3] = {2, 2, 1};
-    stat = nc_put_vara(ncid, cr21_id, cr21_startset, cr21_countset, cr21_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char br22_data[8] = {64, 62, 68, 66, 56, 54, 60, 58} ;
-    size_t br22_startset[3] = {0, 0, 0} ;
-    size_t br22_countset[3] = {2, 2, 2};
-    stat = nc_put_vara(ncid, br22_id, br22_startset, br22_countset, br22_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr23_data[12] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390} ;
-    size_t sr23_startset[3] = {0, 0, 0} ;
-    size_t sr23_countset[3] = {2, 2, 3};
-    stat = nc_put_vara(ncid, sr23_id, sr23_startset, sr23_countset, sr23_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float fr31_data[6] = {((float)26244), ((float)26325), ((float)26406), ((float)25515), ((float)25596), ((float)25677)} ;
-    size_t fr31_startset[3] = {0, 0, 0} ;
-    size_t fr31_countset[3] = {2, 3, 1};
-    stat = nc_put_vara(ncid, fr31_id, fr31_startset, fr31_countset, fr31_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double dr32_data[12] = {((double)40000), ((double)39990), ((double)40100), ((double)40090), ((double)40200), ((double)40190), ((double)39000), ((double)38990), ((double)39100), ((double)39090), ((double)39200), ((double)39190)} ;
-    size_t dr32_startset[3] = {0, 0, 0} ;
-    size_t dr32_countset[3] = {2, 3, 2};
-    stat = nc_put_vara(ncid, dr32_id, dr32_startset, dr32_countset, dr32_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr33_data = "1\000\000two3\000\0004\000\0005\000\000six" ;
-    size_t cr33_startset[3] = {0, 0, 0} ;
-    size_t cr33_countset[3] = {2, 3, 3};
-    stat = nc_put_vara(ncid, cr33_id, cr33_startset, cr33_countset, cr33_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c111_data = "@" ;
-    size_t c111_startset[3] = {0, 0, 0} ;
-    size_t c111_countset[3] = {1, 1, 1};
-    stat = nc_put_vara(ncid, c111_id, c111_startset, c111_countset, c111_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b112_data[2] = {64, 62} ;
-    size_t b112_startset[3] = {0, 0, 0} ;
-    size_t b112_countset[3] = {1, 1, 2};
-    stat = nc_put_vara(ncid, b112_id, b112_startset, b112_countset, b112_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s113_data[3] = {2500, 2495, 2490} ;
-    size_t s113_startset[3] = {0, 0, 0} ;
-    size_t s113_countset[3] = {1, 1, 3};
-    stat = nc_put_vara(ncid, s113_id, s113_startset, s113_countset, s113_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f121_data[2] = {((float)26244), ((float)26325)} ;
-    size_t f121_startset[3] = {0, 0, 0} ;
-    size_t f121_countset[3] = {1, 2, 1};
-    stat = nc_put_vara(ncid, f121_id, f121_startset, f121_countset, f121_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d122_data[4] = {((double)40000), ((double)39990), ((double)40100), ((double)40090)} ;
-    size_t d122_startset[3] = {0, 0, 0} ;
-    size_t d122_countset[3] = {1, 2, 2};
-    stat = nc_put_vara(ncid, d122_id, d122_startset, d122_countset, d122_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c123_data = "one2\000\000" ;
-    size_t c123_startset[3] = {0, 0, 0} ;
-    size_t c123_countset[3] = {1, 2, 3};
-    stat = nc_put_vara(ncid, c123_id, c123_startset, c123_countset, c123_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s131_data[3] = {2500, 2525, 2550} ;
-    size_t s131_startset[3] = {0, 0, 0} ;
-    size_t s131_countset[3] = {1, 3, 1};
-    stat = nc_put_vara(ncid, s131_id, s131_startset, s131_countset, s131_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i132_data[6] = {640000, 639980, 640400, 640380, 640800, 640780} ;
-    size_t i132_startset[3] = {0, 0, 0} ;
-    size_t i132_countset[3] = {1, 3, 2};
-    stat = nc_put_vara(ncid, i132_id, i132_startset, i132_countset, i132_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f133_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)26406), ((float)26397), ((float)26388)} ;
-    size_t f133_startset[3] = {0, 0, 0} ;
-    size_t f133_countset[3] = {1, 3, 3};
-    stat = nc_put_vara(ncid, f133_id, f133_startset, f133_countset, f133_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f211_data[2] = {((float)26244), ((float)25515)} ;
-    size_t f211_startset[3] = {0, 0, 0} ;
-    size_t f211_countset[3] = {2, 1, 1};
-    stat = nc_put_vara(ncid, f211_id, f211_startset, f211_countset, f211_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d212_data[4] = {((double)40000), ((double)39990), ((double)39000), ((double)38990)} ;
-    size_t d212_startset[3] = {0, 0, 0} ;
-    size_t d212_countset[3] = {2, 1, 2};
-    stat = nc_put_vara(ncid, d212_id, d212_startset, d212_countset, d212_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c213_data = "\000\000\000\000\000\000" ;
-    size_t c213_startset[3] = {0, 0, 0} ;
-    size_t c213_countset[3] = {2, 1, 3};
-    stat = nc_put_vara(ncid, c213_id, c213_startset, c213_countset, c213_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s221_data[4] = {2500, 2525, 2375, 2400} ;
-    size_t s221_startset[3] = {0, 0, 0} ;
-    size_t s221_countset[3] = {2, 2, 1};
-    stat = nc_put_vara(ncid, s221_id, s221_startset, s221_countset, s221_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i222_data[8] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380} ;
-    size_t i222_startset[3] = {0, 0, 0} ;
-    size_t i222_countset[3] = {2, 2, 2};
-    stat = nc_put_vara(ncid, i222_id, i222_startset, i222_countset, i222_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f223_data[12] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)25515), ((float)25506), ((float)25497), ((float)25596), ((float)25587), ((float)25578)} ;
-    size_t f223_startset[3] = {0, 0, 0} ;
-    size_t f223_countset[3] = {2, 2, 3};
-    stat = nc_put_vara(ncid, f223_id, f223_startset, f223_countset, f223_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c231_data = "@DHHLP" ;
-    size_t c231_startset[3] = {0, 0, 0} ;
-    size_t c231_countset[3] = {2, 3, 1};
-    stat = nc_put_vara(ncid, c231_id, c231_startset, c231_countset, c231_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b232_data[12] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62} ;
-    size_t b232_startset[3] = {0, 0, 0} ;
-    size_t b232_countset[3] = {2, 3, 2};
-    stat = nc_put_vara(ncid, b232_id, b232_startset, b232_countset, b232_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s233_data[18] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415} ;
-    size_t s233_startset[3] = {0, 0, 0} ;
-    size_t s233_countset[3] = {2, 3, 3};
-    stat = nc_put_vara(ncid, s233_id, s233_startset, s233_countset, s233_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s311_data[3] = {2500, 2375, 2250} ;
-    size_t s311_startset[3] = {0, 0, 0} ;
-    size_t s311_countset[3] = {3, 1, 1};
-    stat = nc_put_vara(ncid, s311_id, s311_startset, s311_countset, s311_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i312_data[6] = {640000, 639980, 632000, 631980, 624000, 623980} ;
-    size_t i312_startset[3] = {0, 0, 0} ;
-    size_t i312_countset[3] = {3, 1, 2};
-    stat = nc_put_vara(ncid, i312_id, i312_startset, i312_countset, i312_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f313_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497), ((float)24786), ((float)24777), ((float)24768)} ;
-    size_t f313_startset[3] = {0, 0, 0} ;
-    size_t f313_countset[3] = {3, 1, 3};
-    stat = nc_put_vara(ncid, f313_id, f313_startset, f313_countset, f313_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_MINUS_name_MINUS_dashes_data[1] = {((double)-1)};
-    stat = nc_put_var1(ncid, var_MINUS_name_MINUS_dashes_id, &count, var_MINUS_name_MINUS_dashes_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_PERIOD_name_PERIOD_dots_data[1] = {((double)-2)};
-    stat = nc_put_var1(ncid, var_PERIOD_name_PERIOD_dots_id, &count, var_PERIOD_name_PERIOD_dots_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_PLUS_name_PLUS_plusses_data[1] = {((double)9.969209968386869e+36)};
-    stat = nc_put_var1(ncid, var_PLUS_name_PLUS_plusses_id, &count, var_PLUS_name_PLUS_plusses_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_ATSIGN_name_ATSIGN_ats_data[1] = {((double)9.969209968386869e+36)};
-    stat = nc_put_var1(ncid, var_ATSIGN_name_ATSIGN_ats_id, &count, var_ATSIGN_name_ATSIGN_ats_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    stat = nc_close(ncid);
-    check_err(stat,__LINE__,__FILE__);
-    return 0;
-}
diff --git a/ncdump/ctest64.c b/ncdump/ctest64.c
deleted file mode 100644
index b5fb314..0000000
--- a/ncdump/ctest64.c
+++ /dev/null
@@ -1,1472 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <netcdf.h>
-
-
-void
-check_err(const int stat, const int line, const char *file) {
-    if (stat != NC_NOERR) {
-        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
-        fflush(stderr);
-        exit(1);
-    }
-}
-
-int
-main() {/* create ctest0_64.nc */
-
-    int  stat;  /* return status */
-    int  ncid;  /* netCDF id */
-
-    /* dimension ids */
-    int Dr_dim;
-    int D1_dim;
-    int D2_dim;
-    int D3_dim;
-    int dim_MINUS_name_MINUS_dashes_dim;
-    int dim_PERIOD_name_PERIOD_dots_dim;
-    int dim_PLUS_name_PLUS_plusses_dim;
-    int dim_ATSIGN_name_ATSIGN_ats_dim;
-
-    /* dimension lengths */
-    size_t Dr_len = NC_UNLIMITED;
-    size_t D1_len = 1;
-    size_t D2_len = 2;
-    size_t D3_len = 3;
-    size_t dim_MINUS_name_MINUS_dashes_len = 4;
-    size_t dim_PERIOD_name_PERIOD_dots_len = 5;
-    size_t dim_PLUS_name_PLUS_plusses_len = 6;
-    size_t dim_ATSIGN_name_ATSIGN_ats_len = 7;
-
-    /* variable ids */
-    int c_id;
-    int b_id;
-    int s_id;
-    int i_id;
-    int f_id;
-    int d_id;
-    int cr_id;
-    int br_id;
-    int sr_id;
-    int ir_id;
-    int fr_id;
-    int dr_id;
-    int c1_id;
-    int b1_id;
-    int s1_id;
-    int i1_id;
-    int f1_id;
-    int d1_id;
-    int c2_id;
-    int b2_id;
-    int s2_id;
-    int i2_id;
-    int f2_id;
-    int d2_id;
-    int c3_id;
-    int b3_id;
-    int s3_id;
-    int i3_id;
-    int f3_id;
-    int d3_id;
-    int cr1_id;
-    int br2_id;
-    int sr3_id;
-    int f11_id;
-    int d12_id;
-    int c13_id;
-    int s21_id;
-    int i22_id;
-    int f23_id;
-    int c31_id;
-    int b32_id;
-    int s33_id;
-    int sr11_id;
-    int ir12_id;
-    int fr13_id;
-    int cr21_id;
-    int br22_id;
-    int sr23_id;
-    int fr31_id;
-    int dr32_id;
-    int cr33_id;
-    int c111_id;
-    int b112_id;
-    int s113_id;
-    int f121_id;
-    int d122_id;
-    int c123_id;
-    int s131_id;
-    int i132_id;
-    int f133_id;
-    int f211_id;
-    int d212_id;
-    int c213_id;
-    int s221_id;
-    int i222_id;
-    int f223_id;
-    int c231_id;
-    int b232_id;
-    int s233_id;
-    int s311_id;
-    int i312_id;
-    int f313_id;
-    int var_MINUS_name_MINUS_dashes_id;
-    int var_PERIOD_name_PERIOD_dots_id;
-    int var_PLUS_name_PLUS_plusses_id;
-    int var_ATSIGN_name_ATSIGN_ats_id;
-
-    /* rank (number of dimensions) for each variable */
-#   define RANK_c 0
-#   define RANK_b 0
-#   define RANK_s 0
-#   define RANK_i 0
-#   define RANK_f 0
-#   define RANK_d 0
-#   define RANK_cr 1
-#   define RANK_br 1
-#   define RANK_sr 1
-#   define RANK_ir 1
-#   define RANK_fr 1
-#   define RANK_dr 1
-#   define RANK_c1 1
-#   define RANK_b1 1
-#   define RANK_s1 1
-#   define RANK_i1 1
-#   define RANK_f1 1
-#   define RANK_d1 1
-#   define RANK_c2 1
-#   define RANK_b2 1
-#   define RANK_s2 1
-#   define RANK_i2 1
-#   define RANK_f2 1
-#   define RANK_d2 1
-#   define RANK_c3 1
-#   define RANK_b3 1
-#   define RANK_s3 1
-#   define RANK_i3 1
-#   define RANK_f3 1
-#   define RANK_d3 1
-#   define RANK_cr1 2
-#   define RANK_br2 2
-#   define RANK_sr3 2
-#   define RANK_f11 2
-#   define RANK_d12 2
-#   define RANK_c13 2
-#   define RANK_s21 2
-#   define RANK_i22 2
-#   define RANK_f23 2
-#   define RANK_c31 2
-#   define RANK_b32 2
-#   define RANK_s33 2
-#   define RANK_sr11 3
-#   define RANK_ir12 3
-#   define RANK_fr13 3
-#   define RANK_cr21 3
-#   define RANK_br22 3
-#   define RANK_sr23 3
-#   define RANK_fr31 3
-#   define RANK_dr32 3
-#   define RANK_cr33 3
-#   define RANK_c111 3
-#   define RANK_b112 3
-#   define RANK_s113 3
-#   define RANK_f121 3
-#   define RANK_d122 3
-#   define RANK_c123 3
-#   define RANK_s131 3
-#   define RANK_i132 3
-#   define RANK_f133 3
-#   define RANK_f211 3
-#   define RANK_d212 3
-#   define RANK_c213 3
-#   define RANK_s221 3
-#   define RANK_i222 3
-#   define RANK_f223 3
-#   define RANK_c231 3
-#   define RANK_b232 3
-#   define RANK_s233 3
-#   define RANK_s311 3
-#   define RANK_i312 3
-#   define RANK_f313 3
-#   define RANK_var_MINUS_name_MINUS_dashes 0
-#   define RANK_var_PERIOD_name_PERIOD_dots 0
-#   define RANK_var_PLUS_name_PLUS_plusses 0
-#   define RANK_var_ATSIGN_name_ATSIGN_ats 0
-
-    /* variable shapes */
-    int cr_dims[RANK_cr];
-    int br_dims[RANK_br];
-    int sr_dims[RANK_sr];
-    int ir_dims[RANK_ir];
-    int fr_dims[RANK_fr];
-    int dr_dims[RANK_dr];
-    int c1_dims[RANK_c1];
-    int b1_dims[RANK_b1];
-    int s1_dims[RANK_s1];
-    int i1_dims[RANK_i1];
-    int f1_dims[RANK_f1];
-    int d1_dims[RANK_d1];
-    int c2_dims[RANK_c2];
-    int b2_dims[RANK_b2];
-    int s2_dims[RANK_s2];
-    int i2_dims[RANK_i2];
-    int f2_dims[RANK_f2];
-    int d2_dims[RANK_d2];
-    int c3_dims[RANK_c3];
-    int b3_dims[RANK_b3];
-    int s3_dims[RANK_s3];
-    int i3_dims[RANK_i3];
-    int f3_dims[RANK_f3];
-    int d3_dims[RANK_d3];
-    int cr1_dims[RANK_cr1];
-    int br2_dims[RANK_br2];
-    int sr3_dims[RANK_sr3];
-    int f11_dims[RANK_f11];
-    int d12_dims[RANK_d12];
-    int c13_dims[RANK_c13];
-    int s21_dims[RANK_s21];
-    int i22_dims[RANK_i22];
-    int f23_dims[RANK_f23];
-    int c31_dims[RANK_c31];
-    int b32_dims[RANK_b32];
-    int s33_dims[RANK_s33];
-    int sr11_dims[RANK_sr11];
-    int ir12_dims[RANK_ir12];
-    int fr13_dims[RANK_fr13];
-    int cr21_dims[RANK_cr21];
-    int br22_dims[RANK_br22];
-    int sr23_dims[RANK_sr23];
-    int fr31_dims[RANK_fr31];
-    int dr32_dims[RANK_dr32];
-    int cr33_dims[RANK_cr33];
-    int c111_dims[RANK_c111];
-    int b112_dims[RANK_b112];
-    int s113_dims[RANK_s113];
-    int f121_dims[RANK_f121];
-    int d122_dims[RANK_d122];
-    int c123_dims[RANK_c123];
-    int s131_dims[RANK_s131];
-    int i132_dims[RANK_i132];
-    int f133_dims[RANK_f133];
-    int f211_dims[RANK_f211];
-    int d212_dims[RANK_d212];
-    int c213_dims[RANK_c213];
-    int s221_dims[RANK_s221];
-    int i222_dims[RANK_i222];
-    int f223_dims[RANK_f223];
-    int c231_dims[RANK_c231];
-    int b232_dims[RANK_b232];
-    int s233_dims[RANK_s233];
-    int s311_dims[RANK_s311];
-    int i312_dims[RANK_i312];
-    int f313_dims[RANK_f313];
-
-    /* enter define mode */
-    stat = nc_create("ctest0_64.nc", NC_CLOBBER|NC_64BIT_OFFSET, &ncid);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* define dimensions */
-    stat = nc_def_dim(ncid, "Dr", Dr_len, &Dr_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "D1", D1_len, &D1_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "D2", D2_len, &D2_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "D3", D3_len, &D3_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim-name-dashes", dim_MINUS_name_MINUS_dashes_len, &dim_MINUS_name_MINUS_dashes_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim.name.dots", dim_PERIOD_name_PERIOD_dots_len, &dim_PERIOD_name_PERIOD_dots_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim+name+plusses", dim_PLUS_name_PLUS_plusses_len, &dim_PLUS_name_PLUS_plusses_dim);
-    check_err(stat,__LINE__,__FILE__);
-    stat = nc_def_dim(ncid, "dim at name@ats", dim_ATSIGN_name_ATSIGN_ats_len, &dim_ATSIGN_name_ATSIGN_ats_dim);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* define variables */
-
-    stat = nc_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    br_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    ir_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    fr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    dr_dims[0] = Dr_dim;
-    stat = nc_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d1_dims[0] = D1_dim;
-    stat = nc_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d2_dims[0] = D2_dim;
-    stat = nc_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d3_dims[0] = D3_dim;
-    stat = nc_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr1_dims[0] = Dr_dim;
-    cr1_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    br2_dims[0] = Dr_dim;
-    br2_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr3_dims[0] = Dr_dim;
-    sr3_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f11_dims[0] = D1_dim;
-    f11_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d12_dims[0] = D1_dim;
-    d12_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c13_dims[0] = D1_dim;
-    c13_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s21_dims[0] = D2_dim;
-    s21_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i22_dims[0] = D2_dim;
-    i22_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f23_dims[0] = D2_dim;
-    f23_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c31_dims[0] = D3_dim;
-    c31_dims[1] = D1_dim;
-    stat = nc_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b32_dims[0] = D3_dim;
-    b32_dims[1] = D2_dim;
-    stat = nc_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s33_dims[0] = D3_dim;
-    s33_dims[1] = D3_dim;
-    stat = nc_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr11_dims[0] = Dr_dim;
-    sr11_dims[1] = D1_dim;
-    sr11_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    ir12_dims[0] = Dr_dim;
-    ir12_dims[1] = D1_dim;
-    ir12_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    fr13_dims[0] = Dr_dim;
-    fr13_dims[1] = D1_dim;
-    fr13_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr21_dims[0] = Dr_dim;
-    cr21_dims[1] = D2_dim;
-    cr21_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    br22_dims[0] = Dr_dim;
-    br22_dims[1] = D2_dim;
-    br22_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    sr23_dims[0] = Dr_dim;
-    sr23_dims[1] = D2_dim;
-    sr23_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    fr31_dims[0] = Dr_dim;
-    fr31_dims[1] = D3_dim;
-    fr31_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    dr32_dims[0] = Dr_dim;
-    dr32_dims[1] = D3_dim;
-    dr32_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    cr33_dims[0] = Dr_dim;
-    cr33_dims[1] = D3_dim;
-    cr33_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c111_dims[0] = D1_dim;
-    c111_dims[1] = D1_dim;
-    c111_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b112_dims[0] = D1_dim;
-    b112_dims[1] = D1_dim;
-    b112_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s113_dims[0] = D1_dim;
-    s113_dims[1] = D1_dim;
-    s113_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f121_dims[0] = D1_dim;
-    f121_dims[1] = D2_dim;
-    f121_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d122_dims[0] = D1_dim;
-    d122_dims[1] = D2_dim;
-    d122_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c123_dims[0] = D1_dim;
-    c123_dims[1] = D2_dim;
-    c123_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s131_dims[0] = D1_dim;
-    s131_dims[1] = D3_dim;
-    s131_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i132_dims[0] = D1_dim;
-    i132_dims[1] = D3_dim;
-    i132_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f133_dims[0] = D1_dim;
-    f133_dims[1] = D3_dim;
-    f133_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f211_dims[0] = D2_dim;
-    f211_dims[1] = D1_dim;
-    f211_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    d212_dims[0] = D2_dim;
-    d212_dims[1] = D1_dim;
-    d212_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c213_dims[0] = D2_dim;
-    c213_dims[1] = D1_dim;
-    c213_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s221_dims[0] = D2_dim;
-    s221_dims[1] = D2_dim;
-    s221_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i222_dims[0] = D2_dim;
-    i222_dims[1] = D2_dim;
-    i222_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f223_dims[0] = D2_dim;
-    f223_dims[1] = D2_dim;
-    f223_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    c231_dims[0] = D2_dim;
-    c231_dims[1] = D3_dim;
-    c231_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    b232_dims[0] = D2_dim;
-    b232_dims[1] = D3_dim;
-    b232_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s233_dims[0] = D2_dim;
-    s233_dims[1] = D3_dim;
-    s233_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    s311_dims[0] = D3_dim;
-    s311_dims[1] = D1_dim;
-    s311_dims[2] = D1_dim;
-    stat = nc_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    i312_dims[0] = D3_dim;
-    i312_dims[1] = D1_dim;
-    i312_dims[2] = D2_dim;
-    stat = nc_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    f313_dims[0] = D3_dim;
-    f313_dims[1] = D1_dim;
-    f313_dims[2] = D3_dim;
-    stat = nc_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var-name-dashes", NC_DOUBLE, RANK_var_MINUS_name_MINUS_dashes, 0, &var_MINUS_name_MINUS_dashes_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var.name.dots", NC_DOUBLE, RANK_var_PERIOD_name_PERIOD_dots, 0, &var_PERIOD_name_PERIOD_dots_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var+name+plusses", NC_DOUBLE, RANK_var_PLUS_name_PLUS_plusses, 0, &var_PLUS_name_PLUS_plusses_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    stat = nc_def_var(ncid, "var at name@ats", NC_DOUBLE, RANK_var_ATSIGN_name_ATSIGN_ats, 0, &var_ATSIGN_name_ATSIGN_ats_id);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* assign global attributes */
-
-    {
-    stat = nc_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const signed char c0_Gb_att[2] = {-128, 127} ;
-    stat = nc_put_att_schar(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, c0_Gb_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const short c0_Gs_att[3] = {-32768, 0, 32767} ;
-    stat = nc_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, c0_Gs_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gi_att[3] = {-2147483647, 0, 2147483647} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 3, c0_Gi_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const float c0_Gf_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
-    stat = nc_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 3, c0_Gf_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const double c0_Gd_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
-    stat = nc_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 3, c0_Gd_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_MINUS_name_MINUS_dashes_att[1] = {-1} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt-name-dashes", NC_INT, 1, c0_Gatt_MINUS_name_MINUS_dashes_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_DOT_name_DOT_dots_att[1] = {-2} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt.name.dots", NC_INT, 1, c0_Gatt_DOT_name_DOT_dots_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_PLUS_name_PLUS_plusses_att[1] = {-3} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt+name+plusses", NC_INT, 1, c0_Gatt_PLUS_name_PLUS_plusses_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_Gatt_ATSIGN_name_ATSIGN_ats_att[1] = {-4} ;
-    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt at name@ats", NC_INT, 1, c0_Gatt_ATSIGN_name_ATSIGN_ats_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    /* assign per-variable attributes */
-
-    {
-    static const int c0_att_MINUS_name_MINUS_dashes_att[1] = {4} ;
-    stat = nc_put_att_int(ncid, c_id, "att-name-dashes", NC_INT, 1, c0_att_MINUS_name_MINUS_dashes_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_att_DOT_name_DOT_dots_att[1] = {5} ;
-    stat = nc_put_att_int(ncid, c_id, "att.name.dots", NC_INT, 1, c0_att_DOT_name_DOT_dots_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_att_PLUS_name_PLUS_plusses_att[1] = {6} ;
-    stat = nc_put_att_int(ncid, c_id, "att+name+plusses", NC_INT, 1, c0_att_PLUS_name_PLUS_plusses_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_att_ATSIGN_name_ATSIGN_ats_att[1] = {7} ;
-    stat = nc_put_att_int(ncid, c_id, "att at name@ats", NC_INT, 1, c0_att_ATSIGN_name_ATSIGN_ats_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    stat = nc_put_att_text(ncid, b_id, "c", 1, "");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const signed char c0_b_att[4] = {0, 127, -128, -1} ;
-    stat = nc_put_att_schar(ncid, s_id, "b", NC_BYTE, 4, c0_b_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const short c0_s_att[3] = {-32768, 0, 32767} ;
-    stat = nc_put_att_short(ncid, s_id, "s", NC_SHORT, 3, c0_s_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const int c0_i_att[3] = {-2147483647, 0, 2147483647} ;
-    stat = nc_put_att_int(ncid, i_id, "i", NC_INT, 3, c0_i_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const float c0_f_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
-    stat = nc_put_att_float(ncid, i_id, "f", NC_FLOAT, 3, c0_f_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    static const double c0_d_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
-    stat = nc_put_att_double(ncid, i_id, "d", NC_DOUBLE, 3, c0_d_att);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    stat = nc_put_att_text(ncid, f_id, "c", 1, "x");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-    {
-    stat = nc_put_att_text(ncid, d_id, "c", 8, "abcd\tZ$&");
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    /* leave define mode */
-    stat = nc_enddef (ncid);
-    check_err(stat,__LINE__,__FILE__);
-
-    /* assign variable data */
-
-    {
-    size_t count = 0;
-    static char c_data[1] = {'2'};
-    stat = nc_put_var1(ncid, c_id, &count, c_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static signed char b_data[1] = {-2};
-    stat = nc_put_var1(ncid, b_id, &count, b_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static short s_data[1] = {-5};
-    stat = nc_put_var1(ncid, s_id, &count, s_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static int i_data[1] = {-20};
-    stat = nc_put_var1(ncid, i_id, &count, i_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static float f_data[1] = {((float)-9)};
-    stat = nc_put_var1(ncid, f_id, &count, f_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double d_data[1] = {((double)-10)};
-    stat = nc_put_var1(ncid, d_id, &count, d_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr_data = "ab" ;
-    size_t cr_startset[1] = {0} ;
-    size_t cr_countset[1] = {2};
-    stat = nc_put_vara(ncid, cr_id, cr_startset, cr_countset, cr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char br_data[2] = {-128, 127} ;
-    size_t br_startset[1] = {0} ;
-    size_t br_countset[1] = {2};
-    stat = nc_put_vara(ncid, br_id, br_startset, br_countset, br_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr_data[2] = {-32768, 32767} ;
-    size_t sr_startset[1] = {0} ;
-    size_t sr_countset[1] = {2};
-    stat = nc_put_vara(ncid, sr_id, sr_startset, sr_countset, sr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int ir_data[2] = {-2147483646, 2147483647} ;
-    size_t ir_startset[1] = {0} ;
-    size_t ir_countset[1] = {2};
-    stat = nc_put_vara(ncid, ir_id, ir_startset, ir_countset, ir_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float fr_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
-    size_t fr_startset[1] = {0} ;
-    size_t fr_countset[1] = {2};
-    stat = nc_put_vara(ncid, fr_id, fr_startset, fr_countset, fr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double dr_data[2] = {((double)-1e+308), ((double)1e+308)} ;
-    size_t dr_startset[1] = {0} ;
-    size_t dr_countset[1] = {2};
-    stat = nc_put_vara(ncid, dr_id, dr_startset, dr_countset, dr_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c1_data = "\000" ;
-    size_t c1_startset[1] = {0} ;
-    size_t c1_countset[1] = {1};
-    stat = nc_put_vara(ncid, c1_id, c1_startset, c1_countset, c1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b1_data[1] = {-128} ;
-    size_t b1_startset[1] = {0} ;
-    size_t b1_countset[1] = {1};
-    stat = nc_put_vara(ncid, b1_id, b1_startset, b1_countset, b1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s1_data[1] = {-32768} ;
-    size_t s1_startset[1] = {0} ;
-    size_t s1_countset[1] = {1};
-    stat = nc_put_vara(ncid, s1_id, s1_startset, s1_countset, s1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i1_data[1] = {-2147483646} ;
-    size_t i1_startset[1] = {0} ;
-    size_t i1_countset[1] = {1};
-    stat = nc_put_vara(ncid, i1_id, i1_startset, i1_countset, i1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f1_data[1] = {((float)-9.9999996e+35)} ;
-    size_t f1_startset[1] = {0} ;
-    size_t f1_countset[1] = {1};
-    stat = nc_put_vara(ncid, f1_id, f1_startset, f1_countset, f1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d1_data[1] = {((double)-1e+308)} ;
-    size_t d1_startset[1] = {0} ;
-    size_t d1_countset[1] = {1};
-    stat = nc_put_vara(ncid, d1_id, d1_startset, d1_countset, d1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c2_data = "ab" ;
-    size_t c2_startset[1] = {0} ;
-    size_t c2_countset[1] = {2};
-    stat = nc_put_vara(ncid, c2_id, c2_startset, c2_countset, c2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b2_data[2] = {-128, 127} ;
-    size_t b2_startset[1] = {0} ;
-    size_t b2_countset[1] = {2};
-    stat = nc_put_vara(ncid, b2_id, b2_startset, b2_countset, b2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s2_data[2] = {-32768, 32767} ;
-    size_t s2_startset[1] = {0} ;
-    size_t s2_countset[1] = {2};
-    stat = nc_put_vara(ncid, s2_id, s2_startset, s2_countset, s2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i2_data[2] = {-2147483646, 2147483647} ;
-    size_t i2_startset[1] = {0} ;
-    size_t i2_countset[1] = {2};
-    stat = nc_put_vara(ncid, i2_id, i2_startset, i2_countset, i2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f2_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
-    size_t f2_startset[1] = {0} ;
-    size_t f2_countset[1] = {2};
-    stat = nc_put_vara(ncid, f2_id, f2_startset, f2_countset, f2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d2_data[2] = {((double)-1e+308), ((double)1e+308)} ;
-    size_t d2_startset[1] = {0} ;
-    size_t d2_countset[1] = {2};
-    stat = nc_put_vara(ncid, d2_id, d2_startset, d2_countset, d2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c3_data = "\001\177." ;
-    size_t c3_startset[1] = {0} ;
-    size_t c3_countset[1] = {3};
-    stat = nc_put_vara(ncid, c3_id, c3_startset, c3_countset, c3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b3_data[3] = {-128, 127, -1} ;
-    size_t b3_startset[1] = {0} ;
-    size_t b3_countset[1] = {3};
-    stat = nc_put_vara(ncid, b3_id, b3_startset, b3_countset, b3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s3_data[3] = {-32768, 0, 32767} ;
-    size_t s3_startset[1] = {0} ;
-    size_t s3_countset[1] = {3};
-    stat = nc_put_vara(ncid, s3_id, s3_startset, s3_countset, s3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i3_data[3] = {-2147483646, 0, 2147483647} ;
-    size_t i3_startset[1] = {0} ;
-    size_t i3_countset[1] = {3};
-    stat = nc_put_vara(ncid, i3_id, i3_startset, i3_countset, i3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f3_data[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
-    size_t f3_startset[1] = {0} ;
-    size_t f3_countset[1] = {3};
-    stat = nc_put_vara(ncid, f3_id, f3_startset, f3_countset, f3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d3_data[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
-    size_t d3_startset[1] = {0} ;
-    size_t d3_countset[1] = {3};
-    stat = nc_put_vara(ncid, d3_id, d3_startset, d3_countset, d3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr1_data = "xy" ;
-    size_t cr1_startset[2] = {0, 0} ;
-    size_t cr1_countset[2] = {2, 1};
-    stat = nc_put_vara(ncid, cr1_id, cr1_startset, cr1_countset, cr1_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char br2_data[4] = {-24, -26, -20, -22} ;
-    size_t br2_startset[2] = {0, 0} ;
-    size_t br2_countset[2] = {2, 2};
-    stat = nc_put_vara(ncid, br2_id, br2_startset, br2_countset, br2_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr3_data[6] = {-375, -380, -385, -350, -355, -360} ;
-    size_t sr3_startset[2] = {0, 0} ;
-    size_t sr3_countset[2] = {2, 3};
-    stat = nc_put_vara(ncid, sr3_id, sr3_startset, sr3_countset, sr3_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f11_data[1] = {((float)-2187)} ;
-    size_t f11_startset[2] = {0, 0} ;
-    size_t f11_countset[2] = {1, 1};
-    stat = nc_put_vara(ncid, f11_id, f11_startset, f11_countset, f11_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d12_data[2] = {((double)-3000), ((double)-3010)} ;
-    size_t d12_startset[2] = {0, 0} ;
-    size_t d12_countset[2] = {1, 2};
-    stat = nc_put_vara(ncid, d12_id, d12_startset, d12_countset, d12_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c13_data = "\tb\177" ;
-    size_t c13_startset[2] = {0, 0} ;
-    size_t c13_countset[2] = {1, 3};
-    stat = nc_put_vara(ncid, c13_id, c13_startset, c13_countset, c13_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s21_data[2] = {-375, -350} ;
-    size_t s21_startset[2] = {0, 0} ;
-    size_t s21_countset[2] = {2, 1};
-    stat = nc_put_vara(ncid, s21_id, s21_startset, s21_countset, s21_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i22_data[4] = {-24000, -24020, -23600, -23620} ;
-    size_t i22_startset[2] = {0, 0} ;
-    size_t i22_countset[2] = {2, 2};
-    stat = nc_put_vara(ncid, i22_id, i22_startset, i22_countset, i22_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f23_data[6] = {((float)-2187), ((float)-2196), ((float)-2205), ((float)-2106), ((float)-2115), ((float)-2124)} ;
-    size_t f23_startset[2] = {0, 0} ;
-    size_t f23_countset[2] = {2, 3};
-    stat = nc_put_vara(ncid, f23_id, f23_startset, f23_countset, f23_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c31_data = "+- " ;
-    size_t c31_startset[2] = {0, 0} ;
-    size_t c31_countset[2] = {3, 1};
-    stat = nc_put_vara(ncid, c31_id, c31_startset, c31_countset, c31_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b32_data[6] = {-24, -26, -20, -22, -16, -18} ;
-    size_t b32_startset[2] = {0, 0} ;
-    size_t b32_countset[2] = {3, 2};
-    stat = nc_put_vara(ncid, b32_id, b32_startset, b32_countset, b32_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s33_data[9] = {-375, -380, -385, -350, -355, -360, -325, -330, -335} ;
-    size_t s33_startset[2] = {0, 0} ;
-    size_t s33_countset[2] = {3, 3};
-    stat = nc_put_vara(ncid, s33_id, s33_startset, s33_countset, s33_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr11_data[2] = {2500, 2375} ;
-    size_t sr11_startset[3] = {0, 0, 0} ;
-    size_t sr11_countset[3] = {2, 1, 1};
-    stat = nc_put_vara(ncid, sr11_id, sr11_startset, sr11_countset, sr11_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int ir12_data[4] = {640000, 639980, 632000, 631980} ;
-    size_t ir12_startset[3] = {0, 0, 0} ;
-    size_t ir12_countset[3] = {2, 1, 2};
-    stat = nc_put_vara(ncid, ir12_id, ir12_startset, ir12_countset, ir12_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float fr13_data[6] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497)} ;
-    size_t fr13_startset[3] = {0, 0, 0} ;
-    size_t fr13_countset[3] = {2, 1, 3};
-    stat = nc_put_vara(ncid, fr13_id, fr13_startset, fr13_countset, fr13_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr21_data = "@DHL" ;
-    size_t cr21_startset[3] = {0, 0, 0} ;
-    size_t cr21_countset[3] = {2, 2, 1};
-    stat = nc_put_vara(ncid, cr21_id, cr21_startset, cr21_countset, cr21_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char br22_data[8] = {64, 62, 68, 66, 56, 54, 60, 58} ;
-    size_t br22_startset[3] = {0, 0, 0} ;
-    size_t br22_countset[3] = {2, 2, 2};
-    stat = nc_put_vara(ncid, br22_id, br22_startset, br22_countset, br22_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short sr23_data[12] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390} ;
-    size_t sr23_startset[3] = {0, 0, 0} ;
-    size_t sr23_countset[3] = {2, 2, 3};
-    stat = nc_put_vara(ncid, sr23_id, sr23_startset, sr23_countset, sr23_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float fr31_data[6] = {((float)26244), ((float)26325), ((float)26406), ((float)25515), ((float)25596), ((float)25677)} ;
-    size_t fr31_startset[3] = {0, 0, 0} ;
-    size_t fr31_countset[3] = {2, 3, 1};
-    stat = nc_put_vara(ncid, fr31_id, fr31_startset, fr31_countset, fr31_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double dr32_data[12] = {((double)40000), ((double)39990), ((double)40100), ((double)40090), ((double)40200), ((double)40190), ((double)39000), ((double)38990), ((double)39100), ((double)39090), ((double)39200), ((double)39190)} ;
-    size_t dr32_startset[3] = {0, 0, 0} ;
-    size_t dr32_countset[3] = {2, 3, 2};
-    stat = nc_put_vara(ncid, dr32_id, dr32_startset, dr32_countset, dr32_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* cr33_data = "1\000\000two3\000\0004\000\0005\000\000six" ;
-    size_t cr33_startset[3] = {0, 0, 0} ;
-    size_t cr33_countset[3] = {2, 3, 3};
-    stat = nc_put_vara(ncid, cr33_id, cr33_startset, cr33_countset, cr33_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c111_data = "@" ;
-    size_t c111_startset[3] = {0, 0, 0} ;
-    size_t c111_countset[3] = {1, 1, 1};
-    stat = nc_put_vara(ncid, c111_id, c111_startset, c111_countset, c111_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b112_data[2] = {64, 62} ;
-    size_t b112_startset[3] = {0, 0, 0} ;
-    size_t b112_countset[3] = {1, 1, 2};
-    stat = nc_put_vara(ncid, b112_id, b112_startset, b112_countset, b112_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s113_data[3] = {2500, 2495, 2490} ;
-    size_t s113_startset[3] = {0, 0, 0} ;
-    size_t s113_countset[3] = {1, 1, 3};
-    stat = nc_put_vara(ncid, s113_id, s113_startset, s113_countset, s113_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f121_data[2] = {((float)26244), ((float)26325)} ;
-    size_t f121_startset[3] = {0, 0, 0} ;
-    size_t f121_countset[3] = {1, 2, 1};
-    stat = nc_put_vara(ncid, f121_id, f121_startset, f121_countset, f121_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d122_data[4] = {((double)40000), ((double)39990), ((double)40100), ((double)40090)} ;
-    size_t d122_startset[3] = {0, 0, 0} ;
-    size_t d122_countset[3] = {1, 2, 2};
-    stat = nc_put_vara(ncid, d122_id, d122_startset, d122_countset, d122_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c123_data = "one2\000\000" ;
-    size_t c123_startset[3] = {0, 0, 0} ;
-    size_t c123_countset[3] = {1, 2, 3};
-    stat = nc_put_vara(ncid, c123_id, c123_startset, c123_countset, c123_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s131_data[3] = {2500, 2525, 2550} ;
-    size_t s131_startset[3] = {0, 0, 0} ;
-    size_t s131_countset[3] = {1, 3, 1};
-    stat = nc_put_vara(ncid, s131_id, s131_startset, s131_countset, s131_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i132_data[6] = {640000, 639980, 640400, 640380, 640800, 640780} ;
-    size_t i132_startset[3] = {0, 0, 0} ;
-    size_t i132_countset[3] = {1, 3, 2};
-    stat = nc_put_vara(ncid, i132_id, i132_startset, i132_countset, i132_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f133_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)26406), ((float)26397), ((float)26388)} ;
-    size_t f133_startset[3] = {0, 0, 0} ;
-    size_t f133_countset[3] = {1, 3, 3};
-    stat = nc_put_vara(ncid, f133_id, f133_startset, f133_countset, f133_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f211_data[2] = {((float)26244), ((float)25515)} ;
-    size_t f211_startset[3] = {0, 0, 0} ;
-    size_t f211_countset[3] = {2, 1, 1};
-    stat = nc_put_vara(ncid, f211_id, f211_startset, f211_countset, f211_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    double d212_data[4] = {((double)40000), ((double)39990), ((double)39000), ((double)38990)} ;
-    size_t d212_startset[3] = {0, 0, 0} ;
-    size_t d212_countset[3] = {2, 1, 2};
-    stat = nc_put_vara(ncid, d212_id, d212_startset, d212_countset, d212_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c213_data = "\000\000\000\000\000\000" ;
-    size_t c213_startset[3] = {0, 0, 0} ;
-    size_t c213_countset[3] = {2, 1, 3};
-    stat = nc_put_vara(ncid, c213_id, c213_startset, c213_countset, c213_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s221_data[4] = {2500, 2525, 2375, 2400} ;
-    size_t s221_startset[3] = {0, 0, 0} ;
-    size_t s221_countset[3] = {2, 2, 1};
-    stat = nc_put_vara(ncid, s221_id, s221_startset, s221_countset, s221_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i222_data[8] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380} ;
-    size_t i222_startset[3] = {0, 0, 0} ;
-    size_t i222_countset[3] = {2, 2, 2};
-    stat = nc_put_vara(ncid, i222_id, i222_startset, i222_countset, i222_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f223_data[12] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)25515), ((float)25506), ((float)25497), ((float)25596), ((float)25587), ((float)25578)} ;
-    size_t f223_startset[3] = {0, 0, 0} ;
-    size_t f223_countset[3] = {2, 2, 3};
-    stat = nc_put_vara(ncid, f223_id, f223_startset, f223_countset, f223_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    char* c231_data = "@DHHLP" ;
-    size_t c231_startset[3] = {0, 0, 0} ;
-    size_t c231_countset[3] = {2, 3, 1};
-    stat = nc_put_vara(ncid, c231_id, c231_startset, c231_countset, c231_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    signed char b232_data[12] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62} ;
-    size_t b232_startset[3] = {0, 0, 0} ;
-    size_t b232_countset[3] = {2, 3, 2};
-    stat = nc_put_vara(ncid, b232_id, b232_startset, b232_countset, b232_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s233_data[18] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415} ;
-    size_t s233_startset[3] = {0, 0, 0} ;
-    size_t s233_countset[3] = {2, 3, 3};
-    stat = nc_put_vara(ncid, s233_id, s233_startset, s233_countset, s233_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    short s311_data[3] = {2500, 2375, 2250} ;
-    size_t s311_startset[3] = {0, 0, 0} ;
-    size_t s311_countset[3] = {3, 1, 1};
-    stat = nc_put_vara(ncid, s311_id, s311_startset, s311_countset, s311_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    int i312_data[6] = {640000, 639980, 632000, 631980, 624000, 623980} ;
-    size_t i312_startset[3] = {0, 0, 0} ;
-    size_t i312_countset[3] = {3, 1, 2};
-    stat = nc_put_vara(ncid, i312_id, i312_startset, i312_countset, i312_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    float f313_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497), ((float)24786), ((float)24777), ((float)24768)} ;
-    size_t f313_startset[3] = {0, 0, 0} ;
-    size_t f313_countset[3] = {3, 1, 3};
-    stat = nc_put_vara(ncid, f313_id, f313_startset, f313_countset, f313_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_MINUS_name_MINUS_dashes_data[1] = {((double)-1)};
-    stat = nc_put_var1(ncid, var_MINUS_name_MINUS_dashes_id, &count, var_MINUS_name_MINUS_dashes_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_PERIOD_name_PERIOD_dots_data[1] = {((double)-2)};
-    stat = nc_put_var1(ncid, var_PERIOD_name_PERIOD_dots_id, &count, var_PERIOD_name_PERIOD_dots_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_PLUS_name_PLUS_plusses_data[1] = {((double)9.969209968386869e+36)};
-    stat = nc_put_var1(ncid, var_PLUS_name_PLUS_plusses_id, &count, var_PLUS_name_PLUS_plusses_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    {
-    size_t count = 0;
-    static double var_ATSIGN_name_ATSIGN_ats_data[1] = {((double)9.969209968386869e+36)};
-    stat = nc_put_var1(ncid, var_ATSIGN_name_ATSIGN_ats_id, &count, var_ATSIGN_name_ATSIGN_ats_data);
-    check_err(stat,__LINE__,__FILE__);
-    }
-
-
-    stat = nc_close(ncid);
-    check_err(stat,__LINE__,__FILE__);
-    return 0;
-}
diff --git a/ncdump/ctests.sh b/ncdump/ctests.sh
index d19ead7..b07cc82 100755
--- a/ncdump/ctests.sh
+++ b/ncdump/ctests.sh
@@ -172,8 +172,8 @@ fi
 
 set -e
 
-rm -fr results
-mkdir results
+rm -fr results_ctests
+mkdir results_ctests
 
 failcount=0
 passcount=0
@@ -190,7 +190,7 @@ for x in ${TESTSET} ; do
     if test "$x" = "$s" ; then isxfail=1; fi
   done
   ok=0;
-  cd results
+  cd results_ctests
   if ${NCGEN4} -lc -k${KFLAG} ${cdl}/${x}.cdl >${x}.c
     then ok=1; else ok=0; fi
   if $CC ${INCL} -c ${x}.c
@@ -204,7 +204,7 @@ for x in ${TESTSET} ; do
   cd ..
 if test 1 = 1; then
   # compare with expected
-  if diff -b -w ${expected}/${x}.dmp results/${x}.dmp
+  if diff -b -w ${expected}/${x}.dmp results_ctests/${x}.dmp
     then ok=1; else ok=0; fi
   if test "$ok" = "1" ; then
     echo "*** PASS: ${x}"
@@ -221,6 +221,7 @@ done
 
 totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
+rm -fr results_ctests
 
 echo "PASSED: ${okcount}/${totalcount} ; ${xfailcount} expected failures ; ${failcount} unexpected failures"
 
diff --git a/ncdump/dumplib.c b/ncdump/dumplib.c
index 45434d6..863ad7a 100644
--- a/ncdump/dumplib.c
+++ b/ncdump/dumplib.c
@@ -113,62 +113,6 @@ char float_att_fmt[] = "%#.NNgf";
 char float_attx_fmt[] = "%#.NNg";
 char double_att_fmt[] = "%#.NNg";
 
-#ifndef HAVE_STRLCAT
-/*	$OpenBSD: strlcat.c,v 1.12 2005/03/30 20:13:52 otto Exp $	*/
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller at courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left).  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
-	char *d = dst;
-	const char *s = src;
-	size_t n = siz;
-	size_t dlen;
-
-	/* Find the end of dst and adjust bytes left but don't go past end */
-	while (n-- != 0 && *d != '\0')
-		d++;
-	dlen = d - dst;
-	n = siz - dlen;
-
-	if (n == 0)
-		return(dlen + strlen(s));
-	while (*s != '\0') {
-		if (n != 1) {
-			*d++ = *s;
-			n--;
-		}
-		s++;
-	}
-	*d = '\0';
-
-	return(dlen + (s - src));	/* count does not include NUL */
-}
-#endif /* ! HAVE_STRLCAT */
-
-
 /* magic number stored in a safebuf and checked, hoping it will be
  * changed if buffer was overwritten inadvertently */
 #define SAFEBUF_CERT 2147114711
diff --git a/ncdump/dumplib.h b/ncdump/dumplib.h
index be6e720..2ce26ea 100644
--- a/ncdump/dumplib.h
+++ b/ncdump/dumplib.h
@@ -50,11 +50,6 @@ extern char double_att_fmt[];
 extern "C" {
 #endif
 
-#ifndef HAVE_STRLCAT
-/* Append src to dst of size siz */
-extern size_t strlcat(char *dst, const char *src, size_t siz);
-#endif /* ! HAVE_STRLCAT */
-
 /* In case different formats specified with -d option, set them here. */
 extern void	set_formats ( int flt_digs, int dbl_digs );
 
diff --git a/ncdump/expected/Makefile.in b/ncdump/expected/Makefile.in
index 38bae1b..f71db2c 100644
--- a/ncdump/expected/Makefile.in
+++ b/ncdump/expected/Makefile.in
@@ -135,7 +135,6 @@ AM_CPPFLAGS = @AM_CPPFLAGS@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -158,12 +157,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -189,6 +190,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -203,6 +205,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
diff --git a/ncdump/indent.h b/ncdump/indent.h
index d69c3ad..15b8981 100644
--- a/ncdump/indent.h
+++ b/ncdump/indent.h
@@ -1,8 +1,10 @@
 /*********************************************************************
  *   Copyright 2007, UCAR/Unidata
  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
- *   $Header: /upc/share/CVS/netcdf-3/ncdump/indent.h,v 1.1 2007/05/20 20:42:30 russ Exp $
+ *   Russ Rew
  *********************************************************************/
+#ifndef _INDENT_H
+#define _INDENT_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -18,3 +20,5 @@ extern int  indent_get();	/* return current indent */
 #ifdef __cplusplus
 }
 #endif
+
+#endif /* _INDENT_H */
diff --git a/ncdump/isnan.h b/ncdump/isnan.h
index 3d7f50e..c62f801 100644
--- a/ncdump/isnan.h
+++ b/ncdump/isnan.h
@@ -1,8 +1,10 @@
 /*********************************************************************
  *   Copyright 2008, University Corporation for Atmospheric Research
  *   See netcdf/README file for copying and redistribution conditions.
- *   $Id: isnan.h,v 1.3 2008/04/23 22:05:00 russ Exp $
+ *   Russ Rew
  *********************************************************************/
+#ifndef _ISNAN_H
+#define _ISNAN_H
 
 #include "config.h"
 
@@ -20,3 +22,5 @@
 #if ! (defined(isfinite) || HAVE_DECL_ISFINITE)
 #define isfinite(x) (!(isinf(x)||isnan(x)))
 #endif /* !HAVE_DECL_ISFINITE */
+
+#endif /* _ISNAN_H */
diff --git a/ncdump/nccopy.1 b/ncdump/nccopy.1
index 7a462a5..7838093 100644
--- a/ncdump/nccopy.1
+++ b/ncdump/nccopy.1
@@ -20,6 +20,7 @@ nccopy
 \%[\-h \fI chunk_cache \fP]
 \%[\-e \fI cache_elems \fP]
 \%[\-r]
+\%[\-F \fI filterspec \fP]
 \%\fI infile \fP
 \%\fI outfile \fP
 .hy
@@ -251,6 +252,30 @@ Read netCDF classic or 64-bit offset input file into a diskless netCDF
 file in memory before copying.  Requires that input file be small
 enough to fit into memory.  For \fBnccopy\fP, this doesn't seem to provide
 any significant speedup, so may not be a useful option.
+.IP "\fB \-F \fP \fIfilterspec\fP"
+For netCDF-4 output, including netCDF-4 classic model, specify a filter
+to apply to an specified variable in the output. As a rule, the filter
+is a compression/decompression algorithm with a unique numeric identifier
+assigned by the HDF Group (see https://support.hdfgroup.org/services/filters.html).
+.IP
+The \fIfilterspec\fP argument has this general form.
+.RS
+fqn,filterid,param1,param2...paramn
+.RE
+The fqn (fully qualified name) is the name
+of a variable prefixed by its containing
+groups with the group names separated by forward slash ('/').
+An example might be \FI/g1/g2/var\fP. Alternatively,
+just the variable name can be given if it is in the root group:
+e.g. \FIvar\fP. Backslash escapes may be used as needed.
+The filterid is an unsigned positive integer representing the id
+assigned by the HDFgroup to the filter. Following the id is a sequence of
+parameters defining the operation of the filter. Each parameter
+is a 32-bit unsigned integer.
+.IP
+This parameter may be repeated multiple times with different
+variable names.
+
 .SH EXAMPLES
 .LP
 Make a copy of foo1.nc, a netCDF file of any type, to foo2.nc, a
diff --git a/ncdump/nccopy.c b/ncdump/nccopy.c
index 7d1aef2..2e50389 100644
--- a/ncdump/nccopy.c
+++ b/ncdump/nccopy.c
@@ -8,6 +8,7 @@
 
 #include "config.h"		/* for USE_NETCDF4 macro */
 #include <stdlib.h>
+#include <stdio.h>
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #endif
@@ -15,12 +16,15 @@
 #include <unistd.h>
 #endif
 #include <string.h>
-#include <netcdf.h>
+#include "netcdf.h"
 #include "nciter.h"
 #include "utils.h"
 #include "chunkspec.h"
 #include "dimmap.h"
 #include "nccomps.h"
+#include "ncfilter.h"
+
+#undef DEBUGFILTER
 
 #ifdef _MSC_VER
 #include "XGetopt.h"
@@ -40,6 +44,33 @@ int optind;
 #define NC_CLASSIC_MODEL 0x0100 /* Enforce classic model if netCDF-4 not available. */
 #endif
 
+/* Ascii characters requiring escaping as lead*/
+#define ESCAPESD "0123456789"
+#define ESCAPES " !\"#$%&'()*,:;<=>?[]\\^`{|}~"
+
+#ifdef USE_NETCDF4
+
+/* The unique id for a variable requires also the enclosing group id */
+typedef struct VarID {
+    int grpid;
+    int varid;
+} VarID;
+
+#define MAX_FILTER_SPECS 64
+#define MAX_FILTER_PARAMS 256
+
+struct FilterSpec {
+    char* fqn;
+    unsigned int filterid;
+    size_t nparams;
+    unsigned int* params;
+};
+
+static int nfilterspecs = 0; /* Number of defined filter specs */
+static struct FilterSpec filterspecs[MAX_FILTER_SPECS];
+
+#endif
+
 /* Global variables for command-line requests */
 char *progname;	       /* for error messages */
 static int option_kind = SAME_AS_INPUT;
@@ -127,6 +158,123 @@ nc_inq_parid(int ncid, const char *fullname, int *locidp) {
     return NC_NOERR;
 }
 
+/* Compute the fully qualified name of a  (grpid,varid) pair; caller must free */
+static int
+computeFQN(VarID vid, char** fqnp)
+{
+    int stat = NC_NOERR;
+    size_t len;
+    char* fqn = NULL;
+    char vname[NC_MAX_NAME+1];
+    char escname[(2*NC_MAX_NAME)+1];
+    int first;
+    char *p, *q;
+
+    if((stat = nc_inq_grpname_full(vid.grpid,&len,NULL))) goto done;
+    fqn = (char*)malloc(len+1+(2*NC_MAX_NAME)+1);
+    if(fqn == NULL) {stat = NC_ENOMEM; goto done;}
+    if((stat=nc_inq_grpname_full(vid.grpid,&len,fqn))) goto done;
+    fqn[len] = '\0'; /* guarantee */
+    if((stat=nc_inq_varname(vid.grpid,vid.varid,vname))) goto done;
+    vname[NC_MAX_NAME] = '\0';
+    if(strlen(fqn) > 1) strcat(fqn,"/");
+    p = vname;
+    q = escname;
+    for(first=1;*p;first=0) {
+	if((first && strchr(ESCAPESD,*p) != NULL)
+           || strchr(ESCAPES,*p) != NULL) *q++ = '\\';
+	*q++ = *p++;
+    }
+    *q++ = '\0'; /* guarantee */
+    strcat(fqn,escname);
+done:
+    if(stat == NC_NOERR && fqnp != NULL) *fqnp = fqn;
+    return stat;
+}
+
+#if 0
+static int
+parseFQN(int ncid, const char* fqn0, VarID* idp)
+{
+    int stat = NC_NOERR;
+    char* fqn;
+    VarID vid;
+    char* p;
+    char* q;
+    char* segment;
+
+    vid.grpid = ncid;
+    if(fqn0 == NULL || fqn0[1] != '/')
+	{stat = NC_EBADNAME; goto done;}
+    fqn = strdup(fqn0+1); /* skip leading '/'*/
+    p = fqn;
+    for(;;) {
+	int newgrp;
+	segment = p;
+	q = p;
+        while(*p != '\0' && *p != '/') {
+	    if(*p == '\\') p++;
+	    *q++ = *p++;
+	}
+        if(*p == '\0') break;
+	*p++ = '\0';
+	if((stat=nc_inq_grp_ncid(vid.grpid,segment,&newgrp))) goto done;
+	vid.grpid = newgrp;
+    }
+    /* Segment should point to the varname */
+    if((stat=nc_inq_varid(vid.grpid,segment,&vid.varid))) goto done;
+done:
+    if(fqn) free(fqn);
+    if(stat == NC_NOERR && idp != NULL) *idp = vid;
+    return stat;
+}
+#endif
+
+static int
+parsefilterspec(const char* optarg0, struct FilterSpec* spec)
+{
+    int stat = NC_NOERR;
+    char* optarg = NULL;
+    unsigned int* params = NULL;
+    size_t nparams;
+    unsigned int id;
+    char* p = NULL;
+    char* remainder = NULL;
+
+    if(optarg0 == NULL || strlen(optarg0) == 0 || spec == NULL) return 0;
+    optarg = strdup(optarg0);
+
+    /* Collect the fqn, taking escapes into account */
+    p = optarg;
+    remainder = NULL;
+    for(;*p;p++) {
+	if(*p == '\\') p++;
+	else if(*p == ',') {*p = '\0'; remainder = p+1; break;}
+	else if(*p == '\0') {remainder = p; break;}
+	/* else continue */
+    }
+    if(strlen(optarg) == 0) return 0; /* fqn does not exist */
+    /* Make sure leading '/' is in place */
+    if(optarg[0]=='/')
+	spec->fqn = strdup(optarg);
+    else {
+        spec->fqn = (char*)malloc(1+strlen(optarg)+1);
+	strcpy(spec->fqn,"/");
+        strcat(spec->fqn,optarg);
+    }
+
+    /* Collect the id+parameters */
+    if((stat = NC_parsefilterspec(remainder,&id,&nparams,&params)) == NC_NOERR) {
+        if(spec != NULL) {
+            spec->filterid = id;
+            spec->nparams = nparams;
+            spec->params = params;
+	}
+    }
+    return stat;
+}
+
+
 /* Return size of chunk in bytes for a variable varid in a group igrp, or 0 if
  * layout is contiguous */
 static int
@@ -567,6 +715,66 @@ copy_var_specials(int igrp, int varid, int ogrp, int o_varid)
     return stat;
 }
 
+/* Copy netCDF-4 specific variable filter properties */
+/* Watch out if input is netcdf-3 */
+static int
+copy_var_filter(int igrp, int varid, int ogrp, int o_varid)
+{
+    int stat = NC_NOERR;
+#ifdef USE_NETCDF4
+    VarID vid = {igrp,varid};
+    VarID ovid = {ogrp,o_varid};
+    /* handle filter parameters, copying from input, overriding with command-line options */
+    struct FilterSpec spec;
+    int i, found;
+    char* ofqn = NULL;
+    int format, oformat;
+
+    /* Get file format of the input and output */
+    if((stat=nc_inq_format(vid.grpid,&format))) goto done;
+    if((stat=nc_inq_format(ovid.grpid,&oformat))) goto done;
+
+    if(oformat != NC_FORMAT_NETCDF4 && oformat != NC_FORMAT_NETCDF4_CLASSIC)
+	goto done; /* Can only use filter when output is netcdf4 */
+
+    /* Compute the output vid's FQN */
+    if((stat = computeFQN(ovid,&ofqn))) goto done;
+    /* See if any filter spec is defined for this output variable */
+    for(found=0,i=0;i<nfilterspecs;i++) {
+	if(strcmp(filterspecs[i].fqn,ofqn)==0) {spec = filterspecs[i]; found = 1; break;}
+    }
+    if(!found) {
+	spec.filterid = 0; /* marker to indicate not filter to apply */
+	if((oformat == NC_FORMAT_NETCDF4
+            || oformat != NC_FORMAT_NETCDF4_CLASSIC)
+	   && (format == NC_FORMAT_NETCDF4
+               || format != NC_FORMAT_NETCDF4_CLASSIC)
+	) {
+	    /* Only bother to look if both input and  output are netcdf-4 */
+	    if((stat=nc_inq_var_filter(vid.grpid,vid.varid,&spec.filterid,&spec.nparams,NULL)))
+	        goto done;
+	    if(spec.filterid > 0) {/* input has a filter */
+  	        spec.params = (unsigned int*)malloc(sizeof(unsigned int)*spec.nparams);
+	        if((stat=nc_inq_var_filter(vid.grpid,vid.varid,&spec.filterid,&spec.nparams,spec.params)))
+		    goto done;
+	    }
+	}
+    }
+    /* Apply filter spec if any */
+    if(spec.filterid > 0) {/* Apply filter */
+#ifdef USE_NETCDF4
+	if((stat=nc_def_var_filter(ovid.grpid,ovid.varid,spec.filterid,spec.nparams,spec.params)))
+	        goto done;
+#endif
+    }
+done:
+    /* Cleanup */
+    if(spec.filterid > 0 && spec.nparams > 0 && spec.params != NULL)
+	free(spec.params);
+#endif /*USE_NETCDF4*/
+    return stat;
+}
+
 /* Set output variable o_varid (in group ogrp) to use chunking
  * specified on command line, only called for classic format input and
  * netCDF-4 format output, so no existing chunk lengths to override. */
@@ -849,6 +1057,7 @@ copy_var(int igrp, int varid, int ogrp)
 		/* Set compression if specified in command line option */
 		NC_CHECK(set_var_compressed(ogrp, o_varid));
 	    }
+	    NC_CHECK(copy_var_filter(igrp, varid, ogrp, o_varid));
 	}
     }
 #endif	/* USE_NETCDF4 */
@@ -1560,6 +1769,8 @@ usage(void)
   [-h n]    set size in bytes of chunk_cache for chunked variables\n\
   [-e n]    set number of elements that chunk_cache can hold\n\
   [-r]      read whole input file into diskless file on open (classic or 64-bit offset or cdf5 formats only)\n\
+  [-F filterspec] specify the compression algorithm to apply to an output variable.\n\
+  [-Ln]     set log level to n (>= 0); ignored if logging isn't enabled.\n\
   infile    name of netCDF input file\n\
   outfile   name for netCDF output file\n"
 
@@ -1576,6 +1787,9 @@ main(int argc, char**argv)
     char* inputfile = NULL;
     char* outputfile = NULL;
     int c;
+#ifdef USE_NETCDF4
+    struct FilterSpec filterspec;
+#endif
 
 /* table of formats for legal -k values */
     struct Kvalues {
@@ -1630,7 +1844,7 @@ main(int argc, char**argv)
        usage();
     }
 
-    while ((c = getopt(argc, argv, "k:3467d:sum:c:h:e:rwxg:G:v:V:")) != -1) {
+    while ((c = getopt(argc, argv, "k:3467d:sum:c:h:e:rwxg:G:v:V:F:L:")) != -1) {
 	switch(c) {
         case 'k': /* for specifying variant of netCDF format to be generated
                      Format names:
@@ -1745,6 +1959,29 @@ main(int argc, char**argv)
 	    make_lvars (optarg, &option_nlvars, &option_lvars);
 	    option_varstruct = false;
 	    break;
+    case 'L': /* Set logging, if logging support was compiled in. */
+#ifdef LOGGING
+      {
+        int level = atoi(optarg);
+        if(level >= 0)
+          nc_set_log_level(level);
+      }
+#endif
+      break;
+	case 'F': /* optional filter spec for a specified variable */
+#ifdef USE_NETCDF4
+	    if(parsefilterspec(optarg,&filterspec) != NC_NOERR)
+		usage();
+	    if(nfilterspecs >= (MAX_FILTER_SPECS-1))
+		error("too many -F filterspecs\n");
+	    filterspecs[nfilterspecs] = filterspec;
+	    nfilterspecs++;
+	    // Force output to be netcdf-4
+	    option_kind = NC_FORMAT_NETCDF4;
+#else
+	    error("-F requires netcdf-4");
+#endif
+	    break;
 	default:
 	    usage();
         }
@@ -1762,8 +1999,25 @@ main(int argc, char**argv)
 	error("output would overwrite input");
     }
 
+#ifdef USE_NETCDF4
+#ifdef DEBUGFILTER
+    { int i,j;
+        for(i=0;i<nfilterspecs;i++) {
+	    struct FilterSpec *spec = &filterspecs[i];
+	    fprintf(stderr,"filterspecs[%d]={fqn=|%s| filterid=%u nparams=%ld params=",
+		i,spec->fqn,spec->filterid,(unsigned long)spec->nparams);
+	    for(j=0;j<spec->nparams;j++) {
+		if(j>0) fprintf(stderr,",");
+		fprintf(stderr,"%u",spec->params[j]);
+	    }
+	    fprintf(stderr,"}\n");
+	    fflush(stderr);
+	}
+    }
+#endif /*DEBUGFILTER*/
+#endif /*USE_NETCDF4*/
+
     if(copy(inputfile, outputfile) != NC_NOERR)
         exit(EXIT_FAILURE);
     exit(EXIT_SUCCESS);
 }
-END_OF_MAIN()
diff --git a/ncdump/ncdump.c b/ncdump/ncdump.c
index bbaba37..492cf6c 100644
--- a/ncdump/ncdump.c
+++ b/ncdump/ncdump.c
@@ -34,8 +34,8 @@ int optind;
 #include <locale.h>
 #endif	/* HAVE_LOCALE_H */
 
-#include "netcdf_mem.h"
 #include "netcdf.h"
+#include "netcdf_mem.h"
 #include "utils.h"
 #include "nccomps.h"
 #include "nctime0.h"		/* new iso time and calendar stuff */
@@ -273,7 +273,7 @@ kind_string(int kind)
     case NC_FORMAT_NETCDF4_CLASSIC:
 	return "netCDF-4 classic model";
     default:
-	error("unrecognized file format: %d");
+       error("unrecognized file format: %d", kind);
 	return "unrecognized";
     }
 }
@@ -1052,6 +1052,27 @@ pr_att_specials(
 	    printf(" ;\n");
 	}
     }
+    /* _Filter */
+    {
+	unsigned int id;
+	size_t nparams;
+	unsigned int* params = NULL;
+	if(nc_inq_var_filter(ncid, varid, &id, &nparams, NULL) == NC_NOERR
+	   && id > 0) {
+	    if(nparams > 0) {
+	        params = (unsigned int*)calloc(1,sizeof(unsigned int)*nparams);
+	        NC_CHECK(nc_inq_var_filter(ncid, varid, &id, &nparams, params));
+	    }
+	    pr_att_name(ncid,varp->name,NC_ATT_FILTER);
+	    printf(" = \"%u",id);
+	    if(nparams > 0) {
+	        int i;
+		for(i=0;i<nparams;i++)	
+		    printf(",%u",params[i]);
+	    }
+	    printf("\" ;\n");
+	}
+    }
     {
 	int no_fill = 0;
 	/* Don't get the fill_value, it's set explicitly with
@@ -2336,6 +2357,3 @@ main(int argc, char *argv[])
     }
     exit(EXIT_SUCCESS);
 }
-
-
-END_OF_MAIN()
diff --git a/ncdump/nctime0.h b/ncdump/nctime0.h
index a59b921..c3558e2 100644
--- a/ncdump/nctime0.h
+++ b/ncdump/nctime0.h
@@ -1,8 +1,10 @@
 /*********************************************************************
  *   Copyright 2008, University Corporation for Atmospheric Research
  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
- *   $Id: nctime.h,v 1.6 2010/03/18 19:24:26 russ Exp $
+ *   Russ Rew
  *********************************************************************/
+#ifndef _NCTIME0_H
+#define _NCTIME0_H
 
 #include "nctime.h"
 
@@ -12,3 +14,6 @@ extern int is_valid_time_unit(const char *units);
 extern int is_bounds_att(ncatt_t *attp);
 extern void get_timeinfo(int ncid, int varid, ncvar_t *vp);
 extern void print_att_times(int ncid, int varid, const ncatt_t *att);
+
+#endif /* _NCTIME0_H */
+
diff --git a/ncdump/nctrunc.c b/ncdump/nctrunc.c
index b47011a..b64c163 100644
--- a/ncdump/nctrunc.c
+++ b/ncdump/nctrunc.c
@@ -12,7 +12,6 @@
 int
 main(int argc, char** argv)
 {
-    long pos = 0;
     unsigned char buffer[BUFLEN];
     size_t count, red, avail, trunc;
     unsigned char* p = buffer;
diff --git a/ncdump/ocprint.c b/ncdump/ocprint.c
index abbb41e..9bf5cc3 100644
--- a/ncdump/ocprint.c
+++ b/ncdump/ocprint.c
@@ -340,9 +340,6 @@ main(int argc, char **argv)
     }
 
     if(ocopt.rcfile != NULL) {
-        if(strlen(ocopt.rcfile) == 0 || strcmp(NORC,ocopt.rcfile)==0)
-	    {free(ocopt.rcfile); ocopt.rcfile = NULL;}
-	oc_set_rcfile(ocopt.rcfile);
     }
 
     if (ocopt.debug.verbose)
diff --git a/ncdump/ref_ctest.c b/ncdump/ref_ctest.c
index 6077b13..d9b487c 100644
--- a/ncdump/ref_ctest.c
+++ b/ncdump/ref_ctest.c
@@ -2,1332 +2,1471 @@
 #include <stdlib.h>
 #include <netcdf.h>
 
+
 void
 check_err(const int stat, const int line, const char *file) {
     if (stat != NC_NOERR) {
-	   (void) fprintf(stderr, "ZZZ: line %d of %s: %s\n", line, file, nc_strerror(stat));
+        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
+        fflush(stderr);
         exit(1);
     }
 }
 
 int
-main() {			/* create ctest0.nc */
-
-   int  stat;			/* return status */
-   int  ncid;			/* netCDF id */
-
-   /* dimension ids */
-   int Dr_dim;
-   int D1_dim;
-   int D2_dim;
-   int D3_dim;
-   int dim_MINUS_name_MINUS_dashes_dim;
-   int dim_PERIOD_name_PERIOD_dots_dim;
-   int dim_PLUS_name_PLUS_plusses_dim;
-   int dim_ATSIGN_name_ATSIGN_ats_dim;
-
-   /* dimension lengths */
-   size_t Dr_len = NC_UNLIMITED;
-   size_t D1_len = 1;
-   size_t D2_len = 2;
-   size_t D3_len = 3;
-   size_t dim_MINUS_name_MINUS_dashes_len = 4;
-   size_t dim_PERIOD_name_PERIOD_dots_len = 5;
-   size_t dim_PLUS_name_PLUS_plusses_len = 6;
-   size_t dim_ATSIGN_name_ATSIGN_ats_len = 7;
-
-   /* variable ids */
-   int c_id;
-   int b_id;
-   int s_id;
-   int i_id;
-   int f_id;
-   int d_id;
-   int cr_id;
-   int br_id;
-   int sr_id;
-   int ir_id;
-   int fr_id;
-   int dr_id;
-   int c1_id;
-   int b1_id;
-   int s1_id;
-   int i1_id;
-   int f1_id;
-   int d1_id;
-   int c2_id;
-   int b2_id;
-   int s2_id;
-   int i2_id;
-   int f2_id;
-   int d2_id;
-   int c3_id;
-   int b3_id;
-   int s3_id;
-   int i3_id;
-   int f3_id;
-   int d3_id;
-   int cr1_id;
-   int br2_id;
-   int sr3_id;
-   int f11_id;
-   int d12_id;
-   int c13_id;
-   int s21_id;
-   int i22_id;
-   int f23_id;
-   int c31_id;
-   int b32_id;
-   int s33_id;
-   int sr11_id;
-   int ir12_id;
-   int fr13_id;
-   int cr21_id;
-   int br22_id;
-   int sr23_id;
-   int fr31_id;
-   int dr32_id;
-   int cr33_id;
-   int c111_id;
-   int b112_id;
-   int s113_id;
-   int f121_id;
-   int d122_id;
-   int c123_id;
-   int s131_id;
-   int i132_id;
-   int f133_id;
-   int f211_id;
-   int d212_id;
-   int c213_id;
-   int s221_id;
-   int i222_id;
-   int f223_id;
-   int c231_id;
-   int b232_id;
-   int s233_id;
-   int s311_id;
-   int i312_id;
-   int f313_id;
-   int var_MINUS_name_MINUS_dashes_id;
-   int var_PERIOD_name_PERIOD_dots_id;
-   int var_PLUS_name_PLUS_plusses_id;
-   int var_ATSIGN_name_ATSIGN_ats_id;
-
-   /* rank (number of dimensions) for each variable */
-#  define RANK_c 0
-#  define RANK_b 0
-#  define RANK_s 0
-#  define RANK_i 0
-#  define RANK_f 0
-#  define RANK_d 0
-#  define RANK_cr 1
-#  define RANK_br 1
-#  define RANK_sr 1
-#  define RANK_ir 1
-#  define RANK_fr 1
-#  define RANK_dr 1
-#  define RANK_c1 1
-#  define RANK_b1 1
-#  define RANK_s1 1
-#  define RANK_i1 1
-#  define RANK_f1 1
-#  define RANK_d1 1
-#  define RANK_c2 1
-#  define RANK_b2 1
-#  define RANK_s2 1
-#  define RANK_i2 1
-#  define RANK_f2 1
-#  define RANK_d2 1
-#  define RANK_c3 1
-#  define RANK_b3 1
-#  define RANK_s3 1
-#  define RANK_i3 1
-#  define RANK_f3 1
-#  define RANK_d3 1
-#  define RANK_cr1 2
-#  define RANK_br2 2
-#  define RANK_sr3 2
-#  define RANK_f11 2
-#  define RANK_d12 2
-#  define RANK_c13 2
-#  define RANK_s21 2
-#  define RANK_i22 2
-#  define RANK_f23 2
-#  define RANK_c31 2
-#  define RANK_b32 2
-#  define RANK_s33 2
-#  define RANK_sr11 3
-#  define RANK_ir12 3
-#  define RANK_fr13 3
-#  define RANK_cr21 3
-#  define RANK_br22 3
-#  define RANK_sr23 3
-#  define RANK_fr31 3
-#  define RANK_dr32 3
-#  define RANK_cr33 3
-#  define RANK_c111 3
-#  define RANK_b112 3
-#  define RANK_s113 3
-#  define RANK_f121 3
-#  define RANK_d122 3
-#  define RANK_c123 3
-#  define RANK_s131 3
-#  define RANK_i132 3
-#  define RANK_f133 3
-#  define RANK_f211 3
-#  define RANK_d212 3
-#  define RANK_c213 3
-#  define RANK_s221 3
-#  define RANK_i222 3
-#  define RANK_f223 3
-#  define RANK_c231 3
-#  define RANK_b232 3
-#  define RANK_s233 3
-#  define RANK_s311 3
-#  define RANK_i312 3
-#  define RANK_f313 3
-#  define RANK_var_MINUS_name_MINUS_dashes 0
-#  define RANK_var_PERIOD_name_PERIOD_dots 0
-#  define RANK_var_PLUS_name_PLUS_plusses 0
-#  define RANK_var_ATSIGN_name_ATSIGN_ats 0
-
-   /* variable shapes */
-   int cr_dims[RANK_cr];
-   int br_dims[RANK_br];
-   int sr_dims[RANK_sr];
-   int ir_dims[RANK_ir];
-   int fr_dims[RANK_fr];
-   int dr_dims[RANK_dr];
-   int c1_dims[RANK_c1];
-   int b1_dims[RANK_b1];
-   int s1_dims[RANK_s1];
-   int i1_dims[RANK_i1];
-   int f1_dims[RANK_f1];
-   int d1_dims[RANK_d1];
-   int c2_dims[RANK_c2];
-   int b2_dims[RANK_b2];
-   int s2_dims[RANK_s2];
-   int i2_dims[RANK_i2];
-   int f2_dims[RANK_f2];
-   int d2_dims[RANK_d2];
-   int c3_dims[RANK_c3];
-   int b3_dims[RANK_b3];
-   int s3_dims[RANK_s3];
-   int i3_dims[RANK_i3];
-   int f3_dims[RANK_f3];
-   int d3_dims[RANK_d3];
-   int cr1_dims[RANK_cr1];
-   int br2_dims[RANK_br2];
-   int sr3_dims[RANK_sr3];
-   int f11_dims[RANK_f11];
-   int d12_dims[RANK_d12];
-   int c13_dims[RANK_c13];
-   int s21_dims[RANK_s21];
-   int i22_dims[RANK_i22];
-   int f23_dims[RANK_f23];
-   int c31_dims[RANK_c31];
-   int b32_dims[RANK_b32];
-   int s33_dims[RANK_s33];
-   int sr11_dims[RANK_sr11];
-   int ir12_dims[RANK_ir12];
-   int fr13_dims[RANK_fr13];
-   int cr21_dims[RANK_cr21];
-   int br22_dims[RANK_br22];
-   int sr23_dims[RANK_sr23];
-   int fr31_dims[RANK_fr31];
-   int dr32_dims[RANK_dr32];
-   int cr33_dims[RANK_cr33];
-   int c111_dims[RANK_c111];
-   int b112_dims[RANK_b112];
-   int s113_dims[RANK_s113];
-   int f121_dims[RANK_f121];
-   int d122_dims[RANK_d122];
-   int c123_dims[RANK_c123];
-   int s131_dims[RANK_s131];
-   int i132_dims[RANK_i132];
-   int f133_dims[RANK_f133];
-   int f211_dims[RANK_f211];
-   int d212_dims[RANK_d212];
-   int c213_dims[RANK_c213];
-   int s221_dims[RANK_s221];
-   int i222_dims[RANK_i222];
-   int f223_dims[RANK_f223];
-   int c231_dims[RANK_c231];
-   int b232_dims[RANK_b232];
-   int s233_dims[RANK_s233];
-   int s311_dims[RANK_s311];
-   int i312_dims[RANK_i312];
-   int f313_dims[RANK_f313];
-
-   /* attribute vectors */
-   int c_att_MINUS_name_MINUS_dashes[1];
-   int c_att_PERIOD_name_PERIOD_dots[1];
-   int c_att_PLUS_name_PLUS_plusses[1];
-   int c_att_ATSIGN_name_ATSIGN_ats[1];
-   int s_b[4];
-   short s_s[3];
-   int i_i[3];
-   float i_f[3];
-   double i_d[3];
-   int cdf_Gb[2];
-   short cdf_Gs[3];
-   int cdf_Gi[3];
-   float cdf_Gf[3];
-   double cdf_Gd[3];
-   int cdf_Gatt_MINUS_name_MINUS_dashes[1];
-   int cdf_Gatt_PERIOD_name_PERIOD_dots[1];
-   int cdf_Gatt_PLUS_name_PLUS_plusses[1];
-   int cdf_Gatt_ATSIGN_name_ATSIGN_ats[1];
-
-   /* enter define mode */
-   stat = nc_create("ctest0.nc", NC_CLOBBER, &ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define dimensions */
-   stat = nc_def_dim(ncid, "Dr", Dr_len, &Dr_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "D1", D1_len, &D1_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "D2", D2_len, &D2_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "D3", D3_len, &D3_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim-name-dashes", dim_MINUS_name_MINUS_dashes_len, &dim_MINUS_name_MINUS_dashes_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim.name.dots", dim_PERIOD_name_PERIOD_dots_len, &dim_PERIOD_name_PERIOD_dots_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim+name+plusses", dim_PLUS_name_PLUS_plusses_len, &dim_PLUS_name_PLUS_plusses_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim at name@ats", dim_ATSIGN_name_ATSIGN_ats_len, &dim_ATSIGN_name_ATSIGN_ats_dim);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define variables */
-
-   stat = nc_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   br_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   ir_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   fr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   dr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr1_dims[0] = Dr_dim;
-   cr1_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   br2_dims[0] = Dr_dim;
-   br2_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr3_dims[0] = Dr_dim;
-   sr3_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f11_dims[0] = D1_dim;
-   f11_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d12_dims[0] = D1_dim;
-   d12_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c13_dims[0] = D1_dim;
-   c13_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s21_dims[0] = D2_dim;
-   s21_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i22_dims[0] = D2_dim;
-   i22_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f23_dims[0] = D2_dim;
-   f23_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c31_dims[0] = D3_dim;
-   c31_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b32_dims[0] = D3_dim;
-   b32_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s33_dims[0] = D3_dim;
-   s33_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr11_dims[0] = Dr_dim;
-   sr11_dims[1] = D1_dim;
-   sr11_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   ir12_dims[0] = Dr_dim;
-   ir12_dims[1] = D1_dim;
-   ir12_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   fr13_dims[0] = Dr_dim;
-   fr13_dims[1] = D1_dim;
-   fr13_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr21_dims[0] = Dr_dim;
-   cr21_dims[1] = D2_dim;
-   cr21_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   br22_dims[0] = Dr_dim;
-   br22_dims[1] = D2_dim;
-   br22_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr23_dims[0] = Dr_dim;
-   sr23_dims[1] = D2_dim;
-   sr23_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   fr31_dims[0] = Dr_dim;
-   fr31_dims[1] = D3_dim;
-   fr31_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   dr32_dims[0] = Dr_dim;
-   dr32_dims[1] = D3_dim;
-   dr32_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr33_dims[0] = Dr_dim;
-   cr33_dims[1] = D3_dim;
-   cr33_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c111_dims[0] = D1_dim;
-   c111_dims[1] = D1_dim;
-   c111_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b112_dims[0] = D1_dim;
-   b112_dims[1] = D1_dim;
-   b112_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s113_dims[0] = D1_dim;
-   s113_dims[1] = D1_dim;
-   s113_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f121_dims[0] = D1_dim;
-   f121_dims[1] = D2_dim;
-   f121_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d122_dims[0] = D1_dim;
-   d122_dims[1] = D2_dim;
-   d122_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c123_dims[0] = D1_dim;
-   c123_dims[1] = D2_dim;
-   c123_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s131_dims[0] = D1_dim;
-   s131_dims[1] = D3_dim;
-   s131_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i132_dims[0] = D1_dim;
-   i132_dims[1] = D3_dim;
-   i132_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f133_dims[0] = D1_dim;
-   f133_dims[1] = D3_dim;
-   f133_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f211_dims[0] = D2_dim;
-   f211_dims[1] = D1_dim;
-   f211_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d212_dims[0] = D2_dim;
-   d212_dims[1] = D1_dim;
-   d212_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c213_dims[0] = D2_dim;
-   c213_dims[1] = D1_dim;
-   c213_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s221_dims[0] = D2_dim;
-   s221_dims[1] = D2_dim;
-   s221_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i222_dims[0] = D2_dim;
-   i222_dims[1] = D2_dim;
-   i222_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f223_dims[0] = D2_dim;
-   f223_dims[1] = D2_dim;
-   f223_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c231_dims[0] = D2_dim;
-   c231_dims[1] = D3_dim;
-   c231_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b232_dims[0] = D2_dim;
-   b232_dims[1] = D3_dim;
-   b232_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s233_dims[0] = D2_dim;
-   s233_dims[1] = D3_dim;
-   s233_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s311_dims[0] = D3_dim;
-   s311_dims[1] = D1_dim;
-   s311_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i312_dims[0] = D3_dim;
-   i312_dims[1] = D1_dim;
-   i312_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f313_dims[0] = D3_dim;
-   f313_dims[1] = D1_dim;
-   f313_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var-name-dashes", NC_DOUBLE, RANK_var_MINUS_name_MINUS_dashes, 0, &var_MINUS_name_MINUS_dashes_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var.name.dots", NC_DOUBLE, RANK_var_PERIOD_name_PERIOD_dots, 0, &var_PERIOD_name_PERIOD_dots_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var+name+plusses", NC_DOUBLE, RANK_var_PLUS_name_PLUS_plusses, 0, &var_PLUS_name_PLUS_plusses_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var at name@ats", NC_DOUBLE, RANK_var_ATSIGN_name_ATSIGN_ats, 0, &var_ATSIGN_name_ATSIGN_ats_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* assign attributes */
-   c_att_MINUS_name_MINUS_dashes[0] = 4;
-   stat = nc_put_att_int(ncid, c_id, "att-name-dashes", NC_INT, 1, c_att_MINUS_name_MINUS_dashes);
-   check_err(stat,__LINE__,__FILE__);
-   c_att_PERIOD_name_PERIOD_dots[0] = 5;
-   stat = nc_put_att_int(ncid, c_id, "att.name.dots", NC_INT, 1, c_att_PERIOD_name_PERIOD_dots);
-   check_err(stat,__LINE__,__FILE__);
-   c_att_PLUS_name_PLUS_plusses[0] = 6;
-   stat = nc_put_att_int(ncid, c_id, "att+name+plusses", NC_INT, 1, c_att_PLUS_name_PLUS_plusses);
-   check_err(stat,__LINE__,__FILE__);
-   c_att_ATSIGN_name_ATSIGN_ats[0] = 7;
-   stat = nc_put_att_int(ncid, c_id, "att at name@ats", NC_INT, 1, c_att_ATSIGN_name_ATSIGN_ats);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, b_id, "c", 1, "");
-   check_err(stat,__LINE__,__FILE__);
-   s_b[0] = 0;
-   s_b[1] = 127;
-   s_b[2] = -128;
-   s_b[3] = -1;
-   stat = nc_put_att_int(ncid, s_id, "b", NC_BYTE, 4, s_b);
-   check_err(stat,__LINE__,__FILE__);
-   s_s[0] = -32768;
-   s_s[1] = 0;
-   s_s[2] = 32767;
-   stat = nc_put_att_short(ncid, s_id, "s", NC_SHORT, 3, s_s);
-   check_err(stat,__LINE__,__FILE__);
-   i_i[0] = -2147483647;
-   i_i[1] = 0;
-   i_i[2] = 2147483647;
-   stat = nc_put_att_int(ncid, i_id, "i", NC_INT, 3, i_i);
-   check_err(stat,__LINE__,__FILE__);
-   i_f[0] = -9.9999996e+35;
-   i_f[1] = 0;
-   i_f[2] = 9.9999996e+35;
-   stat = nc_put_att_float(ncid, i_id, "f", NC_FLOAT, 3, i_f);
-   check_err(stat,__LINE__,__FILE__);
-   i_d[0] = -1e+308;
-   i_d[1] = 0;
-   i_d[2] = 1e+308;
-   stat = nc_put_att_double(ncid, i_id, "d", NC_DOUBLE, 3, i_d);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, f_id, "c", 1, "x");
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, d_id, "c", 8, "abcd\tZ$&");
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "");
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gb[0] = -128;
-   cdf_Gb[1] = 127;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, cdf_Gb);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gs[0] = -32768;
-   cdf_Gs[1] = 0;
-   cdf_Gs[2] = 32767;
-   stat = nc_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, cdf_Gs);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gi[0] = -2147483647;
-   cdf_Gi[1] = 0;
-   cdf_Gi[2] = 2147483647;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 3, cdf_Gi);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gf[0] = -9.9999996e+35;
-   cdf_Gf[1] = 0;
-   cdf_Gf[2] = 9.9999996e+35;
-   stat = nc_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 3, cdf_Gf);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gd[0] = -1e+308;
-   cdf_Gd[1] = 0;
-   cdf_Gd[2] = 1e+308;
-   stat = nc_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 3, cdf_Gd);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_MINUS_name_MINUS_dashes[0] = -1;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt-name-dashes", NC_INT, 1, cdf_Gatt_MINUS_name_MINUS_dashes);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_PERIOD_name_PERIOD_dots[0] = -2;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt.name.dots", NC_INT, 1, cdf_Gatt_PERIOD_name_PERIOD_dots);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_PLUS_name_PLUS_plusses[0] = -3;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt+name+plusses", NC_INT, 1, cdf_Gatt_PLUS_name_PLUS_plusses);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_ATSIGN_name_ATSIGN_ats[0] = -4;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt at name@ats", NC_INT, 1, cdf_Gatt_ATSIGN_name_ATSIGN_ats);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* leave define mode */
-   stat = nc_enddef (ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   {			/* store c */
-    static char c = '2';
-    stat = nc_put_var_text(ncid, c_id, &c);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store b */
-    static signed char b = -2;
-    stat = nc_put_var_schar(ncid, b_id, &b);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s */
-    static short s = -5;
-    stat = nc_put_var_short(ncid, s_id, &s);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store i */
-    static int i = -20;
-    stat = nc_put_var_int(ncid, i_id, &i);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store f */
-    static float f = -9;
-    stat = nc_put_var_float(ncid, f_id, &f);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store d */
-    static double d = -10.;
-    stat = nc_put_var_double(ncid, d_id, &d);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store cr */
-    static size_t cr_start[RANK_cr];
-    static size_t cr_count[RANK_cr];
-    static char cr[] = {"ab"};
-    Dr_len = 2;			/* number of records of cr data */
-    cr_start[0] = 0;
-    cr_count[0] = Dr_len;
-    stat = nc_put_vara_text(ncid, cr_id, cr_start, cr_count, cr);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store br */
-    static size_t br_start[RANK_br];
-    static size_t br_count[RANK_br];
-    static signed char br[] = {-128, 127};
-    Dr_len = 2;			/* number of records of br data */
-    br_start[0] = 0;
-    br_count[0] = Dr_len;
-    stat = nc_put_vara_schar(ncid, br_id, br_start, br_count, br);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store sr */
-    static size_t sr_start[RANK_sr];
-    static size_t sr_count[RANK_sr];
-    static short sr[] = {-32768, 32767};
-    Dr_len = 2;			/* number of records of sr data */
-    sr_start[0] = 0;
-    sr_count[0] = Dr_len;
-    stat = nc_put_vara_short(ncid, sr_id, sr_start, sr_count, sr);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store ir */
-    static size_t ir_start[RANK_ir];
-    static size_t ir_count[RANK_ir];
-    static int ir[] = {-2147483646, 2147483647};
-    Dr_len = 2;			/* number of records of ir data */
-    ir_start[0] = 0;
-    ir_count[0] = Dr_len;
-    stat = nc_put_vara_int(ncid, ir_id, ir_start, ir_count, ir);
+main() {/* create ctest0.nc */
+
+    int  stat;  /* return status */
+    int  ncid;  /* netCDF id */
+
+    /* dimension ids */
+    int Dr_dim;
+    int D1_dim;
+    int D2_dim;
+    int D3_dim;
+    int dim_MINUS_name_MINUS_dashes_dim;
+    int dim_PERIOD_name_PERIOD_dots_dim;
+    int dim_PLUS_name_PLUS_plusses_dim;
+    int dim_ATSIGN_name_ATSIGN_ats_dim;
+
+    /* dimension lengths */
+    size_t Dr_len = NC_UNLIMITED;
+    size_t D1_len = 1;
+    size_t D2_len = 2;
+    size_t D3_len = 3;
+    size_t dim_MINUS_name_MINUS_dashes_len = 4;
+    size_t dim_PERIOD_name_PERIOD_dots_len = 5;
+    size_t dim_PLUS_name_PLUS_plusses_len = 6;
+    size_t dim_ATSIGN_name_ATSIGN_ats_len = 7;
+
+    /* variable ids */
+    int c_id;
+    int b_id;
+    int s_id;
+    int i_id;
+    int f_id;
+    int d_id;
+    int cr_id;
+    int br_id;
+    int sr_id;
+    int ir_id;
+    int fr_id;
+    int dr_id;
+    int c1_id;
+    int b1_id;
+    int s1_id;
+    int i1_id;
+    int f1_id;
+    int d1_id;
+    int c2_id;
+    int b2_id;
+    int s2_id;
+    int i2_id;
+    int f2_id;
+    int d2_id;
+    int c3_id;
+    int b3_id;
+    int s3_id;
+    int i3_id;
+    int f3_id;
+    int d3_id;
+    int cr1_id;
+    int br2_id;
+    int sr3_id;
+    int f11_id;
+    int d12_id;
+    int c13_id;
+    int s21_id;
+    int i22_id;
+    int f23_id;
+    int c31_id;
+    int b32_id;
+    int s33_id;
+    int sr11_id;
+    int ir12_id;
+    int fr13_id;
+    int cr21_id;
+    int br22_id;
+    int sr23_id;
+    int fr31_id;
+    int dr32_id;
+    int cr33_id;
+    int c111_id;
+    int b112_id;
+    int s113_id;
+    int f121_id;
+    int d122_id;
+    int c123_id;
+    int s131_id;
+    int i132_id;
+    int f133_id;
+    int f211_id;
+    int d212_id;
+    int c213_id;
+    int s221_id;
+    int i222_id;
+    int f223_id;
+    int c231_id;
+    int b232_id;
+    int s233_id;
+    int s311_id;
+    int i312_id;
+    int f313_id;
+    int var_MINUS_name_MINUS_dashes_id;
+    int var_PERIOD_name_PERIOD_dots_id;
+    int var_PLUS_name_PLUS_plusses_id;
+    int var_ATSIGN_name_ATSIGN_ats_id;
+
+    /* rank (number of dimensions) for each variable */
+#   define RANK_c 0
+#   define RANK_b 0
+#   define RANK_s 0
+#   define RANK_i 0
+#   define RANK_f 0
+#   define RANK_d 0
+#   define RANK_cr 1
+#   define RANK_br 1
+#   define RANK_sr 1
+#   define RANK_ir 1
+#   define RANK_fr 1
+#   define RANK_dr 1
+#   define RANK_c1 1
+#   define RANK_b1 1
+#   define RANK_s1 1
+#   define RANK_i1 1
+#   define RANK_f1 1
+#   define RANK_d1 1
+#   define RANK_c2 1
+#   define RANK_b2 1
+#   define RANK_s2 1
+#   define RANK_i2 1
+#   define RANK_f2 1
+#   define RANK_d2 1
+#   define RANK_c3 1
+#   define RANK_b3 1
+#   define RANK_s3 1
+#   define RANK_i3 1
+#   define RANK_f3 1
+#   define RANK_d3 1
+#   define RANK_cr1 2
+#   define RANK_br2 2
+#   define RANK_sr3 2
+#   define RANK_f11 2
+#   define RANK_d12 2
+#   define RANK_c13 2
+#   define RANK_s21 2
+#   define RANK_i22 2
+#   define RANK_f23 2
+#   define RANK_c31 2
+#   define RANK_b32 2
+#   define RANK_s33 2
+#   define RANK_sr11 3
+#   define RANK_ir12 3
+#   define RANK_fr13 3
+#   define RANK_cr21 3
+#   define RANK_br22 3
+#   define RANK_sr23 3
+#   define RANK_fr31 3
+#   define RANK_dr32 3
+#   define RANK_cr33 3
+#   define RANK_c111 3
+#   define RANK_b112 3
+#   define RANK_s113 3
+#   define RANK_f121 3
+#   define RANK_d122 3
+#   define RANK_c123 3
+#   define RANK_s131 3
+#   define RANK_i132 3
+#   define RANK_f133 3
+#   define RANK_f211 3
+#   define RANK_d212 3
+#   define RANK_c213 3
+#   define RANK_s221 3
+#   define RANK_i222 3
+#   define RANK_f223 3
+#   define RANK_c231 3
+#   define RANK_b232 3
+#   define RANK_s233 3
+#   define RANK_s311 3
+#   define RANK_i312 3
+#   define RANK_f313 3
+#   define RANK_var_MINUS_name_MINUS_dashes 0
+#   define RANK_var_PERIOD_name_PERIOD_dots 0
+#   define RANK_var_PLUS_name_PLUS_plusses 0
+#   define RANK_var_ATSIGN_name_ATSIGN_ats 0
+
+    /* variable shapes */
+    int cr_dims[RANK_cr];
+    int br_dims[RANK_br];
+    int sr_dims[RANK_sr];
+    int ir_dims[RANK_ir];
+    int fr_dims[RANK_fr];
+    int dr_dims[RANK_dr];
+    int c1_dims[RANK_c1];
+    int b1_dims[RANK_b1];
+    int s1_dims[RANK_s1];
+    int i1_dims[RANK_i1];
+    int f1_dims[RANK_f1];
+    int d1_dims[RANK_d1];
+    int c2_dims[RANK_c2];
+    int b2_dims[RANK_b2];
+    int s2_dims[RANK_s2];
+    int i2_dims[RANK_i2];
+    int f2_dims[RANK_f2];
+    int d2_dims[RANK_d2];
+    int c3_dims[RANK_c3];
+    int b3_dims[RANK_b3];
+    int s3_dims[RANK_s3];
+    int i3_dims[RANK_i3];
+    int f3_dims[RANK_f3];
+    int d3_dims[RANK_d3];
+    int cr1_dims[RANK_cr1];
+    int br2_dims[RANK_br2];
+    int sr3_dims[RANK_sr3];
+    int f11_dims[RANK_f11];
+    int d12_dims[RANK_d12];
+    int c13_dims[RANK_c13];
+    int s21_dims[RANK_s21];
+    int i22_dims[RANK_i22];
+    int f23_dims[RANK_f23];
+    int c31_dims[RANK_c31];
+    int b32_dims[RANK_b32];
+    int s33_dims[RANK_s33];
+    int sr11_dims[RANK_sr11];
+    int ir12_dims[RANK_ir12];
+    int fr13_dims[RANK_fr13];
+    int cr21_dims[RANK_cr21];
+    int br22_dims[RANK_br22];
+    int sr23_dims[RANK_sr23];
+    int fr31_dims[RANK_fr31];
+    int dr32_dims[RANK_dr32];
+    int cr33_dims[RANK_cr33];
+    int c111_dims[RANK_c111];
+    int b112_dims[RANK_b112];
+    int s113_dims[RANK_s113];
+    int f121_dims[RANK_f121];
+    int d122_dims[RANK_d122];
+    int c123_dims[RANK_c123];
+    int s131_dims[RANK_s131];
+    int i132_dims[RANK_i132];
+    int f133_dims[RANK_f133];
+    int f211_dims[RANK_f211];
+    int d212_dims[RANK_d212];
+    int c213_dims[RANK_c213];
+    int s221_dims[RANK_s221];
+    int i222_dims[RANK_i222];
+    int f223_dims[RANK_f223];
+    int c231_dims[RANK_c231];
+    int b232_dims[RANK_b232];
+    int s233_dims[RANK_s233];
+    int s311_dims[RANK_s311];
+    int i312_dims[RANK_i312];
+    int f313_dims[RANK_f313];
+
+    /* enter define mode */
+    stat = nc_create("ctest0.nc", NC_CLOBBER, &ncid);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* define dimensions */
+    stat = nc_def_dim(ncid, "Dr", Dr_len, &Dr_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "D1", D1_len, &D1_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "D2", D2_len, &D2_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "D3", D3_len, &D3_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim-name-dashes", dim_MINUS_name_MINUS_dashes_len, &dim_MINUS_name_MINUS_dashes_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim.name.dots", dim_PERIOD_name_PERIOD_dots_len, &dim_PERIOD_name_PERIOD_dots_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim+name+plusses", dim_PLUS_name_PLUS_plusses_len, &dim_PLUS_name_PLUS_plusses_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim at name@ats", dim_ATSIGN_name_ATSIGN_ats_len, &dim_ATSIGN_name_ATSIGN_ats_dim);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* define variables */
+
+    stat = nc_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    br_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    ir_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    fr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    dr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr1_dims[0] = Dr_dim;
+    cr1_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    br2_dims[0] = Dr_dim;
+    br2_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr3_dims[0] = Dr_dim;
+    sr3_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f11_dims[0] = D1_dim;
+    f11_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d12_dims[0] = D1_dim;
+    d12_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c13_dims[0] = D1_dim;
+    c13_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s21_dims[0] = D2_dim;
+    s21_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i22_dims[0] = D2_dim;
+    i22_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f23_dims[0] = D2_dim;
+    f23_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c31_dims[0] = D3_dim;
+    c31_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b32_dims[0] = D3_dim;
+    b32_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s33_dims[0] = D3_dim;
+    s33_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr11_dims[0] = Dr_dim;
+    sr11_dims[1] = D1_dim;
+    sr11_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    ir12_dims[0] = Dr_dim;
+    ir12_dims[1] = D1_dim;
+    ir12_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    fr13_dims[0] = Dr_dim;
+    fr13_dims[1] = D1_dim;
+    fr13_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr21_dims[0] = Dr_dim;
+    cr21_dims[1] = D2_dim;
+    cr21_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    br22_dims[0] = Dr_dim;
+    br22_dims[1] = D2_dim;
+    br22_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr23_dims[0] = Dr_dim;
+    sr23_dims[1] = D2_dim;
+    sr23_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    fr31_dims[0] = Dr_dim;
+    fr31_dims[1] = D3_dim;
+    fr31_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    dr32_dims[0] = Dr_dim;
+    dr32_dims[1] = D3_dim;
+    dr32_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr33_dims[0] = Dr_dim;
+    cr33_dims[1] = D3_dim;
+    cr33_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c111_dims[0] = D1_dim;
+    c111_dims[1] = D1_dim;
+    c111_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b112_dims[0] = D1_dim;
+    b112_dims[1] = D1_dim;
+    b112_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s113_dims[0] = D1_dim;
+    s113_dims[1] = D1_dim;
+    s113_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f121_dims[0] = D1_dim;
+    f121_dims[1] = D2_dim;
+    f121_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d122_dims[0] = D1_dim;
+    d122_dims[1] = D2_dim;
+    d122_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c123_dims[0] = D1_dim;
+    c123_dims[1] = D2_dim;
+    c123_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s131_dims[0] = D1_dim;
+    s131_dims[1] = D3_dim;
+    s131_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i132_dims[0] = D1_dim;
+    i132_dims[1] = D3_dim;
+    i132_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f133_dims[0] = D1_dim;
+    f133_dims[1] = D3_dim;
+    f133_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f211_dims[0] = D2_dim;
+    f211_dims[1] = D1_dim;
+    f211_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d212_dims[0] = D2_dim;
+    d212_dims[1] = D1_dim;
+    d212_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c213_dims[0] = D2_dim;
+    c213_dims[1] = D1_dim;
+    c213_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s221_dims[0] = D2_dim;
+    s221_dims[1] = D2_dim;
+    s221_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i222_dims[0] = D2_dim;
+    i222_dims[1] = D2_dim;
+    i222_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f223_dims[0] = D2_dim;
+    f223_dims[1] = D2_dim;
+    f223_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c231_dims[0] = D2_dim;
+    c231_dims[1] = D3_dim;
+    c231_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b232_dims[0] = D2_dim;
+    b232_dims[1] = D3_dim;
+    b232_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s233_dims[0] = D2_dim;
+    s233_dims[1] = D3_dim;
+    s233_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s311_dims[0] = D3_dim;
+    s311_dims[1] = D1_dim;
+    s311_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i312_dims[0] = D3_dim;
+    i312_dims[1] = D1_dim;
+    i312_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f313_dims[0] = D3_dim;
+    f313_dims[1] = D1_dim;
+    f313_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var-name-dashes", NC_DOUBLE, RANK_var_MINUS_name_MINUS_dashes, 0, &var_MINUS_name_MINUS_dashes_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var.name.dots", NC_DOUBLE, RANK_var_PERIOD_name_PERIOD_dots, 0, &var_PERIOD_name_PERIOD_dots_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var+name+plusses", NC_DOUBLE, RANK_var_PLUS_name_PLUS_plusses, 0, &var_PLUS_name_PLUS_plusses_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var at name@ats", NC_DOUBLE, RANK_var_ATSIGN_name_ATSIGN_ats, 0, &var_ATSIGN_name_ATSIGN_ats_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* assign global attributes */
+
+    {
+    stat = nc_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const signed char c0_Gb_att[2] = {-128, 127} ;
+    stat = nc_put_att_schar(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, c0_Gb_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const short c0_Gs_att[3] = {-32768, 0, 32767} ;
+    stat = nc_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, c0_Gs_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gi_att[3] = {-2147483647, 0, 2147483647} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 3, c0_Gi_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const float c0_Gf_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
+    stat = nc_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 3, c0_Gf_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const double c0_Gd_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
+    stat = nc_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 3, c0_Gd_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_MINUS_name_MINUS_dashes_att[1] = {-1} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt-name-dashes", NC_INT, 1, c0_Gatt_MINUS_name_MINUS_dashes_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_DOT_name_DOT_dots_att[1] = {-2} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt.name.dots", NC_INT, 1, c0_Gatt_DOT_name_DOT_dots_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_PLUS_name_PLUS_plusses_att[1] = {-3} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt+name+plusses", NC_INT, 1, c0_Gatt_PLUS_name_PLUS_plusses_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_ATSIGN_name_ATSIGN_ats_att[1] = {-4} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt at name@ats", NC_INT, 1, c0_Gatt_ATSIGN_name_ATSIGN_ats_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    /* assign per-variable attributes */
+
+    {
+    static const int c0_att_MINUS_name_MINUS_dashes_att[1] = {4} ;
+    stat = nc_put_att_int(ncid, c_id, "att-name-dashes", NC_INT, 1, c0_att_MINUS_name_MINUS_dashes_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_att_DOT_name_DOT_dots_att[1] = {5} ;
+    stat = nc_put_att_int(ncid, c_id, "att.name.dots", NC_INT, 1, c0_att_DOT_name_DOT_dots_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_att_PLUS_name_PLUS_plusses_att[1] = {6} ;
+    stat = nc_put_att_int(ncid, c_id, "att+name+plusses", NC_INT, 1, c0_att_PLUS_name_PLUS_plusses_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_att_ATSIGN_name_ATSIGN_ats_att[1] = {7} ;
+    stat = nc_put_att_int(ncid, c_id, "att at name@ats", NC_INT, 1, c0_att_ATSIGN_name_ATSIGN_ats_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    stat = nc_put_att_text(ncid, b_id, "c", 1, "");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const signed char c0_b_att[4] = {0, 127, -128, -1} ;
+    stat = nc_put_att_schar(ncid, s_id, "b", NC_BYTE, 4, c0_b_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const short c0_s_att[3] = {-32768, 0, 32767} ;
+    stat = nc_put_att_short(ncid, s_id, "s", NC_SHORT, 3, c0_s_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_i_att[3] = {-2147483647, 0, 2147483647} ;
+    stat = nc_put_att_int(ncid, i_id, "i", NC_INT, 3, c0_i_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const float c0_f_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
+    stat = nc_put_att_float(ncid, i_id, "f", NC_FLOAT, 3, c0_f_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const double c0_d_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
+    stat = nc_put_att_double(ncid, i_id, "d", NC_DOUBLE, 3, c0_d_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    stat = nc_put_att_text(ncid, f_id, "c", 1, "x");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    stat = nc_put_att_text(ncid, d_id, "c", 8, "abcd\tZ$&");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    /* leave define mode */
+    stat = nc_enddef (ncid);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* assign variable data */
+
+    {
+    size_t count = 0;
+    static char c_data[1] = {'2'};
+    stat = nc_put_var1(ncid, c_id, &count, c_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static signed char b_data[1] = {-2};
+    stat = nc_put_var1(ncid, b_id, &count, b_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static short s_data[1] = {-5};
+    stat = nc_put_var1(ncid, s_id, &count, s_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static int i_data[1] = {-20};
+    stat = nc_put_var1(ncid, i_id, &count, i_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static float f_data[1] = {((float)-9)};
+    stat = nc_put_var1(ncid, f_id, &count, f_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static double d_data[1] = {((double)-10)};
+    stat = nc_put_var1(ncid, d_id, &count, d_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* cr_data = "ab" ;
+    size_t cr_startset[1] = {0} ;
+    size_t cr_countset[1] = {2};
+    stat = nc_put_vara(ncid, cr_id, cr_startset, cr_countset, cr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char br_data[2] = {-128, 127} ;
+    size_t br_startset[1] = {0} ;
+    size_t br_countset[1] = {2};
+    stat = nc_put_vara(ncid, br_id, br_startset, br_countset, br_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short sr_data[2] = {-32768, 32767} ;
+    size_t sr_startset[1] = {0} ;
+    size_t sr_countset[1] = {2};
+    stat = nc_put_vara(ncid, sr_id, sr_startset, sr_countset, sr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int ir_data[2] = {-2147483646, 2147483647} ;
+    size_t ir_startset[1] = {0} ;
+    size_t ir_countset[1] = {2};
+    stat = nc_put_vara(ncid, ir_id, ir_startset, ir_countset, ir_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    float fr_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
+    size_t fr_startset[1] = {0} ;
+    size_t fr_countset[1] = {2};
+    stat = nc_put_vara(ncid, fr_id, fr_startset, fr_countset, fr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    double dr_data[2] = {((double)-1e+308), ((double)1e+308)} ;
+    size_t dr_startset[1] = {0} ;
+    size_t dr_countset[1] = {2};
+    stat = nc_put_vara(ncid, dr_id, dr_startset, dr_countset, dr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* c1_data = "\000" ;
+    size_t c1_startset[1] = {0} ;
+    size_t c1_countset[1] = {1};
+    stat = nc_put_vara(ncid, c1_id, c1_startset, c1_countset, c1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char b1_data[1] = {-128} ;
+    size_t b1_startset[1] = {0} ;
+    size_t b1_countset[1] = {1};
+    stat = nc_put_vara(ncid, b1_id, b1_startset, b1_countset, b1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short s1_data[1] = {-32768} ;
+    size_t s1_startset[1] = {0} ;
+    size_t s1_countset[1] = {1};
+    stat = nc_put_vara(ncid, s1_id, s1_startset, s1_countset, s1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int i1_data[1] = {-2147483646} ;
+    size_t i1_startset[1] = {0} ;
+    size_t i1_countset[1] = {1};
+    stat = nc_put_vara(ncid, i1_id, i1_startset, i1_countset, i1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    float f1_data[1] = {((float)-9.9999996e+35)} ;
+    size_t f1_startset[1] = {0} ;
+    size_t f1_countset[1] = {1};
+    stat = nc_put_vara(ncid, f1_id, f1_startset, f1_countset, f1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    double d1_data[1] = {((double)-1e+308)} ;
+    size_t d1_startset[1] = {0} ;
+    size_t d1_countset[1] = {1};
+    stat = nc_put_vara(ncid, d1_id, d1_startset, d1_countset, d1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* c2_data = "ab" ;
+    size_t c2_startset[1] = {0} ;
+    size_t c2_countset[1] = {2};
+    stat = nc_put_vara(ncid, c2_id, c2_startset, c2_countset, c2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char b2_data[2] = {-128, 127} ;
+    size_t b2_startset[1] = {0} ;
+    size_t b2_countset[1] = {2};
+    stat = nc_put_vara(ncid, b2_id, b2_startset, b2_countset, b2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short s2_data[2] = {-32768, 32767} ;
+    size_t s2_startset[1] = {0} ;
+    size_t s2_countset[1] = {2};
+    stat = nc_put_vara(ncid, s2_id, s2_startset, s2_countset, s2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int i2_data[2] = {-2147483646, 2147483647} ;
+    size_t i2_startset[1] = {0} ;
+    size_t i2_countset[1] = {2};
+    stat = nc_put_vara(ncid, i2_id, i2_startset, i2_countset, i2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    float f2_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
+    size_t f2_startset[1] = {0} ;
+    size_t f2_countset[1] = {2};
+    stat = nc_put_vara(ncid, f2_id, f2_startset, f2_countset, f2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    double d2_data[2] = {((double)-1e+308), ((double)1e+308)} ;
+    size_t d2_startset[1] = {0} ;
+    size_t d2_countset[1] = {2};
+    stat = nc_put_vara(ncid, d2_id, d2_startset, d2_countset, d2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* c3_data = "\001\177." ;
+    size_t c3_startset[1] = {0} ;
+    size_t c3_countset[1] = {3};
+    stat = nc_put_vara(ncid, c3_id, c3_startset, c3_countset, c3_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char b3_data[3] = {-128, 127, -1} ;
+    size_t b3_startset[1] = {0} ;
+    size_t b3_countset[1] = {3};
+    stat = nc_put_vara(ncid, b3_id, b3_startset, b3_countset, b3_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short s3_data[3] = {-32768, 0, 32767} ;
+    size_t s3_startset[1] = {0} ;
+    size_t s3_countset[1] = {3};
+    stat = nc_put_vara(ncid, s3_id, s3_startset, s3_countset, s3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store fr */
-    static size_t fr_start[RANK_fr];
-    static size_t fr_count[RANK_fr];
-    static float fr[] = {-9.9999996e+35, 9.9999996e+35};
-    Dr_len = 2;			/* number of records of fr data */
-    fr_start[0] = 0;
-    fr_count[0] = Dr_len;
-    stat = nc_put_vara_float(ncid, fr_id, fr_start, fr_count, fr);
+
+    {
+    int i3_data[3] = {-2147483646, 0, 2147483647} ;
+    size_t i3_startset[1] = {0} ;
+    size_t i3_countset[1] = {3};
+    stat = nc_put_vara(ncid, i3_id, i3_startset, i3_countset, i3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store dr */
-    static size_t dr_start[RANK_dr];
-    static size_t dr_count[RANK_dr];
-    static double dr[] = {-1.e+308, 1.e+308};
-    Dr_len = 2;			/* number of records of dr data */
-    dr_start[0] = 0;
-    dr_count[0] = Dr_len;
-    stat = nc_put_vara_double(ncid, dr_id, dr_start, dr_count, dr);
+
+    {
+    float f3_data[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
+    size_t f3_startset[1] = {0} ;
+    size_t f3_countset[1] = {3};
+    stat = nc_put_vara(ncid, f3_id, f3_startset, f3_countset, f3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store c1 */
-    static char c1[] = {""};
-    stat = nc_put_var_text(ncid, c1_id, c1);
+
+    {
+    double d3_data[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
+    size_t d3_startset[1] = {0} ;
+    size_t d3_countset[1] = {3};
+    stat = nc_put_vara(ncid, d3_id, d3_startset, d3_countset, d3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store b1 */
-    static signed char b1[] = {-128};
-    stat = nc_put_var_schar(ncid, b1_id, b1);
+
+    {
+    char* cr1_data = "xy" ;
+    size_t cr1_startset[2] = {0, 0} ;
+    size_t cr1_countset[2] = {2, 1};
+    stat = nc_put_vara(ncid, cr1_id, cr1_startset, cr1_countset, cr1_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s1 */
-    static short s1[] = {-32768};
-    stat = nc_put_var_short(ncid, s1_id, s1);
+
+    {
+    signed char br2_data[4] = {-24, -26, -20, -22} ;
+    size_t br2_startset[2] = {0, 0} ;
+    size_t br2_countset[2] = {2, 2};
+    stat = nc_put_vara(ncid, br2_id, br2_startset, br2_countset, br2_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i1 */
-    static int i1[] = {-2147483646};
-    stat = nc_put_var_int(ncid, i1_id, i1);
+
+    {
+    short sr3_data[6] = {-375, -380, -385, -350, -355, -360} ;
+    size_t sr3_startset[2] = {0, 0} ;
+    size_t sr3_countset[2] = {2, 3};
+    stat = nc_put_vara(ncid, sr3_id, sr3_startset, sr3_countset, sr3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f1 */
-    static float f1[] = {-9.9999996e+35};
-    stat = nc_put_var_float(ncid, f1_id, f1);
+    {
+    float f11_data[1] = {((float)-2187)} ;
+    size_t f11_startset[2] = {0, 0} ;
+    size_t f11_countset[2] = {1, 1};
+    stat = nc_put_vara(ncid, f11_id, f11_startset, f11_countset, f11_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d1 */
-    static double d1[] = {-1.e+308};
-    stat = nc_put_var_double(ncid, d1_id, d1);
+    {
+    double d12_data[2] = {((double)-3000), ((double)-3010)} ;
+    size_t d12_startset[2] = {0, 0} ;
+    size_t d12_countset[2] = {1, 2};
+    stat = nc_put_vara(ncid, d12_id, d12_startset, d12_countset, d12_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store c2 */
-    static char c2[] = {"ab"};
-    stat = nc_put_var_text(ncid, c2_id, c2);
+    {
+    char* c13_data = "\tb\177" ;
+    size_t c13_startset[2] = {0, 0} ;
+    size_t c13_countset[2] = {1, 3};
+    stat = nc_put_vara(ncid, c13_id, c13_startset, c13_countset, c13_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store b2 */
-    static signed char b2[] = {-128, 127};
-    stat = nc_put_var_schar(ncid, b2_id, b2);
+    {
+    short s21_data[2] = {-375, -350} ;
+    size_t s21_startset[2] = {0, 0} ;
+    size_t s21_countset[2] = {2, 1};
+    stat = nc_put_vara(ncid, s21_id, s21_startset, s21_countset, s21_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s2 */
-    static short s2[] = {-32768, 32767};
-    stat = nc_put_var_short(ncid, s2_id, s2);
+
+    {
+    int i22_data[4] = {-24000, -24020, -23600, -23620} ;
+    size_t i22_startset[2] = {0, 0} ;
+    size_t i22_countset[2] = {2, 2};
+    stat = nc_put_vara(ncid, i22_id, i22_startset, i22_countset, i22_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i2 */
-    static int i2[] = {-2147483646, 2147483647};
-    stat = nc_put_var_int(ncid, i2_id, i2);
+
+    {
+    float f23_data[6] = {((float)-2187), ((float)-2196), ((float)-2205), ((float)-2106), ((float)-2115), ((float)-2124)} ;
+    size_t f23_startset[2] = {0, 0} ;
+    size_t f23_countset[2] = {2, 3};
+    stat = nc_put_vara(ncid, f23_id, f23_startset, f23_countset, f23_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f2 */
-    static float f2[] = {-9.9999996e+35, 9.9999996e+35};
-    stat = nc_put_var_float(ncid, f2_id, f2);
+
+    {
+    char* c31_data = "+- " ;
+    size_t c31_startset[2] = {0, 0} ;
+    size_t c31_countset[2] = {3, 1};
+    stat = nc_put_vara(ncid, c31_id, c31_startset, c31_countset, c31_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d2 */
-    static double d2[] = {-1.e+308, 1.e+308};
-    stat = nc_put_var_double(ncid, d2_id, d2);
+    {
+    signed char b32_data[6] = {-24, -26, -20, -22, -16, -18} ;
+    size_t b32_startset[2] = {0, 0} ;
+    size_t b32_countset[2] = {3, 2};
+    stat = nc_put_vara(ncid, b32_id, b32_startset, b32_countset, b32_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
+
+    {
+    short s33_data[9] = {-375, -380, -385, -350, -355, -360, -325, -330, -335} ;
+    size_t s33_startset[2] = {0, 0} ;
+    size_t s33_countset[2] = {3, 3};
+    stat = nc_put_vara(ncid, s33_id, s33_startset, s33_countset, s33_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short sr11_data[2] = {2500, 2375} ;
+    size_t sr11_startset[3] = {0, 0, 0} ;
+    size_t sr11_countset[3] = {2, 1, 1};
+    stat = nc_put_vara(ncid, sr11_id, sr11_startset, sr11_countset, sr11_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int ir12_data[4] = {640000, 639980, 632000, 631980} ;
+    size_t ir12_startset[3] = {0, 0, 0} ;
+    size_t ir12_countset[3] = {2, 1, 2};
+    stat = nc_put_vara(ncid, ir12_id, ir12_startset, ir12_countset, ir12_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
 
-   {			/* store c3 */
-    static char c3[] = {"\001\177."};
-    stat = nc_put_var_text(ncid, c3_id, c3);
+    {
+    float fr13_data[6] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497)} ;
+    size_t fr13_startset[3] = {0, 0, 0} ;
+    size_t fr13_countset[3] = {2, 1, 3};
+    stat = nc_put_vara(ncid, fr13_id, fr13_startset, fr13_countset, fr13_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
+
+    {
+    char* cr21_data = "@DHL" ;
+    size_t cr21_startset[3] = {0, 0, 0} ;
+    size_t cr21_countset[3] = {2, 2, 1};
+    stat = nc_put_vara(ncid, cr21_id, cr21_startset, cr21_countset, cr21_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char br22_data[8] = {64, 62, 68, 66, 56, 54, 60, 58} ;
+    size_t br22_startset[3] = {0, 0, 0} ;
+    size_t br22_countset[3] = {2, 2, 2};
+    stat = nc_put_vara(ncid, br22_id, br22_startset, br22_countset, br22_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short sr23_data[12] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390} ;
+    size_t sr23_startset[3] = {0, 0, 0} ;
+    size_t sr23_countset[3] = {2, 2, 3};
+    stat = nc_put_vara(ncid, sr23_id, sr23_startset, sr23_countset, sr23_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
 
-   {			/* store b3 */
-    static signed char b3[] = {-128, 127, -1};
-    stat = nc_put_var_schar(ncid, b3_id, b3);
+    {
+    float fr31_data[6] = {((float)26244), ((float)26325), ((float)26406), ((float)25515), ((float)25596), ((float)25677)} ;
+    size_t fr31_startset[3] = {0, 0, 0} ;
+    size_t fr31_countset[3] = {2, 3, 1};
+    stat = nc_put_vara(ncid, fr31_id, fr31_startset, fr31_countset, fr31_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store s3 */
-    static short s3[] = {-32768, 0, 32767};
-    stat = nc_put_var_short(ncid, s3_id, s3);
+    {
+    double dr32_data[12] = {((double)40000), ((double)39990), ((double)40100), ((double)40090), ((double)40200), ((double)40190), ((double)39000), ((double)38990), ((double)39100), ((double)39090), ((double)39200), ((double)39190)} ;
+    size_t dr32_startset[3] = {0, 0, 0} ;
+    size_t dr32_countset[3] = {2, 3, 2};
+    stat = nc_put_vara(ncid, dr32_id, dr32_startset, dr32_countset, dr32_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store i3 */
-    static int i3[] = {-2147483646, 0, 2147483647};
-    stat = nc_put_var_int(ncid, i3_id, i3);
+    {
+    char* cr33_data = "1\000\000two3\000\0004\000\0005\000\000six" ;
+    size_t cr33_startset[3] = {0, 0, 0} ;
+    size_t cr33_countset[3] = {2, 3, 3};
+    stat = nc_put_vara(ncid, cr33_id, cr33_startset, cr33_countset, cr33_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f3 */
-    static float f3[] = {-9.9999996e+35, 0, 9.9999996e+35};
-    stat = nc_put_var_float(ncid, f3_id, f3);
+    {
+    char* c111_data = "@" ;
+    size_t c111_startset[3] = {0, 0, 0} ;
+    size_t c111_countset[3] = {1, 1, 1};
+    stat = nc_put_vara(ncid, c111_id, c111_startset, c111_countset, c111_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d3 */
-    static double d3[] = {-1.e+308, 0., 1.e+308};
-    stat = nc_put_var_double(ncid, d3_id, d3);
+    {
+    signed char b112_data[2] = {64, 62} ;
+    size_t b112_startset[3] = {0, 0, 0} ;
+    size_t b112_countset[3] = {1, 1, 2};
+    stat = nc_put_vara(ncid, b112_id, b112_startset, b112_countset, b112_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store cr1 */
-    static size_t cr1_start[RANK_cr1];
-    static size_t cr1_count[RANK_cr1];
-    static char cr1[] = {"xy"};
-    Dr_len = 2;			/* number of records of cr1 data */
-    cr1_start[0] = 0;
-    cr1_start[1] = 0;
-    cr1_count[0] = Dr_len;
-    cr1_count[1] = D1_len;
-    stat = nc_put_vara_text(ncid, cr1_id, cr1_start, cr1_count, cr1);
+    {
+    short s113_data[3] = {2500, 2495, 2490} ;
+    size_t s113_startset[3] = {0, 0, 0} ;
+    size_t s113_countset[3] = {1, 1, 3};
+    stat = nc_put_vara(ncid, s113_id, s113_startset, s113_countset, s113_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store br2 */
-    static size_t br2_start[RANK_br2];
-    static size_t br2_count[RANK_br2];
-    static signed char br2[] = {-24, -26, -20, -22};
-    Dr_len = 2;			/* number of records of br2 data */
-    br2_start[0] = 0;
-    br2_start[1] = 0;
-    br2_count[0] = Dr_len;
-    br2_count[1] = D2_len;
-    stat = nc_put_vara_schar(ncid, br2_id, br2_start, br2_count, br2);
+    {
+    float f121_data[2] = {((float)26244), ((float)26325)} ;
+    size_t f121_startset[3] = {0, 0, 0} ;
+    size_t f121_countset[3] = {1, 2, 1};
+    stat = nc_put_vara(ncid, f121_id, f121_startset, f121_countset, f121_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store sr3 */
-    static size_t sr3_start[RANK_sr3];
-    static size_t sr3_count[RANK_sr3];
-    static short sr3[] = {-375, -380, -385, -350, -355, -360};
-    Dr_len = 2;			/* number of records of sr3 data */
-    sr3_start[0] = 0;
-    sr3_start[1] = 0;
-    sr3_count[0] = Dr_len;
-    sr3_count[1] = D3_len;
-    stat = nc_put_vara_short(ncid, sr3_id, sr3_start, sr3_count, sr3);
+    {
+    double d122_data[4] = {((double)40000), ((double)39990), ((double)40100), ((double)40090)} ;
+    size_t d122_startset[3] = {0, 0, 0} ;
+    size_t d122_countset[3] = {1, 2, 2};
+    stat = nc_put_vara(ncid, d122_id, d122_startset, d122_countset, d122_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f11 */
-    static float f11[] = {-2187};
-    stat = nc_put_var_float(ncid, f11_id, f11);
+
+    {
+    char* c123_data = "one2\000\000" ;
+    size_t c123_startset[3] = {0, 0, 0} ;
+    size_t c123_countset[3] = {1, 2, 3};
+    stat = nc_put_vara(ncid, c123_id, c123_startset, c123_countset, c123_data);
     check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store d12 */
-    static double d12[] = {-3000., -3010.};
-    stat = nc_put_var_double(ncid, d12_id, d12);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store c13 */
-    static char c13[] = {"\tb\177"};
-    stat = nc_put_var_text(ncid, c13_id, c13);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s21 */
-    static short s21[] = {-375, -350};
-    stat = nc_put_var_short(ncid, s21_id, s21);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store i22 */
-    static int i22[] = {-24000, -24020, -23600, -23620};
-    stat = nc_put_var_int(ncid, i22_id, i22);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store f23 */
-    static float f23[] = {-2187, -2196, -2205, -2106, -2115, -2124};
-    stat = nc_put_var_float(ncid, f23_id, f23);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store c31 */
-    static char c31[] = {"+- "};
-    stat = nc_put_var_text(ncid, c31_id, c31);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store b32 */
-    static signed char b32[] = {-24, -26, -20, -22, -16, -18};
-    stat = nc_put_var_schar(ncid, b32_id, b32);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s33 */
-    static short s33[] = {-375, -380, -385, -350, -355, -360, -325, -330, -335};
-    stat = nc_put_var_short(ncid, s33_id, s33);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store sr11 */
-    static size_t sr11_start[RANK_sr11];
-    static size_t sr11_count[RANK_sr11];
-    static short sr11[] = {2500, 2375};
-    Dr_len = 2;			/* number of records of sr11 data */
-    sr11_start[0] = 0;
-    sr11_start[1] = 0;
-    sr11_start[2] = 0;
-    sr11_count[0] = Dr_len;
-    sr11_count[1] = D1_len;
-    sr11_count[2] = D1_len;
-    stat = nc_put_vara_short(ncid, sr11_id, sr11_start, sr11_count, sr11);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store ir12 */
-    static size_t ir12_start[RANK_ir12];
-    static size_t ir12_count[RANK_ir12];
-    static int ir12[] = {640000, 639980, 632000, 631980};
-    Dr_len = 2;			/* number of records of ir12 data */
-    ir12_start[0] = 0;
-    ir12_start[1] = 0;
-    ir12_start[2] = 0;
-    ir12_count[0] = Dr_len;
-    ir12_count[1] = D1_len;
-    ir12_count[2] = D2_len;
-    stat = nc_put_vara_int(ncid, ir12_id, ir12_start, ir12_count, ir12);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store fr13 */
-    static size_t fr13_start[RANK_fr13];
-    static size_t fr13_count[RANK_fr13];
-    static float fr13[] = {26244, 26235, 26226, 25515, 25506, 25497};
-    Dr_len = 2;			/* number of records of fr13 data */
-    fr13_start[0] = 0;
-    fr13_start[1] = 0;
-    fr13_start[2] = 0;
-    fr13_count[0] = Dr_len;
-    fr13_count[1] = D1_len;
-    fr13_count[2] = D3_len;
-    stat = nc_put_vara_float(ncid, fr13_id, fr13_start, fr13_count, fr13);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store cr21 */
-    static size_t cr21_start[RANK_cr21];
-    static size_t cr21_count[RANK_cr21];
-    static char cr21[] = {"@DHL"};
-    Dr_len = 2;			/* number of records of cr21 data */
-    cr21_start[0] = 0;
-    cr21_start[1] = 0;
-    cr21_start[2] = 0;
-    cr21_count[0] = Dr_len;
-    cr21_count[1] = D2_len;
-    cr21_count[2] = D1_len;
-    stat = nc_put_vara_text(ncid, cr21_id, cr21_start, cr21_count, cr21);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store br22 */
-    static size_t br22_start[RANK_br22];
-    static size_t br22_count[RANK_br22];
-    static signed char br22[] = {64, 62, 68, 66, 56, 54, 60, 58};
-    Dr_len = 2;			/* number of records of br22 data */
-    br22_start[0] = 0;
-    br22_start[1] = 0;
-    br22_start[2] = 0;
-    br22_count[0] = Dr_len;
-    br22_count[1] = D2_len;
-    br22_count[2] = D2_len;
-    stat = nc_put_vara_schar(ncid, br22_id, br22_start, br22_count, br22);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store sr23 */
-    static size_t sr23_start[RANK_sr23];
-    static size_t sr23_count[RANK_sr23];
-    static short sr23[] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390};
-    Dr_len = 2;			/* number of records of sr23 data */
-    sr23_start[0] = 0;
-    sr23_start[1] = 0;
-    sr23_start[2] = 0;
-    sr23_count[0] = Dr_len;
-    sr23_count[1] = D2_len;
-    sr23_count[2] = D3_len;
-    stat = nc_put_vara_short(ncid, sr23_id, sr23_start, sr23_count, sr23);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store fr31 */
-    static size_t fr31_start[RANK_fr31];
-    static size_t fr31_count[RANK_fr31];
-    static float fr31[] = {26244, 26325, 26406, 25515, 25596, 25677};
-    Dr_len = 2;			/* number of records of fr31 data */
-    fr31_start[0] = 0;
-    fr31_start[1] = 0;
-    fr31_start[2] = 0;
-    fr31_count[0] = Dr_len;
-    fr31_count[1] = D3_len;
-    fr31_count[2] = D1_len;
-    stat = nc_put_vara_float(ncid, fr31_id, fr31_start, fr31_count, fr31);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store dr32 */
-    static size_t dr32_start[RANK_dr32];
-    static size_t dr32_count[RANK_dr32];
-    static double dr32[] = {40000., 39990., 40100., 40090., 40200., 40190., 39000., 38990., 39100., 39090., 39200., 39190.};
-    Dr_len = 2;			/* number of records of dr32 data */
-    dr32_start[0] = 0;
-    dr32_start[1] = 0;
-    dr32_start[2] = 0;
-    dr32_count[0] = Dr_len;
-    dr32_count[1] = D3_len;
-    dr32_count[2] = D2_len;
-    stat = nc_put_vara_double(ncid, dr32_id, dr32_start, dr32_count, dr32);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store cr33 */
-    static size_t cr33_start[RANK_cr33];
-    static size_t cr33_count[RANK_cr33];
-    static char cr33[] = {"1\000\000two3\000\0004\000\0005\000\000six"};
-    Dr_len = 2;			/* number of records of cr33 data */
-    cr33_start[0] = 0;
-    cr33_start[1] = 0;
-    cr33_start[2] = 0;
-    cr33_count[0] = Dr_len;
-    cr33_count[1] = D3_len;
-    cr33_count[2] = D3_len;
-    stat = nc_put_vara_text(ncid, cr33_id, cr33_start, cr33_count, cr33);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store c111 */
-    static char c111[] = {"@"};
-    stat = nc_put_var_text(ncid, c111_id, c111);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store b112 */
-    static signed char b112[] = {64, 62};
-    stat = nc_put_var_schar(ncid, b112_id, b112);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s113 */
-    static short s113[] = {2500, 2495, 2490};
-    stat = nc_put_var_short(ncid, s113_id, s113);
+    }
+
+
+    {
+    short s131_data[3] = {2500, 2525, 2550} ;
+    size_t s131_startset[3] = {0, 0, 0} ;
+    size_t s131_countset[3] = {1, 3, 1};
+    stat = nc_put_vara(ncid, s131_id, s131_startset, s131_countset, s131_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f121 */
-    static float f121[] = {26244, 26325};
-    stat = nc_put_var_float(ncid, f121_id, f121);
+    {
+    int i132_data[6] = {640000, 639980, 640400, 640380, 640800, 640780} ;
+    size_t i132_startset[3] = {0, 0, 0} ;
+    size_t i132_countset[3] = {1, 3, 2};
+    stat = nc_put_vara(ncid, i132_id, i132_startset, i132_countset, i132_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store d122 */
-    static double d122[] = {40000., 39990., 40100., 40090.};
-    stat = nc_put_var_double(ncid, d122_id, d122);
+
+    {
+    float f133_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)26406), ((float)26397), ((float)26388)} ;
+    size_t f133_startset[3] = {0, 0, 0} ;
+    size_t f133_countset[3] = {1, 3, 3};
+    stat = nc_put_vara(ncid, f133_id, f133_startset, f133_countset, f133_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store c123 */
-    static char c123[] = {"one2\000\000"};
-    stat = nc_put_var_text(ncid, c123_id, c123);
+
+    {
+    float f211_data[2] = {((float)26244), ((float)25515)} ;
+    size_t f211_startset[3] = {0, 0, 0} ;
+    size_t f211_countset[3] = {2, 1, 1};
+    stat = nc_put_vara(ncid, f211_id, f211_startset, f211_countset, f211_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s131 */
-    static short s131[] = {2500, 2525, 2550};
-    stat = nc_put_var_short(ncid, s131_id, s131);
+
+    {
+    double d212_data[4] = {((double)40000), ((double)39990), ((double)39000), ((double)38990)} ;
+    size_t d212_startset[3] = {0, 0, 0} ;
+    size_t d212_countset[3] = {2, 1, 2};
+    stat = nc_put_vara(ncid, d212_id, d212_startset, d212_countset, d212_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store i132 */
-    static int i132[] = {640000, 639980, 640400, 640380, 640800, 640780};
-    stat = nc_put_var_int(ncid, i132_id, i132);
+    {
+    char* c213_data = "\000\000\000\000\000\000" ;
+    size_t c213_startset[3] = {0, 0, 0} ;
+    size_t c213_countset[3] = {2, 1, 3};
+    stat = nc_put_vara(ncid, c213_id, c213_startset, c213_countset, c213_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f133 */
-    static float f133[] = {26244, 26235, 26226, 26325, 26316, 26307, 26406, 26397, 26388};
-    stat = nc_put_var_float(ncid, f133_id, f133);
+    {
+    short s221_data[4] = {2500, 2525, 2375, 2400} ;
+    size_t s221_startset[3] = {0, 0, 0} ;
+    size_t s221_countset[3] = {2, 2, 1};
+    stat = nc_put_vara(ncid, s221_id, s221_startset, s221_countset, s221_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f211 */
-    static float f211[] = {26244, 25515};
-    stat = nc_put_var_float(ncid, f211_id, f211);
+    {
+    int i222_data[8] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380} ;
+    size_t i222_startset[3] = {0, 0, 0} ;
+    size_t i222_countset[3] = {2, 2, 2};
+    stat = nc_put_vara(ncid, i222_id, i222_startset, i222_countset, i222_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d212 */
-    static double d212[] = {40000., 39990., 39000., 38990.};
-    stat = nc_put_var_double(ncid, d212_id, d212);
+    {
+    float f223_data[12] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)25515), ((float)25506), ((float)25497), ((float)25596), ((float)25587), ((float)25578)} ;
+    size_t f223_startset[3] = {0, 0, 0} ;
+    size_t f223_countset[3] = {2, 2, 3};
+    stat = nc_put_vara(ncid, f223_id, f223_startset, f223_countset, f223_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s221 */
-    static short s221[] = {2500, 2525, 2375, 2400};
-    stat = nc_put_var_short(ncid, s221_id, s221);
+
+    {
+    char* c231_data = "@DHHLP" ;
+    size_t c231_startset[3] = {0, 0, 0} ;
+    size_t c231_countset[3] = {2, 3, 1};
+    stat = nc_put_vara(ncid, c231_id, c231_startset, c231_countset, c231_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i222 */
-    static int i222[] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380};
-    stat = nc_put_var_int(ncid, i222_id, i222);
+
+    {
+    signed char b232_data[12] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62} ;
+    size_t b232_startset[3] = {0, 0, 0} ;
+    size_t b232_countset[3] = {2, 3, 2};
+    stat = nc_put_vara(ncid, b232_id, b232_startset, b232_countset, b232_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f223 */
-    static float f223[] = {26244, 26235, 26226, 26325, 26316, 26307, 25515, 25506, 25497, 25596, 25587, 25578};
-    stat = nc_put_var_float(ncid, f223_id, f223);
+
+    {
+    short s233_data[18] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415} ;
+    size_t s233_startset[3] = {0, 0, 0} ;
+    size_t s233_countset[3] = {2, 3, 3};
+    stat = nc_put_vara(ncid, s233_id, s233_startset, s233_countset, s233_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store c231 */
-    static char c231[] = {"@DHHLP"};
-    stat = nc_put_var_text(ncid, c231_id, c231);
+    {
+    short s311_data[3] = {2500, 2375, 2250} ;
+    size_t s311_startset[3] = {0, 0, 0} ;
+    size_t s311_countset[3] = {3, 1, 1};
+    stat = nc_put_vara(ncid, s311_id, s311_startset, s311_countset, s311_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store b232 */
-    static signed char b232[] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62};
-    stat = nc_put_var_schar(ncid, b232_id, b232);
+    {
+    int i312_data[6] = {640000, 639980, 632000, 631980, 624000, 623980} ;
+    size_t i312_startset[3] = {0, 0, 0} ;
+    size_t i312_countset[3] = {3, 1, 2};
+    stat = nc_put_vara(ncid, i312_id, i312_startset, i312_countset, i312_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store s233 */
-    static short s233[] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415};
-    stat = nc_put_var_short(ncid, s233_id, s233);
+    {
+    float f313_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497), ((float)24786), ((float)24777), ((float)24768)} ;
+    size_t f313_startset[3] = {0, 0, 0} ;
+    size_t f313_countset[3] = {3, 1, 3};
+    stat = nc_put_vara(ncid, f313_id, f313_startset, f313_countset, f313_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store s311 */
-    static short s311[] = {2500, 2375, 2250};
-    stat = nc_put_var_short(ncid, s311_id, s311);
+    {
+    size_t count = 0;
+    static double var_MINUS_name_MINUS_dashes_data[1] = {((double)-1)};
+    stat = nc_put_var1(ncid, var_MINUS_name_MINUS_dashes_id, &count, var_MINUS_name_MINUS_dashes_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i312 */
-    static int i312[] = {640000, 639980, 632000, 631980, 624000, 623980};
-    stat = nc_put_var_int(ncid, i312_id, i312);
+
+    {
+    size_t count = 0;
+    static double var_PERIOD_name_PERIOD_dots_data[1] = {((double)-2)};
+    stat = nc_put_var1(ncid, var_PERIOD_name_PERIOD_dots_id, &count, var_PERIOD_name_PERIOD_dots_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f313 */
-    static float f313[] = {26244, 26235, 26226, 25515, 25506, 25497, 24786, 24777, 24768};
-    stat = nc_put_var_float(ncid, f313_id, f313);
+
+    {
+    size_t count = 0;
+    static double var_PLUS_name_PLUS_plusses_data[1] = {((double)9.969209968386869e+36)};
+    stat = nc_put_var1(ncid, var_PLUS_name_PLUS_plusses_id, &count, var_PLUS_name_PLUS_plusses_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store var-name-dashes */
-    static double var_MINUS_name_MINUS_dashes = -1.;
-    stat = nc_put_var_double(ncid, var_MINUS_name_MINUS_dashes_id, &var_MINUS_name_MINUS_dashes);
+
+    {
+    size_t count = 0;
+    static double var_ATSIGN_name_ATSIGN_ats_data[1] = {((double)9.969209968386869e+36)};
+    stat = nc_put_var1(ncid, var_ATSIGN_name_ATSIGN_ats_id, &count, var_ATSIGN_name_ATSIGN_ats_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store var.name.dots */
-    static double var_PERIOD_name_PERIOD_dots = -2.;
-    stat = nc_put_var_double(ncid, var_PERIOD_name_PERIOD_dots_id, &var_PERIOD_name_PERIOD_dots);
+    stat = nc_close(ncid);
     check_err(stat,__LINE__,__FILE__);
-   }
-   stat = nc_close(ncid);
-   check_err(stat,__LINE__,__FILE__);
-   return 0;
+    return 0;
 }
diff --git a/ncdump/ref_ctest64.c b/ncdump/ref_ctest64.c
index ea89614..b5fb314 100644
--- a/ncdump/ref_ctest64.c
+++ b/ncdump/ref_ctest64.c
@@ -2,1332 +2,1471 @@
 #include <stdlib.h>
 #include <netcdf.h>
 
+
 void
 check_err(const int stat, const int line, const char *file) {
     if (stat != NC_NOERR) {
-	   (void) fprintf(stderr, "line %d of %s: %s\n", line, file, nc_strerror(stat));
+        (void)fprintf(stderr,"line %d of %s: %s\n", line, file, nc_strerror(stat));
+        fflush(stderr);
         exit(1);
     }
 }
 
 int
-main() {			/* create ctest0_64.nc */
-
-   int  stat;			/* return status */
-   int  ncid;			/* netCDF id */
-
-   /* dimension ids */
-   int Dr_dim;
-   int D1_dim;
-   int D2_dim;
-   int D3_dim;
-   int dim_MINUS_name_MINUS_dashes_dim;
-   int dim_PERIOD_name_PERIOD_dots_dim;
-   int dim_PLUS_name_PLUS_plusses_dim;
-   int dim_ATSIGN_name_ATSIGN_ats_dim;
-
-   /* dimension lengths */
-   size_t Dr_len = NC_UNLIMITED;
-   size_t D1_len = 1;
-   size_t D2_len = 2;
-   size_t D3_len = 3;
-   size_t dim_MINUS_name_MINUS_dashes_len = 4;
-   size_t dim_PERIOD_name_PERIOD_dots_len = 5;
-   size_t dim_PLUS_name_PLUS_plusses_len = 6;
-   size_t dim_ATSIGN_name_ATSIGN_ats_len = 7;
-
-   /* variable ids */
-   int c_id;
-   int b_id;
-   int s_id;
-   int i_id;
-   int f_id;
-   int d_id;
-   int cr_id;
-   int br_id;
-   int sr_id;
-   int ir_id;
-   int fr_id;
-   int dr_id;
-   int c1_id;
-   int b1_id;
-   int s1_id;
-   int i1_id;
-   int f1_id;
-   int d1_id;
-   int c2_id;
-   int b2_id;
-   int s2_id;
-   int i2_id;
-   int f2_id;
-   int d2_id;
-   int c3_id;
-   int b3_id;
-   int s3_id;
-   int i3_id;
-   int f3_id;
-   int d3_id;
-   int cr1_id;
-   int br2_id;
-   int sr3_id;
-   int f11_id;
-   int d12_id;
-   int c13_id;
-   int s21_id;
-   int i22_id;
-   int f23_id;
-   int c31_id;
-   int b32_id;
-   int s33_id;
-   int sr11_id;
-   int ir12_id;
-   int fr13_id;
-   int cr21_id;
-   int br22_id;
-   int sr23_id;
-   int fr31_id;
-   int dr32_id;
-   int cr33_id;
-   int c111_id;
-   int b112_id;
-   int s113_id;
-   int f121_id;
-   int d122_id;
-   int c123_id;
-   int s131_id;
-   int i132_id;
-   int f133_id;
-   int f211_id;
-   int d212_id;
-   int c213_id;
-   int s221_id;
-   int i222_id;
-   int f223_id;
-   int c231_id;
-   int b232_id;
-   int s233_id;
-   int s311_id;
-   int i312_id;
-   int f313_id;
-   int var_MINUS_name_MINUS_dashes_id;
-   int var_PERIOD_name_PERIOD_dots_id;
-   int var_PLUS_name_PLUS_plusses_id;
-   int var_ATSIGN_name_ATSIGN_ats_id;
-
-   /* rank (number of dimensions) for each variable */
-#  define RANK_c 0
-#  define RANK_b 0
-#  define RANK_s 0
-#  define RANK_i 0
-#  define RANK_f 0
-#  define RANK_d 0
-#  define RANK_cr 1
-#  define RANK_br 1
-#  define RANK_sr 1
-#  define RANK_ir 1
-#  define RANK_fr 1
-#  define RANK_dr 1
-#  define RANK_c1 1
-#  define RANK_b1 1
-#  define RANK_s1 1
-#  define RANK_i1 1
-#  define RANK_f1 1
-#  define RANK_d1 1
-#  define RANK_c2 1
-#  define RANK_b2 1
-#  define RANK_s2 1
-#  define RANK_i2 1
-#  define RANK_f2 1
-#  define RANK_d2 1
-#  define RANK_c3 1
-#  define RANK_b3 1
-#  define RANK_s3 1
-#  define RANK_i3 1
-#  define RANK_f3 1
-#  define RANK_d3 1
-#  define RANK_cr1 2
-#  define RANK_br2 2
-#  define RANK_sr3 2
-#  define RANK_f11 2
-#  define RANK_d12 2
-#  define RANK_c13 2
-#  define RANK_s21 2
-#  define RANK_i22 2
-#  define RANK_f23 2
-#  define RANK_c31 2
-#  define RANK_b32 2
-#  define RANK_s33 2
-#  define RANK_sr11 3
-#  define RANK_ir12 3
-#  define RANK_fr13 3
-#  define RANK_cr21 3
-#  define RANK_br22 3
-#  define RANK_sr23 3
-#  define RANK_fr31 3
-#  define RANK_dr32 3
-#  define RANK_cr33 3
-#  define RANK_c111 3
-#  define RANK_b112 3
-#  define RANK_s113 3
-#  define RANK_f121 3
-#  define RANK_d122 3
-#  define RANK_c123 3
-#  define RANK_s131 3
-#  define RANK_i132 3
-#  define RANK_f133 3
-#  define RANK_f211 3
-#  define RANK_d212 3
-#  define RANK_c213 3
-#  define RANK_s221 3
-#  define RANK_i222 3
-#  define RANK_f223 3
-#  define RANK_c231 3
-#  define RANK_b232 3
-#  define RANK_s233 3
-#  define RANK_s311 3
-#  define RANK_i312 3
-#  define RANK_f313 3
-#  define RANK_var_MINUS_name_MINUS_dashes 0
-#  define RANK_var_PERIOD_name_PERIOD_dots 0
-#  define RANK_var_PLUS_name_PLUS_plusses 0
-#  define RANK_var_ATSIGN_name_ATSIGN_ats 0
-
-   /* variable shapes */
-   int cr_dims[RANK_cr];
-   int br_dims[RANK_br];
-   int sr_dims[RANK_sr];
-   int ir_dims[RANK_ir];
-   int fr_dims[RANK_fr];
-   int dr_dims[RANK_dr];
-   int c1_dims[RANK_c1];
-   int b1_dims[RANK_b1];
-   int s1_dims[RANK_s1];
-   int i1_dims[RANK_i1];
-   int f1_dims[RANK_f1];
-   int d1_dims[RANK_d1];
-   int c2_dims[RANK_c2];
-   int b2_dims[RANK_b2];
-   int s2_dims[RANK_s2];
-   int i2_dims[RANK_i2];
-   int f2_dims[RANK_f2];
-   int d2_dims[RANK_d2];
-   int c3_dims[RANK_c3];
-   int b3_dims[RANK_b3];
-   int s3_dims[RANK_s3];
-   int i3_dims[RANK_i3];
-   int f3_dims[RANK_f3];
-   int d3_dims[RANK_d3];
-   int cr1_dims[RANK_cr1];
-   int br2_dims[RANK_br2];
-   int sr3_dims[RANK_sr3];
-   int f11_dims[RANK_f11];
-   int d12_dims[RANK_d12];
-   int c13_dims[RANK_c13];
-   int s21_dims[RANK_s21];
-   int i22_dims[RANK_i22];
-   int f23_dims[RANK_f23];
-   int c31_dims[RANK_c31];
-   int b32_dims[RANK_b32];
-   int s33_dims[RANK_s33];
-   int sr11_dims[RANK_sr11];
-   int ir12_dims[RANK_ir12];
-   int fr13_dims[RANK_fr13];
-   int cr21_dims[RANK_cr21];
-   int br22_dims[RANK_br22];
-   int sr23_dims[RANK_sr23];
-   int fr31_dims[RANK_fr31];
-   int dr32_dims[RANK_dr32];
-   int cr33_dims[RANK_cr33];
-   int c111_dims[RANK_c111];
-   int b112_dims[RANK_b112];
-   int s113_dims[RANK_s113];
-   int f121_dims[RANK_f121];
-   int d122_dims[RANK_d122];
-   int c123_dims[RANK_c123];
-   int s131_dims[RANK_s131];
-   int i132_dims[RANK_i132];
-   int f133_dims[RANK_f133];
-   int f211_dims[RANK_f211];
-   int d212_dims[RANK_d212];
-   int c213_dims[RANK_c213];
-   int s221_dims[RANK_s221];
-   int i222_dims[RANK_i222];
-   int f223_dims[RANK_f223];
-   int c231_dims[RANK_c231];
-   int b232_dims[RANK_b232];
-   int s233_dims[RANK_s233];
-   int s311_dims[RANK_s311];
-   int i312_dims[RANK_i312];
-   int f313_dims[RANK_f313];
-
-   /* attribute vectors */
-   int c_att_MINUS_name_MINUS_dashes[1];
-   int c_att_PERIOD_name_PERIOD_dots[1];
-   int c_att_PLUS_name_PLUS_plusses[1];
-   int c_att_ATSIGN_name_ATSIGN_ats[1];
-   int s_b[4];
-   short s_s[3];
-   int i_i[3];
-   float i_f[3];
-   double i_d[3];
-   int cdf_Gb[2];
-   short cdf_Gs[3];
-   int cdf_Gi[3];
-   float cdf_Gf[3];
-   double cdf_Gd[3];
-   int cdf_Gatt_MINUS_name_MINUS_dashes[1];
-   int cdf_Gatt_PERIOD_name_PERIOD_dots[1];
-   int cdf_Gatt_PLUS_name_PLUS_plusses[1];
-   int cdf_Gatt_ATSIGN_name_ATSIGN_ats[1];
-
-   /* enter define mode */
-   stat = nc_create("ctest0_64.nc", NC_CLOBBER|NC_64BIT_OFFSET, &ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define dimensions */
-   stat = nc_def_dim(ncid, "Dr", Dr_len, &Dr_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "D1", D1_len, &D1_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "D2", D2_len, &D2_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "D3", D3_len, &D3_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim-name-dashes", dim_MINUS_name_MINUS_dashes_len, &dim_MINUS_name_MINUS_dashes_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim.name.dots", dim_PERIOD_name_PERIOD_dots_len, &dim_PERIOD_name_PERIOD_dots_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim+name+plusses", dim_PLUS_name_PLUS_plusses_len, &dim_PLUS_name_PLUS_plusses_dim);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_def_dim(ncid, "dim at name@ats", dim_ATSIGN_name_ATSIGN_ats_len, &dim_ATSIGN_name_ATSIGN_ats_dim);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* define variables */
-
-   stat = nc_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   br_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   ir_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   fr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   dr_dims[0] = Dr_dim;
-   stat = nc_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d1_dims[0] = D1_dim;
-   stat = nc_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d2_dims[0] = D2_dim;
-   stat = nc_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d3_dims[0] = D3_dim;
-   stat = nc_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr1_dims[0] = Dr_dim;
-   cr1_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   br2_dims[0] = Dr_dim;
-   br2_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr3_dims[0] = Dr_dim;
-   sr3_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f11_dims[0] = D1_dim;
-   f11_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d12_dims[0] = D1_dim;
-   d12_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c13_dims[0] = D1_dim;
-   c13_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s21_dims[0] = D2_dim;
-   s21_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i22_dims[0] = D2_dim;
-   i22_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f23_dims[0] = D2_dim;
-   f23_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c31_dims[0] = D3_dim;
-   c31_dims[1] = D1_dim;
-   stat = nc_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b32_dims[0] = D3_dim;
-   b32_dims[1] = D2_dim;
-   stat = nc_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s33_dims[0] = D3_dim;
-   s33_dims[1] = D3_dim;
-   stat = nc_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr11_dims[0] = Dr_dim;
-   sr11_dims[1] = D1_dim;
-   sr11_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   ir12_dims[0] = Dr_dim;
-   ir12_dims[1] = D1_dim;
-   ir12_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   fr13_dims[0] = Dr_dim;
-   fr13_dims[1] = D1_dim;
-   fr13_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr21_dims[0] = Dr_dim;
-   cr21_dims[1] = D2_dim;
-   cr21_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   br22_dims[0] = Dr_dim;
-   br22_dims[1] = D2_dim;
-   br22_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   sr23_dims[0] = Dr_dim;
-   sr23_dims[1] = D2_dim;
-   sr23_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   fr31_dims[0] = Dr_dim;
-   fr31_dims[1] = D3_dim;
-   fr31_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   dr32_dims[0] = Dr_dim;
-   dr32_dims[1] = D3_dim;
-   dr32_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   cr33_dims[0] = Dr_dim;
-   cr33_dims[1] = D3_dim;
-   cr33_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c111_dims[0] = D1_dim;
-   c111_dims[1] = D1_dim;
-   c111_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b112_dims[0] = D1_dim;
-   b112_dims[1] = D1_dim;
-   b112_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s113_dims[0] = D1_dim;
-   s113_dims[1] = D1_dim;
-   s113_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f121_dims[0] = D1_dim;
-   f121_dims[1] = D2_dim;
-   f121_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d122_dims[0] = D1_dim;
-   d122_dims[1] = D2_dim;
-   d122_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c123_dims[0] = D1_dim;
-   c123_dims[1] = D2_dim;
-   c123_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s131_dims[0] = D1_dim;
-   s131_dims[1] = D3_dim;
-   s131_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i132_dims[0] = D1_dim;
-   i132_dims[1] = D3_dim;
-   i132_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f133_dims[0] = D1_dim;
-   f133_dims[1] = D3_dim;
-   f133_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f211_dims[0] = D2_dim;
-   f211_dims[1] = D1_dim;
-   f211_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   d212_dims[0] = D2_dim;
-   d212_dims[1] = D1_dim;
-   d212_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c213_dims[0] = D2_dim;
-   c213_dims[1] = D1_dim;
-   c213_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s221_dims[0] = D2_dim;
-   s221_dims[1] = D2_dim;
-   s221_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i222_dims[0] = D2_dim;
-   i222_dims[1] = D2_dim;
-   i222_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f223_dims[0] = D2_dim;
-   f223_dims[1] = D2_dim;
-   f223_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   c231_dims[0] = D2_dim;
-   c231_dims[1] = D3_dim;
-   c231_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   b232_dims[0] = D2_dim;
-   b232_dims[1] = D3_dim;
-   b232_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s233_dims[0] = D2_dim;
-   s233_dims[1] = D3_dim;
-   s233_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   s311_dims[0] = D3_dim;
-   s311_dims[1] = D1_dim;
-   s311_dims[2] = D1_dim;
-   stat = nc_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   i312_dims[0] = D3_dim;
-   i312_dims[1] = D1_dim;
-   i312_dims[2] = D2_dim;
-   stat = nc_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   f313_dims[0] = D3_dim;
-   f313_dims[1] = D1_dim;
-   f313_dims[2] = D3_dim;
-   stat = nc_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var-name-dashes", NC_DOUBLE, RANK_var_MINUS_name_MINUS_dashes, 0, &var_MINUS_name_MINUS_dashes_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var.name.dots", NC_DOUBLE, RANK_var_PERIOD_name_PERIOD_dots, 0, &var_PERIOD_name_PERIOD_dots_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var+name+plusses", NC_DOUBLE, RANK_var_PLUS_name_PLUS_plusses, 0, &var_PLUS_name_PLUS_plusses_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   stat = nc_def_var(ncid, "var at name@ats", NC_DOUBLE, RANK_var_ATSIGN_name_ATSIGN_ats, 0, &var_ATSIGN_name_ATSIGN_ats_id);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* assign attributes */
-   c_att_MINUS_name_MINUS_dashes[0] = 4;
-   stat = nc_put_att_int(ncid, c_id, "att-name-dashes", NC_INT, 1, c_att_MINUS_name_MINUS_dashes);
-   check_err(stat,__LINE__,__FILE__);
-   c_att_PERIOD_name_PERIOD_dots[0] = 5;
-   stat = nc_put_att_int(ncid, c_id, "att.name.dots", NC_INT, 1, c_att_PERIOD_name_PERIOD_dots);
-   check_err(stat,__LINE__,__FILE__);
-   c_att_PLUS_name_PLUS_plusses[0] = 6;
-   stat = nc_put_att_int(ncid, c_id, "att+name+plusses", NC_INT, 1, c_att_PLUS_name_PLUS_plusses);
-   check_err(stat,__LINE__,__FILE__);
-   c_att_ATSIGN_name_ATSIGN_ats[0] = 7;
-   stat = nc_put_att_int(ncid, c_id, "att at name@ats", NC_INT, 1, c_att_ATSIGN_name_ATSIGN_ats);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, b_id, "c", 1, "");
-   check_err(stat,__LINE__,__FILE__);
-   s_b[0] = 0;
-   s_b[1] = 127;
-   s_b[2] = -128;
-   s_b[3] = -1;
-   stat = nc_put_att_int(ncid, s_id, "b", NC_BYTE, 4, s_b);
-   check_err(stat,__LINE__,__FILE__);
-   s_s[0] = -32768;
-   s_s[1] = 0;
-   s_s[2] = 32767;
-   stat = nc_put_att_short(ncid, s_id, "s", NC_SHORT, 3, s_s);
-   check_err(stat,__LINE__,__FILE__);
-   i_i[0] = -2147483647;
-   i_i[1] = 0;
-   i_i[2] = 2147483647;
-   stat = nc_put_att_int(ncid, i_id, "i", NC_INT, 3, i_i);
-   check_err(stat,__LINE__,__FILE__);
-   i_f[0] = -9.9999996e+35;
-   i_f[1] = 0;
-   i_f[2] = 9.9999996e+35;
-   stat = nc_put_att_float(ncid, i_id, "f", NC_FLOAT, 3, i_f);
-   check_err(stat,__LINE__,__FILE__);
-   i_d[0] = -1e+308;
-   i_d[1] = 0;
-   i_d[2] = 1e+308;
-   stat = nc_put_att_double(ncid, i_id, "d", NC_DOUBLE, 3, i_d);
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, f_id, "c", 1, "x");
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, d_id, "c", 8, "abcd\tZ$&");
-   check_err(stat,__LINE__,__FILE__);
-   stat = nc_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "");
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gb[0] = -128;
-   cdf_Gb[1] = 127;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, cdf_Gb);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gs[0] = -32768;
-   cdf_Gs[1] = 0;
-   cdf_Gs[2] = 32767;
-   stat = nc_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, cdf_Gs);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gi[0] = -2147483647;
-   cdf_Gi[1] = 0;
-   cdf_Gi[2] = 2147483647;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 3, cdf_Gi);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gf[0] = -9.9999996e+35;
-   cdf_Gf[1] = 0;
-   cdf_Gf[2] = 9.9999996e+35;
-   stat = nc_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 3, cdf_Gf);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gd[0] = -1e+308;
-   cdf_Gd[1] = 0;
-   cdf_Gd[2] = 1e+308;
-   stat = nc_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 3, cdf_Gd);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_MINUS_name_MINUS_dashes[0] = -1;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt-name-dashes", NC_INT, 1, cdf_Gatt_MINUS_name_MINUS_dashes);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_PERIOD_name_PERIOD_dots[0] = -2;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt.name.dots", NC_INT, 1, cdf_Gatt_PERIOD_name_PERIOD_dots);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_PLUS_name_PLUS_plusses[0] = -3;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt+name+plusses", NC_INT, 1, cdf_Gatt_PLUS_name_PLUS_plusses);
-   check_err(stat,__LINE__,__FILE__);
-   cdf_Gatt_ATSIGN_name_ATSIGN_ats[0] = -4;
-   stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt at name@ats", NC_INT, 1, cdf_Gatt_ATSIGN_name_ATSIGN_ats);
-   check_err(stat,__LINE__,__FILE__);
-
-   /* leave define mode */
-   stat = nc_enddef (ncid);
-   check_err(stat,__LINE__,__FILE__);
-
-   {			/* store c */
-    static char c = '2';
-    stat = nc_put_var_text(ncid, c_id, &c);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store b */
-    static signed char b = -2;
-    stat = nc_put_var_schar(ncid, b_id, &b);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s */
-    static short s = -5;
-    stat = nc_put_var_short(ncid, s_id, &s);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store i */
-    static int i = -20;
-    stat = nc_put_var_int(ncid, i_id, &i);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store f */
-    static float f = -9;
-    stat = nc_put_var_float(ncid, f_id, &f);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store d */
-    static double d = -10.;
-    stat = nc_put_var_double(ncid, d_id, &d);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store cr */
-    static size_t cr_start[RANK_cr];
-    static size_t cr_count[RANK_cr];
-    static char cr[] = {"ab"};
-    Dr_len = 2;			/* number of records of cr data */
-    cr_start[0] = 0;
-    cr_count[0] = Dr_len;
-    stat = nc_put_vara_text(ncid, cr_id, cr_start, cr_count, cr);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store br */
-    static size_t br_start[RANK_br];
-    static size_t br_count[RANK_br];
-    static signed char br[] = {-128, 127};
-    Dr_len = 2;			/* number of records of br data */
-    br_start[0] = 0;
-    br_count[0] = Dr_len;
-    stat = nc_put_vara_schar(ncid, br_id, br_start, br_count, br);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store sr */
-    static size_t sr_start[RANK_sr];
-    static size_t sr_count[RANK_sr];
-    static short sr[] = {-32768, 32767};
-    Dr_len = 2;			/* number of records of sr data */
-    sr_start[0] = 0;
-    sr_count[0] = Dr_len;
-    stat = nc_put_vara_short(ncid, sr_id, sr_start, sr_count, sr);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store ir */
-    static size_t ir_start[RANK_ir];
-    static size_t ir_count[RANK_ir];
-    static int ir[] = {-2147483646, 2147483647};
-    Dr_len = 2;			/* number of records of ir data */
-    ir_start[0] = 0;
-    ir_count[0] = Dr_len;
-    stat = nc_put_vara_int(ncid, ir_id, ir_start, ir_count, ir);
+main() {/* create ctest0_64.nc */
+
+    int  stat;  /* return status */
+    int  ncid;  /* netCDF id */
+
+    /* dimension ids */
+    int Dr_dim;
+    int D1_dim;
+    int D2_dim;
+    int D3_dim;
+    int dim_MINUS_name_MINUS_dashes_dim;
+    int dim_PERIOD_name_PERIOD_dots_dim;
+    int dim_PLUS_name_PLUS_plusses_dim;
+    int dim_ATSIGN_name_ATSIGN_ats_dim;
+
+    /* dimension lengths */
+    size_t Dr_len = NC_UNLIMITED;
+    size_t D1_len = 1;
+    size_t D2_len = 2;
+    size_t D3_len = 3;
+    size_t dim_MINUS_name_MINUS_dashes_len = 4;
+    size_t dim_PERIOD_name_PERIOD_dots_len = 5;
+    size_t dim_PLUS_name_PLUS_plusses_len = 6;
+    size_t dim_ATSIGN_name_ATSIGN_ats_len = 7;
+
+    /* variable ids */
+    int c_id;
+    int b_id;
+    int s_id;
+    int i_id;
+    int f_id;
+    int d_id;
+    int cr_id;
+    int br_id;
+    int sr_id;
+    int ir_id;
+    int fr_id;
+    int dr_id;
+    int c1_id;
+    int b1_id;
+    int s1_id;
+    int i1_id;
+    int f1_id;
+    int d1_id;
+    int c2_id;
+    int b2_id;
+    int s2_id;
+    int i2_id;
+    int f2_id;
+    int d2_id;
+    int c3_id;
+    int b3_id;
+    int s3_id;
+    int i3_id;
+    int f3_id;
+    int d3_id;
+    int cr1_id;
+    int br2_id;
+    int sr3_id;
+    int f11_id;
+    int d12_id;
+    int c13_id;
+    int s21_id;
+    int i22_id;
+    int f23_id;
+    int c31_id;
+    int b32_id;
+    int s33_id;
+    int sr11_id;
+    int ir12_id;
+    int fr13_id;
+    int cr21_id;
+    int br22_id;
+    int sr23_id;
+    int fr31_id;
+    int dr32_id;
+    int cr33_id;
+    int c111_id;
+    int b112_id;
+    int s113_id;
+    int f121_id;
+    int d122_id;
+    int c123_id;
+    int s131_id;
+    int i132_id;
+    int f133_id;
+    int f211_id;
+    int d212_id;
+    int c213_id;
+    int s221_id;
+    int i222_id;
+    int f223_id;
+    int c231_id;
+    int b232_id;
+    int s233_id;
+    int s311_id;
+    int i312_id;
+    int f313_id;
+    int var_MINUS_name_MINUS_dashes_id;
+    int var_PERIOD_name_PERIOD_dots_id;
+    int var_PLUS_name_PLUS_plusses_id;
+    int var_ATSIGN_name_ATSIGN_ats_id;
+
+    /* rank (number of dimensions) for each variable */
+#   define RANK_c 0
+#   define RANK_b 0
+#   define RANK_s 0
+#   define RANK_i 0
+#   define RANK_f 0
+#   define RANK_d 0
+#   define RANK_cr 1
+#   define RANK_br 1
+#   define RANK_sr 1
+#   define RANK_ir 1
+#   define RANK_fr 1
+#   define RANK_dr 1
+#   define RANK_c1 1
+#   define RANK_b1 1
+#   define RANK_s1 1
+#   define RANK_i1 1
+#   define RANK_f1 1
+#   define RANK_d1 1
+#   define RANK_c2 1
+#   define RANK_b2 1
+#   define RANK_s2 1
+#   define RANK_i2 1
+#   define RANK_f2 1
+#   define RANK_d2 1
+#   define RANK_c3 1
+#   define RANK_b3 1
+#   define RANK_s3 1
+#   define RANK_i3 1
+#   define RANK_f3 1
+#   define RANK_d3 1
+#   define RANK_cr1 2
+#   define RANK_br2 2
+#   define RANK_sr3 2
+#   define RANK_f11 2
+#   define RANK_d12 2
+#   define RANK_c13 2
+#   define RANK_s21 2
+#   define RANK_i22 2
+#   define RANK_f23 2
+#   define RANK_c31 2
+#   define RANK_b32 2
+#   define RANK_s33 2
+#   define RANK_sr11 3
+#   define RANK_ir12 3
+#   define RANK_fr13 3
+#   define RANK_cr21 3
+#   define RANK_br22 3
+#   define RANK_sr23 3
+#   define RANK_fr31 3
+#   define RANK_dr32 3
+#   define RANK_cr33 3
+#   define RANK_c111 3
+#   define RANK_b112 3
+#   define RANK_s113 3
+#   define RANK_f121 3
+#   define RANK_d122 3
+#   define RANK_c123 3
+#   define RANK_s131 3
+#   define RANK_i132 3
+#   define RANK_f133 3
+#   define RANK_f211 3
+#   define RANK_d212 3
+#   define RANK_c213 3
+#   define RANK_s221 3
+#   define RANK_i222 3
+#   define RANK_f223 3
+#   define RANK_c231 3
+#   define RANK_b232 3
+#   define RANK_s233 3
+#   define RANK_s311 3
+#   define RANK_i312 3
+#   define RANK_f313 3
+#   define RANK_var_MINUS_name_MINUS_dashes 0
+#   define RANK_var_PERIOD_name_PERIOD_dots 0
+#   define RANK_var_PLUS_name_PLUS_plusses 0
+#   define RANK_var_ATSIGN_name_ATSIGN_ats 0
+
+    /* variable shapes */
+    int cr_dims[RANK_cr];
+    int br_dims[RANK_br];
+    int sr_dims[RANK_sr];
+    int ir_dims[RANK_ir];
+    int fr_dims[RANK_fr];
+    int dr_dims[RANK_dr];
+    int c1_dims[RANK_c1];
+    int b1_dims[RANK_b1];
+    int s1_dims[RANK_s1];
+    int i1_dims[RANK_i1];
+    int f1_dims[RANK_f1];
+    int d1_dims[RANK_d1];
+    int c2_dims[RANK_c2];
+    int b2_dims[RANK_b2];
+    int s2_dims[RANK_s2];
+    int i2_dims[RANK_i2];
+    int f2_dims[RANK_f2];
+    int d2_dims[RANK_d2];
+    int c3_dims[RANK_c3];
+    int b3_dims[RANK_b3];
+    int s3_dims[RANK_s3];
+    int i3_dims[RANK_i3];
+    int f3_dims[RANK_f3];
+    int d3_dims[RANK_d3];
+    int cr1_dims[RANK_cr1];
+    int br2_dims[RANK_br2];
+    int sr3_dims[RANK_sr3];
+    int f11_dims[RANK_f11];
+    int d12_dims[RANK_d12];
+    int c13_dims[RANK_c13];
+    int s21_dims[RANK_s21];
+    int i22_dims[RANK_i22];
+    int f23_dims[RANK_f23];
+    int c31_dims[RANK_c31];
+    int b32_dims[RANK_b32];
+    int s33_dims[RANK_s33];
+    int sr11_dims[RANK_sr11];
+    int ir12_dims[RANK_ir12];
+    int fr13_dims[RANK_fr13];
+    int cr21_dims[RANK_cr21];
+    int br22_dims[RANK_br22];
+    int sr23_dims[RANK_sr23];
+    int fr31_dims[RANK_fr31];
+    int dr32_dims[RANK_dr32];
+    int cr33_dims[RANK_cr33];
+    int c111_dims[RANK_c111];
+    int b112_dims[RANK_b112];
+    int s113_dims[RANK_s113];
+    int f121_dims[RANK_f121];
+    int d122_dims[RANK_d122];
+    int c123_dims[RANK_c123];
+    int s131_dims[RANK_s131];
+    int i132_dims[RANK_i132];
+    int f133_dims[RANK_f133];
+    int f211_dims[RANK_f211];
+    int d212_dims[RANK_d212];
+    int c213_dims[RANK_c213];
+    int s221_dims[RANK_s221];
+    int i222_dims[RANK_i222];
+    int f223_dims[RANK_f223];
+    int c231_dims[RANK_c231];
+    int b232_dims[RANK_b232];
+    int s233_dims[RANK_s233];
+    int s311_dims[RANK_s311];
+    int i312_dims[RANK_i312];
+    int f313_dims[RANK_f313];
+
+    /* enter define mode */
+    stat = nc_create("ctest0_64.nc", NC_CLOBBER|NC_64BIT_OFFSET, &ncid);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* define dimensions */
+    stat = nc_def_dim(ncid, "Dr", Dr_len, &Dr_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "D1", D1_len, &D1_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "D2", D2_len, &D2_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "D3", D3_len, &D3_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim-name-dashes", dim_MINUS_name_MINUS_dashes_len, &dim_MINUS_name_MINUS_dashes_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim.name.dots", dim_PERIOD_name_PERIOD_dots_len, &dim_PERIOD_name_PERIOD_dots_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim+name+plusses", dim_PLUS_name_PLUS_plusses_len, &dim_PLUS_name_PLUS_plusses_dim);
+    check_err(stat,__LINE__,__FILE__);
+    stat = nc_def_dim(ncid, "dim at name@ats", dim_ATSIGN_name_ATSIGN_ats_len, &dim_ATSIGN_name_ATSIGN_ats_dim);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* define variables */
+
+    stat = nc_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    br_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    ir_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    fr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    dr_dims[0] = Dr_dim;
+    stat = nc_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d1_dims[0] = D1_dim;
+    stat = nc_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d2_dims[0] = D2_dim;
+    stat = nc_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d3_dims[0] = D3_dim;
+    stat = nc_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr1_dims[0] = Dr_dim;
+    cr1_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    br2_dims[0] = Dr_dim;
+    br2_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr3_dims[0] = Dr_dim;
+    sr3_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f11_dims[0] = D1_dim;
+    f11_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d12_dims[0] = D1_dim;
+    d12_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c13_dims[0] = D1_dim;
+    c13_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s21_dims[0] = D2_dim;
+    s21_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i22_dims[0] = D2_dim;
+    i22_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f23_dims[0] = D2_dim;
+    f23_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c31_dims[0] = D3_dim;
+    c31_dims[1] = D1_dim;
+    stat = nc_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b32_dims[0] = D3_dim;
+    b32_dims[1] = D2_dim;
+    stat = nc_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s33_dims[0] = D3_dim;
+    s33_dims[1] = D3_dim;
+    stat = nc_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr11_dims[0] = Dr_dim;
+    sr11_dims[1] = D1_dim;
+    sr11_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    ir12_dims[0] = Dr_dim;
+    ir12_dims[1] = D1_dim;
+    ir12_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    fr13_dims[0] = Dr_dim;
+    fr13_dims[1] = D1_dim;
+    fr13_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr21_dims[0] = Dr_dim;
+    cr21_dims[1] = D2_dim;
+    cr21_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    br22_dims[0] = Dr_dim;
+    br22_dims[1] = D2_dim;
+    br22_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    sr23_dims[0] = Dr_dim;
+    sr23_dims[1] = D2_dim;
+    sr23_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    fr31_dims[0] = Dr_dim;
+    fr31_dims[1] = D3_dim;
+    fr31_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    dr32_dims[0] = Dr_dim;
+    dr32_dims[1] = D3_dim;
+    dr32_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    cr33_dims[0] = Dr_dim;
+    cr33_dims[1] = D3_dim;
+    cr33_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c111_dims[0] = D1_dim;
+    c111_dims[1] = D1_dim;
+    c111_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b112_dims[0] = D1_dim;
+    b112_dims[1] = D1_dim;
+    b112_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s113_dims[0] = D1_dim;
+    s113_dims[1] = D1_dim;
+    s113_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f121_dims[0] = D1_dim;
+    f121_dims[1] = D2_dim;
+    f121_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d122_dims[0] = D1_dim;
+    d122_dims[1] = D2_dim;
+    d122_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c123_dims[0] = D1_dim;
+    c123_dims[1] = D2_dim;
+    c123_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s131_dims[0] = D1_dim;
+    s131_dims[1] = D3_dim;
+    s131_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i132_dims[0] = D1_dim;
+    i132_dims[1] = D3_dim;
+    i132_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f133_dims[0] = D1_dim;
+    f133_dims[1] = D3_dim;
+    f133_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f211_dims[0] = D2_dim;
+    f211_dims[1] = D1_dim;
+    f211_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    d212_dims[0] = D2_dim;
+    d212_dims[1] = D1_dim;
+    d212_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c213_dims[0] = D2_dim;
+    c213_dims[1] = D1_dim;
+    c213_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s221_dims[0] = D2_dim;
+    s221_dims[1] = D2_dim;
+    s221_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i222_dims[0] = D2_dim;
+    i222_dims[1] = D2_dim;
+    i222_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f223_dims[0] = D2_dim;
+    f223_dims[1] = D2_dim;
+    f223_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    c231_dims[0] = D2_dim;
+    c231_dims[1] = D3_dim;
+    c231_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    b232_dims[0] = D2_dim;
+    b232_dims[1] = D3_dim;
+    b232_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s233_dims[0] = D2_dim;
+    s233_dims[1] = D3_dim;
+    s233_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    s311_dims[0] = D3_dim;
+    s311_dims[1] = D1_dim;
+    s311_dims[2] = D1_dim;
+    stat = nc_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    i312_dims[0] = D3_dim;
+    i312_dims[1] = D1_dim;
+    i312_dims[2] = D2_dim;
+    stat = nc_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    f313_dims[0] = D3_dim;
+    f313_dims[1] = D1_dim;
+    f313_dims[2] = D3_dim;
+    stat = nc_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var-name-dashes", NC_DOUBLE, RANK_var_MINUS_name_MINUS_dashes, 0, &var_MINUS_name_MINUS_dashes_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var.name.dots", NC_DOUBLE, RANK_var_PERIOD_name_PERIOD_dots, 0, &var_PERIOD_name_PERIOD_dots_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var+name+plusses", NC_DOUBLE, RANK_var_PLUS_name_PLUS_plusses, 0, &var_PLUS_name_PLUS_plusses_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    stat = nc_def_var(ncid, "var at name@ats", NC_DOUBLE, RANK_var_ATSIGN_name_ATSIGN_ats, 0, &var_ATSIGN_name_ATSIGN_ats_id);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* assign global attributes */
+
+    {
+    stat = nc_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const signed char c0_Gb_att[2] = {-128, 127} ;
+    stat = nc_put_att_schar(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, c0_Gb_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const short c0_Gs_att[3] = {-32768, 0, 32767} ;
+    stat = nc_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, c0_Gs_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gi_att[3] = {-2147483647, 0, 2147483647} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 3, c0_Gi_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const float c0_Gf_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
+    stat = nc_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 3, c0_Gf_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const double c0_Gd_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
+    stat = nc_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 3, c0_Gd_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_MINUS_name_MINUS_dashes_att[1] = {-1} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt-name-dashes", NC_INT, 1, c0_Gatt_MINUS_name_MINUS_dashes_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_DOT_name_DOT_dots_att[1] = {-2} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt.name.dots", NC_INT, 1, c0_Gatt_DOT_name_DOT_dots_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_PLUS_name_PLUS_plusses_att[1] = {-3} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt+name+plusses", NC_INT, 1, c0_Gatt_PLUS_name_PLUS_plusses_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_Gatt_ATSIGN_name_ATSIGN_ats_att[1] = {-4} ;
+    stat = nc_put_att_int(ncid, NC_GLOBAL, "Gatt at name@ats", NC_INT, 1, c0_Gatt_ATSIGN_name_ATSIGN_ats_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    /* assign per-variable attributes */
+
+    {
+    static const int c0_att_MINUS_name_MINUS_dashes_att[1] = {4} ;
+    stat = nc_put_att_int(ncid, c_id, "att-name-dashes", NC_INT, 1, c0_att_MINUS_name_MINUS_dashes_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_att_DOT_name_DOT_dots_att[1] = {5} ;
+    stat = nc_put_att_int(ncid, c_id, "att.name.dots", NC_INT, 1, c0_att_DOT_name_DOT_dots_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_att_PLUS_name_PLUS_plusses_att[1] = {6} ;
+    stat = nc_put_att_int(ncid, c_id, "att+name+plusses", NC_INT, 1, c0_att_PLUS_name_PLUS_plusses_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_att_ATSIGN_name_ATSIGN_ats_att[1] = {7} ;
+    stat = nc_put_att_int(ncid, c_id, "att at name@ats", NC_INT, 1, c0_att_ATSIGN_name_ATSIGN_ats_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    stat = nc_put_att_text(ncid, b_id, "c", 1, "");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const signed char c0_b_att[4] = {0, 127, -128, -1} ;
+    stat = nc_put_att_schar(ncid, s_id, "b", NC_BYTE, 4, c0_b_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const short c0_s_att[3] = {-32768, 0, 32767} ;
+    stat = nc_put_att_short(ncid, s_id, "s", NC_SHORT, 3, c0_s_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const int c0_i_att[3] = {-2147483647, 0, 2147483647} ;
+    stat = nc_put_att_int(ncid, i_id, "i", NC_INT, 3, c0_i_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const float c0_f_att[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
+    stat = nc_put_att_float(ncid, i_id, "f", NC_FLOAT, 3, c0_f_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    static const double c0_d_att[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
+    stat = nc_put_att_double(ncid, i_id, "d", NC_DOUBLE, 3, c0_d_att);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    stat = nc_put_att_text(ncid, f_id, "c", 1, "x");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+    {
+    stat = nc_put_att_text(ncid, d_id, "c", 8, "abcd\tZ$&");
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    /* leave define mode */
+    stat = nc_enddef (ncid);
+    check_err(stat,__LINE__,__FILE__);
+
+    /* assign variable data */
+
+    {
+    size_t count = 0;
+    static char c_data[1] = {'2'};
+    stat = nc_put_var1(ncid, c_id, &count, c_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static signed char b_data[1] = {-2};
+    stat = nc_put_var1(ncid, b_id, &count, b_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static short s_data[1] = {-5};
+    stat = nc_put_var1(ncid, s_id, &count, s_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static int i_data[1] = {-20};
+    stat = nc_put_var1(ncid, i_id, &count, i_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static float f_data[1] = {((float)-9)};
+    stat = nc_put_var1(ncid, f_id, &count, f_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    size_t count = 0;
+    static double d_data[1] = {((double)-10)};
+    stat = nc_put_var1(ncid, d_id, &count, d_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* cr_data = "ab" ;
+    size_t cr_startset[1] = {0} ;
+    size_t cr_countset[1] = {2};
+    stat = nc_put_vara(ncid, cr_id, cr_startset, cr_countset, cr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char br_data[2] = {-128, 127} ;
+    size_t br_startset[1] = {0} ;
+    size_t br_countset[1] = {2};
+    stat = nc_put_vara(ncid, br_id, br_startset, br_countset, br_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short sr_data[2] = {-32768, 32767} ;
+    size_t sr_startset[1] = {0} ;
+    size_t sr_countset[1] = {2};
+    stat = nc_put_vara(ncid, sr_id, sr_startset, sr_countset, sr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int ir_data[2] = {-2147483646, 2147483647} ;
+    size_t ir_startset[1] = {0} ;
+    size_t ir_countset[1] = {2};
+    stat = nc_put_vara(ncid, ir_id, ir_startset, ir_countset, ir_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    float fr_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
+    size_t fr_startset[1] = {0} ;
+    size_t fr_countset[1] = {2};
+    stat = nc_put_vara(ncid, fr_id, fr_startset, fr_countset, fr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    double dr_data[2] = {((double)-1e+308), ((double)1e+308)} ;
+    size_t dr_startset[1] = {0} ;
+    size_t dr_countset[1] = {2};
+    stat = nc_put_vara(ncid, dr_id, dr_startset, dr_countset, dr_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* c1_data = "\000" ;
+    size_t c1_startset[1] = {0} ;
+    size_t c1_countset[1] = {1};
+    stat = nc_put_vara(ncid, c1_id, c1_startset, c1_countset, c1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char b1_data[1] = {-128} ;
+    size_t b1_startset[1] = {0} ;
+    size_t b1_countset[1] = {1};
+    stat = nc_put_vara(ncid, b1_id, b1_startset, b1_countset, b1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short s1_data[1] = {-32768} ;
+    size_t s1_startset[1] = {0} ;
+    size_t s1_countset[1] = {1};
+    stat = nc_put_vara(ncid, s1_id, s1_startset, s1_countset, s1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int i1_data[1] = {-2147483646} ;
+    size_t i1_startset[1] = {0} ;
+    size_t i1_countset[1] = {1};
+    stat = nc_put_vara(ncid, i1_id, i1_startset, i1_countset, i1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    float f1_data[1] = {((float)-9.9999996e+35)} ;
+    size_t f1_startset[1] = {0} ;
+    size_t f1_countset[1] = {1};
+    stat = nc_put_vara(ncid, f1_id, f1_startset, f1_countset, f1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    double d1_data[1] = {((double)-1e+308)} ;
+    size_t d1_startset[1] = {0} ;
+    size_t d1_countset[1] = {1};
+    stat = nc_put_vara(ncid, d1_id, d1_startset, d1_countset, d1_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* c2_data = "ab" ;
+    size_t c2_startset[1] = {0} ;
+    size_t c2_countset[1] = {2};
+    stat = nc_put_vara(ncid, c2_id, c2_startset, c2_countset, c2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char b2_data[2] = {-128, 127} ;
+    size_t b2_startset[1] = {0} ;
+    size_t b2_countset[1] = {2};
+    stat = nc_put_vara(ncid, b2_id, b2_startset, b2_countset, b2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short s2_data[2] = {-32768, 32767} ;
+    size_t s2_startset[1] = {0} ;
+    size_t s2_countset[1] = {2};
+    stat = nc_put_vara(ncid, s2_id, s2_startset, s2_countset, s2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int i2_data[2] = {-2147483646, 2147483647} ;
+    size_t i2_startset[1] = {0} ;
+    size_t i2_countset[1] = {2};
+    stat = nc_put_vara(ncid, i2_id, i2_startset, i2_countset, i2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    float f2_data[2] = {((float)-9.9999996e+35), ((float)9.9999996e+35)} ;
+    size_t f2_startset[1] = {0} ;
+    size_t f2_countset[1] = {2};
+    stat = nc_put_vara(ncid, f2_id, f2_startset, f2_countset, f2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    double d2_data[2] = {((double)-1e+308), ((double)1e+308)} ;
+    size_t d2_startset[1] = {0} ;
+    size_t d2_countset[1] = {2};
+    stat = nc_put_vara(ncid, d2_id, d2_startset, d2_countset, d2_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    char* c3_data = "\001\177." ;
+    size_t c3_startset[1] = {0} ;
+    size_t c3_countset[1] = {3};
+    stat = nc_put_vara(ncid, c3_id, c3_startset, c3_countset, c3_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char b3_data[3] = {-128, 127, -1} ;
+    size_t b3_startset[1] = {0} ;
+    size_t b3_countset[1] = {3};
+    stat = nc_put_vara(ncid, b3_id, b3_startset, b3_countset, b3_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short s3_data[3] = {-32768, 0, 32767} ;
+    size_t s3_startset[1] = {0} ;
+    size_t s3_countset[1] = {3};
+    stat = nc_put_vara(ncid, s3_id, s3_startset, s3_countset, s3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store fr */
-    static size_t fr_start[RANK_fr];
-    static size_t fr_count[RANK_fr];
-    static float fr[] = {-9.9999996e+35, 9.9999996e+35};
-    Dr_len = 2;			/* number of records of fr data */
-    fr_start[0] = 0;
-    fr_count[0] = Dr_len;
-    stat = nc_put_vara_float(ncid, fr_id, fr_start, fr_count, fr);
+
+    {
+    int i3_data[3] = {-2147483646, 0, 2147483647} ;
+    size_t i3_startset[1] = {0} ;
+    size_t i3_countset[1] = {3};
+    stat = nc_put_vara(ncid, i3_id, i3_startset, i3_countset, i3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store dr */
-    static size_t dr_start[RANK_dr];
-    static size_t dr_count[RANK_dr];
-    static double dr[] = {-1.e+308, 1.e+308};
-    Dr_len = 2;			/* number of records of dr data */
-    dr_start[0] = 0;
-    dr_count[0] = Dr_len;
-    stat = nc_put_vara_double(ncid, dr_id, dr_start, dr_count, dr);
+
+    {
+    float f3_data[3] = {((float)-9.9999996e+35), ((float)0), ((float)9.9999996e+35)} ;
+    size_t f3_startset[1] = {0} ;
+    size_t f3_countset[1] = {3};
+    stat = nc_put_vara(ncid, f3_id, f3_startset, f3_countset, f3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store c1 */
-    static char c1[] = {""};
-    stat = nc_put_var_text(ncid, c1_id, c1);
+
+    {
+    double d3_data[3] = {((double)-1e+308), ((double)0), ((double)1e+308)} ;
+    size_t d3_startset[1] = {0} ;
+    size_t d3_countset[1] = {3};
+    stat = nc_put_vara(ncid, d3_id, d3_startset, d3_countset, d3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store b1 */
-    static signed char b1[] = {-128};
-    stat = nc_put_var_schar(ncid, b1_id, b1);
+
+    {
+    char* cr1_data = "xy" ;
+    size_t cr1_startset[2] = {0, 0} ;
+    size_t cr1_countset[2] = {2, 1};
+    stat = nc_put_vara(ncid, cr1_id, cr1_startset, cr1_countset, cr1_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s1 */
-    static short s1[] = {-32768};
-    stat = nc_put_var_short(ncid, s1_id, s1);
+
+    {
+    signed char br2_data[4] = {-24, -26, -20, -22} ;
+    size_t br2_startset[2] = {0, 0} ;
+    size_t br2_countset[2] = {2, 2};
+    stat = nc_put_vara(ncid, br2_id, br2_startset, br2_countset, br2_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i1 */
-    static int i1[] = {-2147483646};
-    stat = nc_put_var_int(ncid, i1_id, i1);
+
+    {
+    short sr3_data[6] = {-375, -380, -385, -350, -355, -360} ;
+    size_t sr3_startset[2] = {0, 0} ;
+    size_t sr3_countset[2] = {2, 3};
+    stat = nc_put_vara(ncid, sr3_id, sr3_startset, sr3_countset, sr3_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f1 */
-    static float f1[] = {-9.9999996e+35};
-    stat = nc_put_var_float(ncid, f1_id, f1);
+    {
+    float f11_data[1] = {((float)-2187)} ;
+    size_t f11_startset[2] = {0, 0} ;
+    size_t f11_countset[2] = {1, 1};
+    stat = nc_put_vara(ncid, f11_id, f11_startset, f11_countset, f11_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d1 */
-    static double d1[] = {-1.e+308};
-    stat = nc_put_var_double(ncid, d1_id, d1);
+    {
+    double d12_data[2] = {((double)-3000), ((double)-3010)} ;
+    size_t d12_startset[2] = {0, 0} ;
+    size_t d12_countset[2] = {1, 2};
+    stat = nc_put_vara(ncid, d12_id, d12_startset, d12_countset, d12_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store c2 */
-    static char c2[] = {"ab"};
-    stat = nc_put_var_text(ncid, c2_id, c2);
+    {
+    char* c13_data = "\tb\177" ;
+    size_t c13_startset[2] = {0, 0} ;
+    size_t c13_countset[2] = {1, 3};
+    stat = nc_put_vara(ncid, c13_id, c13_startset, c13_countset, c13_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store b2 */
-    static signed char b2[] = {-128, 127};
-    stat = nc_put_var_schar(ncid, b2_id, b2);
+    {
+    short s21_data[2] = {-375, -350} ;
+    size_t s21_startset[2] = {0, 0} ;
+    size_t s21_countset[2] = {2, 1};
+    stat = nc_put_vara(ncid, s21_id, s21_startset, s21_countset, s21_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s2 */
-    static short s2[] = {-32768, 32767};
-    stat = nc_put_var_short(ncid, s2_id, s2);
+
+    {
+    int i22_data[4] = {-24000, -24020, -23600, -23620} ;
+    size_t i22_startset[2] = {0, 0} ;
+    size_t i22_countset[2] = {2, 2};
+    stat = nc_put_vara(ncid, i22_id, i22_startset, i22_countset, i22_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i2 */
-    static int i2[] = {-2147483646, 2147483647};
-    stat = nc_put_var_int(ncid, i2_id, i2);
+
+    {
+    float f23_data[6] = {((float)-2187), ((float)-2196), ((float)-2205), ((float)-2106), ((float)-2115), ((float)-2124)} ;
+    size_t f23_startset[2] = {0, 0} ;
+    size_t f23_countset[2] = {2, 3};
+    stat = nc_put_vara(ncid, f23_id, f23_startset, f23_countset, f23_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f2 */
-    static float f2[] = {-9.9999996e+35, 9.9999996e+35};
-    stat = nc_put_var_float(ncid, f2_id, f2);
+
+    {
+    char* c31_data = "+- " ;
+    size_t c31_startset[2] = {0, 0} ;
+    size_t c31_countset[2] = {3, 1};
+    stat = nc_put_vara(ncid, c31_id, c31_startset, c31_countset, c31_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d2 */
-    static double d2[] = {-1.e+308, 1.e+308};
-    stat = nc_put_var_double(ncid, d2_id, d2);
+    {
+    signed char b32_data[6] = {-24, -26, -20, -22, -16, -18} ;
+    size_t b32_startset[2] = {0, 0} ;
+    size_t b32_countset[2] = {3, 2};
+    stat = nc_put_vara(ncid, b32_id, b32_startset, b32_countset, b32_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
+
+    {
+    short s33_data[9] = {-375, -380, -385, -350, -355, -360, -325, -330, -335} ;
+    size_t s33_startset[2] = {0, 0} ;
+    size_t s33_countset[2] = {3, 3};
+    stat = nc_put_vara(ncid, s33_id, s33_startset, s33_countset, s33_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short sr11_data[2] = {2500, 2375} ;
+    size_t sr11_startset[3] = {0, 0, 0} ;
+    size_t sr11_countset[3] = {2, 1, 1};
+    stat = nc_put_vara(ncid, sr11_id, sr11_startset, sr11_countset, sr11_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    int ir12_data[4] = {640000, 639980, 632000, 631980} ;
+    size_t ir12_startset[3] = {0, 0, 0} ;
+    size_t ir12_countset[3] = {2, 1, 2};
+    stat = nc_put_vara(ncid, ir12_id, ir12_startset, ir12_countset, ir12_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
 
-   {			/* store c3 */
-    static char c3[] = {"\001\177."};
-    stat = nc_put_var_text(ncid, c3_id, c3);
+    {
+    float fr13_data[6] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497)} ;
+    size_t fr13_startset[3] = {0, 0, 0} ;
+    size_t fr13_countset[3] = {2, 1, 3};
+    stat = nc_put_vara(ncid, fr13_id, fr13_startset, fr13_countset, fr13_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
+
+    {
+    char* cr21_data = "@DHL" ;
+    size_t cr21_startset[3] = {0, 0, 0} ;
+    size_t cr21_countset[3] = {2, 2, 1};
+    stat = nc_put_vara(ncid, cr21_id, cr21_startset, cr21_countset, cr21_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    signed char br22_data[8] = {64, 62, 68, 66, 56, 54, 60, 58} ;
+    size_t br22_startset[3] = {0, 0, 0} ;
+    size_t br22_countset[3] = {2, 2, 2};
+    stat = nc_put_vara(ncid, br22_id, br22_startset, br22_countset, br22_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
+
+    {
+    short sr23_data[12] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390} ;
+    size_t sr23_startset[3] = {0, 0, 0} ;
+    size_t sr23_countset[3] = {2, 2, 3};
+    stat = nc_put_vara(ncid, sr23_id, sr23_startset, sr23_countset, sr23_data);
+    check_err(stat,__LINE__,__FILE__);
+    }
+
 
-   {			/* store b3 */
-    static signed char b3[] = {-128, 127, -1};
-    stat = nc_put_var_schar(ncid, b3_id, b3);
+    {
+    float fr31_data[6] = {((float)26244), ((float)26325), ((float)26406), ((float)25515), ((float)25596), ((float)25677)} ;
+    size_t fr31_startset[3] = {0, 0, 0} ;
+    size_t fr31_countset[3] = {2, 3, 1};
+    stat = nc_put_vara(ncid, fr31_id, fr31_startset, fr31_countset, fr31_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store s3 */
-    static short s3[] = {-32768, 0, 32767};
-    stat = nc_put_var_short(ncid, s3_id, s3);
+    {
+    double dr32_data[12] = {((double)40000), ((double)39990), ((double)40100), ((double)40090), ((double)40200), ((double)40190), ((double)39000), ((double)38990), ((double)39100), ((double)39090), ((double)39200), ((double)39190)} ;
+    size_t dr32_startset[3] = {0, 0, 0} ;
+    size_t dr32_countset[3] = {2, 3, 2};
+    stat = nc_put_vara(ncid, dr32_id, dr32_startset, dr32_countset, dr32_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store i3 */
-    static int i3[] = {-2147483646, 0, 2147483647};
-    stat = nc_put_var_int(ncid, i3_id, i3);
+    {
+    char* cr33_data = "1\000\000two3\000\0004\000\0005\000\000six" ;
+    size_t cr33_startset[3] = {0, 0, 0} ;
+    size_t cr33_countset[3] = {2, 3, 3};
+    stat = nc_put_vara(ncid, cr33_id, cr33_startset, cr33_countset, cr33_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f3 */
-    static float f3[] = {-9.9999996e+35, 0, 9.9999996e+35};
-    stat = nc_put_var_float(ncid, f3_id, f3);
+    {
+    char* c111_data = "@" ;
+    size_t c111_startset[3] = {0, 0, 0} ;
+    size_t c111_countset[3] = {1, 1, 1};
+    stat = nc_put_vara(ncid, c111_id, c111_startset, c111_countset, c111_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d3 */
-    static double d3[] = {-1.e+308, 0., 1.e+308};
-    stat = nc_put_var_double(ncid, d3_id, d3);
+    {
+    signed char b112_data[2] = {64, 62} ;
+    size_t b112_startset[3] = {0, 0, 0} ;
+    size_t b112_countset[3] = {1, 1, 2};
+    stat = nc_put_vara(ncid, b112_id, b112_startset, b112_countset, b112_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store cr1 */
-    static size_t cr1_start[RANK_cr1];
-    static size_t cr1_count[RANK_cr1];
-    static char cr1[] = {"xy"};
-    Dr_len = 2;			/* number of records of cr1 data */
-    cr1_start[0] = 0;
-    cr1_start[1] = 0;
-    cr1_count[0] = Dr_len;
-    cr1_count[1] = D1_len;
-    stat = nc_put_vara_text(ncid, cr1_id, cr1_start, cr1_count, cr1);
+    {
+    short s113_data[3] = {2500, 2495, 2490} ;
+    size_t s113_startset[3] = {0, 0, 0} ;
+    size_t s113_countset[3] = {1, 1, 3};
+    stat = nc_put_vara(ncid, s113_id, s113_startset, s113_countset, s113_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store br2 */
-    static size_t br2_start[RANK_br2];
-    static size_t br2_count[RANK_br2];
-    static signed char br2[] = {-24, -26, -20, -22};
-    Dr_len = 2;			/* number of records of br2 data */
-    br2_start[0] = 0;
-    br2_start[1] = 0;
-    br2_count[0] = Dr_len;
-    br2_count[1] = D2_len;
-    stat = nc_put_vara_schar(ncid, br2_id, br2_start, br2_count, br2);
+    {
+    float f121_data[2] = {((float)26244), ((float)26325)} ;
+    size_t f121_startset[3] = {0, 0, 0} ;
+    size_t f121_countset[3] = {1, 2, 1};
+    stat = nc_put_vara(ncid, f121_id, f121_startset, f121_countset, f121_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store sr3 */
-    static size_t sr3_start[RANK_sr3];
-    static size_t sr3_count[RANK_sr3];
-    static short sr3[] = {-375, -380, -385, -350, -355, -360};
-    Dr_len = 2;			/* number of records of sr3 data */
-    sr3_start[0] = 0;
-    sr3_start[1] = 0;
-    sr3_count[0] = Dr_len;
-    sr3_count[1] = D3_len;
-    stat = nc_put_vara_short(ncid, sr3_id, sr3_start, sr3_count, sr3);
+    {
+    double d122_data[4] = {((double)40000), ((double)39990), ((double)40100), ((double)40090)} ;
+    size_t d122_startset[3] = {0, 0, 0} ;
+    size_t d122_countset[3] = {1, 2, 2};
+    stat = nc_put_vara(ncid, d122_id, d122_startset, d122_countset, d122_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f11 */
-    static float f11[] = {-2187};
-    stat = nc_put_var_float(ncid, f11_id, f11);
+
+    {
+    char* c123_data = "one2\000\000" ;
+    size_t c123_startset[3] = {0, 0, 0} ;
+    size_t c123_countset[3] = {1, 2, 3};
+    stat = nc_put_vara(ncid, c123_id, c123_startset, c123_countset, c123_data);
     check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store d12 */
-    static double d12[] = {-3000., -3010.};
-    stat = nc_put_var_double(ncid, d12_id, d12);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store c13 */
-    static char c13[] = {"\tb\177"};
-    stat = nc_put_var_text(ncid, c13_id, c13);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s21 */
-    static short s21[] = {-375, -350};
-    stat = nc_put_var_short(ncid, s21_id, s21);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store i22 */
-    static int i22[] = {-24000, -24020, -23600, -23620};
-    stat = nc_put_var_int(ncid, i22_id, i22);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store f23 */
-    static float f23[] = {-2187, -2196, -2205, -2106, -2115, -2124};
-    stat = nc_put_var_float(ncid, f23_id, f23);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store c31 */
-    static char c31[] = {"+- "};
-    stat = nc_put_var_text(ncid, c31_id, c31);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store b32 */
-    static signed char b32[] = {-24, -26, -20, -22, -16, -18};
-    stat = nc_put_var_schar(ncid, b32_id, b32);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s33 */
-    static short s33[] = {-375, -380, -385, -350, -355, -360, -325, -330, -335};
-    stat = nc_put_var_short(ncid, s33_id, s33);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store sr11 */
-    static size_t sr11_start[RANK_sr11];
-    static size_t sr11_count[RANK_sr11];
-    static short sr11[] = {2500, 2375};
-    Dr_len = 2;			/* number of records of sr11 data */
-    sr11_start[0] = 0;
-    sr11_start[1] = 0;
-    sr11_start[2] = 0;
-    sr11_count[0] = Dr_len;
-    sr11_count[1] = D1_len;
-    sr11_count[2] = D1_len;
-    stat = nc_put_vara_short(ncid, sr11_id, sr11_start, sr11_count, sr11);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store ir12 */
-    static size_t ir12_start[RANK_ir12];
-    static size_t ir12_count[RANK_ir12];
-    static int ir12[] = {640000, 639980, 632000, 631980};
-    Dr_len = 2;			/* number of records of ir12 data */
-    ir12_start[0] = 0;
-    ir12_start[1] = 0;
-    ir12_start[2] = 0;
-    ir12_count[0] = Dr_len;
-    ir12_count[1] = D1_len;
-    ir12_count[2] = D2_len;
-    stat = nc_put_vara_int(ncid, ir12_id, ir12_start, ir12_count, ir12);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store fr13 */
-    static size_t fr13_start[RANK_fr13];
-    static size_t fr13_count[RANK_fr13];
-    static float fr13[] = {26244, 26235, 26226, 25515, 25506, 25497};
-    Dr_len = 2;			/* number of records of fr13 data */
-    fr13_start[0] = 0;
-    fr13_start[1] = 0;
-    fr13_start[2] = 0;
-    fr13_count[0] = Dr_len;
-    fr13_count[1] = D1_len;
-    fr13_count[2] = D3_len;
-    stat = nc_put_vara_float(ncid, fr13_id, fr13_start, fr13_count, fr13);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store cr21 */
-    static size_t cr21_start[RANK_cr21];
-    static size_t cr21_count[RANK_cr21];
-    static char cr21[] = {"@DHL"};
-    Dr_len = 2;			/* number of records of cr21 data */
-    cr21_start[0] = 0;
-    cr21_start[1] = 0;
-    cr21_start[2] = 0;
-    cr21_count[0] = Dr_len;
-    cr21_count[1] = D2_len;
-    cr21_count[2] = D1_len;
-    stat = nc_put_vara_text(ncid, cr21_id, cr21_start, cr21_count, cr21);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store br22 */
-    static size_t br22_start[RANK_br22];
-    static size_t br22_count[RANK_br22];
-    static signed char br22[] = {64, 62, 68, 66, 56, 54, 60, 58};
-    Dr_len = 2;			/* number of records of br22 data */
-    br22_start[0] = 0;
-    br22_start[1] = 0;
-    br22_start[2] = 0;
-    br22_count[0] = Dr_len;
-    br22_count[1] = D2_len;
-    br22_count[2] = D2_len;
-    stat = nc_put_vara_schar(ncid, br22_id, br22_start, br22_count, br22);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store sr23 */
-    static size_t sr23_start[RANK_sr23];
-    static size_t sr23_count[RANK_sr23];
-    static short sr23[] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390};
-    Dr_len = 2;			/* number of records of sr23 data */
-    sr23_start[0] = 0;
-    sr23_start[1] = 0;
-    sr23_start[2] = 0;
-    sr23_count[0] = Dr_len;
-    sr23_count[1] = D2_len;
-    sr23_count[2] = D3_len;
-    stat = nc_put_vara_short(ncid, sr23_id, sr23_start, sr23_count, sr23);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store fr31 */
-    static size_t fr31_start[RANK_fr31];
-    static size_t fr31_count[RANK_fr31];
-    static float fr31[] = {26244, 26325, 26406, 25515, 25596, 25677};
-    Dr_len = 2;			/* number of records of fr31 data */
-    fr31_start[0] = 0;
-    fr31_start[1] = 0;
-    fr31_start[2] = 0;
-    fr31_count[0] = Dr_len;
-    fr31_count[1] = D3_len;
-    fr31_count[2] = D1_len;
-    stat = nc_put_vara_float(ncid, fr31_id, fr31_start, fr31_count, fr31);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store dr32 */
-    static size_t dr32_start[RANK_dr32];
-    static size_t dr32_count[RANK_dr32];
-    static double dr32[] = {40000., 39990., 40100., 40090., 40200., 40190., 39000., 38990., 39100., 39090., 39200., 39190.};
-    Dr_len = 2;			/* number of records of dr32 data */
-    dr32_start[0] = 0;
-    dr32_start[1] = 0;
-    dr32_start[2] = 0;
-    dr32_count[0] = Dr_len;
-    dr32_count[1] = D3_len;
-    dr32_count[2] = D2_len;
-    stat = nc_put_vara_double(ncid, dr32_id, dr32_start, dr32_count, dr32);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store cr33 */
-    static size_t cr33_start[RANK_cr33];
-    static size_t cr33_count[RANK_cr33];
-    static char cr33[] = {"1\000\000two3\000\0004\000\0005\000\000six"};
-    Dr_len = 2;			/* number of records of cr33 data */
-    cr33_start[0] = 0;
-    cr33_start[1] = 0;
-    cr33_start[2] = 0;
-    cr33_count[0] = Dr_len;
-    cr33_count[1] = D3_len;
-    cr33_count[2] = D3_len;
-    stat = nc_put_vara_text(ncid, cr33_id, cr33_start, cr33_count, cr33);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store c111 */
-    static char c111[] = {"@"};
-    stat = nc_put_var_text(ncid, c111_id, c111);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store b112 */
-    static signed char b112[] = {64, 62};
-    stat = nc_put_var_schar(ncid, b112_id, b112);
-    check_err(stat,__LINE__,__FILE__);
-   }
-
-   {			/* store s113 */
-    static short s113[] = {2500, 2495, 2490};
-    stat = nc_put_var_short(ncid, s113_id, s113);
+    }
+
+
+    {
+    short s131_data[3] = {2500, 2525, 2550} ;
+    size_t s131_startset[3] = {0, 0, 0} ;
+    size_t s131_countset[3] = {1, 3, 1};
+    stat = nc_put_vara(ncid, s131_id, s131_startset, s131_countset, s131_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f121 */
-    static float f121[] = {26244, 26325};
-    stat = nc_put_var_float(ncid, f121_id, f121);
+    {
+    int i132_data[6] = {640000, 639980, 640400, 640380, 640800, 640780} ;
+    size_t i132_startset[3] = {0, 0, 0} ;
+    size_t i132_countset[3] = {1, 3, 2};
+    stat = nc_put_vara(ncid, i132_id, i132_startset, i132_countset, i132_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store d122 */
-    static double d122[] = {40000., 39990., 40100., 40090.};
-    stat = nc_put_var_double(ncid, d122_id, d122);
+
+    {
+    float f133_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)26406), ((float)26397), ((float)26388)} ;
+    size_t f133_startset[3] = {0, 0, 0} ;
+    size_t f133_countset[3] = {1, 3, 3};
+    stat = nc_put_vara(ncid, f133_id, f133_startset, f133_countset, f133_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store c123 */
-    static char c123[] = {"one2\000\000"};
-    stat = nc_put_var_text(ncid, c123_id, c123);
+
+    {
+    float f211_data[2] = {((float)26244), ((float)25515)} ;
+    size_t f211_startset[3] = {0, 0, 0} ;
+    size_t f211_countset[3] = {2, 1, 1};
+    stat = nc_put_vara(ncid, f211_id, f211_startset, f211_countset, f211_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s131 */
-    static short s131[] = {2500, 2525, 2550};
-    stat = nc_put_var_short(ncid, s131_id, s131);
+
+    {
+    double d212_data[4] = {((double)40000), ((double)39990), ((double)39000), ((double)38990)} ;
+    size_t d212_startset[3] = {0, 0, 0} ;
+    size_t d212_countset[3] = {2, 1, 2};
+    stat = nc_put_vara(ncid, d212_id, d212_startset, d212_countset, d212_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store i132 */
-    static int i132[] = {640000, 639980, 640400, 640380, 640800, 640780};
-    stat = nc_put_var_int(ncid, i132_id, i132);
+    {
+    char* c213_data = "\000\000\000\000\000\000" ;
+    size_t c213_startset[3] = {0, 0, 0} ;
+    size_t c213_countset[3] = {2, 1, 3};
+    stat = nc_put_vara(ncid, c213_id, c213_startset, c213_countset, c213_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f133 */
-    static float f133[] = {26244, 26235, 26226, 26325, 26316, 26307, 26406, 26397, 26388};
-    stat = nc_put_var_float(ncid, f133_id, f133);
+    {
+    short s221_data[4] = {2500, 2525, 2375, 2400} ;
+    size_t s221_startset[3] = {0, 0, 0} ;
+    size_t s221_countset[3] = {2, 2, 1};
+    stat = nc_put_vara(ncid, s221_id, s221_startset, s221_countset, s221_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store f211 */
-    static float f211[] = {26244, 25515};
-    stat = nc_put_var_float(ncid, f211_id, f211);
+    {
+    int i222_data[8] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380} ;
+    size_t i222_startset[3] = {0, 0, 0} ;
+    size_t i222_countset[3] = {2, 2, 2};
+    stat = nc_put_vara(ncid, i222_id, i222_startset, i222_countset, i222_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store d212 */
-    static double d212[] = {40000., 39990., 39000., 38990.};
-    stat = nc_put_var_double(ncid, d212_id, d212);
+    {
+    float f223_data[12] = {((float)26244), ((float)26235), ((float)26226), ((float)26325), ((float)26316), ((float)26307), ((float)25515), ((float)25506), ((float)25497), ((float)25596), ((float)25587), ((float)25578)} ;
+    size_t f223_startset[3] = {0, 0, 0} ;
+    size_t f223_countset[3] = {2, 2, 3};
+    stat = nc_put_vara(ncid, f223_id, f223_startset, f223_countset, f223_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store s221 */
-    static short s221[] = {2500, 2525, 2375, 2400};
-    stat = nc_put_var_short(ncid, s221_id, s221);
+
+    {
+    char* c231_data = "@DHHLP" ;
+    size_t c231_startset[3] = {0, 0, 0} ;
+    size_t c231_countset[3] = {2, 3, 1};
+    stat = nc_put_vara(ncid, c231_id, c231_startset, c231_countset, c231_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i222 */
-    static int i222[] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380};
-    stat = nc_put_var_int(ncid, i222_id, i222);
+
+    {
+    signed char b232_data[12] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62} ;
+    size_t b232_startset[3] = {0, 0, 0} ;
+    size_t b232_countset[3] = {2, 3, 2};
+    stat = nc_put_vara(ncid, b232_id, b232_startset, b232_countset, b232_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f223 */
-    static float f223[] = {26244, 26235, 26226, 26325, 26316, 26307, 25515, 25506, 25497, 25596, 25587, 25578};
-    stat = nc_put_var_float(ncid, f223_id, f223);
+
+    {
+    short s233_data[18] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415} ;
+    size_t s233_startset[3] = {0, 0, 0} ;
+    size_t s233_countset[3] = {2, 3, 3};
+    stat = nc_put_vara(ncid, s233_id, s233_startset, s233_countset, s233_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store c231 */
-    static char c231[] = {"@DHHLP"};
-    stat = nc_put_var_text(ncid, c231_id, c231);
+    {
+    short s311_data[3] = {2500, 2375, 2250} ;
+    size_t s311_startset[3] = {0, 0, 0} ;
+    size_t s311_countset[3] = {3, 1, 1};
+    stat = nc_put_vara(ncid, s311_id, s311_startset, s311_countset, s311_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store b232 */
-    static signed char b232[] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62};
-    stat = nc_put_var_schar(ncid, b232_id, b232);
+    {
+    int i312_data[6] = {640000, 639980, 632000, 631980, 624000, 623980} ;
+    size_t i312_startset[3] = {0, 0, 0} ;
+    size_t i312_countset[3] = {3, 1, 2};
+    stat = nc_put_vara(ncid, i312_id, i312_startset, i312_countset, i312_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store s233 */
-    static short s233[] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415};
-    stat = nc_put_var_short(ncid, s233_id, s233);
+    {
+    float f313_data[9] = {((float)26244), ((float)26235), ((float)26226), ((float)25515), ((float)25506), ((float)25497), ((float)24786), ((float)24777), ((float)24768)} ;
+    size_t f313_startset[3] = {0, 0, 0} ;
+    size_t f313_countset[3] = {3, 1, 3};
+    stat = nc_put_vara(ncid, f313_id, f313_startset, f313_countset, f313_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store s311 */
-    static short s311[] = {2500, 2375, 2250};
-    stat = nc_put_var_short(ncid, s311_id, s311);
+    {
+    size_t count = 0;
+    static double var_MINUS_name_MINUS_dashes_data[1] = {((double)-1)};
+    stat = nc_put_var1(ncid, var_MINUS_name_MINUS_dashes_id, &count, var_MINUS_name_MINUS_dashes_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store i312 */
-    static int i312[] = {640000, 639980, 632000, 631980, 624000, 623980};
-    stat = nc_put_var_int(ncid, i312_id, i312);
+
+    {
+    size_t count = 0;
+    static double var_PERIOD_name_PERIOD_dots_data[1] = {((double)-2)};
+    stat = nc_put_var1(ncid, var_PERIOD_name_PERIOD_dots_id, &count, var_PERIOD_name_PERIOD_dots_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store f313 */
-    static float f313[] = {26244, 26235, 26226, 25515, 25506, 25497, 24786, 24777, 24768};
-    stat = nc_put_var_float(ncid, f313_id, f313);
+
+    {
+    size_t count = 0;
+    static double var_PLUS_name_PLUS_plusses_data[1] = {((double)9.969209968386869e+36)};
+    stat = nc_put_var1(ncid, var_PLUS_name_PLUS_plusses_id, &count, var_PLUS_name_PLUS_plusses_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
 
-   {			/* store var-name-dashes */
-    static double var_MINUS_name_MINUS_dashes = -1.;
-    stat = nc_put_var_double(ncid, var_MINUS_name_MINUS_dashes_id, &var_MINUS_name_MINUS_dashes);
+
+    {
+    size_t count = 0;
+    static double var_ATSIGN_name_ATSIGN_ats_data[1] = {((double)9.969209968386869e+36)};
+    stat = nc_put_var1(ncid, var_ATSIGN_name_ATSIGN_ats_id, &count, var_ATSIGN_name_ATSIGN_ats_data);
     check_err(stat,__LINE__,__FILE__);
-   }
+    }
+
 
-   {			/* store var.name.dots */
-    static double var_PERIOD_name_PERIOD_dots = -2.;
-    stat = nc_put_var_double(ncid, var_PERIOD_name_PERIOD_dots_id, &var_PERIOD_name_PERIOD_dots);
+    stat = nc_close(ncid);
     check_err(stat,__LINE__,__FILE__);
-   }
-   stat = nc_close(ncid);
-   check_err(stat,__LINE__,__FILE__);
-   return 0;
+    return 0;
 }
diff --git a/ncdump/ref_null_byte_padding_test.nc b/ncdump/ref_null_byte_padding_test.nc
new file mode 100644
index 0000000..40d7da1
Binary files /dev/null and b/ncdump/ref_null_byte_padding_test.nc differ
diff --git a/ncdump/test_360_day_1900.nc b/ncdump/ref_test_360_day_1900.nc
similarity index 100%
rename from ncdump/test_360_day_1900.nc
rename to ncdump/ref_test_360_day_1900.nc
diff --git a/ncdump/test_365_day_1900.nc b/ncdump/ref_test_365_day_1900.nc
similarity index 100%
rename from ncdump/test_365_day_1900.nc
rename to ncdump/ref_test_365_day_1900.nc
diff --git a/ncdump/test_366_day_1900.nc b/ncdump/ref_test_366_day_1900.nc
similarity index 100%
rename from ncdump/test_366_day_1900.nc
rename to ncdump/ref_test_366_day_1900.nc
diff --git a/ncdump/ref_test_corrupt_magic.nc b/ncdump/ref_test_corrupt_magic.nc
new file mode 100644
index 0000000..edd0b32
Binary files /dev/null and b/ncdump/ref_test_corrupt_magic.nc differ
diff --git a/ncdump/ref_tst_nc4_utf8_4.cdl b/ncdump/ref_tst_nc4_utf8_4.cdl
new file mode 100644
index 0000000..b5ad801
--- /dev/null
+++ b/ncdump/ref_tst_nc4_utf8_4.cdl
@@ -0,0 +1,24 @@
+netcdf nc4_utf8 {
+dimensions:
+	xā = 2 ;
+	㼿y = 2 ;
+	Καλημέρα = 18 ;
+variables:
+	int 􍐪(xā, 㼿y) ;
+	char Καλημέρα(Καλημέρα) ;
+		Καλημέρα:units = "Καλημέρα" ;
+	string s(xā);
+		string s:satt = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ";
+
+// global attributes:
+		:Gā = "ā㼿y􍐪" ;
+data:
+
+ 􍐪 =
+  1, 2,
+  3, 4 ;
+
+ Καλημέρα = "\316\232\316\261\316\273\316\267\316\274\341\275\263\317\201\316\261" ;
+
+ s = "キャク", "龥";
+}
diff --git a/ncdump/run_ncgen_nc4_tests.sh b/ncdump/run_ncgen_nc4_tests.sh
index 7172102..c239fa7 100755
--- a/ncdump/run_ncgen_nc4_tests.sh
+++ b/ncdump/run_ncgen_nc4_tests.sh
@@ -1,14 +1,14 @@
 #!/bin/sh
 # This shell script runs the ncdump tests.
-# $Id: run_nc4_tests.sh,v 1.4 2010/05/18 20:05:23 dmh Exp $
+# Dennis Heimbigner
 
 if test "x$srcdir" = x ; then srcdir="."; fi
 . ../test_common.sh
 
 ##
 # Function to test a netCDF CDL file.
-# 1. Generate binary nc.
-# Use ncdump to compare against original CDL file.
+# First generate binary nc. Then use ncdump to compare against
+# original CDL file.
 # Input: CDL file name, minus the suffix, output filename
 # Other input: arguments.
 #
@@ -16,7 +16,8 @@ if test "x$srcdir" = x ; then srcdir="."; fi
 #     $ validateNC compound_datasize_test -k nc4
 ##
 validateNC() {
-    BASENAME=$1
+    ORIGNAME=$1
+    BASENAME=tst_$1_run_ncgen_nc4_tests
     INFILE=$top_srcdir/ncgen/$1.cdl
     TMPFILE=tst_$2.cdl
     shift
@@ -25,13 +26,11 @@ validateNC() {
 
     echo "*** generating $BASENAME.nc ***"
     ${NCGEN} $ARGS -o $BASENAME.nc $INFILE
-    ${NCDUMP} $BASENAME.nc | sed 's/e+0/e+/g' > $TMPFILE
+    ${NCDUMP} -n $ORIGNAME $BASENAME.nc | sed 's/e+0/e+/g' > $TMPFILE
     echo "*** comparing binary against source CDL file *** "
     diff -b -w $INFILE $TMPFILE
 }
 
-
-
 echo "*** Testing ncgen for netCDF-4."
 set -e
 
@@ -42,7 +41,7 @@ echo "*** creating netCDF-4 classic model file c0_4c.nc from c0.cdl..."
 validateNC "c0" "c0_4c" -k nc7 -b
 
 echo "*** creating C code for CAM file ref_camrun.cdl..."
-${NCGEN} -lc $top_srcdir/ncgen/ref_camrun.cdl >ref_camrun.c
+${NCGEN} -lc $top_srcdir/ncgen/ref_camrun.cdl > camrun.c
 
 echo "*** test for jira NCF-199 bug"
 validateNC "ncf199" "ncf199" -k nc4
diff --git a/ncdump/run_ncgen_tests.sh b/ncdump/run_ncgen_tests.sh
index 7238c20..eb516e1 100755
--- a/ncdump/run_ncgen_tests.sh
+++ b/ncdump/run_ncgen_tests.sh
@@ -24,7 +24,8 @@ fi
 #VALGRIND="valgrind -q --error-exitcode=2 --leak-check=full"
 
 validateNC() {
-    BASENAME=$1
+    ORIGNAME=$1
+    BASENAME=tst_$1_run_ncgen_tests
     INFILE=$top_srcdir/ncgen/$1.cdl
     TMPFILE=tst_$2.cdl
     shift
@@ -37,24 +38,24 @@ validateNC() {
     else
     ${VALGRIND} ${NCGEN} $ARGS -o $BASENAME.nc $INFILE
     fi
-    ${NCDUMP} $BASENAME.nc | sed 's/e+0/e+/g' > $TMPFILE
+    ${NCDUMP} -n $ORIGNAME $BASENAME.nc | sed 's/e+0/e+/g' > $TMPFILE
     echo "*** comparing $BASENAME.nc against $INFILE *** "
     diff -b -w $INFILE $TMPFILE
 }
 
-echo "*** creating classic file c0.nc from c0.cdl..."
+echo "*** creating classic file c0_run_ncgen_tests.nc from c0.cdl..."
 
 validateNC c0 c0 -b
 
-echo "*** creating 64-bit offset file c0_64.nc from c0.cdl..."
+echo "*** creating 64-bit offset file c0_64_run_ncgen_tests.nc from c0.cdl..."
 
 validateNC c0 "c0_64" -k 64-bit-offset -b
 
 if test "x$USE_CDF5" = x1 ; then
 
     echo "*** creating 64-bit data file c5.nc from c5.cdl..."
-    ${NCGEN} -k 64-bit-data -b -o c5.nc $top_srcdir/ncgen/c5.cdl
-    if [ ! -f c5.nc ]; then
+    ${NCGEN} -k 64-bit-data -b -o tst_c5_run_ncgen_tests.nc $top_srcdir/ncgen/c5.cdl
+    if [ ! -f tst_c5_run_ncgen_tests.nc ]; then
         echo "Failure."
         exit 1
     fi
diff --git a/ncdump/run_utf8_nc4_tests.sh b/ncdump/run_utf8_nc4_tests.sh
index e013b20..1a595ea 100755
--- a/ncdump/run_utf8_nc4_tests.sh
+++ b/ncdump/run_utf8_nc4_tests.sh
@@ -1,20 +1,18 @@
 #!/bin/sh
+# This script runs UTF-8 tests for netCDF-4.
+# Ward Fisher, Dennis Heimbigner, Ed Hartnett
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
-
 . ../test_common.sh
-
-#
-# 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.
-
 set -e
 
 echo ""
+echo "*** Testing netcdf-4 file with utf8 characters..."
+
+rm -f tst_utf8_nc4.nc tst_utf8_nc4.cdl
+${NCGEN} -4 -b -o tst_utf8_nc4.nc ${srcdir}/ref_tst_utf8_4.cdl
+${NCDUMP} -n 'utf8' tst_utf8_nc4.nc > tst_utf8_nc4.cdl
+diff -b -w tst_utf8_nc4.cdl ${srcdir}/ref_tst_utf8_4.cdl
 
-rm -f utf8.nc utf8.cdl
-echo "*** creating enhanced file with utf8 characters..."
-${NCGEN} -4 -b -o utf8.nc ${srcdir}/ref_tst_utf8_4.cdl
-echo "*** dump and compare utf8 output..."
-${NCDUMP} utf8.nc > utf8.cdl
-diff -b -w utf8.cdl ${srcdir}/ref_tst_utf8_4.cdl
+echo "*** NetCDF-4 UTF8 testing passed!"
+exit 0
diff --git a/ncdump/run_utf8_tests.sh b/ncdump/run_utf8_tests.sh
index 1c98e30..679f8b1 100755
--- a/ncdump/run_utf8_tests.sh
+++ b/ncdump/run_utf8_tests.sh
@@ -1,41 +1,43 @@
+# This shell script runs ncdump tests relating to the new UTF8 name stuff.
+# Russ Rew, Dennis Heimbigner, Ward Fisher, Ed Hartnett
 #!/bin/sh
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
 . ../test_common.sh
-
-# This shell script runs ncdump tests relating to the new UTF8 name stuff.
-
 set -e
+
 echo ""
 echo "*** Testing ncgen and ncdump for UTF8 support..."
 
-if test "x$builddir" = x ; then
-builddir="."
-fi
-if test "x$srcdir" = x ; then
-srcdir="."
-fi
+# Run tst_utf8.c to produce test file tst_utf8.nc.
+${execdir}/tst_utf8
+
+# if test "x$builddir" = x ; then
+# builddir="."
+# fi
+# if test "x$srcdir" = x ; then
+# srcdir="."
+# fi
 
-rm -f utf8.nc utf8.cdl
+rm -f tst_utf8_nc3.nc tst_utf8_nc3.cdl
 echo "*** creating classic offset file with utf8 characters..."
-${NCGEN} -b -o utf8.nc ${srcdir}/ref_tst_utf8.cdl
+${NCGEN} -b -o tst_utf8_nc3.nc ${srcdir}/ref_tst_utf8.cdl
 echo "*** dump and compare utf8 output..."
-${NCDUMP} utf8.nc > utf8.cdl
-diff -b -w utf8.cdl ${srcdir}/ref_tst_utf8.cdl
+${NCDUMP} -n utf8 tst_utf8_nc3.nc > tst_utf8_nc3.cdl
+diff -b -w tst_utf8_nc3.cdl ${srcdir}/ref_tst_utf8.cdl
 
-rm -f utf8.nc utf8.cdl
+rm -f tst_utf8_64.nc tst_utf8_64.cdl
 echo "*** creating 64-bit offset file with utf8 characters..."
-${NCGEN} -k 64-bit-offset -b -o utf8.nc ${srcdir}/ref_tst_utf8.cdl
+${NCGEN} -k 64-bit-offset -b -o tst_utf8_64.nc ${srcdir}/ref_tst_utf8.cdl
 echo "*** (64 bit) dump and compare utf8 output..."
-${NCDUMP} utf8.nc > utf8.cdl
-diff -b -w utf8.cdl ${srcdir}/ref_tst_utf8.cdl
+${NCDUMP} -n utf8 tst_utf8_64.nc > tst_utf8_64.cdl
+diff -b -w tst_utf8_64.cdl ${srcdir}/ref_tst_utf8.cdl
 
 echo "*** dumping tst_utf8.nc to tst_utf8.cdl..."
-rm -f tst8.cdl
-sed -e 's/^netcdf tst_unicode/netcdf tst_utf8/' <${srcdir}/ref_tst_unicode.cdl >tst8.cdl
-${NCDUMP} tst_utf8.nc > tst_utf8.cdl
-echo "*** comparing tst_utf8.cdl with tst8.cdl..."
-diff -b -w tst_utf8.cdl tst8.cdl
-rm -f tst8.cdl result
+rm -f tst_tst8.cdl tst_utf8_tst8.cdl
+sed -e 's/^netcdf tst_unicode/netcdf tst_utf8/' <${srcdir}/ref_tst_unicode.cdl > tst_tst8.cdl
+${NCDUMP} tst_utf8.nc > tst_utf8_tst8.cdl
+echo "*** comparing tst_utf8_tst8.cdl with tst_tst8.cdl..."
+diff -b -w tst_utf8_tst8.cdl tst_tst8.cdl
 echo "*** All utf8 tests of ncgen and ncdump passed!"
 exit 0
diff --git a/ncdump/test_corrupt_magic.cdl b/ncdump/test_corrupt_magic.cdl
new file mode 100644
index 0000000..f3795f9
--- /dev/null
+++ b/ncdump/test_corrupt_magic.cdl
@@ -0,0 +1,11 @@
+netcdf test_corrupt_magic {
+dimensions:
+	recNum = 8;
+variables:
+	string UTC_time(recNum) ;
+data:
+
+ UTC_time = "2012-03-04 03:54:19", "2012-03-04 03:54:42", 
+    "2012-03-04 03:54:59", "2012-03-04 03:55:20", "2012-03-04 03:55:43", 
+    "2012-03-04 03:56:09", "2012-03-04 03:56:41", "2012-03-04 03:57:12" ;
+}
diff --git a/ncdump/tst_calendars.sh b/ncdump/tst_calendars.sh
index 5c9cedf..b188f15 100755
--- a/ncdump/tst_calendars.sh
+++ b/ncdump/tst_calendars.sh
@@ -23,7 +23,7 @@ TSTS="test_360_day_1900 test_365_day_1900 test_366_day_1900"
 for t in $TSTS ; do
   rm -f ./${t}.cdl
   echo "create: ${t}.cdl from ${t}.nc"
-  ${NCDUMP} -n ${t} -t $srcdir/${t}.nc > ${t}.cdl
+  ${NCDUMP} -n ${t} -t $srcdir/ref_${t}.nc > ${t}.cdl
   echo "compare: ${t}.cdl ref_${t}.cdl"
   diff -b ${t}.cdl $srcdir/ref_${t}.cdl
   rm -f ${t}.cdl
diff --git a/ncdump/tst_compress.c b/ncdump/tst_compress.c
index 9be200d..7c6b730 100644
--- a/ncdump/tst_compress.c
+++ b/ncdump/tst_compress.c
@@ -4,7 +4,7 @@
 
    Create a compressible test file for nccopy to compress.
 
-   $Id$
+   Russ Rew, Ward Fisher, Dennis Heimbigner
 */
 
 #include "config.h"
diff --git a/ncdump/tst_dimsizes.sh b/ncdump/tst_dimsizes.sh
index 0df2828..e08faba 100755
--- a/ncdump/tst_dimsizes.sh
+++ b/ncdump/tst_dimsizes.sh
@@ -20,16 +20,16 @@ ${execdir}/tst_dimsizes
 
 echo "*** Verify that ncdump can read dimsizes"
 
-rm -fr ./tmp
-if ${NCDUMP} -h tst_dimsize_classic.nc > ./tmp ; then
+rm -fr ./tmp_tst_dimsizes
+if ${NCDUMP} -h tst_dimsize_classic.nc > ./tmp_tst_dimsizes ; then
 echo "*** PASS: ncdump tst_dimsize_classic.nc"
 else
 echo "*** FAIL: ncdump tst_dimsize_classic.nc"
 RETURN=1
 fi
 
-rm -fr ./tmp
-if ${NCDUMP} -h tst_dimsize_64offset.nc > ./tmp ; then
+rm -fr ./tmp_tst_dimsizes
+if ${NCDUMP} -h tst_dimsize_64offset.nc > ./tmp_tst_dimsizes ; then
 echo "*** PASS: ncdump tst_dimsize_64offset.nc"
 else
 echo "*** FAIL: ncdump tst_dimsize_64offset.nc"
@@ -37,8 +37,8 @@ RETURN=1
 fi
 
 if test -f tst_dimsize_64data.nc ; then
-  rm -fr ./tmp
-  if ${NCDUMP} -h tst_dimsize_64data.nc > ./tmp ; then
+  rm -fr ./tmp_tst_dimsizes
+  if ${NCDUMP} -h tst_dimsize_64data.nc > ./tmp_tst_dimsizes ; then
     echo "*** PASS: ncdump tst_dimsize_64data.nc"
   else
     echo "*** FAIL: ncdump tst_dimsize_64data.nc"
@@ -47,6 +47,6 @@ if test -f tst_dimsize_64data.nc ; then
 fi
 
 # Cleanup
-rm -f tmp tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc
+rm -f tmp_tst_dimsizes tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc
 
 exit $RETURN
diff --git a/ncdump/tst_fileinfo.sh b/ncdump/tst_fileinfo.sh
index c81d278..87e0ee0 100755
--- a/ncdump/tst_fileinfo.sh
+++ b/ncdump/tst_fileinfo.sh
@@ -13,13 +13,13 @@ HDF=$srcdir/hdf5_fileinfo.hdf
 NF=ref_tst_compounds4.nc
 
 # Do a false negative test 
-rm -f ./tmp
-if $NCDUMP -s $builddir/$NF | fgrep '_IsNetcdf4 = 0' > ./tmp ; then
+rm -f ./tmp_tst_fileinfo
+if $NCDUMP -s $builddir/$NF | fgrep '_IsNetcdf4 = 0' > ./tmp_tst_fileinfo ; then
    echo "Pass: False negative for file: $NF"
 else
    echo "FAIL: False negative for file: $NF"
 fi
-rm -f ./tmp
+rm -f ./tmp_tst_fileinfo
 
 if ${execdir}/tst_fileinfo > /dev/null ; then
    # look at the _IsNetcdf4 flag
diff --git a/ncdump/tst_fillbug.c b/ncdump/tst_fillbug.c
index fc92d9f..0a77ee2 100644
--- a/ncdump/tst_fillbug.c
+++ b/ncdump/tst_fillbug.c
@@ -1,3 +1,8 @@
+/* 
+This is part of the netCDF package. Copyright 2017 University
+Corporation for Atmospheric Research/Unidata. See COPYRIGHT file for
+conditions of use. See www.unidata.ucar.edu for more info.
+*/
 #include <nc_tests.h>
 #include "err_macros.h"
 #include <stdio.h>
@@ -83,7 +88,7 @@ main(int argc, char **argv)
 	int format, ndims, nvars, ngatts, xdimid, ndims_grp, dimids_grp[3],
 	    unlimids[1], d_grp, nunlim, nvars_grp, varids_grp[3], v_grp,
 	    varid, varndims, vardims[3], varnatts, vartype, dimids[3], is_recvar,
-	    vdims[3], id, ntypes, numgrps;
+            id, ntypes, numgrps;
 	size_t dimsize, len;
 	char dimname[20], varname[20];
 	if ( nc_inq_format(ncid, &format)) ERR;
@@ -139,7 +144,6 @@ main(int argc, char **argv)
 	    }
 	    for (id = 0; id < varndims; id++) {
 		if( nc_inq_dimlen(ncid, vardims[id], &len) ) ERR;
-		vdims[id] = len;
 	    }
 	    if (varid == 0) {
 		/* read Time variable */
diff --git a/ncdump/tst_fillbug.sh b/ncdump/tst_fillbug.sh
index a583e16..f83081f 100755
--- a/ncdump/tst_fillbug.sh
+++ b/ncdump/tst_fillbug.sh
@@ -8,6 +8,7 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 echo ""
 echo "*** Running ncdump bug test."
 
+${execdir}/tst_fillbug
 # echo "*** dumping tst_fillbug.nc to tst_fillbug.cdl..."
 ${NCDUMP} tst_fillbug.nc > tst_fillbug.cdl
 # echo "*** comparing tst_fillbug.cdl with ref_tst_fillbug.cdl..."
diff --git a/ncdump/tst_formatx3.sh b/ncdump/tst_formatx3.sh
index 9c00ca3..548b56b 100755
--- a/ncdump/tst_formatx3.sh
+++ b/ncdump/tst_formatx3.sh
@@ -24,19 +24,19 @@ echo ""
 echo "*** Testing extended file format output."
 set -e
 echo "Test extended format output for a netcdf-3 file"
-rm -f tmp
-${NCGEN} -k nc3 -b -o ./test.nc $srcdir/ref_tst_small.cdl
-${NCDUMP} -K test.nc >tmp
-if ! grep 'classic mode=00000000' <tmp ; then
+rm -f tmp_tst_formatx3
+${NCGEN} -k nc3 -b -o ./tst_formatx3.nc $srcdir/ref_tst_small.cdl
+${NCDUMP} -K tst_formatx3.nc >tmp_tst_formatx3
+if ! grep 'classic mode=00000000' <tmp_tst_formatx3 ; then
 echo "*** Fail: extended format for a classic file"
 ECODE=1
 fi
 
 echo "Test extended format output for a 64-bit offset netcdf-3 file"
-rm -f tmp
-${NCGEN} -k nc6 -b -o ./test.nc $srcdir/ref_tst_small.cdl
-${NCDUMP} -K test.nc >tmp
-if ! grep '64-bit offset mode=00000200' <tmp ; then
+rm -f tmp_tst_formatx3
+${NCGEN} -k nc6 -b -o ./tst_formatx3.nc $srcdir/ref_tst_small.cdl
+${NCDUMP} -K tst_formatx3.nc >tmp_tst_formatx3
+if ! grep '64-bit offset mode=00000200' <tmp_tst_formatx3 ; then
 echo "*** Fail: extended format for a 64-bit classic file"
 ECODE=1
 fi
@@ -46,15 +46,15 @@ fi
 
 if test "x$USE_CDF5" = x1 ; then
     echo "Test extended format output for a 64-bit CDF-5 classic file"
-    rm -f tmp
-    ${NCGEN} -k5 -b -o ./test.nc $srcdir/ref_tst_small.cdl
-    ${NCDUMP} -K test.nc >tmp
-    if ! grep -F '64-bit data mode=00000020' <tmp ; then
+    rm -f tmp_tst_formatx3
+    ${NCGEN} -k5 -b -o ./tst_formatx3.nc $srcdir/ref_tst_small.cdl
+    ${NCDUMP} -K tst_formatx3.nc >tmp_tst_formatx3
+    if ! grep -F '64-bit data mode=00000020' <tmp_tst_formatx3 ; then
         echo "*** Fail: extended format for a 64-bit CDF-5 classic file"
         ECODE=1
     fi
 fi
 
-rm -f tmp test.nc
+rm -f tmp_tst_formatx3 tst_formatx3.nc
 
 exit $ECODE
diff --git a/ncdump/tst_formatx4.sh b/ncdump/tst_formatx4.sh
index 8d2a86d..f206c33 100755
--- a/ncdump/tst_formatx4.sh
+++ b/ncdump/tst_formatx4.sh
@@ -10,24 +10,24 @@ echo ""
 echo "*** Testing extended file format output."
 set -e
 echo "Test extended format output for a netcdf-4 file"
-rm -f tmp
-${NCGEN} -k nc4 -b -o ./test.nc $srcdir/ref_tst_small.cdl
-${NCDUMP} -K test.nc >tmp
-if ! grep 'HDF5 mode=00001000' <tmp ; then
+rm -f tmp_tst_formatx4
+${NCGEN} -k nc4 -b -o ./tst_formatx4.nc $srcdir/ref_tst_small.cdl
+${NCDUMP} -K tst_formatx4.nc >tmp_tst_formatx4
+if ! grep 'HDF5 mode=00001000' <tmp_tst_formatx4 ; then
 echo "*** Fail: extended format for a netcdf-4 file"
 ECODE=1
 fi
 
 echo "Test extended format output for a classic netcdf-4 file"
-rm -f tmp
-${NCGEN} -k nc7 -b -o ./test.nc $srcdir/ref_tst_small.cdl
-${NCDUMP} -K test.nc >tmp
-if ! grep 'HDF5 mode=00001000' <tmp ; then
+rm -f tmp_tst_formatx4
+${NCGEN} -k nc7 -b -o ./tst_formatx4.nc $srcdir/ref_tst_small.cdl
+${NCDUMP} -K tst_formatx4.nc >tmp_tst_formatx4
+if ! grep 'HDF5 mode=00001000' <tmp_tst_formatx4 ; then
 echo "*** Fail: extended format for a classic netcdf-4 file"
 ECODE=1
 fi
 
-rm -f tmp test.nc
+rm -f tmp_tst_formatx4 tst_formatx4.nc
 
 exit $ECODE
 
diff --git a/ncdump/tst_h_rdc0.c b/ncdump/tst_h_rdc0.c
index 3344f88..5a3c060 100644
--- a/ncdump/tst_h_rdc0.c
+++ b/ncdump/tst_h_rdc0.c
@@ -3,15 +3,18 @@
    See COPYRIGHT file for conditions of use.
 
    Use HDF5 to read c0.nc, a file created by ncdump. This check was
-   added to detect a problem in the early HDF5 1.8.0 releases.
+   added to detect a problem in the early HDF5 1.8.0 releases. This
+   program is called from the test script tst_netcdf4.sh, which uses
+   ncgen to create the test file c0_tst_netcdf4.nc, which this program
+   reads with HDF5.
 
-   $Id: tst_h_rdc0.c,v 1.5 2010/06/01 15:34:53 ed Exp $
+   Ed Hartnett
 */
 #include <nc_tests.h>
 #include "err_macros.h"
 #include <hdf5.h>
 
-#define FILE_NAME "c0.nc"
+#define FILE_NAME "tst_netcdf4_c0.nc"
 #define MAX_NAME 1024
 
 int
@@ -19,7 +22,6 @@ main()
 {
    printf("\n*** Checking HDF5 file c0.nc.\n");
    printf("*** Checking HDF5 objcts...");
-
    {
       hid_t fileid, grpid;
       hsize_t num_obj, i;
@@ -42,6 +44,5 @@ main()
 	  H5Fclose(fileid) < 0) ERR;
    }
    SUMMARIZE_ERR;
-
    FINAL_RESULTS;
 }
diff --git a/ncdump/tst_h_scalar.c b/ncdump/tst_h_scalar.c
index 950e090..6fd640c 100644
--- a/ncdump/tst_h_scalar.c
+++ b/ncdump/tst_h_scalar.c
@@ -5,6 +5,8 @@
    This program sets up HDF5 files that contain scalar attributes and
    variables, of both string and numeric datatypes.  ncdump should handle
    all of these.
+
+   Russ Rew
 */
 
 #include <nc_tests.h>
@@ -103,7 +105,6 @@ main()
         hid_t dcplid;
 	hid_t scalar_spaceid;
         hid_t vlstr_typeid, fixstr_typeid;
-	hid_t attid;
 
         /* Create scalar dataspace */
 	if ((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;
@@ -183,7 +184,6 @@ main()
     printf("*** Revise file through netCDF-4 API...");
     {
 	int ncid, varid;
-        int ret;
         char *vlstr;
 
 	if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
diff --git a/ncdump/tst_h_scalar.sh b/ncdump/tst_h_scalar.sh
index 7fccec7..f5b6698 100755
--- a/ncdump/tst_h_scalar.sh
+++ b/ncdump/tst_h_scalar.sh
@@ -9,6 +9,7 @@ set -e
 echo ""
 echo "*** Running ncdump scalar test."
 
+${execdir}/tst_h_scalar
 # echo "*** dumping tst_h_scalar.nc to tst_h_scalar.cdl..."
 ${NCDUMP} tst_h_scalar.nc > tst_h_scalar.cdl
 # echo "*** comparing tst_h_scalar.cdl with ref_tst_h_scalar.cdl..."
diff --git a/ncdump/tst_hdf5_offset.sh b/ncdump/tst_hdf5_offset.sh
new file mode 100755
index 0000000..96e8ddb
--- /dev/null
+++ b/ncdump/tst_hdf5_offset.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
+. ../test_common.sh
+
+set -e
+
+# This tests that we can detect an HDF5 file with an offset
+
+rm -f ./offset.cdl ./offset.nc
+cp ${srcdir}/small.cdl ./offset.cdl
+${NCGEN} -4 ./offset.cdl
+
+# Test a 512 byte offset
+rm -f L512.hdf5
+# verify size of L512.bin
+#LSIZE=`wc -c ${srcdir}/L512.bin | cut -d ' ' -f 1`
+cat ${srcdir}/L512.bin offset.nc > L512.hdf5
+K=`${NCDUMP} -k L512.hdf5`
+if test "x$K" = "xnetCDF-4" ; then
+echo "***Pass: 512 offset"
+else
+echo "***FAIL: 512 offset"
+FAILURES=1
+fi
+
+# Test a 1024 byte offset
+rm -f L1024.hdf5
+cat ${srcdir}/L512.bin ${srcdir}/L512.bin offset.nc > L1024.hdf5
+K=`${NCDUMP} -k L1024.hdf5`
+if test "x$K" = "xnetCDF-4" ; then
+echo "***Pass: 1024 offset"
+else
+echo "***FAIL: 1024 offset"
+FAILURES=1
+fi
+
+#cleanup
+rm -f L512.hdf5 L1024.hdf5
+rm -f ./offset.cdl ./offset.nc
+
+if test "x$FAILURES" = x1 ; then
+exit 1
+fi
+exit 0
diff --git a/ncdump/tst_inmemory_nc3.sh b/ncdump/tst_inmemory_nc3.sh
index 8513154..c80c81f 100755
--- a/ncdump/tst_inmemory_nc3.sh
+++ b/ncdump/tst_inmemory_nc3.sh
@@ -13,19 +13,19 @@ PASS=1
 CLASSIC="small ref_tst_nans ref_tst_utf8"
 EXTENDED="ref_nc_test_netcdf4 ref_tst_comp ref_tst_opaque_data"
 
-rm -fr ./results
-mkdir ./results
+rm -fr ./results_tst_inmemory_nc3
+mkdir ./results_tst_inmemory_nc3
 
 # Dump classic files two ways and compare
 dotest() {
 K=$1
 for f in $2 ; do
   echo "Testing ${f}"
-  ${NCGEN} -$K -o ./results/${f}.nc ${srcdir}/${f}.cdl
-  ${NCDUMP} ./results/${f}.nc > ./results/${f}.cdl
-  ${NCDUMP} -Xm ./results/${f}.nc > ./results/${f}.cdx
-  diff -w ./results/${f}.cdl ./results/${f}.cdx &> ./results/${f}.diff
-  if test -s ./results/${f}.diff ; then
+  ${NCGEN} -$K -o ./results_tst_inmemory_nc3/${f}.nc ${srcdir}/${f}.cdl
+  ${NCDUMP} ./results_tst_inmemory_nc3/${f}.nc > ./results_tst_inmemory_nc3/${f}.cdl
+  ${NCDUMP} -Xm ./results_tst_inmemory_nc3/${f}.nc > ./results_tst_inmemory_nc3/${f}.cdx
+  diff -w ./results_tst_inmemory_nc3/${f}.cdl ./results_tst_inmemory_nc3/${f}.cdx &> ./results_tst_inmemory_nc3/${f}.diff
+  if test -s ./results_tst_inmemory_nc3/${f}.diff ; then
     echo "***FAIL: $f"
     PASS=0
   fi
@@ -35,7 +35,7 @@ done
 dotest "3" "$CLASSIC"
 
 # Cleanup
-rm -fr results
+rm -fr results_tst_inmemory_nc3
 
 if test "x$PASS" = x1 ; then
   echo "*** PASS all tests"
diff --git a/ncdump/tst_inmemory_nc4.sh b/ncdump/tst_inmemory_nc4.sh
index 2bab172..2fca023 100755
--- a/ncdump/tst_inmemory_nc4.sh
+++ b/ncdump/tst_inmemory_nc4.sh
@@ -13,19 +13,19 @@ PASS=1
 CLASSIC="small ref_tst_nans ref_tst_utf8"
 EXTENDED="ref_nc_test_netcdf4 ref_tst_comp ref_tst_opaque_data"
 
-rm -fr ./results
-mkdir ./results
+rm -fr ./results_tst_inmemory_nc4
+mkdir ./results_tst_inmemory_nc4
 
 # Dump classic files two ways and compare
 dotest() {
 K=$1
 for f in $2 ; do
   echo "Testing ${f}"
-  ${NCGEN} -$K -o ./results/${f}.nc ${srcdir}/${f}.cdl
-  ${NCDUMP} ./results/${f}.nc > ./results/${f}.cdl
-  ${NCDUMP} -Xm ./results/${f}.nc > ./results/${f}.cdx
-  diff -w ./results/${f}.cdl ./results/${f}.cdx &> ./results/${f}.diff
-  if test -s ./results/${f}.diff ; then
+  ${NCGEN} -$K -o ./results_tst_inmemory_nc4/${f}.nc ${srcdir}/${f}.cdl
+  ${NCDUMP} ./results_tst_inmemory_nc4/${f}.nc > ./results_tst_inmemory_nc4/${f}.cdl
+  ${NCDUMP} -Xm ./results_tst_inmemory_nc4/${f}.nc > ./results_tst_inmemory_nc4/${f}.cdx
+  diff -w ./results_tst_inmemory_nc4/${f}.cdl ./results_tst_inmemory_nc4/${f}.cdx &> ./results_tst_inmemory_nc4/${f}.diff
+  if test -s ./results_tst_inmemory_nc4/${f}.diff ; then
     echo "***FAIL: $f"
     PASS=0
   fi
@@ -42,7 +42,7 @@ if test -f ${top_builddir}/config.h ; then
 fi
 
 # Cleanup
-rm -fr results
+rm -fr results_tst_inmemory_nc4
 
 if test "x$PASS" = x1 ; then
   echo "*** PASS all tests"
diff --git a/ncdump/tst_nccopy3.sh b/ncdump/tst_nccopy3.sh
index 402d5e5..1b023e5 100755
--- a/ncdump/tst_nccopy3.sh
+++ b/ncdump/tst_nccopy3.sh
@@ -1,10 +1,13 @@
 #!/bin/sh
+# For a netCDF-3 build, test nccopy on netCDF files in this
+# directory. This test depends on a bunch of other ncdump tests
+# running first, to produce the data files that are used to test
+# nccopy.
+# Dennis Heimbigner
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 . ../test_common.sh
 
-# For a netCDF-3 build, test nccopy on netCDF files in this directory
-
 set -e
 echo ""
 
@@ -20,8 +23,8 @@ else
   exit 1
 fi
 
-TESTFILES='c0 c0tmp ctest0 ctest0_64 test0_offset test1_offset
- tst_calendars tst_mslp tst_mslp_64 tst_ncml tst_small tst_utf8 utf8'
+TESTFILES='tst_output_c0 tst_output_c0tmp ctest0 ctest0_64 test0_offset test1_offset
+ tst_calendars tst_mslp tst_mslp_64 tst_ncml tst_small tst_utf8'
 
 if test "x$HAVE_CDF5" = x1 ; then
     TESTFILES="$TESTFILES small small2"
@@ -30,21 +33,21 @@ fi
 
 echo "*** Testing netCDF-3 features of nccopy on ncdump/*.nc files"
 for i in $TESTFILES ; do
-    echo "*** Testing nccopy $i.nc copy_of_$i.nc ..."
-    ${NCCOPY} $i.nc copy_of_$i.nc
-    ${NCDUMP} -n copy_of_$i $i.nc > tmp.cdl
-    ${NCDUMP} copy_of_$i.nc > copy_of_$i.cdl
-    diff copy_of_$i.cdl tmp.cdl
-    rm copy_of_$i.nc copy_of_$i.cdl tmp.cdl
+    echo "*** Testing nccopy $i.nc nccopy3_copy_of_$i.nc ..."
+    ${NCCOPY} $i.nc nccopy3_copy_of_$i.nc
+    ${NCDUMP} -n nccopy3_copy_of_$i $i.nc > tmp_tst_nccopy3.cdl
+    ${NCDUMP} nccopy3_copy_of_$i.nc > nccopy3_copy_of_$i.cdl
+    diff nccopy3_copy_of_$i.cdl tmp_tst_nccopy3.cdl
+    rm nccopy3_copy_of_$i.nc nccopy3_copy_of_$i.cdl tmp_tst_nccopy3.cdl
 done
 echo "*** Testing nccopy -u"
 ${NCGEN} -b $srcdir/tst_brecs.cdl
 # convert record dimension to fixed-size dimension
-$NCCOPY -u tst_brecs.nc copy_of_tst_brecs.nc
-${NCDUMP} -n copy_of_tst_brecs tst_brecs.nc | sed '/ = UNLIMITED ;/s/\(.*\) = UNLIMITED ; \/\/ (\(.*\) currently)/\1 = \2 ;/' > tmp.cdl
-${NCDUMP} copy_of_tst_brecs.nc >  copy_of_tst_brecs.cdl
-diff -b copy_of_tst_brecs.cdl tmp.cdl
-rm copy_of_tst_brecs.cdl tmp.cdl tst_brecs.nc copy_of_tst_brecs.nc
+$NCCOPY -u tst_brecs.nc nccopy3_copy_of_tst_brecs.nc
+${NCDUMP} -n nccopy3_copy_of_tst_brecs tst_brecs.nc | sed '/ = UNLIMITED ;/s/\(.*\) = UNLIMITED ; \/\/ (\(.*\) currently)/\1 = \2 ;/' > tmp_tst_nccopy3.cdl
+${NCDUMP} nccopy3_copy_of_tst_brecs.nc >  nccopy3_copy_of_tst_brecs.cdl
+diff -b nccopy3_copy_of_tst_brecs.cdl tmp_tst_nccopy3.cdl
+rm nccopy3_copy_of_tst_brecs.cdl tmp_tst_nccopy3.cdl tst_brecs.nc nccopy3_copy_of_tst_brecs.nc
 
 echo "*** All nccopy tests passed!"
 exit 0
diff --git a/ncdump/tst_nccopy4.sh b/ncdump/tst_nccopy4.sh
index 79caeb1..6784664 100755
--- a/ncdump/tst_nccopy4.sh
+++ b/ncdump/tst_nccopy4.sh
@@ -16,6 +16,10 @@ TESTFILES='tst_comp tst_comp2 tst_enum_data tst_fillbug
  tst_solar_cmp tst_special_atts tst_string_data tst_unicode
  tst_vlen_data'
 
+# Run these programs to create some test files.
+${execdir}/tst_comp2
+${execdir}/tst_compress
+
 echo "*** Testing netCDF-4 features of nccopy on ncdump/*.nc files"
 for i in $TESTFILES ; do
     echo "*** Test nccopy $i.nc copy_of_$i.nc ..."
@@ -86,7 +90,7 @@ echo "*** Test that nccopy -c works as intended for record dimension default (1)
 ${NCGEN} -b -o tst_bug321.nc $srcdir/tst_bug321.cdl
 $NCCOPY -k nc7 -c"lat/2,lon/2" tst_bug321.nc tmp.nc
 ${NCDUMP} -n tst_bug321 tmp.nc > tmp.cdl
-diff $srcdir/tst_bug321.cdl tmp.cdl
+diff -b $srcdir/tst_bug321.cdl tmp.cdl
 # echo "*** Test that nccopy compression with chunking can improve compression"
 rm tst_chunking.nc tmp.nc tmp.cdl tmp-chunked.nc tmp-chunked.cdl tmp-unchunked.nc tmp-unchunked.cdl
 
diff --git a/ncdump/tst_ncgen4.sh b/ncdump/tst_ncgen4.sh
index 90fc9d4..a5be263 100755
--- a/ncdump/tst_ncgen4.sh
+++ b/ncdump/tst_ncgen4.sh
@@ -1,9 +1,13 @@
 #!/bin/sh
+# Tests for ncgen4 using list of test cdl files from the cdl4
+# directory, and comparing output to expected results in the expected4
+# directory. Note that these tests are run for classic files in
+# tst_ncgen4_classic.sh
+# Dennis Heimbigner
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
 . ../test_common.sh
 
-verbose=1
 set -e
 
 # To add a new test,
@@ -15,14 +19,9 @@ set -e
 # 4. Add the new files into cdl4/Makefile.am
 #    and expected4/Makefile.am 
 
-
+verbose=1
 export verbose
 
-KFLAG=1 ; export KFLAG
-echo "*** Performing diff tests: k=1"
-sh ${srcdir}/tst_ncgen4_diff.sh
-echo "*** Performing cycle tests: k=1"
-sh  ${srcdir}/tst_ncgen4_cycle.sh
 KFLAG=3 ; export KFLAG
 echo "*** Performing diff tests: k=3"
 sh  ${srcdir}/tst_ncgen4_diff.sh
@@ -33,5 +32,7 @@ echo "*** Performing diff tests: k=4"
 sh  ${srcdir}/tst_ncgen4_diff.sh
 echo "*** Performing cycle tests: k=4"
 sh  ${srcdir}/tst_ncgen4_cycle.sh
-exit
+rm -rf ${RESULTSDIR}
+echo "SUCCESS!!"
+exit 0
 
diff --git a/ncdump/tst_ncgen4_classic.sh b/ncdump/tst_ncgen4_classic.sh
index f704306..e72f3f4 100755
--- a/ncdump/tst_ncgen4_classic.sh
+++ b/ncdump/tst_ncgen4_classic.sh
@@ -1,4 +1,8 @@
 #!/bin/sh
+# Tests for ncgen4 using list of test cdl files from the cdl4
+# directory, and comparing output to expected results in the expected4
+# directory. Same as tst_ncgen4.sh but for classic format.
+# Dennie Heimbigner
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
 . ../test_common.sh
@@ -6,12 +10,13 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 set -e
 echo ""
 verbose=0
-
 export verbose
 
+echo "*** Performing diff/cycle tests for classic format: k=1"
 KFLAG=1 ; export KFLAG
-sh  ${srcdir}/tst_ncgen4_diff.sh
-sh  ${srcdir}/tst_ncgen4_cycle.sh
+bash -x  ${srcdir}/tst_ncgen4_diff.sh
+bash -x  ${srcdir}/tst_ncgen4_cycle.sh
+echo "SUCCESS!!"
 exit 0
 
 
diff --git a/ncdump/tst_ncgen4_cycle.sh b/ncdump/tst_ncgen4_cycle.sh
index 879eaa2..6a3766e 100755
--- a/ncdump/tst_ncgen4_cycle.sh
+++ b/ncdump/tst_ncgen4_cycle.sh
@@ -16,6 +16,7 @@ fi
 
 echo "*** Cycle testing ncgen with -k${KFLAG}"
 
+mkdir ${RESULTSDIR}
 cd ${RESULTSDIR}
 for x in ${TESTSET} ; do
   test "x$verbose" = x1 && echo "*** Testing: ${x}"
@@ -34,18 +35,19 @@ for x in ${TESTSET} ; do
 	echo "xfail test: ${x}: ignored"
         xfailcount=`expr $xfailcount + 1`	
   else
-    rm -f ${x}.nc ${x}.dmp
+    rm -f ${x}_$$.nc ${x}_$$.dmp
     # step 1: use original cdl to build the .nc
-    ${NCGEN} -b -k${KFLAG} -o ${x}.nc ${cdl}/${x}.cdl
+    ${NCGEN} -b -k${KFLAG} -o ${x}_$$.nc ${cdl}/${x}.cdl
     # step 2: dump .nc file
-    ${NCDUMP} ${headflag} ${specflag} ${x}.nc > ${x}.dmp
+    ${NCDUMP} ${headflag} ${specflag} -n ${x} ${x}_$$.nc > ${x}_$$.dmp
     # step 3: use ncgen and the ncdump output to (re-)build the .nc
-    rm -f ${x}.nc
-    ${NCGEN} -b -k${KFLAG} -o ${x}.nc ${x}.dmp
+    rm -f ${x}_$$.nc
+    ${NCGEN} -b -k${KFLAG} -o ${x}_$$.nc ${x}_$$.dmp
     # step 4: dump .nc file again
-    ${NCDUMP} ${headflag} ${specflag} ${x}.nc > ${x}.dmp2
+    ${NCDUMP} ${headflag} ${specflag} -n ${x} ${x}_$$.nc > ${x}_$$.dmp2
     # compare the two ncdump outputs
-    if diff -b -w ${x}.dmp ${x}.dmp2 ; then ok=1; else ok=0; fi
+    if diff -b -w ${x}_$$.dmp ${x}_$$.dmp2 ; then ok=1; else ok=0; fi
+    rm -f ${x}_$$.nc ${x}_$$.dmp
     if test "x$ok" = "x1" ; then
       test "x$verbose" = x1 && echo "*** SUCCEED: ${x}"
       passcount=`expr $passcount + 1`
@@ -61,6 +63,7 @@ totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
 
 echo "*** PASSED: ${okcount}/${totalcount} ; ${failcount} unexpected failures; ${xfailcount} expected failures ignored"
+rm -rf ${RESULTSDIR}
 
 if test $failcount -gt 0 ; then
   exit 1
diff --git a/ncdump/tst_ncgen4_diff.sh b/ncdump/tst_ncgen4_diff.sh
index de5619f..044ee8e 100755
--- a/ncdump/tst_ncgen4_diff.sh
+++ b/ncdump/tst_ncgen4_diff.sh
@@ -20,6 +20,7 @@ fi
 
 echo "*** Testing ncgen with -k${KFLAG}"
 
+mkdir ${RESULTSDIR}
 cd ${RESULTSDIR}
 for x in ${TESTSET} ; do
   if test $verbose = 1 ; then echo "*** Testing: ${x}" ; fi
@@ -35,10 +36,10 @@ for x in ${TESTSET} ; do
 	if test "x${t}" = "x${x}" ; then isxfail=1; fi
 	done
   rm -f ${x}.nc ${x}.dmp
-  ${NCGEN} -b -k${KFLAG} -o ${x}.nc ${cdl}/${x}.cdl
+  ${NCGEN} -b -k${KFLAG} -o ${x}_$$.nc ${cdl}/${x}.cdl
   # dump .nc file
   # if windows, we need to remove any leading 0's in exponents.
-  ${NCDUMP} ${headflag} ${specflag} ${x}.nc | sed 's/e+0/e+/g' > ${x}.dmp
+  ${NCDUMP} ${headflag} ${specflag} -n ${x} ${x}_$$.nc | sed 's/e+0/e+/g' > ${x}.dmp
   # compare the expected (silently if XFAIL)
   if test "x$isxfail" = "x1" -a "x$SHOWXFAILS" = "x" ; then
     if diff -b -bw ${expected}/${x}.dmp ${x}.dmp >/dev/null 2>&1; then ok=1; else ok=0; fi
@@ -62,6 +63,7 @@ totalcount=`expr $passcount + $failcount + $xfailcount`
 okcount=`expr $passcount + $xfailcount`
 
 echo "*** PASSED: ${okcount}/${totalcount} ; ${xfailcount} expected failures ; ${failcount} unexpected failures"
+rm -rf ${RESULTSDIR}
 
 if test $failcount -gt 0 ; then
   exit 1
diff --git a/ncdump/tst_ncgen_shared.sh b/ncdump/tst_ncgen_shared.sh
index 82c9bdb..9bf84a2 100755
--- a/ncdump/tst_ncgen_shared.sh
+++ b/ncdump/tst_ncgen_shared.sh
@@ -14,7 +14,7 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 #    and expected/Makefile.am 
 
 set -e
-RESULTSDIR="./results"
+RESULTSDIR="./results_$$"
 #SHOWXFAILS=1
 
 # Locate the cdl and expected directory
@@ -143,5 +143,4 @@ failcount=0
 passcount=0
 xfailcount=0
 
-rm -fr results
-mkdir results
+rm -fr $RESULTSDIR
diff --git a/ncdump/tst_netcdf4.sh b/ncdump/tst_netcdf4.sh
index 6120de9..4c12602 100755
--- a/ncdump/tst_netcdf4.sh
+++ b/ncdump/tst_netcdf4.sh
@@ -1,92 +1,107 @@
-#!/bin/sh
+#!/bin/bash
+# This shell script tests ncdump for netcdf-4
+# Ed Hartnett, Dennis Heimbigner, Ward Fisher
 
-if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 . ../test_common.sh
 
-# This shell script tests ncdump for netcdf-4
-
 set -e
 
+function ERR {
+    RES=$?
+    if [ $RES -ne 0 ]; then
+        echo "Error found: $RES"
+        exit $RES
+    fi
+}
+
 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} -k nc4 -b -o c0_4.nc ${ncgenc04}
-# 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 -b c1_4.cdl $srcdir/ref_ctest1_nc4.cdl
-
-echo "*** Testing ncgen and ncdump test output for netCDF-4 classic format."
-# echo "*** creating netcdf-4 classic file c0.nc from c0.cdl..."
-${NCGEN} -k nc7 -b -o c0.nc ${ncgenc0}
-# echo "*** creating c1.cdl from c0.nc..."
-
-# echo "*** comparing c1.cdl with ref_ctest1_nc4c.cdl..."
-diff -b c1.cdl $srcdir/ref_ctest1_nc4c.cdl
-
-echo "*** Testing ncdump output for netCDF-4 features."
-${NCDUMP} tst_solar_1.nc | sed 's/e+0/e+/g' > tst_solar_1.cdl
-# echo "*** comparing tst_solar_1.cdl with ref_tst_solar_1.cdl..."
-diff -b tst_solar_1.cdl $srcdir/ref_tst_solar_1.cdl
-${NCDUMP} tst_solar_2.nc | sed 's/e+0/e+/g' > tst_solar_2.cdl
-# echo "*** comparing tst_solar_2.cdl with ref_tst_solar_2.cdl..."
-diff -b tst_solar_2.cdl $srcdir/ref_tst_solar_2.cdl
-${NCDUMP} tst_group_data.nc | sed 's/e+0/e+/g' > tst_group_data.cdl
-# echo "*** comparing tst_group_data.cdl with ref_tst_group_data.cdl..."
-diff -b tst_group_data.cdl $srcdir/ref_tst_group_data.cdl
-
-# Temporary hack to skip a couple tests that won't work in windows
-# without changing the format of the string. See:
-#
-# http://www.mingw.org/wiki/Posix_path_conversion
-
-if [[ "$OSTYPE" != 'msys' ]]; then
-echo "*** Testing -v option with absolute name and groups..."
-${NCDUMP} -v /g2/g3/var tst_group_data.nc | sed 's/e+0/e+/g' > tst_group_data.cdl
-# echo "*** comparing tst_group_data.cdl with ref_tst_group_data_v23.cdl..."
-diff -b tst_group_data.cdl $srcdir/ref_tst_group_data_v23.cdl
-fi
+echo "*** Testing ncgen and ncdump for netCDF-4 format."
+${NCGEN} -k nc4 -b -o tst_netcdf4_c0_4.nc ${ncgenc04} ;ERR
+${NCDUMP} -n c1 tst_netcdf4_c0_4.nc | sed 's/e+0/e+/g' > tst_netcdf4_c1_4.cdl ; ERR
+diff -b tst_netcdf4_c1_4.cdl $srcdir/ref_ctest1_nc4.cdl ; ERR
 
+echo "*** Creating test output tst_netcdf4_c0.nc."
+${NCGEN} -k nc7 -b -o tst_netcdf4_c0.nc ${ncgenc0} ; ERR
+
+echo "*** Testing that program tst_h_rdc0 can read tst_netcdf4_c0.nc."
+${execdir}/tst_h_rdc0 ; ERR
+
+echo "*** Running tst_create_files.c to create test files."
+${execdir}/tst_create_files ; ERR
+echo "*** Testing tst_create_files output for netCDF-4 features."
+${NCDUMP} tst_solar_1.nc | sed 's/e+0/e+/g' > tst_solar_1.cdl ; ERR
+diff -b tst_solar_1.cdl $srcdir/ref_tst_solar_1.cdl ; ERR
+${NCDUMP} tst_solar_2.nc | sed 's/e+0/e+/g' > tst_solar_2.cdl ; ERR
+diff -b tst_solar_2.cdl $srcdir/ref_tst_solar_2.cdl ; ERR
+
+echo "*** Running tst_group_data.c to create test files."
+${execdir}/tst_group_data ; ERR
+${NCDUMP} tst_group_data.nc | sed 's/e+0/e+/g' > tst_group_data.cdl ; ERR
+diff -b tst_group_data.cdl $srcdir/ref_tst_group_data.cdl ; ERR
+
+echo "*** Testing -v option with absolute name and groups..."
+${NCDUMP} -v g2/g3/var tst_group_data.nc | sed 's/e+0/e+/g' > tst_group_data.cdl ; ERR
+diff -b tst_group_data.cdl $srcdir/ref_tst_group_data_v23.cdl ; ERR
 
 echo "*** Testing -v option with relative name and groups..."
-${NCDUMP} -v var,var2 tst_group_data.nc | sed 's/e+0/e+/g' > tst_group_data.cdl
-# echo "*** comparing tst_group_data.cdl with ref_tst_group_data.cdl..."
-diff -b tst_group_data.cdl $srcdir/ref_tst_group_data.cdl
-${NCDUMP} tst_enum_data.nc | sed 's/e+0/e+/g' > tst_enum_data.cdl
-# echo "*** comparing tst_enum_data.cdl with ref_tst_enum_data.cdl..."
-diff -b tst_enum_data.cdl $srcdir/ref_tst_enum_data.cdl
-${NCDUMP} tst_opaque_data.nc | sed 's/e+0/e+/g' > tst_opaque_data.cdl
-# echo "*** comparing tst_opaque_data.cdl with ref_tst_opaque_data.cdl..."
-diff -b tst_opaque_data.cdl $srcdir/ref_tst_opaque_data.cdl
-${NCDUMP} tst_vlen_data.nc | sed 's/e+0/e+/g' > tst_vlen_data.cdl
-# echo "*** comparing tst_vlen_data.cdl with ref_tst_vlen_data.cdl..."
-diff -b tst_vlen_data.cdl $srcdir/ref_tst_vlen_data.cdl
-${NCDUMP} tst_comp.nc | sed 's/e+0/e+/g' > tst_comp.cdl
-# echo "*** comparing tst_comp.cdl with ref_tst_comp.cdl..."
-diff -b tst_comp.cdl $srcdir/ref_tst_comp.cdl
-# echo "*** creating tst_nans.cdl from tst_nans.nc"
-${NCDUMP} tst_nans.nc | sed 's/e+0/e+/g' > tst_nans.cdl
-# echo "*** comparing ncdump of generated file with ref_tst_nans.cdl ..."
-diff -b tst_nans.cdl $srcdir/ref_tst_nans.cdl
+${NCDUMP} -v var,var2 tst_group_data.nc | sed 's/e+0/e+/g' > tst_group_data.cdl ; ERR
+diff -b tst_group_data.cdl $srcdir/ref_tst_group_data.cdl ; ERR
+
+echo "*** Running tst_enum_data.c to create test files."
+${execdir}/tst_enum_data ; ERR
+${NCDUMP} tst_enum_data.nc | sed 's/e+0/e+/g' > tst_enum_data.cdl ; ERR
+diff -b tst_enum_data.cdl $srcdir/ref_tst_enum_data.cdl ; ERR
+
+echo "*** Running tst_opaque_data.c to create test files."
+${execdir}/tst_opaque_data ; ERR
+${NCDUMP} tst_opaque_data.nc | sed 's/e+0/e+/g' > tst_opaque_data.cdl ; ERR
+diff -b tst_opaque_data.cdl $srcdir/ref_tst_opaque_data.cdl ; ERR
+
+echo "*** Running tst_vlen_data.c to create test files."
+${execdir}/tst_vlen_data ; ERR
+${NCDUMP} tst_vlen_data.nc | sed 's/e+0/e+/g' > tst_vlen_data.cdl ; ERR
+diff -b tst_vlen_data.cdl $srcdir/ref_tst_vlen_data.cdl ; ERR
+
+echo "*** Running tst_comp.c to create test files."
+${execdir}/tst_comp ; ERR
+${NCDUMP} tst_comp.nc | sed 's/e+0/e+/g' > tst_comp.cdl ; ERR
+diff -b tst_comp.cdl $srcdir/ref_tst_comp.cdl ; ERR
+
+echo "*** Running tst_nans.c to create test files."
+${execdir}/tst_nans ; ERR
+${NCDUMP} tst_nans.nc | sed 's/e+0/e+/g' > tst_nans.cdl ; ERR
+diff -b tst_nans.cdl $srcdir/ref_tst_nans.cdl ; ERR
+
 # Do unicode test only if it exists => BUILD_UTF8 is true
 if test -f ./tst_unicode -o -f ./tst_unicode.exe ; then
   echo "*** dumping tst_unicode.nc to tst_unicode.cdl..."
-  ./tst_unicode
-${NCDUMP} tst_unicode.nc | sed 's/e+0/e+/g' > tst_unicode.cdl
+  ${execdir}/tst_unicode ; ERR
+${NCDUMP} tst_unicode.nc | sed 's/e+0/e+/g' > tst_unicode.cdl ; ERR
   #echo "*** comparing tst_unicode.cdl with ref_tst_unicode.cdl..."
   #diff -b tst_unicode.cdl $srcdir/ref_tst_unicode.cdl
 fi
-${execdir}/tst_special_atts
+
+echo "*** Running tst_special_atts.c to create test files."
+${execdir}/tst_special_atts ; ERR
 ${NCDUMP} -c -s tst_special_atts.nc \
     | sed 's/e+0/e+/g' \
     | sed -e 's/netcdflibversion=.*[|]/netcdflibversion=0.0.0|/' \
     | sed -e 's/hdf5libversion=.*"/hdf5libversion=0.0.0"/' \
     | sed -e 's|_SuperblockVersion = [0-9]|_SuperblockVersion = 0|' \
-    | cat > tst_special_atts.cdl
+    | cat > tst_special_atts.cdl ; ERR
 echo "*** comparing tst_special_atts.cdl with ref_tst_special_atts.cdl..."
-diff -b tst_special_atts.cdl $srcdir/ref_tst_special_atts.cdl
+diff -b tst_special_atts.cdl $srcdir/ref_tst_special_atts.cdl ; ERR
+
+#echo ""
+#echo "*** Testing ncdump on file with corrupted header "
+#rm -f ./ignore_tst_netcdf4
+#if ${NCDUMP} ${srcdir}/ref_test_corrupt_magic.nc > ./ignore_tst_netcdf4 2>&1 ; then
+#echo "***Fail: ncdump should have failed on ref_test_corrupt_magic.nc"
+#else
+#echo "***XFail: ncdump properly failed on ref_test_corrupt_magic.nc"
+#fi
+#rm -fr ./ignore_tst_netcdf4
 
 echo "*** All ncgen and ncdump test output for netCDF-4 format passed!"
 exit 0
-
-
diff --git a/ncdump/tst_netcdf4_4.sh b/ncdump/tst_netcdf4_4.sh
index 74e3856..4da9b4b 100755
--- a/ncdump/tst_netcdf4_4.sh
+++ b/ncdump/tst_netcdf4_4.sh
@@ -1,10 +1,10 @@
 #!/bin/sh
+# This shell script runs extra tests ncdump for netcdf-4
+# Dennis Heimbigner, Ward Fisher
 
 if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
 . ../test_common.sh
 
-# This shell script runs extra tests ncdump for netcdf-4
-
 set -e
 
 echo ""
@@ -19,12 +19,14 @@ echo "*** Running extra netcdf-4 tests."
 #
 # Short term solution, use sed when on windows/MSYS to 
 # remove the './','../../ncdump'.
-# 
+#
+
+echo "*** running tst_string_data to create test files..."
+${execdir}/tst_string_data
 
 if [ `uname | cut -d "_" -f 1` = "MINGW32" ]; then # MINGW Platforms
 
     echo "*** dumping tst_string_data.nc to tst_string_data.cdl..."
-
     ${NCDUMP} tst_string_data.nc > tst_string_data.cdl
     TMPNAME=`head -n 1 tst_string_data.cdl | cut -d" " -f 2`
     NEWNAME=`basename $TMPNAME`
diff --git a/ncdump/tst_null_byte_padding.sh b/ncdump/tst_null_byte_padding.sh
new file mode 100755
index 0000000..50deb86
--- /dev/null
+++ b/ncdump/tst_null_byte_padding.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
+. ../test_common.sh
+
+# This shell script tests a file which doesn't adhere to the
+# documented null-byte padding for header information.
+# See https://github.com/Unidata/netcdf-c/issues/657 for more info.
+
+set -e
+
+echo ""
+echo "*** Testing compatibility with non-null-byte padded test file."
+${NCDUMP} $srcdir/ref_null_byte_padding_test.nc
+
+echo "Passed."
+exit 0
diff --git a/ncdump/tst_output.sh b/ncdump/tst_output.sh
index 053886e..87a5318 100755
--- a/ncdump/tst_output.sh
+++ b/ncdump/tst_output.sh
@@ -1,9 +1,6 @@
 #!/bin/sh
 
-export SETX=1
-set -x
-
-if test "x$srcdir" = x ; then srcdir=`pwd`; fi 
+if test "x$srcdir" = x ; then srcdir=`pwd`; fi
 . ../test_common.sh
 
 # This shell script tests the output from several previous tests.
@@ -11,19 +8,27 @@ set -e
 
 echo ""
 echo "*** Testing ncgen and ncdump test output for classic format."
-echo "*** creating ctest1.cdl from ctest0.nc..."
-${NCDUMP} -n c1 ${builddir}/ctest0.nc | sed 's/e+0/e+/g' > ctest1.cdl
-echo "*** creating c0.nc from c0.cdl..."
-${NCGEN} -b -o c0.nc ${ncgenc0}
-echo "*** creating c1.cdl from c0.nc..."
-${NCDUMP} -n c1 ${builddir}/c0.nc | sed 's/e+0/e+/g' > c1.cdl
+
+echo "*** Testing that ncgen produces correct C code from c0.cdl."
+${execdir}/ref_ctest
+${NCGEN} -lc -o ctest0.nc $srcdir/../ncgen/c0.cdl > tst_output_ctest.c
+diff -b tst_output_ctest.c $srcdir/ref_ctest.c
+
+echo "*** creating ctest1.cdl from tst_output_ctest0.nc..."
+${NCDUMP} -n c1 ${builddir}/ctest0.nc | sed 's/e+0/e+/g' > tst_output_ctest1.cdl
+echo "*** creating tst_output_c0.nc from c0.cdl..."
+${NCGEN} -b -o tst_output_c0.nc ${ncgenc0}
+echo "*** creating tst_output_c1.cdl from tst_output_c0.nc..."
+${NCDUMP} -n c1 ${builddir}/tst_output_c0.nc | sed 's/e+0/e+/g' > tst_output_c1.cdl
+echo "*** comparing tst_output_c1.cdl with ref_ctest1_nc4c.cdl..."
+diff -b tst_output_c1.cdl $srcdir/ref_ctest1_nc4c.cdl
 echo "*** comparing ncdump of C program output (ctest1.cdl) with c1.cdl..."
-diff -b c1.cdl ctest1.cdl
+diff -b tst_output_c1.cdl tst_output_ctest1.cdl
 echo "*** test output for ncdump -k"
-KIND=`${NCDUMP} -k c0.nc`
+KIND=`${NCDUMP} -k tst_output_c0.nc`
 test "$KIND" = "classic";
-${NCGEN} -k $KIND -b -o c0tmp.nc ${ncgenc0}
-cmp c0tmp.nc c0.nc
+${NCGEN} -k $KIND -b -o tst_output_c0tmp.nc ${ncgenc0}
+cmp tst_output_c0tmp.nc tst_output_c0.nc
 
 echo "*** test output for ncdump -x"
 echo "*** creating tst_ncml.nc from tst_ncml.cdl"
@@ -43,19 +48,24 @@ diff -b tst_format_att.cdl $srcdir/ref_tst_format_att.cdl
 
 echo "*** All ncgen and ncdump test output for classic format passed!"
 
+echo "*** Testing that ncgen with c0.cdl for 64-bit offset format."
+${execdir}/ref_ctest64
+${NCGEN}  -k2 -lc -o ctest0_64.nc $srcdir/../ncgen/c0.cdl > tst_output_ctest64.c
+diff -b tst_output_ctest64.c $srcdir/ref_ctest64.c
+
 echo "*** Testing ncgen and ncdump test output for 64-bit offset format."
 echo "*** creating ctest1_64.cdl from test0_64.nc..."
-${NCDUMP} -n c1 ctest0_64.nc | sed 's/e+0/e+/g' > ctest1_64.cdl
-echo "*** creating c0.nc from c0.cdl..."
-${NCGEN} -k nc6 -b -o c0.nc ${ncgenc0}
-echo "*** creating c1.cdl from c0.nc..."
-${NCDUMP} -n c1 c0.nc | sed 's/e+0/e+/g' > c1.cdl
-echo "*** comparing ncdump of C program output (ctest1_64.cdl) with c1.cdl..."
-diff -b c1.cdl ctest1_64.cdl
+${NCDUMP} -n c1 ctest0_64.nc | sed 's/e+0/e+/g' > tst_output_ctest1_64.cdl
+echo "*** creating tst_output_c0_64.nc from c0.cdl..."
+${NCGEN} -k nc6 -b -o tst_output_c0_64.nc ${ncgenc0}
+echo "*** creating tst_output_c1_64.cdl from tst_output_c0_64.nc..."
+${NCDUMP} -n c1 tst_output_c0_64.nc | sed 's/e+0/e+/g' > tst_output_c1_64.cdl
+echo "*** comparing ncdump of C program output (ctest1_64.cdl) with tst_output_c1_64.cdl..."
+diff -b tst_output_c1_64.cdl tst_output_ctest1_64.cdl
 echo "*** test output for ncdump -k"
-test "`${NCDUMP} -k c0.nc`" = "64-bit offset";
-${NCGEN} -k nc6 -b -o c0tmp.nc ${ncgenc0}
-cmp c0tmp.nc c0.nc
+test "`${NCDUMP} -k tst_output_c0_64.nc`" = "64-bit offset";
+${NCGEN} -k nc6 -b -o tst_output_c0_64_tmp.nc ${ncgenc0}
+cmp tst_output_c0_64_tmp.nc tst_output_c0_64.nc
 
 echo "*** test output for ncdump -s"
 echo "*** creating tst_mslp_64.nc from tst_mslp.cdl"
diff --git a/ncdump/tst_string_data.c b/ncdump/tst_string_data.c
index 0d5a030..47b1e00 100644
--- a/ncdump/tst_string_data.c
+++ b/ncdump/tst_string_data.c
@@ -4,7 +4,7 @@
 
    Create a test file with a string data for ncdump to read.
 
-   $Id: tst_string_data.c,v 1.7 2009/01/28 18:19:48 russ Exp $
+   Russ Rew
 */
 
 #include <nc_tests.h>
diff --git a/ncdump/utils.h b/ncdump/utils.h
index 6d06ed7..237647a 100644
--- a/ncdump/utils.h
+++ b/ncdump/utils.h
@@ -5,6 +5,8 @@
  *   Stuff that's common to both ncdump and nccopy
  *
  *********************************************************************/
+#ifndef _UTILS_H
+#define _UTILS_H
 
 #include "config.h"
 
@@ -157,3 +159,6 @@ extern int getrootid(int grpid);
 #ifdef __cplusplus
 }
 #endif
+
+#endif /* _UTILS_H */
+
diff --git a/ncdump/vardata.c b/ncdump/vardata.c
index b31a0ab..9bd2c38 100644
--- a/ncdump/vardata.c
+++ b/ncdump/vardata.c
@@ -533,7 +533,6 @@ vardata(
     int id;
     size_t nels;
     size_t ncols;
-    size_t nrows;
     int vrank = vp->ndims;
 
     int level = 0;
@@ -576,7 +575,6 @@ vardata(
 	if (vrank > 1)
 	  add[vrank-2] = 1;
     }
-    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));
diff --git a/ncdump/vardata.h b/ncdump/vardata.h
index 287bb79..a705207 100644
--- a/ncdump/vardata.h
+++ b/ncdump/vardata.h
@@ -1,8 +1,10 @@
 /*********************************************************************
  *   Copyright 1993, University Corporation for Atmospheric Research
  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
- *   $Header: /upc/share/CVS/netcdf-3/ncdump/vardata.h,v 1.7 2007/10/08 02:47:57 russ Exp $
+ *   Russ Rew
  *********************************************************************/
+#ifndef _VARDATA_H
+#define _VARDATA_H
 
 extern char *progname;		/* for error messages */
 
@@ -43,3 +45,5 @@ extern void pr_any_att_vals( const ncatt_t *attp, const void *vals );
 #ifdef __cplusplus
 }
 #endif
+
+#endif /* _VARDATA_H */
diff --git a/ncgen/Makefile.am b/ncgen/Makefile.am
index ee9ec34..9faf13c 100644
--- a/ncgen/Makefile.am
+++ b/ncgen/Makefile.am
@@ -52,6 +52,8 @@ CLEANFILES = c0.nc c0_64.nc c0_4.nc c0_4c.nc ref_camrun.c \
 # autoconf will forcibly delete files of the name *.tab.*
 # Note also that this should be built under linux or cygwin
 # using bison version 3 or later.
+# Note also that this code is in a shell script if you do
+# not want to other to ./configure.
 
 makeparser::
 	flex -Pncg -8 ncgen.l
diff --git a/ncgen/Makefile.in b/ncgen/Makefile.in
index c7d9a94..c398c97 100644
--- a/ncgen/Makefile.in
+++ b/ncgen/Makefile.in
@@ -101,9 +101,6 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
 bin_PROGRAMS = ncgen$(EXEEXT)
 subdir = ncgen
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -233,11 +230,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -260,12 +256,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -291,6 +289,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -305,6 +304,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -408,7 +408,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 LDADD = ${top_builddir}/liblib/libnetcdf.la
@@ -860,6 +860,8 @@ uninstall-man: uninstall-man1
 # autoconf will forcibly delete files of the name *.tab.*
 # Note also that this should be built under linux or cygwin
 # using bison version 3 or later.
+# Note also that this code is in a shell script if you do
+# not want to other to ./configure.
 
 makeparser::
 	flex -Pncg -8 ncgen.l
diff --git a/ncgen/cvt.c b/ncgen/cvt.c
index 81113e4..3b57cf9 100644
--- a/ncgen/cvt.c
+++ b/ncgen/cvt.c
@@ -509,9 +509,9 @@ case CASE(NC_OPAQUE,NC_CHAR):
     tmp.charv	= *(char*)bytes;
   break;
 case CASE(NC_OPAQUE,NC_BYTE):
-  if(bytes)
-    tmp.uint8v	= *(unsigned char*)bytes;
-    break;
+   if(bytes)
+      tmp.uint8v	= *(unsigned char*)bytes;
+   break;
 case CASE(NC_OPAQUE,NC_UBYTE):
   if(bytes)  
     tmp.uint8v	= *(unsigned char*)bytes;
@@ -642,3 +642,17 @@ convertstringtochars(NCConstant* str)
     }
     return dl;
 }
+
+unsigned int
+convertFilterID(const char* id)
+{
+    unsigned int nid = 0;
+    int ok = 0;
+
+    /* for now, must be an integer */
+    ok = sscanf(id,"%u",&nid);
+    if(ok == 1)
+	return nid;
+    return 0; /* Not a recognizable id */
+}
+
diff --git a/ncgen/genbin.c b/ncgen/genbin.c
index 26a85c0..e107a50 100644
--- a/ncgen/genbin.c
+++ b/ncgen/genbin.c
@@ -241,6 +241,33 @@ genbin_definespecialattributes(Symbol* var)
                                  NULL);
         check_err(stat,__LINE__,__FILE__);
     }
+    if(special->flags & _FILTER_FLAG) {
+	/* Special check for alternate way to specify _Deflate */
+	if(special->_FilterID == ZIP_ID) {
+	    unsigned int level;
+	    if(special->nparams == 0 || special->_FilterParams == NULL)
+		level = 9; /* default */
+	    else
+		level = special->_FilterParams[0];
+	    if(level < 0 || level > 9)
+		derror("Illegal deflate level");		
+	    else {
+	        stat = nc_def_var_deflate(var->container->ncid,
+	                var->ncid,
+	                (special->_Shuffle == 1?1:0),
+	                (level >= 0?1:0),
+			level);
+	    }
+	} else {
+	    stat = nc_def_var_filter(var->container->ncid,
+			var->ncid,
+			special->_FilterID,
+			special->nparams,
+			special->_FilterParams
+			);
+	}
+        check_err(stat,__LINE__,__FILE__);
+    }
 }
 #endif /*USE_NETCDF4*/
 
diff --git a/ncgen/genc.c b/ncgen/genc.c
index f1c0748..58eaf4e 100644
--- a/ncgen/genc.c
+++ b/ncgen/genc.c
@@ -111,6 +111,21 @@ gen_ncc(const char *filename)
                 codedump(tmp);
                 codeline("} ;");
             }
+            if(special->flags & _FILTER_FLAG) {
+                int i;
+                unsigned int* params = special->_FilterParams;
+                if(special->nparams == 0 || params == NULL) continue;
+                bbClear(tmp);
+                for(i=0;i<special->nparams;i++) {
+                    bbprintf(tmp,"%s%luU",
+                            (i == 0?"":", "),params[i]);
+                }
+                bbprintf0(stmt,"static unsigned int %s_filterparams[%d] = {",
+                            cname(var),special->nparams);
+                codedump(stmt);
+                codedump(tmp);
+                codeline("} ;");
+            }
 	    bbFree(tmp);
         }
 	codeline("");
@@ -494,6 +509,47 @@ genc_definespecialattributes(Symbol* vsym)
         codedump(stmt);
         codelined(1,"check_err(stat,__LINE__,__FILE__);");
     }
+    if(special->flags & _FILTER_FLAG) {
+	/* Special check for alternate way to specify _Deflate */
+	if(special->_FilterID == ZIP_ID) {
+	    unsigned int level;
+	    if(special->nparams == 0 || special->_FilterParams == NULL)
+		level = 9; /* default */
+	    else
+		level = special->_FilterParams[0];
+	    if(level < 0 || level > 9)
+		derror("Illegal deflate level");		
+	    else {
+	        bbprintf0(stmt,
+	                "    stat = nc_def_var_deflate(%s, %s, %s, %d, %d);\n",
+	                groupncid(vsym->container),
+	                varncid(vsym),
+	                (special->_Shuffle == 1?"NC_SHUFFLE":"NC_NOSHUFFLE"),
+	                (level >= 0?1:0),
+			level);
+	        codedump(stmt);
+	    }
+	} else {
+	        bbprintf0(stmt,
+	                "    stat = nc_def_var_filter(%s, %s, %u, %lu, ",
+	                groupncid(vsym->container),
+	                varncid(vsym),
+			special->_FilterID,
+			special->nparams
+			);
+	        codedump(stmt);
+	        if(special->nparams == 0 || special->_FilterParams == NULL)
+	            codepartial("NULL");
+        	else {
+	            bbprintf0(stmt,"%s_filterparams",cname(vsym));
+	            codedump(stmt);
+		}
+	        codeline(");");
+	}
+        codelined(1,"check_err(stat,__LINE__,__FILE__);");
+    }
+
+
 }
 #endif /*USE_NETCDF4*/
 
diff --git a/ncgen/genlib.h b/ncgen/genlib.h
index 9450b0d..afa5e27 100644
--- a/ncgen/genlib.h
+++ b/ncgen/genlib.h
@@ -88,7 +88,7 @@ extern Symbol* makearraytype(Symbol*, Dimset*);
 extern void convert1(NCConstant*,NCConstant*); /* Convert an arbitrary value to another */
 extern void setprimlength(NCConstant* prim, unsigned long len);
 extern struct Datalist* convertstringtochars(NCConstant* str);
-
+extern unsigned int convertFilterID(const char* id);
 
 /* from: semantic.c */
 extern  void processsemantics(void);
diff --git a/ncgen/includes.h b/ncgen/includes.h
index 507e9a9..84e617e 100644
--- a/ncgen/includes.h
+++ b/ncgen/includes.h
@@ -48,7 +48,6 @@
 #include "util.h"
 #include "debug.h"
 #include "nc.h"
-
 #ifdef USE_NETCDF4
 #include "nc4internal.h"
 #endif
diff --git a/ncgen/main.c b/ncgen/main.c
index dd6079c..5eb97df 100644
--- a/ncgen/main.c
+++ b/ncgen/main.c
@@ -57,7 +57,7 @@ size_t nciterbuffersize;
 struct Vlendata* vlendata;
 
 char *netcdf_name; /* command line -o file name */
-char *datasetname; /* name from the netcdf <name> {} */
+char *datasetname; /* name from the netcdf <name> {} || from -N */
 
 extern FILE *ncgin;
 
@@ -67,7 +67,7 @@ void usage( void );
 int main( int argc, char** argv );
 
 /* Define tables vs modes for legal -k values*/
-struct Kvalues legalkinds[NKVALUES] = {
+struct Kvalues legalkinds[] = {
     /* NetCDF-3 classic format (32-bit offsets) */
     {"classic", NC_FORMAT_CLASSIC}, /* canonical format name */
     {"nc3", NC_FORMAT_CLASSIC},	    /* short format name */
@@ -200,6 +200,8 @@ usage(void)
 " [-o outfile]"
 " [-P]"
 " [-x]"
+" [-N datasetname]"
+" [-L loglevel]"
 " [file ... ]",
 	   progname);
     derror("netcdf library version %s", nc_inq_libvers());
@@ -250,7 +252,7 @@ main(
     (void) par_io_init(32, 32);
 #endif
 
-    while ((c = getopt(argc, argv, "134567bB:cdD:fhHk:l:M:no:Pv:xL:")) != EOF)
+    while ((c = getopt(argc, argv, "134567bB:cdD:fhHk:l:M:no:Pv:xL:N:")) != EOF)
       switch(c) {
 	case 'd':
 	  debug = 1;
@@ -324,6 +326,9 @@ main(
 	case 'o':		/* to explicitly specify output name */
 	  netcdf_name = nulldup(optarg);
 	  break;
+	case 'N':		/* to explicitly specify dataset name */
+	  datasetname = nulldup(optarg);
+	  break;
 	case 'x': /* set nofill mode to speed up creation of large files */
 	  nofill_flag = 1;
 	  break;
@@ -583,7 +588,6 @@ main(
 
     return 0;
 }
-END_OF_MAIN()
 
 void
 init_netcdf(void) /* initialize global counts, flags */
diff --git a/ncgen/makeparser.sh b/ncgen/makeparser.sh
new file mode 100644
index 0000000..644a8be
--- /dev/null
+++ b/ncgen/makeparser.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+	flex -Pncg -8 ncgen.l
+	rm -f ncgenl.c
+	sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
+	bison -pncg -t -d ncgen.y
+	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/nc_iter.h b/ncgen/nc_iter.h
index 5a2eed4..8c9f70a 100644
--- a/ncgen/nc_iter.h
+++ b/ncgen/nc_iter.h
@@ -4,8 +4,8 @@
  *   "$Id $"
  *********************************************************************/
 
-#ifndef _NCITER_
-#define _NCITER_
+#ifndef _NC_ITER_H
+#define _NC_ITER_H
 
 #include <netcdf.h>
 
@@ -49,4 +49,4 @@ nc_next_iter(nciter_t *iterp, size_t *start, size_t *count);
 }
 #endif
 
-#endif /* _NCITER_ */
+#endif /* _NC_ITER_H */
diff --git a/ncgen/ncgen.h b/ncgen/ncgen.h
index 040b283..685c2e5 100644
--- a/ncgen/ncgen.h
+++ b/ncgen/ncgen.h
@@ -93,7 +93,7 @@ various C global variables
 #define _ISNETCDF4_FLAG     0x200
 #define _SUPERBLOCK_FLAG    0x400
 #define _FORMAT_FLAG        0x800
-
+#define _FILTER_FLAG        0x1000
 
 extern struct Specialtoken {
     char* name;
@@ -115,8 +115,18 @@ char* name;
 int k_flag;
 };
 
-#define NKVALUES 100
-extern struct Kvalues legalkinds[NKVALUES];
+extern struct Kvalues legalkinds[];
+
+struct FilterID {
+char* name;
+unsigned int id;
+};
+
+#define ZIP_ID  0xFFFFFFFF
+#define SZIP_ID  0xFFFFFFFE
+#define BZIP2_ID 307U
+#define ZFP_ID 32013U
+#define FPZIP_ID 32014U
 
 /* Note: some non-var specials (i.e. _Format) are not included in this struct*/
 typedef struct Specialdata {
@@ -130,6 +140,9 @@ typedef struct Specialdata {
     int           _Shuffle;      /* 0 => false, 1 => true*/
     int           _Endianness;   /* 1 =>little, 2 => big*/
     int           _Fill ;        /* 0 => false, 1 => true WATCHOUT: this is inverse of NOFILL*/
+    unsigned int  _FilterID;
+    size_t nparams;          /*  |_FilterParms| ; 0 => not specified*/
+        unsigned int* _FilterParams; /* NULL => defaults*/
 } Specialdata;
 
 typedef struct GlobalSpecialdata {
diff --git a/ncgen/ncgen.l b/ncgen/ncgen.l
index 42ff6dc..76672a1 100644
--- a/ncgen/ncgen.l
+++ b/ncgen/ncgen.l
@@ -132,6 +132,7 @@ struct Specialtoken specials[] = {
 {"_NCProperties",_NCPROPS,_NCPROPS_FLAG},
 {"_IsNetcdf4",_ISNETCDF4,_ISNETCDF4_FLAG},
 {"_SuperblockVersion",_SUPERBLOCK,_SUPERBLOCK_FLAG},
+{"_Filter",_FILTER,_FILTER_FLAG},
 {NULL,0} /* null terminate */
 };
 
@@ -210,7 +211,7 @@ NUMBER       [+-]?[0-9][0-9]*[Uu]?([BbSs]|[Ll]|[Ll][Ll])?
 DBLNUMBER    [+-]?[0-9]*\.[0-9]*{exp}?[LlDd]?|[+-]?[0-9]*{exp}[LlDd]?
 FLTNUMBER    [+-]?[0-9]*\.[0-9]*{exp}?[Ff]|[+-]?[0-9]*{exp}[Ff]
 
-SPECIAL "_FillValue"|"_Format"|"_Storage"|"_ChunkSizes"|"_Fletcher32"|"_DeflateLevel"|"_Shuffle"|"_Endianness"|"_NoFill"|"_NCProperties"|"_IsNetcdf4"|"_SuperblockVersion"
+SPECIAL "_FillValue"|"_Format"|"_Storage"|"_ChunkSizes"|"_Fletcher32"|"_DeflateLevel"|"_Shuffle"|"_Endianness"|"_NoFill"|"_NCProperties"|"_IsNetcdf4"|"_SuperblockVersion"|"_Filter"
 
 USASCII   [\x01-\x7F]
 
@@ -274,6 +275,8 @@ ulong|uint|uinteger	{return lexdebug(UINT_K);}
 int64			{return lexdebug(INT64_K);}
 uint64			{return lexdebug(UINT64_K);}
 double			{return lexdebug(DOUBLE_K);}
+string                  {return lexdebug(STRING_K);}
+
 unlimited|UNLIMITED	{int32_val = -1;
 			 return lexdebug(NC_UNLIMITED_K);}
 
@@ -355,7 +358,8 @@ NIL|nil|Nil {
 		    q = p;
 		    while((c=*p++)) {if(c > ' ') *q++ = c;}
 		    *q = '\0';
-		    datasetname = bbDup(lextext);
+		    if(datasetname == NULL)
+		        datasetname = bbDup(lextext);
 		    BEGIN(INITIAL);
 		    return lexdebug(DATASETID);
 		}
@@ -381,7 +385,6 @@ NIL|nil|Nil {
 		    int slen = strlen(ncgtext);
 		    char* stag = NULL;
 		    int tag = NC_NAT;
-		    int signchar = 0;
 		    int isneg = 0;
 		    int c = ncgtext[0];
 		    int fail = 0;
@@ -655,7 +658,6 @@ Return the value.
 static unsigned long long
 parseULL(char* text, int* failp)
 {
-    int result = 0;
     extern int errno;
     char* endptr;
     unsigned long long uint64 = 0;
diff --git a/ncgen/ncgen.y b/ncgen/ncgen.y
index 48bacb0..0cfa03b 100644
--- a/ncgen/ncgen.y
+++ b/ncgen/ncgen.y
@@ -73,7 +73,10 @@ char* primtypenames[PRIMNO] = {
 "string"
 };
 
-static int GLOBAL_SPECIAL = _NCPROPS_FLAG | _ISNETCDF4_FLAG | _SUPERBLOCK_FLAG | _FORMAT_FLAG ;
+static int GLOBAL_SPECIAL = _NCPROPS_FLAG
+                            | _ISNETCDF4_FLAG
+                            | _SUPERBLOCK_FLAG
+                            | _FORMAT_FLAG ;
 
 /*Defined in ncgen.l*/
 extern int lineno;              /* line number for error messages */
@@ -119,6 +122,7 @@ static int containsfills(Datalist* list);
 static void datalistextend(Datalist* dl, NCConstant* con);
 static void vercheck(int ncid);
 static long long extractint(NCConstant con);
+static int parsefilterflag(const char* sdata0, Specialdata* special);
 
 int yylex(void);
 
@@ -141,7 +145,7 @@ 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;
+NCConstant     constant;
 }
 
 %token <sym>
@@ -152,11 +156,12 @@ NCConstant       constant;
         INT_K       /* keyword for int datatype */
         FLOAT_K     /* keyword for float datatype */
         DOUBLE_K    /* keyword for double datatype */
-        UBYTE_K      /* keyword for unsigned byte datatype */
-        USHORT_K     /* keyword for unsigned short datatype */
-        UINT_K       /* keyword for unsigned int datatype */
-        INT64_K       /* keyword for long long datatype */
-        UINT64_K       /* keyword for unsigned long long datatype */
+        UBYTE_K     /* keyword for unsigned byte datatype */
+        USHORT_K    /* keyword for unsigned short datatype */
+        UINT_K      /* keyword for unsigned int datatype */
+        INT64_K     /* keyword for long long datatype */
+        UINT64_K    /* keyword for unsigned long long datatype */
+        STRING_K    /* keyword for string datatype */
         IDENT       /* name for a dimension, variable, or attribute */
         TERMSTRING  /* terminal string */
         CHAR_CONST  /* char constant (not ever generated by ncgen.l) */
@@ -195,6 +200,7 @@ NCConstant       constant;
 	_NCPROPS
 	_ISNETCDF4
 	_SUPERBLOCK
+	_FILTER
 	DATASETID
 
 %type <sym> ident typename primtype dimd varspec
@@ -430,6 +436,7 @@ primtype:         CHAR_K  { $$ = primsymbols[NC_CHAR]; }
                 | UINT_K   { vercheck(NC_UINT); $$ = primsymbols[NC_UINT]; }
                 | INT64_K   { vercheck(NC_INT64); $$ = primsymbols[NC_INT64]; }
                 | UINT64_K   { vercheck(NC_UINT64); $$ = primsymbols[NC_UINT64]; }
+                | STRING_K   { vercheck(NC_STRING); $$ = primsymbols[NC_STRING]; }
                 ;
 
 dimsection:     /* empty */
@@ -742,6 +749,8 @@ attrdecl:
 	    {$$ = makespecial(_SHUFFLE_FLAG,$1,NULL,(void*)&$5,1);}
 	| type_var_ref ':' _ENDIANNESS '=' conststring
 	    {$$ = makespecial(_ENDIAN_FLAG,$1,NULL,(void*)&$5,1);}
+	| type_var_ref ':' _FILTER '=' conststring
+	    {$$ = makespecial(_FILTER_FLAG,$1,NULL,(void*)&$5,1);}
 	| type_var_ref ':' _NOFILL '=' constbool
 	    {$$ = makespecial(_NOFILL_FLAG,$1,NULL,(void*)&$5,1);}
 	| ':' _FORMAT '=' conststring
@@ -1189,6 +1198,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
     case _STORAGE_FLAG:
     case _NCPROPS_FLAG:
     case _ENDIAN_FLAG:
+    case _FILTER_FLAG:
 	iconst.nctype = NC_STRING;
 	convert1(con,&iconst);
 	if(iconst.nctype == NC_STRING)
@@ -1318,6 +1328,15 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
                 special->flags |= _STORAGE_FLAG;
                 special->_Storage = NC_CHUNKED;
                 } break;
+          case _FILTER_FLAG:
+		/* Parse the filter spec */
+		if(parsefilterflag(sdata,special) == NC_NOERR)
+                    special->flags |= _FILTER_FLAG;
+		else {
+		    efree(special->_FilterParams);
+		    derror("_Filter: unparseable filter spec: %s",sdata);
+		}
+                break;
             default: PANIC1("makespecial: illegal token: %d",tag);
          }
     }
@@ -1428,6 +1447,23 @@ specialname(int tag)
 }
 
 /*
+Parse a filter spec string and store it in special
+*/
+static int
+parsefilterflag(const char* sdata0, Specialdata* special)
+{
+    int stat = NC_NOERR;
+
+    if(sdata0 == NULL || strlen(sdata0) == 0) goto fail;
+    sdata = strdup(sdata0);
+
+    stat = NC_parsefilterspec(sdata0, &special->_FilterID, &special->nparams, &special->_FilterParams);
+    if(stat)
+        derror("Malformed filter spec: %s",sdata);
+    return stat;
+}
+
+/*
 Since the arguments are all simple constants,
 we can evaluate the function immediately
 and return its value.
diff --git a/ncgen/ncgenl.c b/ncgen/ncgenl.c
index 0680ecc..a6facb6 100644
--- a/ncgen/ncgenl.c
+++ b/ncgen/ncgenl.c
@@ -1,5 +1,5 @@
 
-#line 3 "lex.ncg.c"
+#line 2 "ncgenl.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -7,11 +7,17 @@
 
 #define yy_create_buffer ncg_create_buffer
 #define yy_delete_buffer ncg_delete_buffer
-#define yy_flex_debug ncg_flex_debug
+#define yy_scan_buffer ncg_scan_buffer
+#define yy_scan_string ncg_scan_string
+#define yy_scan_bytes ncg_scan_bytes
 #define yy_init_buffer ncg_init_buffer
 #define yy_flush_buffer ncg_flush_buffer
 #define yy_load_buffer_state ncg_load_buffer_state
 #define yy_switch_to_buffer ncg_switch_to_buffer
+#define yypush_buffer_state ncgpush_buffer_state
+#define yypop_buffer_state ncgpop_buffer_state
+#define yyensure_buffer_stack ncgensure_buffer_stack
+#define yy_flex_debug ncg_flex_debug
 #define yyin ncgin
 #define yyleng ncgleng
 #define yylex ncglex
@@ -27,11 +33,245 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 0
+#define YY_FLEX_SUBMINOR_VERSION 4
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
+#ifdef yy_create_buffer
+#define ncg_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer ncg_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define ncg_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer ncg_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define ncg_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer ncg_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define ncg_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string ncg_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define ncg_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes ncg_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define ncg_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer ncg_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define ncg_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer ncg_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define ncg_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state ncg_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define ncg_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer ncg_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define ncgpush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state ncgpush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define ncgpop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state ncgpop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define ncgensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack ncgensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define ncglex_ALREADY_DEFINED
+#else
+#define yylex ncglex
+#endif
+
+#ifdef yyrestart
+#define ncgrestart_ALREADY_DEFINED
+#else
+#define yyrestart ncgrestart
+#endif
+
+#ifdef yylex_init
+#define ncglex_init_ALREADY_DEFINED
+#else
+#define yylex_init ncglex_init
+#endif
+
+#ifdef yylex_init_extra
+#define ncglex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra ncglex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define ncglex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy ncglex_destroy
+#endif
+
+#ifdef yyget_debug
+#define ncgget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug ncgget_debug
+#endif
+
+#ifdef yyset_debug
+#define ncgset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug ncgset_debug
+#endif
+
+#ifdef yyget_extra
+#define ncgget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra ncgget_extra
+#endif
+
+#ifdef yyset_extra
+#define ncgset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra ncgset_extra
+#endif
+
+#ifdef yyget_in
+#define ncgget_in_ALREADY_DEFINED
+#else
+#define yyget_in ncgget_in
+#endif
+
+#ifdef yyset_in
+#define ncgset_in_ALREADY_DEFINED
+#else
+#define yyset_in ncgset_in
+#endif
+
+#ifdef yyget_out
+#define ncgget_out_ALREADY_DEFINED
+#else
+#define yyget_out ncgget_out
+#endif
+
+#ifdef yyset_out
+#define ncgset_out_ALREADY_DEFINED
+#else
+#define yyset_out ncgset_out
+#endif
+
+#ifdef yyget_leng
+#define ncgget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng ncgget_leng
+#endif
+
+#ifdef yyget_text
+#define ncgget_text_ALREADY_DEFINED
+#else
+#define yyget_text ncgget_text
+#endif
+
+#ifdef yyget_lineno
+#define ncgget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno ncgget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define ncgset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno ncgset_lineno
+#endif
+
+#ifdef yywrap
+#define ncgwrap_ALREADY_DEFINED
+#else
+#define yywrap ncgwrap
+#endif
+
+#ifdef yyalloc
+#define ncgalloc_ALREADY_DEFINED
+#else
+#define yyalloc ncgalloc
+#endif
+
+#ifdef yyrealloc
+#define ncgrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc ncgrealloc
+#endif
+
+#ifdef yyfree
+#define ncgfree_ALREADY_DEFINED
+#else
+#define yyfree ncgfree
+#endif
+
+#ifdef yytext
+#define ncgtext_ALREADY_DEFINED
+#else
+#define yytext ncgtext
+#endif
+
+#ifdef yyleng
+#define ncgleng_ALREADY_DEFINED
+#else
+#define yyleng ncgleng
+#endif
+
+#ifdef yyin
+#define ncgin_ALREADY_DEFINED
+#else
+#define yyin ncgin
+#endif
+
+#ifdef yyout
+#define ncgout_ALREADY_DEFINED
+#else
+#define yyout ncgout
+#endif
+
+#ifdef yy_flex_debug
+#define ncg_flex_debug_ALREADY_DEFINED
+#else
+#define yy_flex_debug ncg_flex_debug
+#endif
+
+#ifdef yylineno
+#define ncglineno_ALREADY_DEFINED
+#else
+#define yylineno ncglineno
+#endif
+
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
 /* begin standard C headers. */
@@ -102,60 +342,48 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#ifndef SIZE_MAX
+#define SIZE_MAX               (~(size_t)0)
+#endif
+
 #endif /* ! C99 */
 
 #endif /* ! FLEXINT_H */
 
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
+/* begin standard C++ headers. */
 
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
 #define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
 #else
-#define yyconst
+#define yynoreturn
 #endif
 
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ *   integer in range [0..255] for use as an array index.
  */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
 
 /* Enter a start condition.  This macro really ought to take a parameter,
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
 #define BEGIN (yy_start) = 1 + 2 *
-
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
 #define YY_START (((yy_start) - 1) / 2)
 #define YYSTATE YY_START
-
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE ncgrestart(ncgin  )
-
+#define YY_NEW_FILE yyrestart( yyin  )
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
@@ -185,14 +413,14 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
 typedef size_t yy_size_t;
 #endif
 
-extern yy_size_t ncgleng;
+extern int yyleng;
 
-extern FILE *ncgin, *ncgout;
+extern FILE *yyin, *yyout;
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
-
+    
     #define YY_LESS_LINENO(n)
     #define YY_LINENO_REWIND_TO(ptr)
     
@@ -200,16 +428,15 @@ extern FILE *ncgin, *ncgout;
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ncgtext. */ \
+		/* Undo effects of setting up yytext. */ \
         int yyless_macro_arg = (n); \
         YY_LESS_LINENO(yyless_macro_arg);\
 		*yy_cp = (yy_hold_char); \
 		YY_RESTORE_YY_MORE_OFFSET \
 		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-		YY_DO_BEFORE_ACTION; /* set up ncgtext again */ \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
-
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -224,7 +451,7 @@ struct yy_buffer_state
 	/* Size of input buffer in bytes, not including room for EOB
 	 * characters.
 	 */
-	yy_size_t yy_buf_size;
+	int yy_buf_size;
 
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
@@ -252,7 +479,7 @@ struct yy_buffer_state
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
-    
+
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 */
@@ -269,8 +496,8 @@ struct yy_buffer_state
 	 * possible backing-up.
 	 *
 	 * When we actually see the EOF, we change the status to "new"
-	 * (via ncgrestart()), so that the user can continue scanning by
-	 * just pointing ncgin at a new input file.
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
 	 */
 #define YY_BUFFER_EOF_PENDING 2
 
@@ -280,7 +507,7 @@ struct yy_buffer_state
 /* Stack of input buffers. */
 static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
 static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
@@ -291,111 +518,100 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
                           ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
                           : NULL)
-
 /* Same as previous macro, but useful when we know that the buffer stack is not
  * NULL or when we need an lvalue. For internal use only.
  */
 #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
 
-/* yy_hold_char holds the character lost when ncgtext is formed. */
+/* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
 static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-yy_size_t ncgleng;
+int yyleng;
 
 /* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
+static char *yy_c_buf_p = NULL;
 static int yy_init = 0;		/* whether we need to initialize */
 static int yy_start = 0;	/* start state number */
 
-/* Flag which is used to allow ncgwrap()'s to do buffer switches
- * instead of setting up a fresh ncgin.  A bit of a hack ...
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
  */
 static int yy_did_buffer_switch_on_eof;
 
-void ncgrestart (FILE *input_file  );
-void ncg_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE ncg_create_buffer (FILE *file,int size  );
-void ncg_delete_buffer (YY_BUFFER_STATE b  );
-void ncg_flush_buffer (YY_BUFFER_STATE b  );
-void ncgpush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void ncgpop_buffer_state (void );
-
-static void ncgensure_buffer_stack (void );
-static void ncg_load_buffer_state (void );
-static void ncg_init_buffer (YY_BUFFER_STATE b,FILE *file  );
-
-#define YY_FLUSH_BUFFER ncg_flush_buffer(YY_CURRENT_BUFFER )
+void yyrestart ( FILE *input_file  );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size  );
+void yy_delete_buffer ( YY_BUFFER_STATE b  );
+void yy_flush_buffer ( YY_BUFFER_STATE b  );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state ( void );
 
-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,yy_size_t len  );
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file  );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
 
-void *ncgalloc (yy_size_t  );
-void *ncgrealloc (void *,yy_size_t  );
-void ncgfree (void *  );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len  );
 
-#define yy_new_buffer ncg_create_buffer
+void *yyalloc ( yy_size_t  );
+void *yyrealloc ( void *, yy_size_t  );
+void yyfree ( void *  );
 
+#define yy_new_buffer yy_create_buffer
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
-        ncgensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ncg_create_buffer(ncgin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
-
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
-        ncgensure_buffer_stack (); \
+        yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            ncg_create_buffer(ncgin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
-
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
 /* Begin user sect3 */
+typedef flex_uint8_t YY_CHAR;
 
-typedef unsigned char YY_CHAR;
-
-FILE *ncgin = (FILE *) 0, *ncgout = (FILE *) 0;
+FILE *yyin = NULL, *yyout = NULL;
 
 typedef int yy_state_type;
 
-extern int ncglineno;
+extern int yylineno;
+int yylineno = 1;
 
-int ncglineno = 1;
-
-extern char *ncgtext;
+extern char *yytext;
 #ifdef yytext_ptr
 #undef yytext_ptr
 #endif
-#define yytext_ptr ncgtext
+#define yytext_ptr yytext
 
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-#if defined(__GNUC__) && __GNUC__ >= 3
-__attribute__((__noreturn__))
-#endif
-static void yy_fatal_error (yyconst char msg[]  );
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg  );
 
 /* Done after the current pattern has been matched and before the
- * corresponding action - sets up ncgtext.
+ * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
-	ncgleng = (size_t) (yy_cp - yy_bp); \
+	yyleng = (int) (yy_cp - yy_bp); \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 48
-#define YY_END_OF_BUFFER 49
+#define YY_NUM_RULES 49
+#define YY_END_OF_BUFFER 50
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -403,57 +619,58 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[417] =
+static const flex_int16_t yy_accept[422] =
     {   0,
-        0,    0,   45,   45,    0,    0,   49,   47,    1,   43,
-       47,   47,   47,   47,   37,   31,   35,   35,   34,   34,
-       34,   34,   34,   34,   34,   47,   34,   34,   34,   34,
-       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
-       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,   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,   34,   34,    0,    0,   45,    0,   46,   33,   39,
-        0,    0,    0,    0,   37,    0,    0,   37,    2,   31,
+        0,    0,   46,   46,    0,    0,   50,   48,    1,   44,
+       48,   48,   48,   48,   38,   32,   36,   36,   35,   35,
+       35,   35,   35,   35,   35,   48,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   48,   48,   48,   46,   49,   34,   49,    1,
+        0,    3,    0,    0,    0,   38,   36,    0,    0,   38,
+       38,    0,   39,   45,    2,   32,    0,    0,    0,    0,
+       36,   36,   36,   36,    0,   35,    0,    0,    0,    0,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,    0,    0,   46,    0,   47,   34,   40,
+        0,    0,    0,    0,   38,    0,    0,   38,    2,   32,
         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,   34,   34,   34,
-       14,   34,   27,   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,   36,    0,   34,   34,   28,   34,   34,   29,   34,
-       34,   34,   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,   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,   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,   34,   34,   34,    0,   34,   26,   34,   34,
-       34,   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,   34,   34,   34,
-
-       34,   34,   22,   34,   34,   34,   21,   34,   34,   34,
-       34,   34,   34,   34,   34,    0
+       35,   35,   35,   35,   35,   35,   31,   28,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       14,   35,   28,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,    0,   43,    0,    0,   38,
+
+        0,   32,    0,    0,    0,    0,    0,    0,    0,    4,
+       37,   37,    0,   35,   35,   29,   35,   35,   30,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   10,    9,   35,   35,   35,   35,    6,   35,
+       35,   35,   35,   14,   35,   35,   35,    8,   35,   35,
+       35,   35,   35,   15,   35,   35,   35,   35,    0,    0,
+       29,    0,   32,    0,    0,    0,    0,    0,    0,    0,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   24,
+       35,   35,   35,   16,   35,   35,   35,   35,   12,   35,
+
+       35,   35,   11,   35,   35,   15,   35,   35,   35,   41,
+       42,    0,    0,    0,    0,   35,   35,   35,   26,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   18,   25,   35,    7,   19,
+        5,   21,   17,   35,   35,   13,   35,    0,    0,   35,
+       35,   35,   35,   35,   35,   35,   35,   33,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+        0,   35,   27,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,    5,   35,   35,   35,   35,   27,   27,   20,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+
+       35,   35,   35,   35,   35,   35,   35,   23,   35,   35,
+       35,   22,   35,   35,   35,   35,   35,   35,   35,   35,
+        0
     } ;
 
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    2,    2,    1,    1,    1,    1,    1,    1,    1,
@@ -485,7 +702,7 @@ static yyconst YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst YY_CHAR yy_meta[69] =
+static const YY_CHAR yy_meta[69] =
     {   0,
         1,    1,    2,    1,    1,    1,    3,    4,    5,    5,
         6,    7,    8,    8,    8,    8,    8,    8,    8,    1,
@@ -496,111 +713,111 @@ static yyconst YY_CHAR yy_meta[69] =
        11,   11,   11,   14,    1,   11,   11,   11
     } ;
 
-static yyconst flex_uint16_t yy_base[435] =
+static const flex_int16_t yy_base[440] =
     {   0,
-        0,    0,  325,  321,  264,  255,  318, 2347,   67, 2347,
+        0,    0,  325,  321,  264,  255,  318, 2387,   67, 2387,
        64,  269,   61,   62,   95,   77,  136,  259,   51,   61,
       188,   97,  118,  150,   65,  195,  233,  153,  183,  222,
       241,  202,  207,  213,  238,  246,  243,  257,  268,  264,
-      298,  276,  221,  219,  218,  270,  236,    0, 2347,   79,
-       87, 2347,  244,  238,  344,    0,  206,  358,  190,    0,
-     2347,  370, 2347, 2347,    0,  342,  377,  177,  175,  174,
-      200, 2347,   54,  377,    0,  254,  397,  171,  170,  169,
+      298,  276,  221,  219,  218,  270,  236,    0, 2387,   79,
+       87, 2387,  244,  238,  344,    0,  206,  358,  190,    0,
+     2387,  370, 2387, 2387,    0,  342,  377,  177,  175,  174,
+      200, 2387,   54,  377,    0,  254,  397,  171,  170,  169,
       358,   85,  404,  373,  376,  398,  391,  406,  412,  417,
       421,  428,  432,  451,  454,  443,  473,  476,  486,  489,
 
       494,  499,  511,  508,  520,  530,  546,  542,  550,  553,
       556,  560,  563,  566,  586,  598,  602,  605,  608,  623,
-      612,  644,  647,  168,  167,  222,  217, 2347,    0, 2347,
+      612,  644,  647,  168,  167,  222,  217, 2387,    0, 2387,
       221,  680,  219,  703,  710,  179,  728,  749,    0,  691,
       666,  765,  159,  158,  135,  130,  128,  651,  125,  123,
       739,  716,  721,  751,  764,  770,  757,  775,  783,  760,
       794,  800,  806,  809,  813,  824,  820,  844,  839,  830,
       854,  850,  862,  869,  874,  886,  904,  893,  908,  917,
-      947,  934,  912,  964,  943,  954,  900,  930,  950,  967,
-      980,  984,  989, 1004, 1010,  118, 2347,  735,    0, 2347,
-
-       50, 1015, 1047,  117,  115,  112,  110,  108,  104,  904,
-       72, 2347,  103, 1028, 1034, 1041, 1045, 1049, 1052, 1058,
-     1075, 1071, 1082, 1093, 1088, 1101, 1106, 1113, 1097, 1132,
-     1118, 1137, 1067, 1123, 1148, 1157, 1144, 1162, 1127, 1167,
-     1153, 1192, 1197, 1179, 1202, 1209, 1183, 1213, 1223, 1218,
-     1234, 1227, 1260, 1249, 1267, 1264, 1270,  160,  154, 2347,
-      107, 1275, 1340,   93,   91,   77,   73,   72,   70, 1284,
-     1310, 1314, 1327, 1330, 1317, 1323, 1333, 1349, 1363, 1366,
-     1353, 1369, 1374, 1399, 1383, 1387, 1404, 2347, 1417, 1413,
-     1437, 1420, 1423, 1434, 1453, 1467, 1430, 1456, 1443, 1474,
-
-     1477, 1489, 1486, 1498, 1492, 1507, 2347, 2347,   85,   65,
-       59,   36, 1532, 1523, 1511, 1528, 1545, 1548, 1542, 1553,
-     1563, 1578, 1566, 1584, 1598, 1589, 1603, 1620, 1633, 1610,
-     1640, 1629, 2347, 1645, 1651, 1654, 2347, 1659, 1664, 1676,
-     1671, 1685,   39,   27, 1694, 1702, 1710, 1690, 1715, 1720,
-     1727, 1724, 1734, 1745, 1759, 1765, 1769, 1776, 1779, 1784,
-     1795, 1799, 1802, 1809, 1819,   24, 1814, 1832, 1849, 1840,
-     1853, 1845, 1858, 1865, 1884, 1870, 1875, 1889, 1895, 1900,
-     1905, 1919,   36, 1908, 1914, 1925, 1939, 1930, 1944, 1963,
-     1977, 1956, 1960, 1951, 1981, 1974, 1994, 1998, 2019, 1986,
-
-     2007, 2030, 2347, 2033, 2037, 2040, 2347, 2044, 2051, 2075,
-     2082, 2086, 2089, 2092, 2098, 2347, 2166, 2180, 2194, 2208,
-     2217, 2226, 2235, 2248, 2262, 2275, 2289, 2299, 2305, 2313,
-     2315, 2321, 2327, 2333
+      947,  934,  912,  964,  943,  954,  900,  957,  973,  969,
+      987,  990,  995, 1006,  999,  118, 2387,  735,    0, 2387,
+
+       50, 1030, 1062,  117,  115,  112,  110,  108,  104,  904,
+       72, 2387,  103, 1020, 1025, 1043, 1046, 1064, 1051, 1069,
+     1076, 1055, 1085, 1088, 1099, 1094, 1118, 1102, 1125, 1132,
+     1137, 1142, 1149, 1156, 1167, 1162, 1172, 1175, 1179, 1192,
+     1197, 1210, 1214, 1205, 1223, 1230, 1227, 1217, 1240, 1247,
+     1262, 1253, 1265, 1298, 1278, 1283, 1295, 1301,  160,  154,
+     2387,  107, 1314, 1350,   93,   91,   77,   73,   72,   70,
+     1332, 1344, 1335, 1320, 1356, 1340, 1352, 1374, 1388, 1391,
+     1366, 1396, 1406, 1412, 1409, 1422, 1428, 1442, 1445, 2387,
+     1448, 1452, 1462, 1459, 1478, 1465, 1495, 1498, 1482, 1508,
+
+     1501, 1515, 1485, 1519, 1531, 1534, 1540, 1545, 1549, 2387,
+     2387,   85,   65,   59,   36, 1564, 1556, 1575, 1553, 1590,
+     1571, 1587, 1594, 1609, 1606, 1601, 1612, 1627, 1642, 1645,
+     1648, 1651, 1661, 1667, 1682, 1685, 2387, 1697, 1691, 1700,
+     1716, 2387, 1703, 1733, 1721, 1707, 1740,   39,   27, 1751,
+     1746, 1754, 1770, 1766, 1758, 1788, 1784, 1763, 1800, 1803,
+     1814, 1818, 1833, 1807, 1821, 1825, 1837, 1851, 1857, 1867,
+       24, 1870, 1874, 1882, 1888, 1892, 1900, 1904, 1908, 1923,
+     1938, 1934, 1913, 1943, 1918, 1948, 1954,   36, 1958, 1964,
+     1968, 1978, 1989, 1994, 2002, 2010, 1999, 2020, 2013, 2033,
+
+     2025, 2036, 2050, 2059, 2045, 2056, 2070, 2387, 2075, 2089,
+     2082, 2387, 2093, 2096, 2100, 2108, 2112, 2132, 2119, 2138,
+     2387, 2206, 2220, 2234, 2248, 2257, 2266, 2275, 2288, 2302,
+     2315, 2329, 2339, 2345, 2353, 2355, 2361, 2367, 2373
     } ;
 
-static yyconst flex_int16_t yy_def[435] =
+static const flex_int16_t yy_def[440] =
     {   0,
-      416,    1,  417,  417,  418,  418,  416,  416,  416,  416,
-      419,  420,  416,  421,  416,  422,  416,   17,  423,  423,
-      423,  423,  423,  423,  423,  416,  423,  423,  423,  423,
-       21,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  416,  416,  416,  424,  424,  425,  416,  416,
-      419,  416,  419,  416,  426,   15,   17,  416,  416,   15,
-      416,  416,  416,  416,  427,  428,  416,  416,  416,  416,
-       17,  416,  416,  416,  429,  423,  416,  416,  416,  416,
-      423,   21,   21,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  416,  416,  424,  424,  416,  425,  416,
-      416,  416,  430,  416,  416,  416,  416,  416,  427,  428,
-      431,  416,  416,  416,  416,  416,  416,  432,  416,  416,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  416,  416,  416,  433,  416,
-
-      416,  434,  416,  416,  416,  416,  416,  416,  416,  432,
-      416,  416,  416,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  416,  416,  416,
-      416,  434,  416,  416,  416,  416,  416,  416,  416,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  416,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-
-      423,  423,  423,  423,  423,  423,  416,  416,  416,  416,
-      416,  416,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  416,  423,  423,  423,  416,  423,  423,  423,
-      423,  423,  416,  416,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  416,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  416,  423,  423,  423,  423,  423,  423,  423,
-      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
-
-      423,  423,  416,  423,  423,  423,  416,  423,  423,  423,
-      423,  423,  423,  423,  423,    0,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416
+      421,    1,  422,  422,  423,  423,  421,  421,  421,  421,
+      424,  425,  421,  426,  421,  427,  421,   17,  428,  428,
+      428,  428,  428,  428,  428,  421,  428,  428,  428,  428,
+       21,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  421,  421,  421,  429,  429,  430,  421,  421,
+      424,  421,  424,  421,  431,   15,   17,  421,  421,   15,
+      421,  421,  421,  421,  432,  433,  421,  421,  421,  421,
+       17,  421,  421,  421,  434,  428,  421,  421,  421,  421,
+      428,   21,   21,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  421,  421,  429,  429,  421,  430,  421,
+      421,  421,  435,  421,  421,  421,  421,  421,  432,  433,
+      436,  421,  421,  421,  421,  421,  421,  437,  421,  421,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  421,  421,  421,  438,  421,
+
+      421,  439,  421,  421,  421,  421,  421,  421,  421,  437,
+      421,  421,  421,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  421,  421,
+      421,  421,  439,  421,  421,  421,  421,  421,  421,  421,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  421,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  421,
+      421,  421,  421,  421,  421,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  421,  428,  428,  428,
+      428,  421,  428,  428,  428,  428,  428,  421,  421,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      421,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  421,  428,  428,
+      428,  428,  428,  428,  428,  428,  428,  428,  428,  428,
+
+      428,  428,  428,  428,  428,  428,  428,  421,  428,  428,
+      428,  421,  428,  428,  428,  428,  428,  428,  428,  428,
+        0,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421
     } ;
 
-static yyconst flex_uint16_t yy_nxt[2416] =
+static const flex_int16_t yy_nxt[2456] =
     {   0,
         8,    9,   10,    9,    8,   11,   12,    8,   13,   14,
        15,   16,   17,   18,   18,   18,   18,   18,   18,    8,
@@ -610,267 +827,271 @@ static yyconst flex_uint16_t yy_nxt[2416] =
        35,   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,  260,   50,   72,   64,  383,   58,   58,   65,   77,
-       59,  262,   52,   76,   76,  260,   90,  366,  261,   77,
+       50,  261,   50,   72,   64,  388,   58,   58,   65,   77,
+       59,  263,   52,   76,   76,  261,   90,  371,  262,   77,
 
       202,  212,   53,   77,   72,   58,   58,   60,   60,   60,
        60,   60,   60,   60,   81,   67,   78,   79,   80,   61,
-       62,   63,  212,  344,   61,   53,   78,   79,   80,  262,
-       78,   79,   80,  343,  140,   77,  312,  202,   61,   62,
-       63,  311,   68,   69,   70,   61,   56,   84,   71,   71,
-       71,   71,   71,   71,   71,  310,   77,  262,   72,  309,
-      308,   58,   78,   79,   80,   73,  307,   76,   66,   72,
-       85,   74,  269,   75,  140,   86,  268,   72,   87,  267,
+       62,   63,  212,  349,   61,   53,   78,   79,   80,  263,
+       78,   79,   80,  348,  140,   77,  315,  202,   61,   62,
+       63,  314,   68,   69,   70,   61,   56,   84,   71,   71,
+       71,   71,   71,   71,   71,  313,   77,  263,   72,  312,
+      311,   58,   78,   79,   80,   73,  310,   76,   66,   72,
+       85,   74,  270,   75,  140,   86,  269,   72,   87,  268,
        58,  202,   91,   78,   79,   80,   73,  213,   77,   76,
        88,   77,  209,   72,   66,   74,   82,   82,   89,  208,
 
        83,   83,   83,   83,   83,   83,   83,   91,   91,   91,
        91,   91,   91,   91,   99,   78,   79,   80,   78,   79,
-       80,   77,  207,  140,  201,  197,   77,  197,  416,  127,
-      100,  196,   91,  150,  149,   76,  101,  416,  147,  146,
-       77,   66,  136,  416,  130,   77,  416,  128,   78,   79,
+       80,   77,  207,  140,  201,  197,   77,  197,  421,  127,
+      100,  196,   91,  150,  149,   76,  101,  421,  147,  146,
+       77,   66,  136,  421,  130,   77,  421,  128,   78,   79,
        80,   77,  106,   78,   79,   80,   92,   93,   94,   95,
        77,   96,  102,  107,   97,  108,   98,   78,   79,   80,
       103,   77,   78,   79,   80,  104,   77,  127,   78,   79,
        80,   77,  125,  124,   77,   91,  110,   78,   79,   80,
-      111,  109,   77,  105,  112,   77,  416,  113,   78,   79,
+      111,  109,   77,  105,  112,   77,  421,  113,   78,   79,
 
        80,  114,   77,   78,   79,   80,   77,   55,   78,   79,
-       80,   78,   79,   80,   77,  115,  123,  416,   49,   78,
+       80,   78,   79,   80,   77,  115,  123,  421,   49,   78,
        79,   80,   78,   79,   80,  117,  116,   49,   47,   78,
-       79,   80,   47,   78,   79,   80,   77,  416,  416,  118,
-      416,   78,   79,   80,  416,  416,  119,  416,  120,  416,
-      121,  416,  416,  141,  416,  122,  132,  132,  132,  132,
-      132,  132,  416,   78,   79,   80,  134,  134,  416,  416,
-      135,  135,  135,  135,  135,  135,  135,  416,  137,  137,
+       79,   80,   47,   78,   79,   80,   77,  421,  421,  118,
+      421,   78,   79,   80,  421,  421,  119,  421,  120,  421,
+      121,  421,  421,  141,  421,  122,  132,  132,  132,  132,
+      132,  132,  421,   78,   79,   80,  134,  134,  421,  421,
+      135,  135,  135,  135,  135,  135,  135,  421,  137,  137,
       142,  133,  138,  138,  138,  138,  138,  138,  138,   66,
-       66,   66,   66,   66,   66,   66,   77,  416,  416,   72,
-
-       76,   76,   76,   76,   76,  416,   73,  143,  144,  145,
-       72,   77,   76,   76,   77,  416,   76,  151,   72,  416,
-      157,  155,  416,   78,   79,   80,  154,   73,  152,   77,
-      153,  416,  156,  152,   72,   76,   77,  158,   78,   79,
-       80,   78,   79,   80,   77,  416,  159,  152,  416,  153,
-       77,  416,  416,  416,  152,   77,   78,   79,   80,   77,
-       76,  416,  157,   78,   79,   80,   77,  416,  416,  416,
-       77,   78,   79,   80,  416,  160,  161,   78,   79,   80,
-      416,   77,   78,   79,   80,  416,   78,   79,   80,   77,
-      416,  416,   77,   78,   79,   80,  167,   78,   79,   80,
-
-      166,  416,  163,  162,  164,  416,  416,  165,   78,   79,
-       80,   77,  416,  416,   77,  416,   78,   79,   80,   78,
-       79,   80,  416,  169,   77,  416,  168,   77,  416,  173,
-      416,  416,   77,  416,  170,  171,  416,   77,   78,   79,
-       80,   78,   79,   80,  172,  174,   77,  416,  416,   77,
-      416,   78,   79,   80,   78,   79,   80,  175,   77,   78,
-       79,   80,  176,  416,   78,   79,   80,  177,   77,  416,
-      416,  416,  416,   78,   79,   80,   78,   79,   80,  178,
-       77,  416,  416,  179,   77,   78,   79,   80,   77,  416,
-      416,   77,  416,  416,   77,   78,   79,   80,   77,  180,
+       66,   66,   66,   66,   66,   66,   77,  421,  421,   72,
+
+       76,   76,   76,   76,   76,  421,   73,  143,  144,  145,
+       72,   77,   76,   76,   77,  421,   76,  151,   72,  421,
+      157,  155,  421,   78,   79,   80,  154,   73,  152,   77,
+      153,  421,  156,  152,   72,   76,   77,  158,   78,   79,
+       80,   78,   79,   80,   77,  421,  159,  152,  421,  153,
+       77,  421,  421,  421,  152,   77,   78,   79,   80,   77,
+       76,  421,  157,   78,   79,   80,   77,  421,  421,  421,
+       77,   78,   79,   80,  421,  160,  161,   78,   79,   80,
+      421,   77,   78,   79,   80,  421,   78,   79,   80,   77,
+      421,  421,   77,   78,   79,   80,  167,   78,   79,   80,
+
+      166,  421,  163,  162,  164,  421,  421,  165,   78,   79,
+       80,   77,  421,  421,   77,  421,   78,   79,   80,   78,
+       79,   80,  421,  169,   77,  421,  168,   77,  421,  173,
+      421,  421,   77,  421,  170,  171,  421,   77,   78,   79,
+       80,   78,   79,   80,  172,  174,   77,  421,  421,   77,
+      421,   78,   79,   80,   78,   79,   80,  175,   77,   78,
+       79,   80,  176,  421,   78,   79,   80,  177,   77,  421,
+      421,  421,  421,   78,   79,   80,   78,   79,   80,  178,
+       77,  421,  421,  179,   77,   78,   79,   80,   77,  421,
+      421,   77,  421,  421,   77,   78,   79,   80,   77,  180,
 
       181,   77,  182,  185,   77,  183,  186,   78,   79,   80,
       157,   78,   79,   80,  184,   78,   79,   80,   78,   79,
        80,   78,   79,   80,   77,   78,   79,   80,   78,   79,
-       80,   78,   79,   80,  416,  416,   77,  416,  416,  187,
-       77,  416,  416,   77,  416,  416,   77,  416,  416,  416,
-       77,   78,   79,   80,  188,  416,  189,  416,  416,  416,
+       80,   78,   79,   80,  421,  421,   77,  421,  421,  187,
+       77,  421,  421,   77,  421,  421,   77,  421,  421,  421,
+       77,   78,   79,   80,  188,  421,  189,  421,  421,  421,
       191,   77,  193,   78,   79,   80,  190,   78,   79,   80,
        78,   79,   80,   78,   79,   80,  192,   78,   79,   80,
-      211,  416,   77,  416,  212,   77,  197,  416,   78,   79,
-       80,  194,  198,  198,  198,  198,  198,  198,  416,  416,
+      211,  421,   77,  421,  212,   77,  197,  421,   78,   79,
+       80,  194,  198,  198,  198,  198,  198,  198,  421,  421,
 
-      416,  211,  141,  195,  203,  416,  416,  416,  212,   78,
+      421,  211,  141,  195,  203,  421,  421,  421,  212,   78,
        79,   80,   78,   79,   80,  135,  135,  135,  135,  135,
       135,  135,  135,  135,  135,  135,  135,  135,  135,  142,
-      416,  204,  205,  206,  200,  416,   63,  416,  416,  200,
-      138,  138,  138,  138,  138,  138,  138,  258,  258,  258,
-      258,  258,  258,  200,   77,   63,  143,  144,  145,   77,
+      421,  204,  205,  206,  200,  421,   63,  421,  421,  200,
+      138,  138,  138,  138,  138,  138,  138,  259,  259,  259,
+      259,  259,  259,  200,   77,   63,  143,  144,  145,   77,
       200,  138,  138,  138,  138,  138,  138,  138,  140,  140,
-      140,  140,  140,   61,  416,   63,  416,   77,   61,  416,
-      214,   78,   79,   80,  140,  416,   78,   79,   80,   77,
-      416,  215,   61,  218,   63,   77,  416,  416,   77,   61,
+      140,  140,  140,   61,  421,   63,  421,   77,   61,  421,
+      214,   78,   79,   80,  140,  421,   78,   79,   80,   77,
+      421,  215,   61,  218,   63,   77,  421,  421,   77,   61,
 
-      416,  416,   77,  140,   78,   79,   80,  416,   77,  216,
-      416,  220,  217,   77,  416,  416,   78,   79,   80,  221,
+      421,  421,   77,  140,   78,   79,   80,  421,   77,  216,
+      421,  220,  217,   77,  421,  421,   78,   79,   80,  221,
       219,   77,   78,   79,   80,   78,   79,   80,  140,   78,
-       79,   80,   77,  416,  416,   78,   79,   80,   77,  222,
-       78,   79,   80,  223,   77,  416,  416,   77,   78,   79,
-       80,   77,  228,  225,  416,  227,  224,  416,   77,   78,
-       79,   80,   77,  416,  416,   78,   79,   80,   77,  226,
+       79,   80,   77,  421,  421,   78,   79,   80,   77,  222,
+       78,   79,   80,  223,   77,  421,  421,   77,   78,   79,
+       80,   77,  228,  225,  421,  227,  224,  421,   77,   78,
+       79,   80,   77,  421,  421,   78,   79,   80,   77,  226,
       229,   78,   79,   80,   78,   79,   80,   77,   78,   79,
-       80,  416,   77,  231,  416,   78,   79,   80,   77,   78,
-       79,   80,   77,  416,  233,   78,   79,   80,  230,  416,
-
-       77,  416,  416,  416,   78,   79,   80,   77,  232,   78,
-       79,   80,   77,  416,  236,   78,   79,   80,  234,   78,
-       79,   80,  416,  235,   77,  416,  416,   78,   79,   80,
-      237,   77,  416,  211,   78,   79,   80,  212,   77,   78,
-       79,   80,   77,  416,  239,  238,   77,  416,  240,  416,
+       80,  421,   77,  231,  421,   78,   79,   80,   77,   78,
+       79,   80,   77,  421,  233,   78,   79,   80,  230,  421,
+
+       77,  421,  421,  421,   78,   79,   80,   77,  232,   78,
+       79,   80,   77,  421,  236,   78,   79,   80,  234,   78,
+       79,   80,  421,  235,   77,  421,  421,   78,   79,   80,
+      237,   77,  421,  211,   78,   79,   80,  212,   77,   78,
+       79,   80,   77,  421,  239,  238,   77,  421,  240,  421,
        77,   78,   79,   80,  211,   77,  249,  219,   78,   79,
-       80,  212,  416,  416,  242,   78,   79,   80,   77,   78,
+       80,  212,  421,  421,  242,   78,   79,   80,  421,   78,
        79,   80,   77,   78,   79,   80,  241,   78,   79,   80,
-      244,   77,   78,   79,   80,   77,  416,  245,   77,  250,
-      416,  243,   77,  416,  251,   78,   79,   80,  247,   78,
-
-       79,   80,   77,  416,  248,   77,  246,  416,   78,   79,
-       80,  416,   78,   79,   80,   78,   79,   80,   77,   78,
-       79,   80,   77,  416,  416,  252,  141,   77,  416,   78,
-       79,   80,   78,   79,   80,  416,  254,  255,  253,  416,
-      416,  416,   77,  416,  416,   78,   79,   80,   77,   78,
-       79,   80,  416,  263,   78,   79,   80,  256,  257,  202,
-      202,  202,  202,  202,  202,  202,   77,  416,  416,   78,
-       79,   80,   77,  273,  416,   78,   79,   80,  270,   77,
-      264,  265,  266,   77,  416,  416,  416,   77,  274,  416,
-       77,  416,  271,   78,   79,   80,   77,  272,  416,   78,
-
-       79,   80,  416,  416,  416,   77,   78,   79,   80,   77,
-       78,   79,   80,   77,   78,   79,   80,   78,   79,   80,
-       77,  276,  416,   78,   79,   80,   77,  275,  416,  416,
-      277,   77,   78,   79,   80,   77,   78,   79,   80,   77,
-       78,   79,   80,  278,   77,  283,  279,   78,   79,   80,
-      281,   77,  280,   78,   79,   80,   77,  416,   78,   79,
-       80,   77,   78,   79,   80,   77,   78,   79,   80,  282,
-       77,   78,   79,   80,  285,   77,  288,  284,   78,   79,
-       80,  286,   77,   78,   79,   80,   77,  416,   78,   79,
-       80,   77,   78,   79,   80,   77,  289,   78,   79,   80,
-
-       77,  287,   78,   79,   80,   77,  416,  291,  292,   78,
-       79,   80,  290,   78,   79,   80,  416,   77,   78,   79,
-       80,   77,   78,   79,   80,  248,  294,   78,   79,   80,
-       77,  416,   78,   79,   80,   77,  416,  416,  416,  416,
-       77,  416,  296,  293,   78,   79,   80,   77,   78,   79,
-       80,   77,  295,  416,  416,  416,   77,   78,   79,   80,
-      298,   77,   78,   79,   80,   77,  416,   78,   79,   80,
-      416,  300,   77,  416,   78,   79,   80,  301,   78,   79,
-       80,  297,  416,   78,   79,   80,  141,   77,   78,   79,
-       80,  299,   78,   79,   80,  303,  416,  416,   77,   78,
-
-       79,   80,   77,  416,  302,   77,  416,  416,   77,  416,
-      306,  416,  416,  263,   78,   79,   80,  416,  304,  416,
-      305,  416,   77,  416,  416,   78,   79,   80,  313,   78,
-       79,   80,   78,   79,   80,   78,   79,   80,  314,  416,
-      264,  265,  266,  262,  262,  262,  262,  262,   77,   78,
-       79,   80,   77,  316,  416,   77,  416,  416,  317,  262,
-      416,   77,  315,  319,  416,   77,  318,  416,   77,  416,
-      416,   77,  416,  320,  416,   78,   79,   80,  262,   78,
-       79,   80,   78,   79,   80,  321,  416,   77,   78,   79,
-       80,   77,   78,   79,   80,   78,   79,   80,   78,   79,
-
-       80,   77,  416,  262,   77,  322,  323,   77,  416,  416,
-      416,  324,   77,  416,   78,   79,   80,  416,   78,   79,
-       80,   77,  325,  328,  326,   77,  416,  416,   78,   79,
-       80,   78,   79,   80,   78,   79,   80,   77,  416,   78,
-       79,   80,   77,  329,  327,  416,  416,  416,   78,   79,
-       80,   77,   78,   79,   80,   77,  333,  332,   77,  416,
-      316,   77,  337,  330,   78,   79,   80,  334,   77,   78,
-       79,   80,   77,  416,  331,   77,  416,  416,   78,   79,
-       80,   77,   78,   79,   80,   78,   79,   80,   78,   79,
-       80,   77,  416,  338,   77,   78,   79,   80,  316,   78,
-
-       79,   80,   78,   79,   80,   77,  416,  416,   78,   79,
-       80,  335,   77,  416,  336,   77,  416,  416,   78,   79,
-       80,   78,   79,   80,   77,  416,  416,   77,  416,  416,
-       77,  416,   78,   79,   80,  339,   77,  416,  416,   78,
-       79,   80,   78,   79,   80,   77,  340,  416,  342,   77,
-      341,   78,   79,   80,   78,   79,   80,   78,   79,   80,
-      345,   77,  416,   78,   79,   80,   77,  416,  416,  347,
-       77,  416,   78,   79,   80,  346,   78,   79,   80,  348,
-       77,  349,  416,   77,  416,  416,   77,  416,   78,   79,
-       80,   77,  416,   78,   79,   80,  416,   78,   79,   80,
-
-      350,   77,  416,  352,   77,  351,  416,   78,   79,   80,
-       78,   79,   80,   78,   79,   80,   77,  416,   78,   79,
-       80,  416,   77,  416,  354,  353,  355,   77,   78,   79,
-       80,   78,   79,   80,  416,  416,   77,  416,  416,  354,
-      416,   77,  416,   78,   79,   80,  416,  416,   77,   78,
-       79,   80,  356,  357,   78,   79,   80,  416,   77,  416,
-      416,  416,  360,   78,   79,   80,  358,   77,   78,   79,
-       80,   77,  416,  416,  359,   78,   79,   80,   77,  416,
-      416,  416,  416,   77,  416,   78,   79,   80,  361,   77,
-      416,  416,   77,  416,   78,   79,   80,   77,   78,   79,
-
-       80,  244,   77,  416,  416,   78,   79,   80,  363,   77,
-       78,   79,   80,  362,   77,  369,   78,   79,   80,   78,
-       79,   80,  416,   77,   78,   79,   80,  416,   77,   78,
-       79,   80,   77,  416,  364,  365,   78,   79,   80,  416,
-       77,   78,   79,   80,  416,  416,  367,  216,   77,  416,
-       78,   79,   80,   77,  416,   78,   79,   80,   77,   78,
-       79,   80,   77,  370,  371,   77,  416,   78,   79,   80,
-      416,  368,   77,  416,  373,   78,   79,   80,  374,  372,
-       78,   79,   80,   77,  416,   78,   79,   80,  416,   78,
-       79,   80,   78,   79,   80,  416,  416,   77,  416,   78,
-
-       79,   80,  375,   77,  416,  416,  416,   77,  416,  376,
-       78,   79,   80,  354,   77,  416,  416,   77,  416,  416,
-      354,  416,   77,  416,   78,   79,   80,  378,  416,  377,
-       78,   79,   80,   77,   78,   79,   80,   77,  416,  416,
-       77,   78,   79,   80,   78,   79,   80,   77,  379,   78,
-       79,   80,   77,  381,  416,  380,  416,   77,  303,  384,
-       78,   79,   80,  382,   78,   79,   80,   78,   79,   80,
-       77,  416,  416,  385,   78,   79,   80,  216,   77,   78,
-       79,   80,  387,   77,   78,   79,   80,   77,  416,  388,
-      416,   77,  416,  416,  416,  416,   77,   78,   79,   80,
-
-      416,  416,  386,   77,  416,   78,   79,   80,   77,  416,
-       78,   79,   80,   77,   78,   79,   80,  389,   78,   79,
-       80,  390,   77,   78,   79,   80,  392,   77,  393,  391,
-       78,   79,   80,   77,  416,   78,   79,   80,   77,  416,
-       78,   79,   80,   77,  378,  416,   77,  394,  385,   78,
-       79,   80,   77,  416,   78,   79,   80,   77,  416,  416,
-       78,   79,   80,   77,  416,   78,   79,   80,   77,  396,
-       78,   79,   80,   78,   79,   80,  395,   77,  399,   78,
-       79,   80,   77,  397,   78,   79,   80,  398,  354,   77,
-       78,   79,   80,  354,   77,   78,   79,   80,   77,  416,
-
-      403,   77,  401,  416,   78,   79,   80,  416,  402,   78,
-       79,   80,   77,  416,  400,   77,   78,   79,   80,   77,
-      416,   78,   79,   80,   77,   78,   79,   80,   78,   79,
-       80,  354,   77,  354,  405,  416,   77,  416,  416,   78,
-       79,   80,   78,   79,   80,   77,   78,   79,   80,  407,
-      416,   78,   79,   80,  404,  354,  406,   77,  416,   78,
-       79,   80,  416,   78,   79,   80,  416,  416,   77,  416,
-      416,   77,   78,   79,   80,   77,  410,  408,   77,  416,
-      416,  409,   77,  416,   78,   79,   80,  416,  416,   77,
-      416,  416,  416,  416,  354,   78,   79,   80,   78,   79,
-
-       80,  416,   78,   79,   80,   78,   79,   80,  354,   78,
-       79,   80,  416,   77,  416,  416,   78,   79,   80,  411,
-       77,  416,  416,  416,   77,  416,  416,   77,  416,  416,
-       77,  416,  416,  416,  416,  416,   77,  414,  412,  416,
-       78,   79,   80,  413,  416,  415,  416,   78,   79,   80,
-      354,   78,   79,   80,   78,   79,   80,   78,   79,   80,
-      416,  416,  416,   78,   79,   80,   46,   46,   46,   46,
+      244,   77,   78,   79,   80,   77,  421,  245,  421,  421,
+      421,  243,   77,  421,  421,   77,  421,  421,  247,   78,
+
+       79,   80,   77,  421,  248,  250,  246,   77,   78,   79,
+       80,   77,   78,   79,   80,  421,  251,  252,  421,   78,
+       79,   80,   78,   79,   80,   77,  421,  253,   77,   78,
+       79,   80,  421,   77,   78,   79,   80,   77,   78,   79,
+       80,  141,  255,  256,   77,  254,  421,  258,  421,  421,
+      421,  421,   78,   79,   80,   78,   79,   80,   77,  257,
+       78,   79,   80,   77,   78,   79,   80,  421,  264,  421,
+      271,   78,   79,   80,  202,  202,  202,  202,  202,  202,
+      202,   77,  421,  272,   77,   78,   79,   80,  274,   77,
+       78,   79,   80,   77,  421,  265,  266,  267,  273,  275,
+
+      421,  421,   77,  421,  421,  277,  421,   77,   78,   79,
+       80,   78,   79,   80,   77,  421,   78,   79,   80,  421,
+       78,   79,   80,   77,  421,  421,   77,  421,  276,   78,
+       79,   80,   77,  278,   78,   79,   80,   77,  279,  421,
+       77,   78,   79,   80,  421,  282,  280,  421,  421,  421,
+       78,   79,   80,   78,   79,   80,   77,  281,  284,   78,
+       79,   80,  283,   77,   78,   79,   80,   78,   79,   80,
+       77,  421,  421,  285,  421,   77,  421,  286,  421,  421,
+       77,  290,  421,   78,   79,   80,  288,   77,  421,  421,
+       78,   79,   80,  287,   77,  421,  421,   78,   79,   80,
+
+       77,  421,   78,   79,   80,   77,  421,   78,   79,   80,
+       77,  421,  421,   77,   78,   79,   80,   77,  421,  421,
+      289,   78,   79,   80,  291,  292,  294,   78,   79,   80,
+       77,  421,   78,   79,   80,   77,  421,   78,   79,   80,
+       78,   79,   80,   77,   78,   79,   80,  296,   77,  421,
+      248,  293,   77,  421,  421,   77,  421,   78,   79,   80,
+      295,   77,   78,   79,   80,   77,  421,  421,   77,  421,
+       78,   79,   80,  297,  421,   78,   79,   80,   77,   78,
+       79,   80,   78,   79,   80,   77,  298,  421,   78,   79,
+       80,   77,   78,   79,   80,   78,   79,   80,  299,  300,
+
+       77,  421,  421,   77,  301,   78,   79,   80,  421,  303,
+      302,  421,   78,   79,   80,  304,   77,  421,   78,   79,
+       80,   77,  421,  421,  306,  141,  421,   78,   79,   80,
+       78,   79,   80,   77,  307,  421,   77,  421,  421,   77,
+      421,  309,  305,   78,   79,   80,  319,  421,   78,   79,
+       80,  308,  264,  263,  263,  263,  263,  263,   77,  421,
+       78,   79,   80,   78,   79,   80,   78,   79,   80,  263,
+       77,  421,  317,   77,  421,  421,  316,  421,   77,  265,
+      266,  267,   77,  318,  320,   78,   79,   80,  263,  321,
+       77,  421,  322,  421,   77,  421,  421,   78,   79,   80,
+
+       78,   79,   80,  421,   77,   78,   79,   80,  326,   78,
+       79,   80,   77,  263,  323,  421,  421,   78,   79,   80,
+      421,   78,   79,   80,  324,  421,   77,  421,  421,   77,
+      421,   78,   79,   80,   77,  325,  327,  421,  421,   78,
+       79,   80,  421,  421,   77,  421,  421,   77,  421,  421,
+       77,  421,  421,   78,   79,   80,   78,   79,   80,  330,
+       77,   78,   79,   80,  328,  329,   77,  331,  332,  421,
+      421,   78,   79,   80,   78,   79,   80,   78,   79,   80,
+       77,  337,  421,   77,  421,  421,   77,   78,   79,   80,
+       77,  319,  421,   78,   79,   80,  336,   77,  333,  421,
+
+       77,  421,  421,   77,  334,  335,  421,   78,   79,   80,
+       78,   79,   80,   78,   79,   80,   77,   78,   79,   80,
+       77,  421,  338,   77,   78,   79,   80,   78,   79,   80,
+       78,   79,   80,   77,  342,  343,   77,  421,  421,   77,
+      319,  421,  339,   78,   79,   80,   77,   78,   79,   80,
+       78,   79,   80,   77,  340,  421,  421,   77,  421,  341,
+       78,   79,   80,   78,   79,   80,   78,   79,   80,   77,
+      421,  421,   77,   78,   79,   80,  421,  344,   77,  421,
+       78,   79,   80,   77,   78,   79,   80,   77,  345,  421,
+      347,   77,  350,  421,   77,  421,   78,   79,   80,   78,
+
+       79,   80,   77,  346,  354,   78,   79,   80,  351,   77,
+       78,   79,   80,   77,   78,   79,   80,  421,   78,   79,
+       80,   78,   79,   80,  353,   77,  421,  421,   77,   78,
+       79,   80,   77,  352,  421,  421,   78,   79,   80,   77,
+       78,   79,   80,  421,   77,  355,  356,   77,  359,  357,
+       77,  421,   78,   79,   80,   78,   79,   80,  421,   78,
+       79,   80,  358,  421,  421,   77,   78,   79,   80,  360,
+      358,   78,   79,   80,   78,   79,   80,   78,   79,   80,
+       77,  421,  421,   77,  421,  421,   77,  421,  421,   77,
+      421,  421,   78,   79,   80,  358,  361,  363,  362,   77,
+
+      421,  421,  364,  421,  421,   77,  421,   78,   79,   80,
+       78,   79,   80,   78,   79,   80,   78,   79,   80,  365,
+       77,  421,  421,   77,  421,  421,   78,   79,   80,   77,
+      366,  421,   78,   79,   80,   77,  421,  421,   77,  421,
+      421,   77,  421,  421,  421,   77,  421,   78,   79,   80,
+       78,   79,   80,  244,   77,  421,   78,   79,   80,   77,
+      421,  421,   78,   79,   80,   78,   79,   80,   78,   79,
+       80,   77,   78,   79,   80,  367,  421,  368,   77,  369,
+      421,   78,   79,   80,   77,  421,   78,   79,   80,   77,
+      370,  216,   77,  421,  421,  374,   77,  421,   78,   79,
+
+       80,   77,  376,  372,   77,   78,   79,   80,   77,  421,
+      421,   78,   79,   80,  375,  373,   78,   79,   80,   78,
+       79,   80,   77,   78,   79,   80,   77,  421,   78,   79,
+       80,   78,   79,   80,  378,   78,   79,   80,   77,  421,
+      377,   77,  421,  421,  379,   77,  380,  421,  421,   78,
+       79,   80,   77,   78,   79,   80,   77,  382,  381,   77,
+      421,  421,  358,   77,  383,   78,   79,   80,   78,   79,
+       80,   77,   78,   79,   80,   77,  421,  358,  384,   78,
+       79,   80,  421,   78,   79,   80,   78,   79,   80,   77,
+       78,   79,   80,  385,  421,   77,  421,  421,   78,   79,
+
+       80,  386,   78,   79,   80,   77,  390,  306,   77,  421,
+      421,  387,   77,  421,  421,  389,   78,   79,   80,  216,
+       77,  392,   78,   79,   80,  421,   77,  421,  421,  421,
+       77,  421,   78,   79,   80,   78,   79,   80,   77,   78,
+       79,   80,   77,  421,  393,  421,   77,   78,   79,   80,
+      391,   77,  421,   78,   79,   80,   77,   78,   79,   80,
+      421,   77,  383,  394,  395,   78,   79,   80,  396,   78,
+       79,   80,   77,   78,   79,   80,   77,  421,   78,   79,
+       80,   77,  421,   78,   79,   80,   77,  398,   78,   79,
+       80,  390,   77,  421,  397,  399,   77,  421,  421,   78,
+
+       79,   80,   77,   78,   79,   80,   77,  421,   78,   79,
+       80,  400,  401,   78,   79,   80,   77,  404,  421,   78,
+       79,   80,  402,   78,   79,   80,  358,   77,  421,   78,
+       79,   80,   77,   78,   79,   80,  421,   77,  358,  421,
+       77,  421,  421,   78,   79,   80,  403,  421,   77,  421,
+      421,   77,  408,  421,   78,   79,   80,  405,   77,   78,
+       79,   80,  406,   77,   78,   79,   80,   78,   79,   80,
+      407,   77,  421,  358,   77,   78,   79,   80,   78,   79,
+       80,  421,  358,   77,  421,   78,   79,   80,   77,  412,
+       78,   79,   80,  410,   77,  421,  409,   77,   78,   79,
+
+       80,   78,   79,   80,  421,  411,  421,  358,   77,  421,
+       78,   79,   80,   77,  421,   78,   79,   80,  415,  413,
+       77,   78,   79,   80,   78,   79,   80,   77,  421,  421,
+      421,   77,  421,  414,   77,   78,   79,   80,   77,  421,
+       78,   79,   80,  358,  416,  421,   77,   78,   79,   80,
+       77,  421,  421,  358,   78,   79,   80,   77,   78,   79,
+       80,   78,   79,   80,  417,   78,   79,   80,  421,  418,
+       77,  421,  420,   78,   79,   80,   77,   78,   79,   80,
+      419,  421,  421,  421,   78,   79,   80,  421,  421,  421,
+      358,  421,  421,  421,  421,  421,  421,   78,   79,   80,
+
+      421,  421,  421,   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,  416,   57,  416,   57,  416,   57,   66,
-      416,  416,   66,  416,   66,   66,   66,   66,   66,   76,
-       76,  416,   76,   76,   76,   76,   76,   76,  126,  126,
+       54,   54,   57,  421,   57,  421,   57,  421,   57,   66,
+      421,  421,   66,  421,   66,   66,   66,   66,   66,   76,
+       76,  421,   76,   76,   76,   76,   76,   76,  126,  126,
       126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+
       126,  126,  129,  129,  129,  129,  129,  129,  129,  129,
-      129,  129,  129,  129,  129,  131,  416,  131,  131,  131,
+      129,  129,  129,  129,  129,  131,  421,  131,  131,  131,
       131,  131,  131,  131,  131,  131,  131,  131,  131,  139,
-      416,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-
+      421,  139,  139,  139,  139,  139,  139,  139,  139,  139,
       139,  139,  139,  140,  140,  140,  140,  140,  140,  140,
-      140,  140,  148,  148,  148,  199,  416,  416,  416,  416,
+      140,  140,  148,  148,  148,  199,  421,  421,  421,  421,
       199,  199,  199,  202,  202,  202,  202,  202,  210,  210,
-      210,  416,  416,  210,  259,  259,  259,  262,  262,  262,
-      262,  262,  262,  262,  262,  262,    7,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416
+      210,  421,  421,  210,  260,  260,  260,  263,  263,  263,
+      263,  263,  263,  263,  263,  263,    7,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421
     } ;
 
-static yyconst flex_int16_t yy_chk[2416] =
+static const flex_int16_t yy_chk[2456] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -880,16 +1101,16 @@ static yyconst flex_int16_t yy_chk[2416] =
         1,    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,  383,   50,   73,   16,  366,   13,   14,   16,   19,
-       14,  344,   51,   82,   82,  201,   25,  343,  201,   20,
+       50,  388,   50,   73,   16,  371,   13,   14,   16,   19,
+       14,  349,   51,   82,   82,  201,   25,  348,  201,   20,
 
-      312,  211,   11,   25,   73,   13,   14,   15,   15,   15,
+      315,  211,   11,   25,   73,   13,   14,   15,   15,   15,
        15,   15,   15,   15,   20,   16,   19,   19,   19,   15,
-       15,   15,  211,  311,   15,   51,   20,   20,   20,  310,
-       25,   25,   25,  309,  269,   22,  268,  267,   15,   15,
-       15,  266,   16,   16,   16,   15,   17,   22,   17,   17,
-       17,   17,   17,   17,   17,  265,   23,  264,   17,  261,
-      259,   17,   22,   22,   22,   17,  258,  213,  209,   17,
+       15,   15,  211,  314,   15,   51,   20,   20,   20,  313,
+       25,   25,   25,  312,  270,   22,  269,  268,   15,   15,
+       15,  267,   16,   16,   16,   15,   17,   22,   17,   17,
+       17,   17,   17,   17,   17,  266,   23,  265,   17,  262,
+      260,   17,   22,   22,   22,   17,  259,  213,  209,   17,
        23,   17,  208,   17,  207,   24,  206,   17,   24,  205,
        17,  204,  196,   23,   23,   23,   17,  150,   24,  149,
        24,   28,  147,   17,  146,   17,   21,   21,   24,  145,
@@ -977,174 +1198,178 @@ static yyconst flex_int16_t yy_chk[2416] =
       176,  178,    0,  210,  174,  174,  174,  210,  187,  175,
       175,  175,  177,    0,  178,  177,  179,    0,  179,    0,
       183,  176,  176,  176,  210,  180,  187,  183,  178,  178,
-      178,  210,    0,    0,  181,  187,  187,  187,  188,  177,
+      178,  210,    0,    0,  181,  187,  187,  187,    0,  177,
       177,  177,  182,  179,  179,  179,  180,  183,  183,  183,
-      182,  185,  180,  180,  180,  181,    0,  184,  189,  188,
-        0,  181,  186,    0,  189,  188,  188,  188,  185,  182,
-
-      182,  182,  184,    0,  186,  190,  184,    0,  185,  185,
-      185,    0,  181,  181,  181,  189,  189,  189,  191,  186,
-      186,  186,  192,    0,    0,  190,  202,  193,    0,  184,
-      184,  184,  190,  190,  190,    0,  192,  193,  191,    0,
-        0,    0,  194,    0,    0,  191,  191,  191,  195,  192,
-      192,  192,    0,  202,  193,  193,  193,  194,  195,  203,
-      203,  203,  203,  203,  203,  203,  214,    0,    0,  194,
-      194,  194,  215,  218,    0,  195,  195,  195,  214,  216,
-      202,  202,  202,  217,    0,    0,    0,  218,  220,    0,
-      219,    0,  215,  214,  214,  214,  220,  217,    0,  215,
-
-      215,  215,    0,    0,    0,  233,  216,  216,  216,  222,
-      217,  217,  217,  221,  218,  218,  218,  219,  219,  219,
-      223,  222,    0,  220,  220,  220,  225,  221,    0,    0,
-      223,  224,  233,  233,  233,  229,  222,  222,  222,  226,
-      221,  221,  221,  224,  227,  229,  225,  223,  223,  223,
-      227,  228,  226,  225,  225,  225,  231,    0,  224,  224,
-      224,  234,  229,  229,  229,  239,  226,  226,  226,  228,
-      230,  227,  227,  227,  231,  232,  236,  230,  228,  228,
-      228,  232,  237,  231,  231,  231,  235,    0,  234,  234,
-      234,  241,  239,  239,  239,  236,  237,  230,  230,  230,
-
-      238,  235,  232,  232,  232,  240,    0,  241,  242,  237,
-      237,  237,  238,  235,  235,  235,    0,  244,  241,  241,
-      241,  247,  236,  236,  236,  240,  245,  238,  238,  238,
-      242,    0,  240,  240,  240,  243,    0,    0,    0,    0,
-      245,    0,  247,  243,  244,  244,  244,  246,  247,  247,
-      247,  248,  246,    0,    0,    0,  250,  242,  242,  242,
-      250,  249,  243,  243,  243,  252,    0,  245,  245,  245,
-        0,  252,  251,    0,  246,  246,  246,  253,  248,  248,
-      248,  249,    0,  250,  250,  250,  262,  254,  249,  249,
-      249,  251,  252,  252,  252,  254,    0,    0,  253,  251,
-
-      251,  251,  256,    0,  253,  255,    0,    0,  257,    0,
-      257,    0,    0,  262,  254,  254,  254,    0,  255,    0,
-      256,    0,  270,    0,    0,  253,  253,  253,  270,  256,
-      256,  256,  255,  255,  255,  257,  257,  257,  271,    0,
-      262,  262,  262,  263,  263,  263,  263,  263,  271,  270,
-      270,  270,  272,  273,    0,  275,    0,    0,  274,  263,
-        0,  276,  272,  276,    0,  273,  275,    0,  274,    0,
-        0,  277,    0,  277,    0,  271,  271,  271,  263,  272,
-      272,  272,  275,  275,  275,  278,    0,  278,  276,  276,
-      276,  281,  273,  273,  273,  274,  274,  274,  277,  277,
-
-      277,  279,    0,  263,  280,  279,  280,  282,    0,    0,
-        0,  281,  283,    0,  278,  278,  278,    0,  281,  281,
-      281,  285,  282,  285,  283,  286,    0,    0,  279,  279,
-      279,  280,  280,  280,  282,  282,  282,  284,    0,  283,
-      283,  283,  287,  286,  284,    0,    0,    0,  285,  285,
-      285,  290,  286,  286,  286,  289,  291,  290,  292,    0,
-      294,  293,  299,  287,  284,  284,  284,  293,  297,  287,
-      287,  287,  294,    0,  289,  291,    0,    0,  290,  290,
-      290,  299,  289,  289,  289,  292,  292,  292,  293,  293,
-      293,  295,    0,  301,  298,  297,  297,  297,  295,  294,
-
-      294,  294,  291,  291,  291,  296,    0,    0,  299,  299,
-      299,  296,  300,    0,  298,  301,    0,    0,  295,  295,
-      295,  298,  298,  298,  303,    0,    0,  302,    0,    0,
-      305,    0,  296,  296,  296,  302,  304,    0,    0,  300,
-      300,  300,  301,  301,  301,  306,  304,    0,  306,  315,
-      305,  303,  303,  303,  302,  302,  302,  305,  305,  305,
-      313,  314,    0,  304,  304,  304,  316,    0,    0,  315,
-      313,    0,  306,  306,  306,  314,  315,  315,  315,  317,
-      319,  318,    0,  317,    0,    0,  318,    0,  314,  314,
-      314,  320,    0,  316,  316,  316,    0,  313,  313,  313,
-
-      319,  321,    0,  321,  323,  320,    0,  319,  319,  319,
-      317,  317,  317,  318,  318,  318,  322,    0,  320,  320,
-      320,    0,  324,    0,  323,  322,  324,  326,  321,  321,
-      321,  323,  323,  323,    0,    0,  325,    0,    0,  326,
-        0,  327,    0,  322,  322,  322,    0,    0,  330,  324,
-      324,  324,  325,  327,  326,  326,  326,    0,  328,    0,
-        0,    0,  330,  325,  325,  325,  328,  332,  327,  327,
-      327,  329,    0,    0,  329,  330,  330,  330,  331,    0,
-        0,    0,    0,  334,    0,  328,  328,  328,  331,  335,
-        0,    0,  336,    0,  332,  332,  332,  338,  329,  329,
-
-      329,  334,  339,    0,    0,  331,  331,  331,  339,  341,
-      334,  334,  334,  336,  340,  348,  335,  335,  335,  336,
-      336,  336,    0,  342,  338,  338,  338,    0,  348,  339,
-      339,  339,  345,    0,  340,  342,  341,  341,  341,    0,
-      346,  340,  340,  340,    0,    0,  345,  346,  347,    0,
-      342,  342,  342,  349,    0,  348,  348,  348,  350,  345,
-      345,  345,  352,  349,  350,  351,    0,  346,  346,  346,
-        0,  347,  353,    0,  352,  347,  347,  347,  353,  351,
-      349,  349,  349,  354,    0,  350,  350,  350,    0,  352,
-      352,  352,  351,  351,  351,    0,    0,  355,    0,  353,
-
-      353,  353,  355,  356,    0,    0,    0,  357,    0,  356,
-      354,  354,  354,  357,  358,    0,    0,  359,    0,    0,
-      358,    0,  360,    0,  355,  355,  355,  360,    0,  359,
-      356,  356,  356,  361,  357,  357,  357,  362,    0,    0,
-      363,  358,  358,  358,  359,  359,  359,  364,  361,  360,
-      360,  360,  367,  364,    0,  362,    0,  365,  363,  367,
-      361,  361,  361,  365,  362,  362,  362,  363,  363,  363,
-      368,    0,    0,  369,  364,  364,  364,  368,  370,  367,
-      367,  367,  371,  372,  365,  365,  365,  369,    0,  372,
-        0,  371,    0,    0,    0,    0,  373,  368,  368,  368,
-
-        0,    0,  370,  374,    0,  370,  370,  370,  376,    0,
-      372,  372,  372,  377,  369,  369,  369,  373,  371,  371,
-      371,  374,  375,  373,  373,  373,  376,  378,  377,  375,
-      374,  374,  374,  379,    0,  376,  376,  376,  380,    0,
-      377,  377,  377,  381,  380,    0,  384,  379,  381,  375,
-      375,  375,  385,    0,  378,  378,  378,  382,    0,    0,
-      379,  379,  379,  386,    0,  380,  380,  380,  388,  386,
-      381,  381,  381,  384,  384,  384,  382,  387,  390,  385,
-      385,  385,  389,  387,  382,  382,  382,  388,  389,  394,
-      386,  386,  386,  391,  392,  388,  388,  388,  393,    0,
-
-      395,  390,  393,    0,  387,  387,  387,    0,  394,  389,
-      389,  389,  396,    0,  392,  391,  394,  394,  394,  395,
-        0,  392,  392,  392,  400,  393,  393,  393,  390,  390,
-      390,  396,  397,  399,  400,    0,  398,    0,    0,  396,
-      396,  396,  391,  391,  391,  401,  395,  395,  395,  402,
-        0,  400,  400,  400,  397,  398,  401,  399,    0,  397,
-      397,  397,    0,  398,  398,  398,    0,    0,  402,    0,
-        0,  404,  401,  401,  401,  405,  406,  404,  406,    0,
-        0,  405,  408,    0,  399,  399,  399,    0,    0,  409,
-        0,    0,    0,    0,  408,  402,  402,  402,  404,  404,
-
-      404,    0,  405,  405,  405,  406,  406,  406,  409,  408,
-      408,  408,    0,  410,    0,    0,  409,  409,  409,  410,
-      411,    0,    0,    0,  412,    0,    0,  413,    0,    0,
-      414,    0,    0,    0,    0,    0,  415,  413,  411,    0,
-      410,  410,  410,  412,    0,  414,    0,  411,  411,  411,
-      415,  412,  412,  412,  413,  413,  413,  414,  414,  414,
-        0,    0,    0,  415,  415,  415,  417,  417,  417,  417,
-      417,  417,  417,  417,  417,  417,  417,  417,  417,  417,
-      418,  418,  418,  418,  418,  418,  418,  418,  418,  418,
-      418,  418,  418,  418,  419,  419,  419,  419,  419,  419,
-
-      419,  419,  419,  419,  419,  419,  419,  419,  420,  420,
-      420,  420,  420,  420,  420,  420,  420,  420,  420,  420,
-      420,  420,  421,    0,  421,    0,  421,    0,  421,  422,
-        0,    0,  422,    0,  422,  422,  422,  422,  422,  423,
-      423,    0,  423,  423,  423,  423,  423,  423,  424,  424,
-      424,  424,  424,  424,  424,  424,  424,  424,  424,  424,
-      424,  424,  425,  425,  425,  425,  425,  425,  425,  425,
-      425,  425,  425,  425,  425,  426,    0,  426,  426,  426,
-      426,  426,  426,  426,  426,  426,  426,  426,  426,  427,
-        0,  427,  427,  427,  427,  427,  427,  427,  427,  427,
-
-      427,  427,  427,  428,  428,  428,  428,  428,  428,  428,
-      428,  428,  429,  429,  429,  430,    0,    0,    0,    0,
-      430,  430,  430,  431,  431,  431,  431,  431,  432,  432,
-      432,    0,    0,  432,  433,  433,  433,  434,  434,  434,
-      434,  434,  434,  434,  434,  434,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-
-      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,
-      416,  416,  416,  416,  416
+      182,  185,  180,  180,  180,  181,    0,  184,    0,    0,
+        0,  181,  186,    0,    0,  188,    0,    0,  185,  182,
+
+      182,  182,  184,    0,  186,  188,  184,  190,  185,  185,
+      185,  189,  181,  181,  181,    0,  188,  189,    0,  186,
+      186,  186,  188,  188,  188,  191,    0,  190,  192,  184,
+      184,  184,    0,  193,  190,  190,  190,  195,  189,  189,
+      189,  202,  192,  193,  194,  191,    0,  195,    0,    0,
+        0,    0,  191,  191,  191,  192,  192,  192,  214,  194,
+      193,  193,  193,  215,  195,  195,  195,    0,  202,    0,
+      214,  194,  194,  194,  203,  203,  203,  203,  203,  203,
+      203,  216,    0,  215,  217,  214,  214,  214,  218,  219,
+      215,  215,  215,  222,    0,  202,  202,  202,  217,  220,
+
+        0,    0,  218,    0,    0,  222,    0,  220,  216,  216,
+      216,  217,  217,  217,  221,    0,  219,  219,  219,    0,
+      222,  222,  222,  223,    0,    0,  224,    0,  221,  218,
+      218,  218,  226,  223,  220,  220,  220,  225,  224,    0,
+      228,  221,  221,  221,    0,  226,  224,    0,    0,    0,
+      223,  223,  223,  224,  224,  224,  227,  225,  228,  226,
+      226,  226,  227,  229,  225,  225,  225,  228,  228,  228,
+      230,    0,    0,  229,    0,  231,    0,  230,    0,    0,
+      232,  236,    0,  227,  227,  227,  232,  233,    0,    0,
+      229,  229,  229,  231,  234,    0,    0,  230,  230,  230,
+
+      236,    0,  231,  231,  231,  235,    0,  232,  232,  232,
+      237,    0,    0,  238,  233,  233,  233,  239,    0,    0,
+      235,  234,  234,  234,  237,  238,  242,  236,  236,  236,
+      240,    0,  235,  235,  235,  241,    0,  237,  237,  237,
+      238,  238,  238,  244,  239,  239,  239,  245,  242,    0,
+      240,  241,  243,    0,    0,  248,    0,  240,  240,  240,
+      243,  245,  241,  241,  241,  247,    0,    0,  246,    0,
+      244,  244,  244,  246,    0,  242,  242,  242,  249,  243,
+      243,  243,  248,  248,  248,  250,  247,    0,  245,  245,
+      245,  252,  247,  247,  247,  246,  246,  246,  249,  250,
+
+      251,    0,    0,  253,  251,  249,  249,  249,    0,  253,
+      252,    0,  250,  250,  250,  254,  255,    0,  252,  252,
+      252,  256,    0,    0,  255,  263,    0,  251,  251,  251,
+      253,  253,  253,  257,  256,    0,  254,    0,    0,  258,
+        0,  258,  254,  255,  255,  255,  274,    0,  256,  256,
+      256,  257,  263,  264,  264,  264,  264,  264,  274,    0,
+      257,  257,  257,  254,  254,  254,  258,  258,  258,  264,
+      271,    0,  272,  273,    0,    0,  271,    0,  276,  263,
+      263,  263,  272,  273,  275,  274,  274,  274,  264,  276,
+      277,    0,  277,    0,  275,    0,    0,  271,  271,  271,
+
+      273,  273,  273,    0,  281,  276,  276,  276,  281,  272,
+      272,  272,  278,  264,  278,    0,    0,  277,  277,  277,
+        0,  275,  275,  275,  279,    0,  279,    0,    0,  280,
+        0,  281,  281,  281,  282,  280,  282,    0,    0,  278,
+      278,  278,    0,    0,  283,    0,    0,  285,    0,    0,
+      284,    0,    0,  279,  279,  279,  280,  280,  280,  285,
+      286,  282,  282,  282,  283,  284,  287,  286,  287,    0,
+        0,  283,  283,  283,  285,  285,  285,  284,  284,  284,
+      288,  293,    0,  289,    0,    0,  291,  286,  286,  286,
+      292,  296,    0,  287,  287,  287,  292,  294,  288,    0,
+
+      293,    0,    0,  296,  289,  291,    0,  288,  288,  288,
+      289,  289,  289,  291,  291,  291,  295,  292,  292,  292,
+      299,    0,  295,  303,  294,  294,  294,  293,  293,  293,
+      296,  296,  296,  297,  302,  304,  298,    0,    0,  301,
+      297,    0,  298,  295,  295,  295,  300,  299,  299,  299,
+      303,  303,  303,  302,  300,    0,    0,  304,    0,  301,
+      297,  297,  297,  298,  298,  298,  301,  301,  301,  305,
+        0,    0,  306,  300,  300,  300,    0,  305,  307,    0,
+      302,  302,  302,  308,  304,  304,  304,  309,  307,    0,
+      309,  319,  316,    0,  317,    0,  305,  305,  305,  306,
+
+      306,  306,  316,  308,  321,  307,  307,  307,  317,  321,
+      308,  308,  308,  318,  309,  309,  309,    0,  319,  319,
+      319,  317,  317,  317,  320,  322,    0,    0,  320,  316,
+      316,  316,  323,  318,    0,    0,  321,  321,  321,  326,
+      318,  318,  318,    0,  325,  322,  323,  324,  326,  324,
+      327,    0,  322,  322,  322,  320,  320,  320,    0,  323,
+      323,  323,  325,    0,    0,  328,  326,  326,  326,  328,
+      327,  325,  325,  325,  324,  324,  324,  327,  327,  327,
+      329,    0,    0,  330,    0,    0,  331,    0,    0,  332,
+        0,    0,  328,  328,  328,  330,  329,  332,  331,  333,
+
+        0,    0,  333,    0,    0,  334,    0,  329,  329,  329,
+      330,  330,  330,  331,  331,  331,  332,  332,  332,  334,
+      335,    0,    0,  336,    0,    0,  333,  333,  333,  339,
+      335,    0,  334,  334,  334,  338,    0,    0,  340,    0,
+        0,  343,    0,    0,    0,  346,    0,  335,  335,  335,
+      336,  336,  336,  338,  341,    0,  339,  339,  339,  345,
+        0,    0,  338,  338,  338,  340,  340,  340,  343,  343,
+      343,  344,  346,  346,  346,  341,    0,  344,  347,  345,
+        0,  341,  341,  341,  351,    0,  345,  345,  345,  350,
+      347,  351,  352,    0,    0,  353,  355,    0,  344,  344,
+
+      344,  358,  355,  350,  354,  347,  347,  347,  353,    0,
+        0,  351,  351,  351,  354,  352,  350,  350,  350,  352,
+      352,  352,  357,  355,  355,  355,  356,    0,  358,  358,
+      358,  354,  354,  354,  357,  353,  353,  353,  359,    0,
+      356,  360,    0,    0,  359,  364,  360,    0,    0,  357,
+      357,  357,  361,  356,  356,  356,  362,  364,  361,  365,
+        0,    0,  362,  366,  365,  359,  359,  359,  360,  360,
+      360,  363,  364,  364,  364,  367,    0,  363,  366,  361,
+      361,  361,    0,  362,  362,  362,  365,  365,  365,  368,
+      366,  366,  366,  367,    0,  369,    0,    0,  363,  363,
+
+      363,  369,  367,  367,  367,  370,  374,  368,  372,    0,
+        0,  370,  373,    0,    0,  372,  368,  368,  368,  373,
+      374,  376,  369,  369,  369,    0,  375,    0,    0,    0,
+      376,    0,  370,  370,  370,  372,  372,  372,  377,  373,
+      373,  373,  378,    0,  377,    0,  379,  374,  374,  374,
+      375,  383,    0,  375,  375,  375,  385,  376,  376,  376,
+        0,  380,  385,  378,  379,  377,  377,  377,  380,  378,
+      378,  378,  382,  379,  379,  379,  381,    0,  383,  383,
+      383,  384,    0,  385,  385,  385,  386,  382,  380,  380,
+      380,  386,  387,    0,  381,  384,  389,    0,    0,  382,
+
+      382,  382,  390,  381,  381,  381,  391,    0,  384,  384,
+      384,  387,  391,  386,  386,  386,  392,  395,    0,  387,
+      387,  387,  392,  389,  389,  389,  396,  393,    0,  390,
+      390,  390,  394,  391,  391,  391,    0,  397,  394,    0,
+      395,    0,    0,  392,  392,  392,  393,    0,  396,    0,
+        0,  399,  400,    0,  393,  393,  393,  397,  398,  394,
+      394,  394,  398,  401,  397,  397,  397,  395,  395,  395,
+      399,  400,    0,  404,  402,  396,  396,  396,  399,  399,
+      399,    0,  401,  405,    0,  398,  398,  398,  403,  407,
+      401,  401,  401,  405,  406,    0,  402,  404,  400,  400,
+
+      400,  402,  402,  402,    0,  406,    0,  403,  407,    0,
+      405,  405,  405,  409,    0,  403,  403,  403,  411,  409,
+      411,  406,  406,  406,  404,  404,  404,  410,    0,    0,
+        0,  413,    0,  410,  414,  407,  407,  407,  415,    0,
+      409,  409,  409,  413,  415,    0,  416,  411,  411,  411,
+      417,    0,    0,  414,  410,  410,  410,  419,  413,  413,
+      413,  414,  414,  414,  416,  415,  415,  415,    0,  417,
+      418,    0,  419,  416,  416,  416,  420,  417,  417,  417,
+      418,    0,    0,    0,  419,  419,  419,    0,    0,    0,
+      420,    0,    0,    0,    0,    0,    0,  418,  418,  418,
+
+        0,    0,    0,  420,  420,  420,  422,  422,  422,  422,
+      422,  422,  422,  422,  422,  422,  422,  422,  422,  422,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  424,  424,  424,  424,  424,  424,
+      424,  424,  424,  424,  424,  424,  424,  424,  425,  425,
+      425,  425,  425,  425,  425,  425,  425,  425,  425,  425,
+      425,  425,  426,    0,  426,    0,  426,    0,  426,  427,
+        0,    0,  427,    0,  427,  427,  427,  427,  427,  428,
+      428,    0,  428,  428,  428,  428,  428,  428,  429,  429,
+      429,  429,  429,  429,  429,  429,  429,  429,  429,  429,
+
+      429,  429,  430,  430,  430,  430,  430,  430,  430,  430,
+      430,  430,  430,  430,  430,  431,    0,  431,  431,  431,
+      431,  431,  431,  431,  431,  431,  431,  431,  431,  432,
+        0,  432,  432,  432,  432,  432,  432,  432,  432,  432,
+      432,  432,  432,  433,  433,  433,  433,  433,  433,  433,
+      433,  433,  434,  434,  434,  435,    0,    0,    0,    0,
+      435,  435,  435,  436,  436,  436,  436,  436,  437,  437,
+      437,    0,    0,  437,  438,  438,  438,  439,  439,  439,
+      439,  439,  439,  439,  439,  439,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421
     } ;
 
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
 
-extern int ncg_flex_debug;
-int ncg_flex_debug = 0;
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1153,7 +1378,7 @@ int ncg_flex_debug = 0;
 #define yymore() yymore_used_but_not_detected
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
-char *ncgtext;
+char *yytext;
 #line 1 "ncgen.l"
 #line 2 "ncgen.l"
 /*********************************************************************
@@ -1289,10 +1514,11 @@ struct Specialtoken specials[] = {
 {"_NCProperties",_NCPROPS,_NCPROPS_FLAG},
 {"_IsNetcdf4",_ISNETCDF4,_ISNETCDF4_FLAG},
 {"_SuperblockVersion",_SUPERBLOCK,_SUPERBLOCK_FLAG},
+{"_Filter",_FILTER,_FILTER_FLAG},
 {NULL,0} /* null terminate */
 };
 
-
+#line 1521 "ncgenl.c"
 
 /* The most correct (validating) version of UTF8 character set
    (Taken from: http://www.w3.org/2005/03/23-lex-U)
@@ -1335,7 +1561,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 1339 "lex.ncg.c"
+#line 1564 "ncgenl.c"
 
 #define INITIAL 0
 #define ST_C_COMMENT 1
@@ -1353,36 +1579,36 @@ ID ([A-Za-z_]|{UTF8})([A-Z.@#\[\]a-z_0-9+-]|{UTF8})*
 #define YY_EXTRA_TYPE void *
 #endif
 
-static int yy_init_globals (void );
+static int yy_init_globals ( void );
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int ncglex_destroy (void );
+int yylex_destroy ( void );
 
-int ncgget_debug (void );
+int yyget_debug ( void );
 
-void ncgset_debug (int debug_flag  );
+void yyset_debug ( int debug_flag  );
 
-YY_EXTRA_TYPE ncgget_extra (void );
+YY_EXTRA_TYPE yyget_extra ( void );
 
-void ncgset_extra (YY_EXTRA_TYPE user_defined  );
+void yyset_extra ( YY_EXTRA_TYPE user_defined  );
 
-FILE *ncgget_in (void );
+FILE *yyget_in ( void );
 
-void ncgset_in  (FILE * _in_str  );
+void yyset_in  ( FILE * _in_str  );
 
-FILE *ncgget_out (void );
+FILE *yyget_out ( void );
 
-void ncgset_out  (FILE * _out_str  );
+void yyset_out  ( FILE * _out_str  );
 
-yy_size_t ncgget_leng (void );
+			int yyget_leng ( void );
 
-char *ncgget_text (void );
+char *yyget_text ( void );
 
-int ncgget_lineno (void );
+int yyget_lineno ( void );
 
-void ncgset_lineno (int _line_number  );
+void yyset_lineno ( int _line_number  );
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1390,32 +1616,31 @@ void ncgset_lineno (int _line_number  );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int ncgwrap (void );
+extern "C" int yywrap ( void );
 #else
-extern int ncgwrap (void );
+extern int yywrap ( void );
 #endif
 #endif
 
 #ifndef YY_NO_UNPUT
     
-    static void yyunput (int c,char *buf_ptr  );
+    static void yyunput ( int c, char *buf_ptr  );
     
 #endif
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
+static void yy_flex_strncpy ( char *, const char *, int );
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
+static int yy_flex_strlen ( const char * );
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (void );
+static int yyinput ( void );
 #else
-static int input (void );
+static int input ( void );
 #endif
 
 #endif
@@ -1435,7 +1660,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 do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -1446,20 +1671,20 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		int n; \
 		for ( n = 0; n < max_size && \
-			     (c = getc( ncgin )) != EOF && c != '\n'; ++n ) \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
 		if ( c == '\n' ) \
 			buf[n++] = (char) c; \
-		if ( c == EOF && ferror( ncgin ) ) \
+		if ( c == EOF && ferror( yyin ) ) \
 			YY_FATAL_ERROR( "input in flex scanner failed" ); \
 		result = n; \
 		} \
 	else \
 		{ \
 		errno=0; \
-		while ( (result = fread(buf, 1, max_size, ncgin))==0 && ferror(ncgin)) \
+		while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
 			{ \
 			if( errno != EINTR) \
 				{ \
@@ -1467,7 +1692,7 @@ static int input (void );
 				break; \
 				} \
 			errno=0; \
-			clearerr(ncgin); \
+			clearerr(yyin); \
 			} \
 		}\
 \
@@ -1500,12 +1725,12 @@ static int input (void );
 #ifndef YY_DECL
 #define YY_DECL_IS_OURS 1
 
-extern int ncglex (void);
+extern int yylex (void);
 
-#define YY_DECL int ncglex (void)
+#define YY_DECL int yylex (void)
 #endif /* !YY_DECL */
 
-/* Code executed at the beginning of each rule, after ncgtext and ncgleng
+/* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
  */
 #ifndef YY_USER_ACTION
@@ -1539,31 +1764,31 @@ YY_DECL
 		if ( ! (yy_start) )
 			(yy_start) = 1;	/* first start state */
 
-		if ( ! ncgin )
-			ncgin = stdin;
+		if ( ! yyin )
+			yyin = stdin;
 
-		if ( ! ncgout )
-			ncgout = stdout;
+		if ( ! yyout )
+			yyout = stdout;
 
 		if ( ! YY_CURRENT_BUFFER ) {
-			ncgensure_buffer_stack ();
+			yyensure_buffer_stack ();
 			YY_CURRENT_BUFFER_LVALUE =
-				ncg_create_buffer(ncgin,YY_BUF_SIZE );
+				yy_create_buffer( yyin, YY_BUF_SIZE );
 		}
 
-		ncg_load_buffer_state( );
+		yy_load_buffer_state(  );
 		}
 
 	{
-#line 217 "ncgen.l"
+#line 218 "ncgen.l"
 
-#line 1561 "lex.ncg.c"
+#line 1785 "ncgenl.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
 		yy_cp = (yy_c_buf_p);
 
-		/* Support of ncgtext. */
+		/* Support of yytext. */
 		*yy_cp = (yy_hold_char);
 
 		/* yy_bp points to the position in yy_ch_buf of the start of
@@ -1584,13 +1809,13 @@ 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 >= 417 )
-					yy_c = yy_meta[(unsigned int) yy_c];
+				if ( yy_current_state >= 422 )
+					yy_c = yy_meta[yy_c];
 				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 2347 );
+		while ( yy_base[yy_current_state] != 2387 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -1616,14 +1841,14 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 218 "ncgen.l"
+#line 219 "ncgen.l"
 { /* whitespace */
 		  break;
 		}
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 222 "ncgen.l"
+#line 223 "ncgen.l"
 { /* comment */
                           break;
                         }
@@ -1631,24 +1856,24 @@ YY_RULE_SETUP
 case 3:
 /* rule 3 can match eol */
 YY_RULE_SETUP
-#line 226 "ncgen.l"
+#line 227 "ncgen.l"
 {int len;
 			 /* In netcdf4, this will be used in a variety
                             of places, so only remove escapes */
 /*
-if(ncgleng > MAXTRST) {
+if(yyleng > MAXTRST) {
 yyerror("string too long, truncated\n");
-ncgtext[MAXTRST-1] = '\0';
+yytext[MAXTRST-1] = '\0';
 }
 */
 		        /* FIX: Assumes unescape also does normalization */
-			bbSetalloc(lextext,ncgleng+1); /*+1 for nul */
+			bbSetalloc(lextext,yyleng+1); /*+1 for nul */
 			/* Adjust length */
-		        bbSetlength(lextext,ncgleng-2); /*-2 for quotes */
+		        bbSetlength(lextext,yyleng-2); /*-2 for quotes */
 			len = unescape(bbContents(lextext),
-                                       (char *)ncgtext+1,ncgleng-2,!ISIDENT);
+                                       (char *)yytext+1,yyleng-2,!ISIDENT);
 			if(len < 0) {
-			    sprintf(errstr,"Illegal character: %s",ncgtext);
+			    sprintf(errstr,"Illegal character: %s",yytext);
 			    yyerror(errstr);
 			}
 			bbSetlength(lextext,len);
@@ -1658,10 +1883,10 @@ ncgtext[MAXTRST-1] = '\0';
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 250 "ncgen.l"
+#line 251 "ncgen.l"
 { /* drop leading 0x; pad to even number of chars */
-		char* p = ncgtext+2;
-		int len = ncgleng - 2;
+		char* p = yytext+2;
+		int len = yyleng - 2;
 		bbClear(lextext);
 	        bbAppendn(lextext,p,len);
 	        if((len % 2) == 1) bbAppend(lextext,'0');
@@ -1673,115 +1898,120 @@ YY_RULE_SETUP
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 262 "ncgen.l"
+#line 263 "ncgen.l"
 {return lexdebug(COMPOUND);}
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 263 "ncgen.l"
+#line 264 "ncgen.l"
 {return lexdebug(ENUM);}
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 264 "ncgen.l"
+#line 265 "ncgen.l"
 {return lexdebug(OPAQUE_);}
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 266 "ncgen.l"
+#line 267 "ncgen.l"
 {return lexdebug(FLOAT_K);}
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 267 "ncgen.l"
+#line 268 "ncgen.l"
 {return lexdebug(CHAR_K);}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 268 "ncgen.l"
+#line 269 "ncgen.l"
 {return lexdebug(BYTE_K);}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 269 "ncgen.l"
+#line 270 "ncgen.l"
 {return lexdebug(UBYTE_K);}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 270 "ncgen.l"
+#line 271 "ncgen.l"
 {return lexdebug(SHORT_K);}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 271 "ncgen.l"
+#line 272 "ncgen.l"
 {return lexdebug(USHORT_K);}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 272 "ncgen.l"
+#line 273 "ncgen.l"
 {return lexdebug(INT_K);}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 273 "ncgen.l"
+#line 274 "ncgen.l"
 {return lexdebug(UINT_K);}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 274 "ncgen.l"
+#line 275 "ncgen.l"
 {return lexdebug(INT64_K);}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 275 "ncgen.l"
+#line 276 "ncgen.l"
 {return lexdebug(UINT64_K);}
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 276 "ncgen.l"
+#line 277 "ncgen.l"
 {return lexdebug(DOUBLE_K);}
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 277 "ncgen.l"
-{int32_val = -1;
-			 return lexdebug(NC_UNLIMITED_K);}
+#line 278 "ncgen.l"
+{return lexdebug(STRING_K);}
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
 #line 280 "ncgen.l"
-{return lexdebug(TYPES);}
+{int32_val = -1;
+			 return lexdebug(NC_UNLIMITED_K);}
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 281 "ncgen.l"
-{return lexdebug(DIMENSIONS);}
+#line 283 "ncgen.l"
+{return lexdebug(TYPES);}
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 282 "ncgen.l"
-{return lexdebug(VARIABLES);}
+#line 284 "ncgen.l"
+{return lexdebug(DIMENSIONS);}
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 283 "ncgen.l"
-{return lexdebug(DATA);}
+#line 285 "ncgen.l"
+{return lexdebug(VARIABLES);}
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 284 "ncgen.l"
-{return lexdebug(GROUP);}
+#line 286 "ncgen.l"
+{return lexdebug(DATA);}
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 286 "ncgen.l"
-{BEGIN(TEXT);return lexdebug(NETCDF);}
+#line 287 "ncgen.l"
+{return lexdebug(GROUP);}
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 288 "ncgen.l"
+#line 289 "ncgen.l"
+{BEGIN(TEXT);return lexdebug(NETCDF);}
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 291 "ncgen.l"
 { /* missing value (pre-2.4 backward compatibility) */
-                if (ncgtext[0] == '-') {
+                if (yytext[0] == '-') {
 		    double_val = NEGNC_INFINITE;
                 } else {
 		    double_val = NC_INFINITE;
@@ -1790,20 +2020,20 @@ YY_RULE_SETUP
 		return lexdebug(DOUBLE_CONST);
 		}
 	YY_BREAK
-case 27:
+case 28:
 YY_RULE_SETUP
-#line 297 "ncgen.l"
+#line 300 "ncgen.l"
 { /* missing value (pre-2.4 backward compatibility) */
 		double_val = NAN;
 		specialconstants = 1;
 		return lexdebug(DOUBLE_CONST);
 		}
 	YY_BREAK
-case 28:
+case 29:
 YY_RULE_SETUP
-#line 303 "ncgen.l"
+#line 306 "ncgen.l"
 {/* missing value (pre-2.4 backward compatibility)*/
-                if (ncgtext[0] == '-') {
+                if (yytext[0] == '-') {
 		    float_val = NEGNC_INFINITEF;
                 } else {
 		    float_val = NC_INFINITEF;
@@ -1812,18 +2042,18 @@ YY_RULE_SETUP
 		return lexdebug(FLOAT_CONST);
 		}
 	YY_BREAK
-case 29:
+case 30:
 YY_RULE_SETUP
-#line 312 "ncgen.l"
+#line 315 "ncgen.l"
 { /* missing value (pre-2.4 backward compatibility) */
 		float_val = NANF;
 		specialconstants = 1;
 		return lexdebug(FLOAT_CONST);
 		}
 	YY_BREAK
-case 30:
+case 31:
 YY_RULE_SETUP
-#line 318 "ncgen.l"
+#line 321 "ncgen.l"
 {
 #ifdef USE_NETCDF4
 		if(l_flag == L_C || l_flag == L_BINARY)
@@ -1834,23 +2064,23 @@ YY_RULE_SETUP
 #endif
 		}
 	YY_BREAK
-case 31:
+case 32:
 YY_RULE_SETUP
-#line 328 "ncgen.l"
+#line 331 "ncgen.l"
 {
 		bbClear(lextext);
-		bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
+		bbAppendn(lextext,(char*)yytext,yyleng+1); /* include null */
 	        bbNull(lextext);
 		yylval.sym = makepath(bbContents(lextext));
 		return lexdebug(PATH);
 		}
 	YY_BREAK
-case 32:
+case 33:
 YY_RULE_SETUP
-#line 337 "ncgen.l"
+#line 340 "ncgen.l"
 {struct Specialtoken* st;
 		bbClear(lextext);
-		bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
+		bbAppendn(lextext,(char*)yytext,yyleng+1); /* include null */
 		bbNull(lextext);
 		for(st=specials;st->name;st++) {
 		    if(strcmp(bbContents(lextext),st->name)==0) {return lexdebug(st->token);}
@@ -1858,32 +2088,33 @@ YY_RULE_SETUP
 		return 0;
 		}
 	YY_BREAK
-case 33:
-/* rule 33 can match eol */
+case 34:
+/* rule 34 can match eol */
 YY_RULE_SETUP
-#line 347 "ncgen.l"
+#line 350 "ncgen.l"
 {
 		    int c;
 		    char* p; char* q;
 		    /* copy the trimmed name */
 		    bbClear(lextext);
-		    bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
+		    bbAppendn(lextext,(char*)yytext,yyleng+1); /* include null */
 		    bbNull(lextext);
 		    p = bbContents(lextext);
 		    q = p;
 		    while((c=*p++)) {if(c > ' ') *q++ = c;}
 		    *q = '\0';
-		    datasetname = bbDup(lextext);
+		    if(datasetname == NULL)
+		        datasetname = bbDup(lextext);
 		    BEGIN(INITIAL);
 		    return lexdebug(DATASETID);
 		}
 	YY_BREAK
-case 34:
+case 35:
 YY_RULE_SETUP
-#line 363 "ncgen.l"
+#line 367 "ncgen.l"
 { char* id; int len;
 		    bbClear(lextext);
-		    bbAppendn(lextext,(char*)ncgtext,ncgleng+1); /* include null */
+		    bbAppendn(lextext,(char*)yytext,yyleng+1); /* include null */
 		    bbNull(lextext);
 		    id = bbContents(lextext);
 		    len = unescape(id,id,bbLength(lextext),ISIDENT);
@@ -1893,9 +2124,9 @@ YY_RULE_SETUP
 		    return lexdebug(IDENT);
 		}
 	YY_BREAK
-case 35:
+case 36:
 YY_RULE_SETUP
-#line 375 "ncgen.l"
+#line 379 "ncgen.l"
 {
 		/*
 		  We need to try to see what size of integer ((u)int).
@@ -1905,7 +2136,6 @@ YY_RULE_SETUP
 		    int slen = strlen(ncgtext);
 		    char* stag = NULL;
 		    int tag = NC_NAT;
-		    int signchar = 0;
 		    int isneg = 0;
 		    int c = ncgtext[0];
 		    int fail = 0;
@@ -1962,27 +2192,27 @@ YY_RULE_SETUP
 done: return 0;
 	    }
 	YY_BREAK
-case 36:
+case 37:
 YY_RULE_SETUP
-#line 441 "ncgen.l"
+#line 444 "ncgen.l"
 {
 		int c;
 		int token = 0;
-		int slen = strlen(ncgtext);
+		int slen = strlen(yytext);
 		char* stag = NULL;
 	        int tag = NC_NAT;
-		char* hex = ncgtext+2; /* point to first true hex digit */
+		char* hex = yytext+2; /* point to first true hex digit */
 		int xlen = (slen - 3);  /* true hex length */
 
-		ncgtext[slen-1] = '\0';
+		yytext[slen-1] = '\0';
 	        /* capture the tag string */
-		tag = collecttag(ncgtext,&stag);
+		tag = collecttag(yytext,&stag);
 		if(tag == NC_NAT) {
 		    sprintf(errstr,"Illegal integer suffix: %s",stag);
 		    yyerror(errstr);
 		    goto done;
 		}
-		ncgtext[slen - strlen(stag)] = '\0';
+		yytext[slen - strlen(stag)] = '\0';
 	        if(xlen > 16) { /* truncate hi order digits */
 		    hex += (xlen - 16);
 		}
@@ -2004,8 +2234,8 @@ YY_RULE_SETUP
 		    token = UINT64_CONST;
 		    break;
 		default: /* should never happen */
-		    if (sscanf((char*)ncgtext, "%i", &uint32_val) != 1) {
-		        sprintf(errstr,"bad unsigned int constant: %s",(char*)ncgtext);
+		    if (sscanf((char*)yytext, "%i", &uint32_val) != 1) {
+		        sprintf(errstr,"bad unsigned int constant: %s",(char*)yytext);
 		        yyerror(errstr);
 		    }
 		    token = UINT_CONST;
@@ -2013,68 +2243,68 @@ YY_RULE_SETUP
 		return lexdebug(token);
 	    }
 	YY_BREAK
-case 37:
+case 38:
 YY_RULE_SETUP
-#line 488 "ncgen.l"
+#line 491 "ncgen.l"
 {
-		if (sscanf((char*)ncgtext, "%le", &double_val) != 1) {
-		    sprintf(errstr,"bad long or double constant: %s",(char*)ncgtext);
+		if (sscanf((char*)yytext, "%le", &double_val) != 1) {
+		    sprintf(errstr,"bad long or double constant: %s",(char*)yytext);
 		    yyerror(errstr);
 		}
                 return lexdebug(DOUBLE_CONST);
                 }
 	YY_BREAK
-case 38:
+case 39:
 YY_RULE_SETUP
-#line 495 "ncgen.l"
+#line 498 "ncgen.l"
 {
-		if (sscanf((char*)ncgtext, "%e", &float_val) != 1) {
-		    sprintf(errstr,"bad float constant: %s",(char*)ncgtext);
+		if (sscanf((char*)yytext, "%e", &float_val) != 1) {
+		    sprintf(errstr,"bad float constant: %s",(char*)yytext);
 		    yyerror(errstr);
 		}
                 return lexdebug(FLOAT_CONST);
                 }
 	YY_BREAK
-case 39:
-/* rule 39 can match eol */
+case 40:
+/* rule 40 can match eol */
 YY_RULE_SETUP
-#line 502 "ncgen.l"
+#line 505 "ncgen.l"
 {
-	        (void) sscanf((char*)&ncgtext[1],"%c",&byte_val);
+	        (void) sscanf((char*)&yytext[1],"%c",&byte_val);
 		return lexdebug(BYTE_CONST);
                 }
 	YY_BREAK
-case 40:
+case 41:
 YY_RULE_SETUP
-#line 506 "ncgen.l"
+#line 509 "ncgen.l"
 {
-		int oct = unescapeoct(&ncgtext[2]);
+		int oct = unescapeoct(&yytext[2]);
 		if(oct < 0) {
-		    sprintf(errstr,"bad octal character constant: %s",(char*)ncgtext);
+		    sprintf(errstr,"bad octal character constant: %s",(char*)yytext);
 		    yyerror(errstr);
 		}
 	        byte_val = (unsigned int)oct;
 		return lexdebug(BYTE_CONST);
                 }
 	YY_BREAK
-case 41:
+case 42:
 YY_RULE_SETUP
-#line 515 "ncgen.l"
+#line 518 "ncgen.l"
 {
-		int hex = unescapehex(&ncgtext[3]);
+		int hex = unescapehex(&yytext[3]);
 		if(byte_val < 0) {
-		    sprintf(errstr,"bad hex character constant: %s",(char*)ncgtext);
+		    sprintf(errstr,"bad hex character constant: %s",(char*)yytext);
 		    yyerror(errstr);
 		}
 		byte_val = (unsigned int)hex;
 		return lexdebug(BYTE_CONST);
                 }
 	YY_BREAK
-case 42:
+case 43:
 YY_RULE_SETUP
-#line 524 "ncgen.l"
+#line 527 "ncgen.l"
 {
-	       switch ((char)ncgtext[2]) {
+	       switch ((char)yytext[2]) {
 	          case 'a': byte_val = '\007'; break; /* not everyone under-
 						       * stands '\a' yet */
      	          case 'b': byte_val = '\b'; break;
@@ -2086,65 +2316,65 @@ YY_RULE_SETUP
 		  case '\\': byte_val = '\\'; break;
 		  case '?': byte_val = '\177'; break;
 		  case '\'': byte_val = '\''; break;
-		  default: byte_val = (char)ncgtext[2];
+		  default: byte_val = (char)yytext[2];
 	           }
 		return lexdebug(BYTE_CONST);
                 }
 	YY_BREAK
-case 43:
-/* rule 43 can match eol */
+case 44:
+/* rule 44 can match eol */
 YY_RULE_SETUP
-#line 542 "ncgen.l"
+#line 545 "ncgen.l"
 {
 		lineno++ ;
                 break;
 		}
 	YY_BREAK
-case 44:
+case 45:
 YY_RULE_SETUP
-#line 547 "ncgen.l"
+#line 550 "ncgen.l"
 {/*initial*/
 	    BEGIN(ST_C_COMMENT);
 	    break;
 	}
 	YY_BREAK
-case 45:
-/* rule 45 can match eol */
+case 46:
+/* rule 46 can match eol */
 YY_RULE_SETUP
-#line 552 "ncgen.l"
+#line 555 "ncgen.l"
 {/* continuation */
 				     break;
 				}
 	YY_BREAK
-case 46:
+case 47:
 YY_RULE_SETUP
-#line 556 "ncgen.l"
+#line 559 "ncgen.l"
 {/* final */
 			    BEGIN(INITIAL);
 			    break;
 			}
 	YY_BREAK
 case YY_STATE_EOF(ST_C_COMMENT):
-#line 561 "ncgen.l"
+#line 564 "ncgen.l"
 {/* final, error */
 			    fprintf(stderr,"unterminated /**/ comment");
 			    BEGIN(INITIAL);
 			    break;
 			}
 	YY_BREAK
-case 47:
+case 48:
 YY_RULE_SETUP
-#line 567 "ncgen.l"
+#line 570 "ncgen.l"
 {/* Note: this next rule will not work for UTF8 characters */
-		return lexdebug(ncgtext[0]) ;
+		return lexdebug(yytext[0]) ;
 		}
 	YY_BREAK
-case 48:
+case 49:
 YY_RULE_SETUP
-#line 570 "ncgen.l"
+#line 573 "ncgen.l"
 ECHO;
 	YY_BREAK
-#line 2148 "lex.ncg.c"
+#line 2377 "ncgenl.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(TEXT):
 	yyterminate();
@@ -2162,15 +2392,15 @@ case YY_STATE_EOF(TEXT):
 			{
 			/* We're scanning a new file or input source.  It's
 			 * possible that this happened because the user
-			 * just pointed ncgin at a new source and called
-			 * ncglex().  If so, then we have to assure
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
 			 * consistency between YY_CURRENT_BUFFER and our
 			 * globals.  Here is the right place to do so, because
 			 * this is the first action (other than possibly a
 			 * back-up) that will match for the new input source.
 			 */
 			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-			YY_CURRENT_BUFFER_LVALUE->yy_input_file = ncgin;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
 			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
 			}
 
@@ -2223,11 +2453,11 @@ case YY_STATE_EOF(TEXT):
 				{
 				(yy_did_buffer_switch_on_eof) = 0;
 
-				if ( ncgwrap( ) )
+				if ( yywrap(  ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
-					 * ncgtext, we can now set up
+					 * yytext, we can now set up
 					 * yy_c_buf_p so that if some total
 					 * hoser (like flex itself) wants to
 					 * call the scanner after we return the
@@ -2277,7 +2507,7 @@ case YY_STATE_EOF(TEXT):
 	} /* end of action switch */
 		} /* end of scanning one token */
 	} /* end of user's declarations */
-} /* end of ncglex */
+} /* end of yylex */
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -2290,7 +2520,7 @@ static int yy_get_next_buffer (void)
 {
     	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	char *source = (yytext_ptr);
-	yy_size_t number_to_move, i;
+	int number_to_move, i;
 	int ret_val;
 
 	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@@ -2319,7 +2549,7 @@ static int yy_get_next_buffer (void)
 	/* Try to read more data. */
 
 	/* First move last chars to start of buffer. */
-	number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
 
 	for ( i = 0; i < number_to_move; ++i )
 		*(dest++) = *(source++);
@@ -2332,7 +2562,7 @@ static int yy_get_next_buffer (void)
 
 	else
 		{
-			yy_size_t num_to_read =
+			int num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -2346,7 +2576,7 @@ static int yy_get_next_buffer (void)
 
 			if ( b->yy_is_our_buffer )
 				{
-				yy_size_t new_size = b->yy_buf_size * 2;
+				int new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -2355,11 +2585,12 @@ static int yy_get_next_buffer (void)
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					ncgrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+					yyrealloc( (void *) b->yy_ch_buf,
+							 (yy_size_t) (b->yy_buf_size + 2)  );
 				}
 			else
 				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
+				b->yy_ch_buf = NULL;
 
 			if ( ! b->yy_ch_buf )
 				YY_FATAL_ERROR(
@@ -2387,7 +2618,7 @@ static int yy_get_next_buffer (void)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			ncgrestart(ncgin  );
+			yyrestart( yyin  );
 			}
 
 		else
@@ -2401,12 +2632,15 @@ static int yy_get_next_buffer (void)
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ncgrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+			(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+		/* "- 2" to take care of EOB's */
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
 	}
 
 	(yy_n_chars) += number_to_move;
@@ -2438,10 +2672,10 @@ 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 >= 417 )
-				yy_c = yy_meta[(unsigned int) yy_c];
+			if ( yy_current_state >= 422 )
+				yy_c = yy_meta[yy_c];
 			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 		}
 
 	return yy_current_state;
@@ -2466,11 +2700,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 >= 417 )
-			yy_c = yy_meta[(unsigned int) yy_c];
+		if ( yy_current_state >= 422 )
+			yy_c = yy_meta[yy_c];
 		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 416);
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+	yy_is_jam = (yy_current_state == 421);
 
 		return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2483,13 +2717,13 @@ static int yy_get_next_buffer (void)
     
     yy_cp = (yy_c_buf_p);
 
-	/* undo effects of setting up ncgtext */
+	/* undo effects of setting up yytext */
 	*yy_cp = (yy_hold_char);
 
 	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
 		{ /* need to shift things up to make room */
 		/* +2 for EOB chars. */
-		yy_size_t number_to_move = (yy_n_chars) + 2;
+		int number_to_move = (yy_n_chars) + 2;
 		char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
 					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
 		char *source =
@@ -2501,7 +2735,7 @@ static int yy_get_next_buffer (void)
 		yy_cp += (int) (dest - source);
 		yy_bp += (int) (dest - source);
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+			(yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
 
 		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
 			YY_FATAL_ERROR( "flex scanner push-back overflow" );
@@ -2540,7 +2774,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+			int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -2557,14 +2791,14 @@ static int yy_get_next_buffer (void)
 					 */
 
 					/* Reset buffer status. */
-					ncgrestart(ncgin );
+					yyrestart( yyin );
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( ncgwrap( ) )
-						return EOF;
+					if ( yywrap(  ) )
+						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
@@ -2583,7 +2817,7 @@ static int yy_get_next_buffer (void)
 		}
 
 	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve ncgtext */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
 	(yy_hold_char) = *++(yy_c_buf_p);
 
 	return c;
@@ -2595,32 +2829,32 @@ static int yy_get_next_buffer (void)
  * 
  * @note This function does not reset the start condition to @c INITIAL .
  */
-    void ncgrestart  (FILE * input_file )
+    void yyrestart  (FILE * input_file )
 {
     
 	if ( ! YY_CURRENT_BUFFER ){
-        ncgensure_buffer_stack ();
+        yyensure_buffer_stack ();
 		YY_CURRENT_BUFFER_LVALUE =
-            ncg_create_buffer(ncgin,YY_BUF_SIZE );
+            yy_create_buffer( yyin, YY_BUF_SIZE );
 	}
 
-	ncg_init_buffer(YY_CURRENT_BUFFER,input_file );
-	ncg_load_buffer_state( );
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_load_buffer_state(  );
 }
 
 /** Switch to a different input buffer.
  * @param new_buffer The new input buffer.
  * 
  */
-    void ncg_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
 {
     
 	/* TODO. We should be able to replace this entire function body
 	 * with
-	 *		ncgpop_buffer_state();
-	 *		ncgpush_buffer_state(new_buffer);
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
      */
-	ncgensure_buffer_stack ();
+	yyensure_buffer_stack ();
 	if ( YY_CURRENT_BUFFER == new_buffer )
 		return;
 
@@ -2633,21 +2867,21 @@ static int yy_get_next_buffer (void)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	ncg_load_buffer_state( );
+	yy_load_buffer_state(  );
 
 	/* We don't actually know whether we did this switch during
-	 * EOF (ncgwrap()) processing, but the only time this flag
-	 * is looked at is after ncgwrap() is called, so it's safe
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
 	 * to go ahead and always set it.
 	 */
 	(yy_did_buffer_switch_on_eof) = 1;
 }
 
-static void ncg_load_buffer_state  (void)
+static void yy_load_buffer_state  (void)
 {
     	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
 	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-	ncgin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
 	(yy_hold_char) = *(yy_c_buf_p);
 }
 
@@ -2657,35 +2891,35 @@ static void ncg_load_buffer_state  (void)
  * 
  * @return the allocated buffer state.
  */
-    YY_BUFFER_STATE ncg_create_buffer  (FILE * file, int  size )
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) ncgalloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
 	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in ncg_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
-	b->yy_buf_size = (yy_size_t)size;
+	b->yy_buf_size = size;
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
 	 */
-	b->yy_ch_buf = (char *) ncgalloc(b->yy_buf_size + 2  );
+	b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2)  );
 	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in ncg_create_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	ncg_init_buffer(b,file );
+	yy_init_buffer( b, file );
 
 	return b;
 }
 
 /** Destroy the buffer.
- * @param b a buffer created with ncg_create_buffer()
+ * @param b a buffer created with yy_create_buffer()
  * 
  */
-    void ncg_delete_buffer (YY_BUFFER_STATE  b )
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
 {
     
 	if ( ! b )
@@ -2695,27 +2929,27 @@ static void ncg_load_buffer_state  (void)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		ncgfree((void *) b->yy_ch_buf  );
+		yyfree( (void *) b->yy_ch_buf  );
 
-	ncgfree((void *) b  );
+	yyfree( (void *) b  );
 }
 
 /* Initializes or reinitializes a buffer.
  * This function is sometimes called more than once on the same buffer,
- * such as during a ncgrestart() or at EOF.
+ * such as during a yyrestart() or at EOF.
  */
-    static void ncg_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
 
 {
 	int oerrno = errno;
     
-	ncg_flush_buffer(b );
+	yy_flush_buffer( b );
 
 	b->yy_input_file = file;
 	b->yy_fill_buffer = 1;
 
-    /* If b is the current buffer, then ncg_init_buffer was _probably_
-     * called from ncgrestart() or through yy_get_next_buffer.
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
      * In that case, we don't want to reset the lineno or column.
      */
     if (b != YY_CURRENT_BUFFER){
@@ -2732,7 +2966,7 @@ static void ncg_load_buffer_state  (void)
  * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
  * 
  */
-    void ncg_flush_buffer (YY_BUFFER_STATE  b )
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
 {
     	if ( ! b )
 		return;
@@ -2752,7 +2986,7 @@ static void ncg_load_buffer_state  (void)
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		ncg_load_buffer_state( );
+		yy_load_buffer_state(  );
 }
 
 /** Pushes the new state onto the stack. The new state becomes
@@ -2761,14 +2995,14 @@ static void ncg_load_buffer_state  (void)
  *  @param new_buffer The new state.
  *  
  */
-void ncgpush_buffer_state (YY_BUFFER_STATE new_buffer )
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
 {
     	if (new_buffer == NULL)
 		return;
 
-	ncgensure_buffer_stack();
+	yyensure_buffer_stack();
 
-	/* This block is copied from ncg_switch_to_buffer. */
+	/* This block is copied from yy_switch_to_buffer. */
 	if ( YY_CURRENT_BUFFER )
 		{
 		/* Flush out information for old buffer. */
@@ -2782,8 +3016,8 @@ void ncgpush_buffer_state (YY_BUFFER_STATE new_buffer )
 		(yy_buffer_stack_top)++;
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
-	/* copied from ncg_switch_to_buffer. */
-	ncg_load_buffer_state( );
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(  );
 	(yy_did_buffer_switch_on_eof) = 1;
 }
 
@@ -2791,18 +3025,18 @@ void ncgpush_buffer_state (YY_BUFFER_STATE new_buffer )
  *  The next element becomes the new top.
  *  
  */
-void ncgpop_buffer_state (void)
+void yypop_buffer_state (void)
 {
     	if (!YY_CURRENT_BUFFER)
 		return;
 
-	ncg_delete_buffer(YY_CURRENT_BUFFER );
+	yy_delete_buffer(YY_CURRENT_BUFFER );
 	YY_CURRENT_BUFFER_LVALUE = NULL;
 	if ((yy_buffer_stack_top) > 0)
 		--(yy_buffer_stack_top);
 
 	if (YY_CURRENT_BUFFER) {
-		ncg_load_buffer_state( );
+		yy_load_buffer_state(  );
 		(yy_did_buffer_switch_on_eof) = 1;
 	}
 }
@@ -2810,7 +3044,7 @@ void ncgpop_buffer_state (void)
 /* Allocates the stack if it does not exist.
  *  Guarantees space for at least one push.
  */
-static void ncgensure_buffer_stack (void)
+static void yyensure_buffer_stack (void)
 {
 	yy_size_t num_to_alloc;
     
@@ -2820,15 +3054,15 @@ static void ncgensure_buffer_stack (void)
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * immediate realloc on the next call.
          */
-		num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
-		(yy_buffer_stack) = (struct yy_buffer_state**)ncgalloc
+      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ncgensure_buffer_stack()" );
-								  
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-				
+
 		(yy_buffer_stack_max) = num_to_alloc;
 		(yy_buffer_stack_top) = 0;
 		return;
@@ -2840,12 +3074,12 @@ static void ncgensure_buffer_stack (void)
 		yy_size_t grow_size = 8 /* arbitrary grow size */;
 
 		num_to_alloc = (yy_buffer_stack_max) + grow_size;
-		(yy_buffer_stack) = (struct yy_buffer_state**)ncgrealloc
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in ncgensure_buffer_stack()" );
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
 		/* zero only the new slots.*/
 		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -2857,9 +3091,9 @@ static void ncgensure_buffer_stack (void)
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * 
- * @return the newly allocated buffer state object. 
+ * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE ncg_scan_buffer  (char * base, yy_size_t  size )
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 {
 	YY_BUFFER_STATE b;
     
@@ -2867,69 +3101,69 @@ YY_BUFFER_STATE ncg_scan_buffer  (char * base, yy_size_t  size )
 	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
 	     base[size-1] != YY_END_OF_BUFFER_CHAR )
 		/* They forgot to leave room for the EOB's. */
-		return 0;
+		return NULL;
 
-	b = (YY_BUFFER_STATE) ncgalloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
 	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in ncg_scan_buffer()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_size = (int) (size - 2);	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
+	b->yy_input_file = NULL;
 	b->yy_n_chars = b->yy_buf_size;
 	b->yy_is_interactive = 0;
 	b->yy_at_bol = 1;
 	b->yy_fill_buffer = 0;
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
-	ncg_switch_to_buffer(b  );
+	yy_switch_to_buffer( b  );
 
 	return b;
 }
 
-/** Setup the input buffer state to scan a string. The next call to ncglex() will
+/** Setup the input buffer state to scan a string. The next call to yylex() will
  * scan from a @e copy of @a str.
  * @param yystr a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
- *       ncg_scan_bytes() instead.
+ *       yy_scan_bytes() instead.
  */
-YY_BUFFER_STATE ncg_scan_string (yyconst char * yystr )
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
 {
     
-	return ncg_scan_bytes(yystr,strlen(yystr) );
+	return yy_scan_bytes( yystr, (int) strlen(yystr) );
 }
 
-/** Setup the input buffer state to scan the given bytes. The next call to ncglex() will
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
  * scan from a @e copy of @a bytes.
  * @param yybytes the byte buffer to scan
  * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE ncg_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
+YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
 	yy_size_t n;
-	yy_size_t i;
+	int i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = _yybytes_len + 2;
-	buf = (char *) ncgalloc(n  );
+	n = (yy_size_t) (_yybytes_len + 2);
+	buf = (char *) yyalloc( n  );
 	if ( ! buf )
-		YY_FATAL_ERROR( "out of dynamic memory in ncg_scan_bytes()" );
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
 	for ( i = 0; i < _yybytes_len; ++i )
 		buf[i] = yybytes[i];
 
 	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
-	b = ncg_scan_buffer(buf,n );
+	b = yy_scan_buffer( buf, n );
 	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in ncg_scan_bytes()" );
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
 	/* It's okay to grow etc. this buffer, and we should throw it
 	 * away when we're done.
@@ -2943,9 +3177,9 @@ YY_BUFFER_STATE ncg_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
+static void yynoreturn yy_fatal_error (const char* msg )
 {
-			(void) fprintf( stderr, "%s\n", msg );
+			fprintf( stderr, "%s\n", msg );
 	exit( YY_EXIT_FAILURE );
 }
 
@@ -2955,14 +3189,14 @@ static void yy_fatal_error (yyconst char* msg )
 #define yyless(n) \
 	do \
 		{ \
-		/* Undo effects of setting up ncgtext. */ \
+		/* Undo effects of setting up yytext. */ \
         int yyless_macro_arg = (n); \
         YY_LESS_LINENO(yyless_macro_arg);\
-		ncgtext[ncgleng] = (yy_hold_char); \
-		(yy_c_buf_p) = ncgtext + yyless_macro_arg; \
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
 		(yy_hold_char) = *(yy_c_buf_p); \
 		*(yy_c_buf_p) = '\0'; \
-		ncgleng = yyless_macro_arg; \
+		yyleng = yyless_macro_arg; \
 		} \
 	while ( 0 )
 
@@ -2971,126 +3205,126 @@ static void yy_fatal_error (yyconst char* msg )
 /** Get the current line number.
  * 
  */
-int ncgget_lineno  (void)
+int yyget_lineno  (void)
 {
-        
-    return ncglineno;
+    
+    return yylineno;
 }
 
 /** Get the input stream.
  * 
  */
-FILE *ncgget_in  (void)
+FILE *yyget_in  (void)
 {
-        return ncgin;
+        return yyin;
 }
 
 /** Get the output stream.
  * 
  */
-FILE *ncgget_out  (void)
+FILE *yyget_out  (void)
 {
-        return ncgout;
+        return yyout;
 }
 
 /** Get the length of the current token.
  * 
  */
-yy_size_t ncgget_leng  (void)
+int yyget_leng  (void)
 {
-        return ncgleng;
+        return yyleng;
 }
 
 /** Get the current token.
  * 
  */
 
-char *ncgget_text  (void)
+char *yyget_text  (void)
 {
-        return ncgtext;
+        return yytext;
 }
 
 /** Set the current line number.
  * @param _line_number line number
  * 
  */
-void ncgset_lineno (int  _line_number )
+void yyset_lineno (int  _line_number )
 {
     
-    ncglineno = _line_number;
+    yylineno = _line_number;
 }
 
 /** Set the input stream. This does not discard the current
  * input buffer.
  * @param _in_str A readable stream.
  * 
- * @see ncg_switch_to_buffer
+ * @see yy_switch_to_buffer
  */
-void ncgset_in (FILE *  _in_str )
+void yyset_in (FILE *  _in_str )
 {
-        ncgin = _in_str ;
+        yyin = _in_str ;
 }
 
-void ncgset_out (FILE *  _out_str )
+void yyset_out (FILE *  _out_str )
 {
-        ncgout = _out_str ;
+        yyout = _out_str ;
 }
 
-int ncgget_debug  (void)
+int yyget_debug  (void)
 {
-        return ncg_flex_debug;
+        return yy_flex_debug;
 }
 
-void ncgset_debug (int  _bdebug )
+void yyset_debug (int  _bdebug )
 {
-        ncg_flex_debug = _bdebug ;
+        yy_flex_debug = _bdebug ;
 }
 
 static int yy_init_globals (void)
 {
         /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from ncglex_destroy(), so don't allocate here.
+     * This function is called from yylex_destroy(), so don't allocate here.
      */
 
-    (yy_buffer_stack) = 0;
+    (yy_buffer_stack) = NULL;
     (yy_buffer_stack_top) = 0;
     (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
+    (yy_c_buf_p) = NULL;
     (yy_init) = 0;
     (yy_start) = 0;
 
 /* Defined in main.c */
 #ifdef YY_STDINIT
-    ncgin = stdin;
-    ncgout = stdout;
+    yyin = stdin;
+    yyout = stdout;
 #else
-    ncgin = (FILE *) 0;
-    ncgout = (FILE *) 0;
+    yyin = NULL;
+    yyout = NULL;
 #endif
 
     /* For future reference: Set errno on error, since we are called by
-     * ncglex_init()
+     * yylex_init()
      */
     return 0;
 }
 
-/* ncglex_destroy is for both reentrant and non-reentrant scanners. */
-int ncglex_destroy  (void)
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
 {
     
     /* Pop the buffer stack, destroying each element. */
 	while(YY_CURRENT_BUFFER){
-		ncg_delete_buffer(YY_CURRENT_BUFFER  );
+		yy_delete_buffer( YY_CURRENT_BUFFER  );
 		YY_CURRENT_BUFFER_LVALUE = NULL;
-		ncgpop_buffer_state();
+		yypop_buffer_state();
 	}
 
 	/* Destroy the stack itself. */
-	ncgfree((yy_buffer_stack) );
+	yyfree((yy_buffer_stack) );
 	(yy_buffer_stack) = NULL;
 
     /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * ncglex() is called, initialization will occur. */
+     * yylex() is called, initialization will occur. */
     yy_init_globals( );
 
     return 0;
@@ -3101,7 +3335,7 @@ int ncglex_destroy  (void)
  */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
 {
 		
 	int i;
@@ -3111,7 +3345,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
+static int yy_flex_strlen (const char * s )
 {
 	int n;
 	for ( n = 0; s[n]; ++n )
@@ -3121,12 +3355,12 @@ static int yy_flex_strlen (yyconst char * s )
 }
 #endif
 
-void *ncgalloc (yy_size_t  size )
+void *yyalloc (yy_size_t  size )
 {
-			return (void *) malloc( size );
+			return malloc(size);
 }
 
-void *ncgrealloc  (void * ptr, yy_size_t  size )
+void *yyrealloc  (void * ptr, yy_size_t  size )
 {
 		
 	/* The cast to (char *) in the following accommodates both
@@ -3136,26 +3370,25 @@ void *ncgrealloc  (void * ptr, yy_size_t  size )
 	 * any pointer type to void*, and deal with argument conversions
 	 * as though doing an assignment.
 	 */
-	return (void *) realloc( (char *) ptr, size );
+	return realloc(ptr, size);
 }
 
-void ncgfree (void * ptr )
+void yyfree (void * ptr )
 {
-			free( (char *) ptr );	/* see ncgrealloc() for (char *) cast */
+			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
 }
 
 #define YYTABLES_NAME "yytables"
 
-#line 570 "ncgen.l"
-
+#line 573 "ncgen.l"
 
 static int
 lexdebug(int token)
 {
     if(debug >= 2)
     {
-	char* text = ncgtext;
-	text[ncgleng] = 0;
+	char* text = yytext;
+	text[yyleng] = 0;
         fprintf(stderr,"Token=%d |%s| line=%d\n",token,text,lineno);
     }
     return token;
@@ -3236,7 +3469,6 @@ Return the value.
 static unsigned long long
 parseULL(char* text, int* failp)
 {
-    int result = 0;
     extern int errno;
     char* endptr;
     unsigned long long uint64 = 0;
diff --git a/ncgen/ncgeny.c b/ncgen/ncgeny.c
index 9e21e44..d39ae3d 100644
--- a/ncgen/ncgeny.c
+++ b/ncgen/ncgeny.c
@@ -136,7 +136,10 @@ char* primtypenames[PRIMNO] = {
 "string"
 };
 
-static int GLOBAL_SPECIAL = _NCPROPS_FLAG | _ISNETCDF4_FLAG | _SUPERBLOCK_FLAG | _FORMAT_FLAG ;
+static int GLOBAL_SPECIAL = _NCPROPS_FLAG
+                            | _ISNETCDF4_FLAG
+                            | _SUPERBLOCK_FLAG
+                            | _FORMAT_FLAG ;
 
 /*Defined in ncgen.l*/
 extern int lineno;              /* line number for error messages */
@@ -182,6 +185,7 @@ static int containsfills(Datalist* list);
 static void datalistextend(Datalist* dl, NCConstant* con);
 static void vercheck(int ncid);
 static long long extractint(NCConstant con);
+static int parsefilterflag(const char* sdata0, Specialdata* special);
 
 int yylex(void);
 
@@ -195,7 +199,7 @@ static void yyerror(fmt,va_alist) const char* fmt; va_dcl;
 extern int lex_init(void);
 
 
-#line 199 "ncgen.tab.c" /* yacc.c:339  */
+#line 203 "ncgeny.c" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -214,7 +218,7 @@ extern int lex_init(void);
 #endif
 
 /* In a future release of Bison, this section will be replaced
-   by #include "ncgen.tab.h".  */
+   by #include "ncgeny.h".  */
 #ifndef YY_NCG_NCGEN_TAB_H_INCLUDED
 # define YY_NCG_NCGEN_TAB_H_INCLUDED
 /* Debug traces.  */
@@ -242,45 +246,47 @@ extern int ncgdebug;
     UINT_K = 267,
     INT64_K = 268,
     UINT64_K = 269,
-    IDENT = 270,
-    TERMSTRING = 271,
-    CHAR_CONST = 272,
-    BYTE_CONST = 273,
-    SHORT_CONST = 274,
-    INT_CONST = 275,
-    INT64_CONST = 276,
-    UBYTE_CONST = 277,
-    USHORT_CONST = 278,
-    UINT_CONST = 279,
-    UINT64_CONST = 280,
-    FLOAT_CONST = 281,
-    DOUBLE_CONST = 282,
-    DIMENSIONS = 283,
-    VARIABLES = 284,
-    NETCDF = 285,
-    DATA = 286,
-    TYPES = 287,
-    COMPOUND = 288,
-    ENUM = 289,
-    OPAQUE_ = 290,
-    OPAQUESTRING = 291,
-    GROUP = 292,
-    PATH = 293,
-    FILLMARKER = 294,
-    NIL = 295,
-    _FILLVALUE = 296,
-    _FORMAT = 297,
-    _STORAGE = 298,
-    _CHUNKSIZES = 299,
-    _DEFLATELEVEL = 300,
-    _SHUFFLE = 301,
-    _ENDIANNESS = 302,
-    _NOFILL = 303,
-    _FLETCHER32 = 304,
-    _NCPROPS = 305,
-    _ISNETCDF4 = 306,
-    _SUPERBLOCK = 307,
-    DATASETID = 308
+    STRING_K = 270,
+    IDENT = 271,
+    TERMSTRING = 272,
+    CHAR_CONST = 273,
+    BYTE_CONST = 274,
+    SHORT_CONST = 275,
+    INT_CONST = 276,
+    INT64_CONST = 277,
+    UBYTE_CONST = 278,
+    USHORT_CONST = 279,
+    UINT_CONST = 280,
+    UINT64_CONST = 281,
+    FLOAT_CONST = 282,
+    DOUBLE_CONST = 283,
+    DIMENSIONS = 284,
+    VARIABLES = 285,
+    NETCDF = 286,
+    DATA = 287,
+    TYPES = 288,
+    COMPOUND = 289,
+    ENUM = 290,
+    OPAQUE_ = 291,
+    OPAQUESTRING = 292,
+    GROUP = 293,
+    PATH = 294,
+    FILLMARKER = 295,
+    NIL = 296,
+    _FILLVALUE = 297,
+    _FORMAT = 298,
+    _STORAGE = 299,
+    _CHUNKSIZES = 300,
+    _DEFLATELEVEL = 301,
+    _SHUFFLE = 302,
+    _ENDIANNESS = 303,
+    _NOFILL = 304,
+    _FLETCHER32 = 305,
+    _NCPROPS = 306,
+    _ISNETCDF4 = 307,
+    _SUPERBLOCK = 308,
+    _FILTER = 309,
+    DATASETID = 310
   };
 #endif
 
@@ -289,16 +295,16 @@ extern int ncgdebug;
 
 union YYSTYPE
 {
-#line 138 "ncgen.y" /* yacc.c:355  */
+#line 142 "ncgen.y" /* yacc.c:355  */
 
 Symbol* sym;
 unsigned long  size; /* allow for zero size to indicate e.g. UNLIMITED*/
 long           mark; /* track indices into the sequence*/
 int            nctype; /* for tracking attribute list type*/
 Datalist*      datalist;
-NCConstant       constant;
+NCConstant     constant;
 
-#line 302 "ncgen.tab.c" /* yacc.c:355  */
+#line 308 "ncgeny.c" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -315,7 +321,7 @@ int ncgparse (void);
 
 /* Copy the second part of user declarations.  */
 
-#line 319 "ncgen.tab.c" /* yacc.c:358  */
+#line 325 "ncgeny.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -557,21 +563,21 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  5
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   370
+#define YYLAST   393
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  63
+#define YYNTOKENS  65
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  67
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  151
+#define YYNRULES  153
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  258
+#define YYNSTATES  262
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   308
+#define YYMAXUTOK   310
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -584,15 +590,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      59,    60,    61,     2,    57,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    62,    56,
-       2,    58,     2,     2,     2,     2,     2,     2,     2,     2,
+      61,    62,    63,     2,    59,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    64,    58,
+       2,    60,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    54,     2,    55,     2,     2,     2,     2,
+       2,     2,     2,    56,     2,    57,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -610,29 +616,30 @@ static const yytype_uint8 yytranslate[] =
       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
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   218,   218,   224,   226,   233,   240,   240,   243,   252,
-     242,   257,   258,   259,   263,   263,   265,   275,   275,   278,
-     279,   280,   281,   284,   284,   287,   317,   319,   336,   345,
-     357,   371,   404,   405,   408,   422,   423,   424,   425,   426,
-     427,   428,   429,   430,   431,   432,   435,   436,   437,   440,
-     441,   444,   444,   446,   447,   451,   458,   468,   480,   481,
-     482,   485,   486,   489,   489,   491,   513,   517,   521,   548,
-     549,   552,   553,   557,   571,   575,   580,   609,   610,   614,
-     615,   620,   630,   650,   661,   672,   691,   698,   698,   701,
-     703,   705,   707,   709,   718,   729,   731,   733,   735,   737,
-     739,   741,   743,   745,   747,   752,   759,   768,   769,   770,
-     773,   774,   777,   781,   782,   786,   790,   791,   796,   797,
-     801,   802,   803,   804,   805,   806,   810,   814,   818,   820,
-     825,   826,   827,   828,   829,   830,   831,   832,   833,   834,
-     835,   836,   840,   841,   845,   847,   849,   851,   856,   860,
-     861,   867
+       0,   224,   224,   230,   232,   239,   246,   246,   249,   258,
+     248,   263,   264,   265,   269,   269,   271,   281,   281,   284,
+     285,   286,   287,   290,   290,   293,   323,   325,   342,   351,
+     363,   377,   410,   411,   414,   428,   429,   430,   431,   432,
+     433,   434,   435,   436,   437,   438,   439,   442,   443,   444,
+     447,   448,   451,   451,   453,   454,   458,   465,   475,   487,
+     488,   489,   492,   493,   496,   496,   498,   520,   524,   528,
+     555,   556,   559,   560,   564,   578,   582,   587,   616,   617,
+     621,   622,   627,   637,   657,   668,   679,   698,   705,   705,
+     708,   710,   712,   714,   716,   725,   736,   738,   740,   742,
+     744,   746,   748,   750,   752,   754,   756,   761,   768,   777,
+     778,   779,   782,   783,   786,   790,   791,   795,   799,   800,
+     805,   806,   810,   811,   812,   813,   814,   815,   819,   823,
+     827,   829,   834,   835,   836,   837,   838,   839,   840,   841,
+     842,   843,   844,   845,   849,   850,   854,   856,   858,   860,
+     865,   869,   870,   876
 };
 #endif
 
@@ -643,18 +650,18 @@ static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "NC_UNLIMITED_K", "CHAR_K", "BYTE_K",
   "SHORT_K", "INT_K", "FLOAT_K", "DOUBLE_K", "UBYTE_K", "USHORT_K",
-  "UINT_K", "INT64_K", "UINT64_K", "IDENT", "TERMSTRING", "CHAR_CONST",
-  "BYTE_CONST", "SHORT_CONST", "INT_CONST", "INT64_CONST", "UBYTE_CONST",
-  "USHORT_CONST", "UINT_CONST", "UINT64_CONST", "FLOAT_CONST",
-  "DOUBLE_CONST", "DIMENSIONS", "VARIABLES", "NETCDF", "DATA", "TYPES",
-  "COMPOUND", "ENUM", "OPAQUE_", "OPAQUESTRING", "GROUP", "PATH",
-  "FILLMARKER", "NIL", "_FILLVALUE", "_FORMAT", "_STORAGE", "_CHUNKSIZES",
-  "_DEFLATELEVEL", "_SHUFFLE", "_ENDIANNESS", "_NOFILL", "_FLETCHER32",
-  "_NCPROPS", "_ISNETCDF4", "_SUPERBLOCK", "DATASETID", "'{'", "'}'",
-  "';'", "','", "'='", "'('", "')'", "'*'", "':'", "$accept", "ncdesc",
-  "datasetid", "rootgroup", "groupbody", "subgrouplist", "namedgroup",
-  "$@1", "$@2", "typesection", "typedecls", "typename",
-  "type_or_attr_decl", "typedecl", "optsemicolon", "enumdecl",
+  "UINT_K", "INT64_K", "UINT64_K", "STRING_K", "IDENT", "TERMSTRING",
+  "CHAR_CONST", "BYTE_CONST", "SHORT_CONST", "INT_CONST", "INT64_CONST",
+  "UBYTE_CONST", "USHORT_CONST", "UINT_CONST", "UINT64_CONST",
+  "FLOAT_CONST", "DOUBLE_CONST", "DIMENSIONS", "VARIABLES", "NETCDF",
+  "DATA", "TYPES", "COMPOUND", "ENUM", "OPAQUE_", "OPAQUESTRING", "GROUP",
+  "PATH", "FILLMARKER", "NIL", "_FILLVALUE", "_FORMAT", "_STORAGE",
+  "_CHUNKSIZES", "_DEFLATELEVEL", "_SHUFFLE", "_ENDIANNESS", "_NOFILL",
+  "_FLETCHER32", "_NCPROPS", "_ISNETCDF4", "_SUPERBLOCK", "_FILTER",
+  "DATASETID", "'{'", "'}'", "';'", "','", "'='", "'('", "')'", "'*'",
+  "':'", "$accept", "ncdesc", "datasetid", "rootgroup", "groupbody",
+  "subgrouplist", "namedgroup", "$@1", "$@2", "typesection", "typedecls",
+  "typename", "type_or_attr_decl", "typedecl", "optsemicolon", "enumdecl",
   "enumidlist", "enumid", "opaquedecl", "vlendecl", "compounddecl",
   "fields", "field", "primtype", "dimsection", "dimdecls",
   "dim_or_attr_decl", "dimdeclist", "dimdecl", "dimd", "vasection",
@@ -678,17 +685,17 @@ static const yytype_uint16 yytoknum[] =
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
      295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
-     305,   306,   307,   308,   123,   125,    59,    44,    61,    40,
-      41,    42,    58
+     305,   306,   307,   308,   309,   310,   123,   125,    59,    44,
+      61,    40,    41,    42,    58
 };
 # endif
 
-#define YYPACT_NINF -133
+#define YYPACT_NINF -145
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-133)))
+  (!!((Yystate) == (-145)))
 
-#define YYTABLE_NINF -106
+#define YYTABLE_NINF -108
 
 #define yytable_value_is_error(Yytable_value) \
   0
@@ -697,32 +704,33 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     -11,   -48,    20,  -133,   -19,  -133,   210,  -133,  -133,  -133,
-    -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,
-    -133,    -3,  -133,  -133,   332,   -16,     8,    -4,  -133,  -133,
-      18,    19,    29,    41,    48,   -22,    47,   128,    56,    75,
-     210,    94,    94,   136,    33,   281,   102,  -133,  -133,     2,
-      63,    64,    65,    68,    71,    74,    76,    77,    78,   102,
-      82,    56,  -133,  -133,    81,    81,    81,    81,    99,   222,
-      88,   210,   117,  -133,  -133,  -133,  -133,  -133,  -133,  -133,
-    -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,
-    -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,  -133,
-     281,  -133,    90,  -133,  -133,  -133,  -133,  -133,  -133,  -133,
-      89,    97,    91,   100,   281,    94,    33,    33,   136,    94,
-     136,   136,   281,   105,  -133,   142,  -133,  -133,  -133,  -133,
-    -133,  -133,   102,   109,  -133,   210,   107,   121,  -133,   123,
-    -133,   125,   210,   148,    35,   281,   333,  -133,   281,   281,
-      90,  -133,   129,  -133,  -133,  -133,  -133,  -133,  -133,    90,
-     332,   127,   131,   130,   132,  -133,   102,    95,   210,   133,
-    -133,   332,  -133,   332,  -133,  -133,  -133,   -23,  -133,   210,
-      90,    90,    33,   278,   135,   102,  -133,   102,   102,   102,
-    -133,  -133,  -133,  -133,  -133,   137,  -133,   138,  -133,   -32,
-     139,  -133,   332,   140,   333,  -133,  -133,  -133,  -133,   144,
-    -133,   141,  -133,   145,  -133,    45,  -133,   143,  -133,  -133,
-     102,   -12,  -133,   281,   147,  -133,  -133,   157,  -133,   102,
-      -2,  -133,  -133,   102,    33,  -133,   146,    25,  -133,  -133,
-      90,  -133,   151,  -133,  -133,  -133,    26,  -133,  -133,  -133,
-     -12,  -133,   210,    -2,  -133,  -133,  -133,  -133
+     -10,   -19,    54,  -145,    12,  -145,   219,  -145,  -145,  -145,
+    -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,
+    -145,  -145,    -8,  -145,  -145,   354,    -9,    26,    11,  -145,
+    -145,    15,    28,    31,    32,    36,   -11,    34,   130,   183,
+      70,   219,    83,    83,    45,    52,   301,    85,  -145,  -145,
+      -1,    42,    46,    49,    50,    51,    57,    58,    59,    60,
+      61,    85,    53,   183,  -145,  -145,    64,    64,    64,    64,
+      88,   255,    66,   219,    95,  -145,  -145,  -145,  -145,  -145,
+    -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,
+    -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,  -145,
+    -145,  -145,   301,  -145,    68,  -145,  -145,  -145,  -145,  -145,
+    -145,  -145,    71,    75,    73,    77,   301,    83,    52,    52,
+      45,    83,    45,    45,    83,   301,    79,  -145,   117,  -145,
+    -145,  -145,  -145,  -145,  -145,    85,    78,  -145,   219,    82,
+      86,  -145,    84,  -145,    87,   219,   118,    30,   301,   355,
+    -145,   301,   301,    68,  -145,    90,  -145,  -145,  -145,  -145,
+    -145,  -145,  -145,    68,   354,    93,    96,    97,   100,  -145,
+      85,    35,   219,   102,  -145,   354,  -145,   354,  -145,  -145,
+    -145,   -28,  -145,   219,    68,    68,    52,   291,   103,    85,
+    -145,    85,    85,    85,  -145,  -145,  -145,  -145,  -145,   104,
+    -145,   105,  -145,   -32,   108,  -145,   354,   107,   355,  -145,
+    -145,  -145,  -145,   115,  -145,   123,  -145,   125,  -145,    38,
+    -145,   140,  -145,  -145,    85,     3,  -145,   301,   143,  -145,
+    -145,   166,  -145,    85,    -7,  -145,  -145,    85,    52,  -145,
+     145,    17,  -145,  -145,    68,  -145,   106,  -145,  -145,  -145,
+      23,  -145,  -145,  -145,     3,  -145,   219,    -7,  -145,  -145,
+    -145,  -145
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -730,56 +738,57 @@ static const yytype_int16 yypact[] =
      means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       0,     0,     0,     3,     0,     1,    87,     2,    35,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,    45,   151,
-     106,     0,     6,    86,     0,    84,    11,     0,    85,   105,
-       0,     0,     0,     0,     0,     0,     0,     0,    12,    46,
-      87,     0,     0,     0,     0,   115,     0,     4,     7,     0,
+       0,     0,     0,     3,     0,     1,    88,     2,    35,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+     153,   108,     0,     6,    87,     0,    85,    11,     0,    86,
+     107,     0,     0,     0,     0,     0,     0,     0,     0,    12,
+      47,    88,     0,     0,     0,     0,   117,     0,     4,     7,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    13,    14,    17,    23,    23,    23,    23,    86,     0,
-       0,    47,    58,    88,   148,   104,    89,   144,   146,   145,
-     147,   150,   149,    90,    91,   141,   130,   131,   132,   133,
-     134,   135,   136,   137,   138,   139,   140,   121,   122,   123,
-     115,   126,    92,   113,   114,   116,   118,   124,   125,   120,
-     105,     0,     0,     0,   115,     0,     0,     0,     0,     0,
-       0,     0,   115,     0,    16,     0,    15,    24,    19,    22,
-      21,    20,     0,     0,    18,    48,     0,    51,    53,     0,
-      52,   105,    59,   107,     0,     0,     0,     8,   115,   115,
-      95,    97,    98,   142,   100,   101,   102,   103,    99,    94,
-       0,     0,     0,     0,     0,    49,     0,     0,    60,     0,
-      63,     0,    64,   108,     5,   119,   117,     0,   128,    87,
-      96,    93,     0,     0,     0,     0,    84,     0,     0,     0,
-      50,    54,    57,    56,    55,     0,    61,    65,    66,    69,
-       0,    83,   109,     0,     0,   127,     6,   143,    31,     0,
-      32,    34,    74,    77,    29,     0,    26,     0,    30,    62,
-       0,     0,    68,   115,     0,   110,   129,     9,    33,     0,
-       0,    76,    25,     0,     0,    67,    69,     0,    71,    73,
-     112,   111,     0,    75,    82,    81,     0,    79,    27,    28,
-       0,    70,    87,     0,    78,    72,    10,    80
+       0,     0,     0,    13,    14,    17,    23,    23,    23,    23,
+      87,     0,     0,    48,    59,    89,   150,   106,    90,   146,
+     148,   147,   149,   152,   151,    91,    92,   143,   132,   133,
+     134,   135,   136,   137,   138,   139,   140,   141,   142,   123,
+     124,   125,   117,   128,    93,   115,   116,   118,   120,   126,
+     127,   122,   107,     0,     0,     0,   117,     0,     0,     0,
+       0,     0,     0,     0,     0,   117,     0,    16,     0,    15,
+      24,    19,    22,    21,    20,     0,     0,    18,    49,     0,
+      52,    54,     0,    53,   107,    60,   109,     0,     0,     0,
+       8,   117,   117,    96,    98,    99,   144,   101,   102,   103,
+     105,   100,   104,    95,     0,     0,     0,     0,     0,    50,
+       0,     0,    61,     0,    64,     0,    65,   110,     5,   121,
+     119,     0,   130,    88,    97,    94,     0,     0,     0,     0,
+      85,     0,     0,     0,    51,    55,    58,    57,    56,     0,
+      62,    66,    67,    70,     0,    84,   111,     0,     0,   129,
+       6,   145,    31,     0,    32,    34,    75,    78,    29,     0,
+      26,     0,    30,    63,     0,     0,    69,   117,     0,   112,
+     131,     9,    33,     0,     0,    77,    25,     0,     0,    68,
+      70,     0,    72,    74,   114,   113,     0,    76,    83,    82,
+       0,    80,    27,    28,     0,    71,    88,     0,    79,    73,
+      10,    81
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -133,  -133,  -133,  -133,    28,     4,  -133,  -133,  -133,  -133,
-    -133,  -109,   150,  -133,    30,  -133,  -133,     5,  -133,  -133,
-    -133,  -133,    57,   -25,  -133,  -133,   104,  -133,    79,  -133,
-    -133,  -133,    73,  -133,  -133,    22,  -133,  -133,    -7,  -133,
-      15,  -133,  -133,    -6,  -133,   -29,   -18,   -39,   -30,   -41,
-    -133,  -133,    44,   -93,  -133,  -133,   106,  -133,  -133,  -133,
-    -133,  -132,  -133,   -42,   -31,   -76,   -21
+    -145,  -145,  -145,  -145,    24,    -2,  -145,  -145,  -145,  -145,
+    -145,  -128,   146,  -145,   -20,  -145,  -145,   -25,  -145,  -145,
+    -145,  -145,    27,   -26,  -145,  -145,    80,  -145,    43,  -145,
+    -145,  -145,    48,  -145,  -145,    -3,  -145,  -145,   -18,  -145,
+       4,  -145,  -145,   -17,  -145,   -30,   -21,   -40,   -33,   -44,
+    -145,  -145,    33,   -99,  -145,  -145,    94,  -145,  -145,  -145,
+    -145,  -144,  -145,   -35,   -31,  -100,   -22
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     2,     4,     7,    22,    35,    48,   179,   242,    39,
-      61,   123,    62,    63,   128,    64,   215,   216,    65,    66,
-      67,   183,   184,    23,    72,   135,   136,   137,   138,   139,
-     143,   168,   169,   170,   197,   198,   222,   237,   238,   211,
-     212,   231,   246,   247,   200,    24,    25,    26,    27,    28,
-     174,   202,   203,   102,   103,   104,   105,   106,   107,   108,
-     177,   109,   152,    81,    82,    83,    29
+      -1,     2,     4,     7,    23,    36,    49,   183,   246,    40,
+      63,   126,    64,    65,   131,    66,   219,   220,    67,    68,
+      69,   187,   188,    24,    74,   138,   139,   140,   141,   142,
+     146,   172,   173,   174,   201,   202,   226,   241,   242,   215,
+     216,   235,   250,   251,   204,    25,    26,    27,    28,    29,
+     178,   206,   207,   104,   105,   106,   107,   108,   109,   110,
+     181,   111,   155,    83,    84,    85,    30
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -787,139 +796,144 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      34,    73,    84,    19,   101,     3,    36,   144,    70,    69,
-      75,    76,    19,    68,   178,    46,    58,    19,   244,     1,
-       5,   150,   245,   162,   110,   111,    20,   221,   113,   159,
-    -105,    70,    69,    47,   204,     6,    68,   205,   124,    30,
-      38,   140,   155,   112,   157,   158,    37,    31,    32,    33,
-     141,    36,    40,    77,    78,   180,   181,    79,    80,   101,
-       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,   226,   101,   153,   154,    41,    42,   214,   110,
-     218,   101,   250,   253,   151,   251,   254,    43,   156,    59,
-     175,    60,   145,   110,    20,   129,   130,   131,   193,    44,
-     232,   110,   233,    71,   101,   140,    45,   101,   101,    49,
-      74,   124,   172,   171,   141,    77,    78,    19,    21,    79,
-      80,   114,   115,   116,   110,   194,   117,   110,   110,   118,
-     240,   185,   119,   132,   120,   121,   122,   127,   172,   171,
-     207,   125,   186,    19,   134,   192,   142,   145,   146,   148,
-     199,   147,    74,    36,   185,   201,    77,    78,   149,   160,
-      79,    80,   161,   165,   213,   186,   124,   217,   124,    50,
-     163,    51,    52,    53,    54,    55,    56,    57,   166,   173,
-     239,   167,   101,   -57,   201,   188,   182,   187,   190,   196,
-     189,   210,   249,   219,    46,   220,   225,   223,   229,   236,
-     228,   234,   110,   241,   230,   221,   252,   206,   213,   239,
-     227,   126,   217,   256,     8,     9,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,     8,     9,    10,    11,
-      12,    13,    14,    15,    16,    17,    18,    19,   248,   164,
-     209,   195,   235,   255,   243,   191,   224,   257,    20,     0,
-       0,   176,     0,     0,     0,     0,     0,     0,     0,     0,
-      20,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    21,     0,     0,     0,     0,     0,     0,     0,
-       0,   133,     8,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,     0,     0,    19,    85,    86,    87,
-      88,    89,    90,    91,    92,    93,    94,    95,    96,     0,
-       0,     0,     0,     0,     0,     0,    20,    97,     0,    20,
-      98,    99,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   208,     0,   100,     8,     9,    10,    11,
-      12,    13,    14,    15,    16,    17,    18,    19,     0,    85,
-      86,    87,    88,    89,    90,    91,    92,    93,    94,    95,
-      96,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      20
+      35,    75,   103,   147,    37,   182,    72,   166,    20,    71,
+      86,    77,    78,    70,   248,    20,    60,   153,   249,    20,
+     158,     1,   160,   161,   112,   113,   163,    47,   115,   225,
+      72,   208,  -107,    71,   209,    31,     3,    70,   197,   127,
+     143,   114,    21,    32,    33,    34,    48,   132,   133,   134,
+      37,   144,   184,   185,     5,    38,    79,    80,   103,    39,
+      81,    82,    76,   218,   230,   222,    79,    80,     6,    41,
+      81,    82,   103,    79,    80,    42,   254,    81,    82,   255,
+     112,   103,   257,   156,   157,   258,   154,   179,    43,   148,
+     159,    44,    45,   162,   112,   236,    46,   237,    50,    73,
+      76,    20,   116,   112,   103,   143,   117,   103,   103,   118,
+     119,   120,   176,   127,   128,   175,   144,   121,   122,   123,
+     124,   125,   130,   135,   137,   145,   112,   148,   244,   112,
+     112,   150,   149,   151,   189,   164,   198,   152,   165,   176,
+     169,   167,   175,   190,   171,   170,    20,   -58,   196,   186,
+     177,   211,   192,   203,    37,   191,   205,   189,   194,   193,
+     200,   214,   223,   256,   224,   229,   190,   217,   227,   127,
+     221,   127,    51,   232,    52,    53,    54,    55,    56,    57,
+      58,   243,   233,   103,    59,   205,   234,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+     238,   245,   240,   253,    47,   112,   225,   210,   231,   129,
+     243,   217,   252,   195,   213,   221,   260,    61,   168,    62,
+     199,   239,    21,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,   259,   247,     0,   228,
+     261,     0,   180,     0,     0,     0,     0,    22,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    21,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    22,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    21,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,     0,     0,
+       0,     0,     0,     0,     0,     0,   136,    20,    87,    88,
+      89,    90,    91,    92,    93,    94,    95,    96,    97,    98,
+      21,     0,     0,     0,     0,     0,     0,     0,    99,     0,
+      21,   100,   101,     0,     0,     0,     0,     0,   212,     0,
+       0,     0,     0,     0,     0,     0,     0,   102,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,     0,    87,    88,    89,    90,    91,    92,    93,    94,
+      95,    96,    97,    98,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    21
 };
 
 static const yytype_int16 yycheck[] =
 {
-      21,    40,    44,    15,    45,    53,    24,   100,    38,    38,
-      41,    42,    15,    38,   146,    37,    37,    15,    20,    30,
-       0,   114,    24,   132,    45,    46,    38,    59,    49,   122,
-      62,    61,    61,    55,    57,    54,    61,    60,    59,    42,
-      32,    71,   118,    41,   120,   121,    62,    50,    51,    52,
-      71,    69,    56,    20,    21,   148,   149,    24,    25,   100,
-       4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-      14,    15,   204,   114,   116,   117,    58,    58,   187,   100,
-     189,   122,    57,    57,   115,    60,    60,    58,   119,    33,
-      55,    35,    57,   114,    38,    65,    66,    67,     3,    58,
-      55,   122,    57,    28,   145,   135,    58,   148,   149,    62,
-      16,   132,   142,   142,   135,    20,    21,    15,    62,    24,
-      25,    58,    58,    58,   145,   167,    58,   148,   149,    58,
-     223,   160,    58,    34,    58,    58,    58,    56,   168,   168,
-     182,    59,   160,    15,    56,   166,    29,    57,    59,    58,
-     171,    54,    16,   171,   183,   173,    20,    21,    58,    54,
-      24,    25,    20,    56,   185,   183,   187,   188,   189,    41,
-      61,    43,    44,    45,    46,    47,    48,    49,    57,    31,
-     221,    58,   223,    58,   202,    54,    57,    60,    56,    56,
-      60,    56,   234,    56,    37,    57,    56,    58,    57,   220,
-      56,    58,   223,    56,    59,    59,    55,   179,   229,   250,
-     206,    61,   233,   252,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    13,    14,    15,   233,   135,
-     183,   168,   220,   250,   229,   166,   202,   253,    38,    -1,
-      -1,   145,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      38,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    62,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    59,     4,     5,     6,     7,     8,     9,    10,    11,
-      12,    13,    14,    15,    -1,    -1,    15,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,    27,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    38,    36,    -1,    38,
-      39,    40,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    55,    -1,    54,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    13,    14,    15,    -1,    16,
-      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
-      27,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      38
+      22,    41,    46,   102,    25,   149,    39,   135,    16,    39,
+      45,    42,    43,    39,    21,    16,    38,   116,    25,    16,
+     120,    31,   122,   123,    46,    47,   125,    38,    50,    61,
+      63,    59,    64,    63,    62,    43,    55,    63,     3,    61,
+      73,    42,    39,    51,    52,    53,    57,    67,    68,    69,
+      71,    73,   151,   152,     0,    64,    21,    22,   102,    33,
+      25,    26,    17,   191,   208,   193,    21,    22,    56,    58,
+      25,    26,   116,    21,    22,    60,    59,    25,    26,    62,
+     102,   125,    59,   118,   119,    62,   117,    57,    60,    59,
+     121,    60,    60,   124,   116,    57,    60,    59,    64,    29,
+      17,    16,    60,   125,   148,   138,    60,   151,   152,    60,
+      60,    60,   145,   135,    61,   145,   138,    60,    60,    60,
+      60,    60,    58,    35,    58,    30,   148,    59,   227,   151,
+     152,    56,    61,    60,   164,    56,   171,    60,    21,   172,
+      58,    63,   172,   164,    60,    59,    16,    60,   170,    59,
+      32,   186,    56,   175,   175,    62,   177,   187,    58,    62,
+      58,    58,    58,    57,    59,    58,   187,   189,    60,   191,
+     192,   193,    42,    58,    44,    45,    46,    47,    48,    49,
+      50,   225,    59,   227,    54,   206,    61,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      60,    58,   224,   238,    38,   227,    61,   183,   210,    63,
+     254,   233,   237,   170,   187,   237,   256,    34,   138,    36,
+     172,   224,    39,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,   254,   233,    -1,   206,
+     257,    -1,   148,    -1,    -1,    -1,    -1,    64,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    39,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    64,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    39,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    61,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    -1,
+      39,    40,    41,    -1,    -1,    -1,    -1,    -1,    57,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    56,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    -1,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    39
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    30,    64,    53,    65,     0,    54,    66,     4,     5,
+       0,    31,    66,    55,    67,     0,    56,    68,     4,     5,
        6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
-      38,    62,    67,    86,   108,   109,   110,   111,   112,   129,
-      42,    50,    51,    52,   129,    68,   109,    62,    32,    72,
-      56,    58,    58,    58,    58,    58,    37,    55,    69,    62,
-      41,    43,    44,    45,    46,    47,    48,    49,   129,    33,
-      35,    73,    75,    76,    78,    81,    82,    83,    86,   108,
-     111,    28,    87,   110,    16,   127,   127,    20,    21,    24,
-      25,   126,   127,   128,   126,    16,    17,    18,    19,    20,
-      21,    22,    23,    24,    25,    26,    27,    36,    39,    40,
-      54,   112,   116,   117,   118,   119,   120,   121,   122,   124,
-     129,   129,    41,   129,    58,    58,    58,    58,    58,    58,
-      58,    58,    58,    74,   129,    59,    75,    56,    77,    77,
-      77,    77,    34,    59,    56,    88,    89,    90,    91,    92,
-     111,   129,    29,    93,   116,    57,    59,    54,    58,    58,
-     116,   127,   125,   126,   126,   128,   127,   128,   128,   116,
-      54,    20,    74,    61,    89,    56,    57,    58,    94,    95,
-      96,   108,   111,    31,   113,    55,   119,   123,   124,    70,
-     116,   116,    57,    84,    85,   108,   109,    60,    54,    60,
-      56,    91,   129,     3,   126,    95,    56,    97,    98,   129,
-     107,   109,   114,   115,    57,    60,    67,   126,    55,    85,
-      56,   102,   103,   129,    74,    79,    80,   129,    74,    56,
-      57,    59,    99,    58,   115,    56,   124,    68,    56,    57,
-      59,   104,    55,    57,    58,    98,   129,   100,   101,   112,
-     116,    56,    71,   103,    20,    24,   105,   106,    80,   126,
-      57,    60,    55,    57,    60,   101,   110,   106
+      16,    39,    64,    69,    88,   110,   111,   112,   113,   114,
+     131,    43,    51,    52,    53,   131,    70,   111,    64,    33,
+      74,    58,    60,    60,    60,    60,    60,    38,    57,    71,
+      64,    42,    44,    45,    46,    47,    48,    49,    50,    54,
+     131,    34,    36,    75,    77,    78,    80,    83,    84,    85,
+      88,   110,   113,    29,    89,   112,    17,   129,   129,    21,
+      22,    25,    26,   128,   129,   130,   128,    17,    18,    19,
+      20,    21,    22,    23,    24,    25,    26,    27,    28,    37,
+      40,    41,    56,   114,   118,   119,   120,   121,   122,   123,
+     124,   126,   131,   131,    42,   131,    60,    60,    60,    60,
+      60,    60,    60,    60,    60,    60,    76,   131,    61,    77,
+      58,    79,    79,    79,    79,    35,    61,    58,    90,    91,
+      92,    93,    94,   113,   131,    30,    95,   118,    59,    61,
+      56,    60,    60,   118,   129,   127,   128,   128,   130,   129,
+     130,   130,   129,   118,    56,    21,    76,    63,    91,    58,
+      59,    60,    96,    97,    98,   110,   113,    32,   115,    57,
+     121,   125,   126,    72,   118,   118,    59,    86,    87,   110,
+     111,    62,    56,    62,    58,    93,   131,     3,   128,    97,
+      58,    99,   100,   131,   109,   111,   116,   117,    59,    62,
+      69,   128,    57,    87,    58,   104,   105,   131,    76,    81,
+      82,   131,    76,    58,    59,    61,   101,    60,   117,    58,
+     126,    70,    58,    59,    61,   106,    57,    59,    60,   100,
+     131,   102,   103,   114,   118,    58,    73,   105,    21,    25,
+     107,   108,    82,   128,    59,    62,    57,    59,    62,   103,
+     112,   108
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    63,    64,    65,    66,    67,    68,    68,    70,    71,
-      69,    72,    72,    72,    73,    73,    74,    75,    75,    76,
-      76,    76,    76,    77,    77,    78,    79,    79,    80,    81,
-      82,    83,    84,    84,    85,    86,    86,    86,    86,    86,
-      86,    86,    86,    86,    86,    86,    87,    87,    87,    88,
-      88,    89,    89,    90,    90,    91,    91,    92,    93,    93,
-      93,    94,    94,    95,    95,    96,    97,    97,    98,    99,
-      99,   100,   100,   101,   102,   102,   103,   104,   104,   105,
-     105,   106,   106,   107,   108,   109,   109,   110,   110,   111,
-     111,   111,   111,   111,   111,   111,   111,   111,   111,   111,
-     111,   111,   111,   111,   111,   112,   112,   113,   113,   113,
-     114,   114,   115,   116,   116,   117,   118,   118,   119,   119,
-     120,   120,   120,   120,   120,   120,   121,   122,   123,   123,
-     124,   124,   124,   124,   124,   124,   124,   124,   124,   124,
-     124,   124,   125,   125,   126,   126,   126,   126,   127,   128,
-     128,   129
+       0,    65,    66,    67,    68,    69,    70,    70,    72,    73,
+      71,    74,    74,    74,    75,    75,    76,    77,    77,    78,
+      78,    78,    78,    79,    79,    80,    81,    81,    82,    83,
+      84,    85,    86,    86,    87,    88,    88,    88,    88,    88,
+      88,    88,    88,    88,    88,    88,    88,    89,    89,    89,
+      90,    90,    91,    91,    92,    92,    93,    93,    94,    95,
+      95,    95,    96,    96,    97,    97,    98,    99,    99,   100,
+     101,   101,   102,   102,   103,   104,   104,   105,   106,   106,
+     107,   107,   108,   108,   109,   110,   111,   111,   112,   112,
+     113,   113,   113,   113,   113,   113,   113,   113,   113,   113,
+     113,   113,   113,   113,   113,   113,   113,   114,   114,   115,
+     115,   115,   116,   116,   117,   118,   118,   119,   120,   120,
+     121,   121,   122,   122,   122,   122,   122,   122,   123,   124,
+     125,   125,   126,   126,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   127,   127,   128,   128,   128,   128,
+     129,   130,   130,   131
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -929,18 +943,18 @@ static const yytype_uint8 yyr2[] =
        9,     0,     1,     2,     1,     2,     1,     1,     2,     2,
        2,     2,     2,     0,     1,     6,     1,     3,     3,     5,
        5,     5,     2,     3,     2,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     0,     1,     2,     2,
-       3,     1,     1,     1,     3,     3,     3,     1,     0,     1,
-       2,     2,     3,     1,     1,     2,     1,     3,     2,     0,
-       3,     1,     3,     1,     1,     3,     2,     0,     3,     1,
-       3,     1,     1,     1,     1,     1,     1,     0,     3,     4,
-       4,     4,     4,     6,     5,     5,     6,     5,     5,     5,
-       5,     5,     5,     5,     4,     1,     1,     0,     1,     2,
-       2,     3,     3,     1,     1,     0,     1,     3,     1,     3,
-       1,     1,     1,     1,     1,     1,     1,     4,     1,     3,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     3,     1,     1,     1,     1,     1,     1,
-       1,     1
+       1,     1,     1,     1,     1,     1,     1,     0,     1,     2,
+       2,     3,     1,     1,     1,     3,     3,     3,     1,     0,
+       1,     2,     2,     3,     1,     1,     2,     1,     3,     2,
+       0,     3,     1,     3,     1,     1,     3,     2,     0,     3,
+       1,     3,     1,     1,     1,     1,     1,     1,     0,     3,
+       4,     4,     4,     4,     6,     5,     5,     6,     5,     5,
+       5,     5,     5,     5,     5,     5,     4,     1,     1,     0,
+       1,     2,     2,     3,     3,     1,     1,     0,     1,     3,
+       1,     3,     1,     1,     1,     1,     1,     1,     1,     4,
+       1,     3,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     3,     1,     1,     1,     1,
+       1,     1,     1,     1
 };
 
 
@@ -1617,19 +1631,19 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 221 "ncgen.y" /* yacc.c:1646  */
+#line 227 "ncgen.y" /* yacc.c:1646  */
     {if (error_count > 0) YYABORT;}
-#line 1623 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1637 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 3:
-#line 224 "ncgen.y" /* yacc.c:1646  */
+#line 230 "ncgen.y" /* yacc.c:1646  */
     {createrootgroup(datasetname);}
-#line 1629 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1643 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 8:
-#line 243 "ncgen.y" /* yacc.c:1646  */
+#line 249 "ncgen.y" /* yacc.c:1646  */
     {
 		Symbol* id = (yyvsp[-1].sym);
                 markcdf4("Group specification");
@@ -1637,29 +1651,29 @@ yyreduce:
                     yyerror("duplicate group declaration within parent group for %s",
                                 id->name);
             }
-#line 1641 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1655 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 9:
-#line 252 "ncgen.y" /* yacc.c:1646  */
+#line 258 "ncgen.y" /* yacc.c:1646  */
     {listpop(groupstack);}
-#line 1647 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1661 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 12:
-#line 258 "ncgen.y" /* yacc.c:1646  */
+#line 264 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1653 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1667 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 13:
-#line 260 "ncgen.y" /* yacc.c:1646  */
+#line 266 "ncgen.y" /* yacc.c:1646  */
     {markcdf4("Type specification");}
-#line 1659 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1673 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 16:
-#line 266 "ncgen.y" /* yacc.c:1646  */
+#line 272 "ncgen.y" /* yacc.c:1646  */
     { /* Use when defining a type */
               (yyvsp[0].sym)->objectclass = NC_TYPE;
               if(dupobjectcheck(NC_TYPE,(yyvsp[0].sym)))
@@ -1667,23 +1681,23 @@ yyreduce:
                             (yyvsp[0].sym)->name);
               listpush(typdefs,(void*)(yyvsp[0].sym));
 	    }
-#line 1671 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1685 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 17:
-#line 275 "ncgen.y" /* yacc.c:1646  */
+#line 281 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1677 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1691 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 275 "ncgen.y" /* yacc.c:1646  */
+#line 281 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1683 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1697 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 25:
-#line 289 "ncgen.y" /* yacc.c:1646  */
+#line 295 "ncgen.y" /* yacc.c:1646  */
     {
 		int i;
                 addtogroup((yyvsp[-3].sym)); /* sets prefix*/
@@ -1710,17 +1724,17 @@ yyreduce:
                 }
                 listsetlength(stack,stackbase);/* remove stack nodes*/
               }
-#line 1714 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1728 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 26:
-#line 318 "ncgen.y" /* yacc.c:1646  */
+#line 324 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 1720 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1734 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 27:
-#line 320 "ncgen.y" /* yacc.c:1646  */
+#line 326 "ncgen.y" /* yacc.c:1646  */
     {
 		    int i;
 		    (yyval.mark)=(yyvsp[-2].mark);
@@ -1735,22 +1749,22 @@ yyreduce:
 		    }
 		    listpush(stack,(void*)(yyvsp[0].sym));
 		}
-#line 1739 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1753 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 28:
-#line 337 "ncgen.y" /* yacc.c:1646  */
+#line 343 "ncgen.y" /* yacc.c:1646  */
     {
             (yyvsp[-2].sym)->objectclass=NC_TYPE;
             (yyvsp[-2].sym)->subclass=NC_ECONST;
             (yyvsp[-2].sym)->typ.econst=(yyvsp[0].constant);
 	    (yyval.sym)=(yyvsp[-2].sym);
         }
-#line 1750 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1764 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 29:
-#line 346 "ncgen.y" /* yacc.c:1646  */
+#line 352 "ncgen.y" /* yacc.c:1646  */
     {
 		    vercheck(NC_OPAQUE);
                     addtogroup((yyvsp[0].sym)); /*sets prefix*/
@@ -1760,11 +1774,11 @@ yyreduce:
                     (yyvsp[0].sym)->typ.size=int32_val;
                     (yyvsp[0].sym)->typ.alignment=nctypealignment(NC_OPAQUE);
                 }
-#line 1764 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1778 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 30:
-#line 358 "ncgen.y" /* yacc.c:1646  */
+#line 364 "ncgen.y" /* yacc.c:1646  */
     {
                     Symbol* basetype = (yyvsp[-4].sym);
 		    vercheck(NC_VLEN);
@@ -1776,11 +1790,11 @@ yyreduce:
                     (yyvsp[0].sym)->typ.size=VLENSIZE;
                     (yyvsp[0].sym)->typ.alignment=nctypealignment(NC_VLEN);
                 }
-#line 1780 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1794 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 31:
-#line 372 "ncgen.y" /* yacc.c:1646  */
+#line 378 "ncgen.y" /* yacc.c:1646  */
     {
 	    int i,j;
 	    vercheck(NC_COMPOUND);
@@ -1810,23 +1824,23 @@ yyreduce:
 	    }
 	    listsetlength(stack,stackbase);/* remove stack nodes*/
           }
-#line 1814 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1828 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 32:
-#line 404 "ncgen.y" /* yacc.c:1646  */
+#line 410 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-1].mark);}
-#line 1820 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1834 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 33:
-#line 405 "ncgen.y" /* yacc.c:1646  */
+#line 411 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-2].mark);}
-#line 1826 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1840 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 34:
-#line 409 "ncgen.y" /* yacc.c:1646  */
+#line 415 "ncgen.y" /* yacc.c:1646  */
     {
 	    int i;
 	    (yyval.mark)=(yyvsp[0].mark);
@@ -1838,112 +1852,118 @@ yyreduce:
 		f->typ.basetype = (yyvsp[-1].sym);
             }
         }
-#line 1842 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1856 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 35:
-#line 422 "ncgen.y" /* yacc.c:1646  */
+#line 428 "ncgen.y" /* yacc.c:1646  */
     { (yyval.sym) = primsymbols[NC_CHAR]; }
-#line 1848 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1862 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 36:
-#line 423 "ncgen.y" /* yacc.c:1646  */
+#line 429 "ncgen.y" /* yacc.c:1646  */
     { (yyval.sym) = primsymbols[NC_BYTE]; }
-#line 1854 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1868 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 37:
-#line 424 "ncgen.y" /* yacc.c:1646  */
+#line 430 "ncgen.y" /* yacc.c:1646  */
     { (yyval.sym) = primsymbols[NC_SHORT]; }
-#line 1860 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1874 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 38:
-#line 425 "ncgen.y" /* yacc.c:1646  */
+#line 431 "ncgen.y" /* yacc.c:1646  */
     { (yyval.sym) = primsymbols[NC_INT]; }
-#line 1866 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1880 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 39:
-#line 426 "ncgen.y" /* yacc.c:1646  */
+#line 432 "ncgen.y" /* yacc.c:1646  */
     { (yyval.sym) = primsymbols[NC_FLOAT]; }
-#line 1872 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1886 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 40:
-#line 427 "ncgen.y" /* yacc.c:1646  */
+#line 433 "ncgen.y" /* yacc.c:1646  */
     { (yyval.sym) = primsymbols[NC_DOUBLE]; }
-#line 1878 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1892 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 41:
-#line 428 "ncgen.y" /* yacc.c:1646  */
+#line 434 "ncgen.y" /* yacc.c:1646  */
     { vercheck(NC_UBYTE); (yyval.sym) = primsymbols[NC_UBYTE]; }
-#line 1884 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1898 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 42:
-#line 429 "ncgen.y" /* yacc.c:1646  */
+#line 435 "ncgen.y" /* yacc.c:1646  */
     { vercheck(NC_USHORT); (yyval.sym) = primsymbols[NC_USHORT]; }
-#line 1890 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1904 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 43:
-#line 430 "ncgen.y" /* yacc.c:1646  */
+#line 436 "ncgen.y" /* yacc.c:1646  */
     { vercheck(NC_UINT); (yyval.sym) = primsymbols[NC_UINT]; }
-#line 1896 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1910 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 44:
-#line 431 "ncgen.y" /* yacc.c:1646  */
+#line 437 "ncgen.y" /* yacc.c:1646  */
     { vercheck(NC_INT64); (yyval.sym) = primsymbols[NC_INT64]; }
-#line 1902 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1916 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 45:
-#line 432 "ncgen.y" /* yacc.c:1646  */
+#line 438 "ncgen.y" /* yacc.c:1646  */
     { vercheck(NC_UINT64); (yyval.sym) = primsymbols[NC_UINT64]; }
-#line 1908 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1922 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 47:
-#line 436 "ncgen.y" /* yacc.c:1646  */
-    {}
-#line 1914 "ncgen.tab.c" /* yacc.c:1646  */
+  case 46:
+#line 439 "ncgen.y" /* yacc.c:1646  */
+    { vercheck(NC_STRING); (yyval.sym) = primsymbols[NC_STRING]; }
+#line 1928 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 48:
-#line 437 "ncgen.y" /* yacc.c:1646  */
+#line 443 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1920 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1934 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 51:
+  case 49:
 #line 444 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1926 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1940 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 52:
-#line 444 "ncgen.y" /* yacc.c:1646  */
+#line 451 "ncgen.y" /* yacc.c:1646  */
+    {}
+#line 1946 "ncgeny.c" /* yacc.c:1646  */
+    break;
+
+  case 53:
+#line 451 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1932 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1952 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 55:
-#line 452 "ncgen.y" /* yacc.c:1646  */
+  case 56:
+#line 459 "ncgen.y" /* yacc.c:1646  */
     {
 		(yyvsp[-2].sym)->dim.declsize = (size_t)extractint((yyvsp[0].constant));
 #ifdef GENDEBUG1
 fprintf(stderr,"dimension: %s = %llu\n",(yyvsp[-2].sym)->name,(unsigned long long)(yyvsp[-2].sym)->dim.declsize);
 #endif
 	      }
-#line 1943 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1963 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 56:
-#line 459 "ncgen.y" /* yacc.c:1646  */
+  case 57:
+#line 466 "ncgen.y" /* yacc.c:1646  */
     {
 		        (yyvsp[-2].sym)->dim.declsize = NC_UNLIMITED;
 		        (yyvsp[-2].sym)->dim.isunlimited = 1;
@@ -1951,11 +1971,11 @@ fprintf(stderr,"dimension: %s = %llu\n",(yyvsp[-2].sym)->name,(unsigned long lon
 fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 #endif
 		   }
-#line 1955 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1975 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 57:
-#line 469 "ncgen.y" /* yacc.c:1646  */
+  case 58:
+#line 476 "ncgen.y" /* yacc.c:1646  */
     {
                      (yyvsp[0].sym)->objectclass=NC_DIM;
                      if(dupobjectcheck(NC_DIM,(yyvsp[0].sym)))
@@ -1965,35 +1985,35 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		     (yyval.sym)=(yyvsp[0].sym);
 		     listpush(dimdefs,(void*)(yyvsp[0].sym));
                    }
-#line 1969 "ncgen.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 59:
-#line 481 "ncgen.y" /* yacc.c:1646  */
-    {}
-#line 1975 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1989 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 60:
-#line 482 "ncgen.y" /* yacc.c:1646  */
+#line 488 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1981 "ncgen.tab.c" /* yacc.c:1646  */
+#line 1995 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 63:
+  case 61:
 #line 489 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1987 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2001 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 64:
-#line 489 "ncgen.y" /* yacc.c:1646  */
+#line 496 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 1993 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2007 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 65:
-#line 492 "ncgen.y" /* yacc.c:1646  */
+#line 496 "ncgen.y" /* yacc.c:1646  */
+    {}
+#line 2013 "ncgeny.c" /* yacc.c:1646  */
+    break;
+
+  case 66:
+#line 499 "ncgen.y" /* yacc.c:1646  */
     {
 		    int i;
 		    stackbase=(yyvsp[0].mark);
@@ -2013,25 +2033,25 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		    }
 		    listsetlength(stack,stackbase);/* remove stack nodes*/
 		}
-#line 2017 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2037 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 66:
-#line 514 "ncgen.y" /* yacc.c:1646  */
+  case 67:
+#line 521 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack);
                  listpush(stack,(void*)(yyvsp[0].sym));
 		}
-#line 2025 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2045 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 67:
-#line 518 "ncgen.y" /* yacc.c:1646  */
+  case 68:
+#line 525 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 2031 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2051 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 68:
-#line 522 "ncgen.y" /* yacc.c:1646  */
+  case 69:
+#line 529 "ncgen.y" /* yacc.c:1646  */
     {
 		    int i;
 		    Dimset dimset;
@@ -2056,35 +2076,35 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
                     (yyvsp[-1].sym)->objectclass=NC_VAR;
 		    listsetlength(stack,stackbase);/* remove stack nodes*/
 		    }
-#line 2060 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2080 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 69:
-#line 548 "ncgen.y" /* yacc.c:1646  */
+  case 70:
+#line 555 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack);}
-#line 2066 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2086 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 70:
-#line 549 "ncgen.y" /* yacc.c:1646  */
+  case 71:
+#line 556 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-1].mark);}
-#line 2072 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2092 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 71:
-#line 552 "ncgen.y" /* yacc.c:1646  */
+  case 72:
+#line 559 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 2078 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2098 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 72:
-#line 554 "ncgen.y" /* yacc.c:1646  */
+  case 73:
+#line 561 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 2084 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2104 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 73:
-#line 558 "ncgen.y" /* yacc.c:1646  */
+  case 74:
+#line 565 "ncgen.y" /* yacc.c:1646  */
     {Symbol* dimsym = (yyvsp[0].sym);
 		dimsym->objectclass = NC_DIM;
 		/* Find the actual dimension*/
@@ -2095,25 +2115,25 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		}
 		(yyval.sym)=dimsym;
 	    }
-#line 2099 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2119 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 74:
-#line 572 "ncgen.y" /* yacc.c:1646  */
+  case 75:
+#line 579 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack);
              listpush(stack,(void*)(yyvsp[0].sym));
 	    }
-#line 2107 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2127 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 75:
-#line 576 "ncgen.y" /* yacc.c:1646  */
+  case 76:
+#line 583 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 2113 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2133 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 76:
-#line 581 "ncgen.y" /* yacc.c:1646  */
+  case 77:
+#line 588 "ncgen.y" /* yacc.c:1646  */
     {
 		int i;
 		Dimset dimset;
@@ -2140,35 +2160,35 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		listsetlength(stack,stackbase);/* remove stack nodes*/
 		(yyval.sym) = (yyvsp[-1].sym);
 	    }
-#line 2144 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2164 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 77:
-#line 609 "ncgen.y" /* yacc.c:1646  */
+  case 78:
+#line 616 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack);}
-#line 2150 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2170 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 78:
-#line 610 "ncgen.y" /* yacc.c:1646  */
+  case 79:
+#line 617 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-1].mark);}
-#line 2156 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2176 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 79:
-#line 614 "ncgen.y" /* yacc.c:1646  */
+  case 80:
+#line 621 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=listlength(stack); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 2162 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2182 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 80:
-#line 616 "ncgen.y" /* yacc.c:1646  */
+  case 81:
+#line 623 "ncgen.y" /* yacc.c:1646  */
     {(yyval.mark)=(yyvsp[-2].mark); listpush(stack,(void*)(yyvsp[0].sym));}
-#line 2168 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2188 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 81:
-#line 621 "ncgen.y" /* yacc.c:1646  */
+  case 82:
+#line 628 "ncgen.y" /* yacc.c:1646  */
     {  /* Anonymous integer dimension.
 	         Can only occur in type definitions*/
 	     char anon[32];
@@ -2178,11 +2198,11 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 	     (yyval.sym)->dim.isconstant = 1;
 	     (yyval.sym)->dim.declsize = uint32_val;
 	    }
-#line 2182 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2202 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 82:
-#line 631 "ncgen.y" /* yacc.c:1646  */
+  case 83:
+#line 638 "ncgen.y" /* yacc.c:1646  */
     {  /* Anonymous integer dimension.
 	         Can only occur in type definitions*/
 	     char anon[32];
@@ -2196,11 +2216,11 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 	     (yyval.sym)->dim.isconstant = 1;
 	     (yyval.sym)->dim.declsize = int32_val;
 	    }
-#line 2200 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2220 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 83:
-#line 651 "ncgen.y" /* yacc.c:1646  */
+  case 84:
+#line 658 "ncgen.y" /* yacc.c:1646  */
     {Symbol* vsym = (yyvsp[0].sym);
 		if(vsym->objectclass != NC_VAR) {
 		    derror("Undefined or forward referenced variable: %s",vsym->name);
@@ -2208,11 +2228,11 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		}
 		(yyval.sym)=vsym;
 	    }
-#line 2212 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2232 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 84:
-#line 662 "ncgen.y" /* yacc.c:1646  */
+  case 85:
+#line 669 "ncgen.y" /* yacc.c:1646  */
     {Symbol* tsym = (yyvsp[0].sym);
 		if(tsym->objectclass != NC_TYPE) {
 		    derror("Undefined or forward referenced type: %s",tsym->name);
@@ -2220,11 +2240,11 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		}
 		(yyval.sym)=tsym;
 	    }
-#line 2224 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2244 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 85:
-#line 673 "ncgen.y" /* yacc.c:1646  */
+  case 86:
+#line 680 "ncgen.y" /* yacc.c:1646  */
     {Symbol* tvsym = (yyvsp[0].sym); Symbol* sym;
 		/* disambiguate*/
 		tvsym->objectclass = NC_VAR;
@@ -2243,53 +2263,53 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		}
 		(yyval.sym)=tvsym;
 	    }
-#line 2247 "ncgen.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 86:
-#line 691 "ncgen.y" /* yacc.c:1646  */
-    {(yyval.sym)=(yyvsp[0].sym);}
-#line 2253 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2267 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 87:
 #line 698 "ncgen.y" /* yacc.c:1646  */
-    {}
-#line 2259 "ncgen.tab.c" /* yacc.c:1646  */
+    {(yyval.sym)=(yyvsp[0].sym);}
+#line 2273 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 88:
-#line 698 "ncgen.y" /* yacc.c:1646  */
+#line 705 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 2265 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2279 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 89:
-#line 702 "ncgen.y" /* yacc.c:1646  */
-    {(yyval.sym) = makespecial(_NCPROPS_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);}
-#line 2271 "ncgen.tab.c" /* yacc.c:1646  */
+#line 705 "ncgen.y" /* yacc.c:1646  */
+    {}
+#line 2285 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 90:
-#line 704 "ncgen.y" /* yacc.c:1646  */
-    {(yyval.sym) = makespecial(_ISNETCDF4_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);}
-#line 2277 "ncgen.tab.c" /* yacc.c:1646  */
+#line 709 "ncgen.y" /* yacc.c:1646  */
+    {(yyval.sym) = makespecial(_NCPROPS_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);}
+#line 2291 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 91:
-#line 706 "ncgen.y" /* yacc.c:1646  */
-    {(yyval.sym) = makespecial(_SUPERBLOCK_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);}
-#line 2283 "ncgen.tab.c" /* yacc.c:1646  */
+#line 711 "ncgen.y" /* yacc.c:1646  */
+    {(yyval.sym) = makespecial(_ISNETCDF4_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);}
+#line 2297 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 92:
-#line 708 "ncgen.y" /* yacc.c:1646  */
-    { (yyval.sym)=makeattribute((yyvsp[-2].sym),NULL,NULL,(yyvsp[0].datalist),ATTRGLOBAL);}
-#line 2289 "ncgen.tab.c" /* yacc.c:1646  */
+#line 713 "ncgen.y" /* yacc.c:1646  */
+    {(yyval.sym) = makespecial(_SUPERBLOCK_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),ATTRGLOBAL);}
+#line 2303 "ncgeny.c" /* yacc.c:1646  */
     break;
 
   case 93:
-#line 710 "ncgen.y" /* yacc.c:1646  */
+#line 715 "ncgen.y" /* yacc.c:1646  */
+    { (yyval.sym)=makeattribute((yyvsp[-2].sym),NULL,NULL,(yyvsp[0].datalist),ATTRGLOBAL);}
+#line 2309 "ncgeny.c" /* yacc.c:1646  */
+    break;
+
+  case 94:
+#line 717 "ncgen.y" /* yacc.c:1646  */
     {Symbol* tsym = (yyvsp[-5].sym); Symbol* vsym = (yyvsp[-4].sym); Symbol* asym = (yyvsp[-2].sym);
 		if(vsym->objectclass == NC_VAR) {
 		    (yyval.sym)=makeattribute(asym,vsym,tsym,(yyvsp[0].datalist),ATTRVAR);
@@ -2298,11 +2318,11 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		    YYABORT;
 		}
 	    }
-#line 2302 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2322 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 94:
-#line 719 "ncgen.y" /* yacc.c:1646  */
+  case 95:
+#line 726 "ncgen.y" /* yacc.c:1646  */
     {Symbol* sym = (yyvsp[-4].sym); Symbol* asym = (yyvsp[-2].sym);
 		if(sym->objectclass == NC_VAR) {
 		    (yyval.sym)=makeattribute(asym,sym,NULL,(yyvsp[0].datalist),ATTRVAR);
@@ -2313,339 +2333,345 @@ fprintf(stderr,"dimension: %s = UNLIMITED\n",(yyvsp[-2].sym)->name);
 		    YYABORT;
 		}
 	    }
-#line 2317 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2337 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 95:
-#line 730 "ncgen.y" /* yacc.c:1646  */
+  case 96:
+#line 737 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[-4].sym),NULL,(void*)(yyvsp[0].datalist),0);}
-#line 2323 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2343 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 96:
-#line 732 "ncgen.y" /* yacc.c:1646  */
+  case 97:
+#line 739 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_FILLVALUE_FLAG,(yyvsp[-4].sym),(yyvsp[-5].sym),(void*)(yyvsp[0].datalist),0);}
-#line 2329 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2349 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 97:
-#line 734 "ncgen.y" /* yacc.c:1646  */
+  case 98:
+#line 741 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_STORAGE_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2335 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2355 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 98:
-#line 736 "ncgen.y" /* yacc.c:1646  */
+  case 99:
+#line 743 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_CHUNKSIZES_FLAG,(yyvsp[-4].sym),NULL,(void*)(yyvsp[0].datalist),0);}
-#line 2341 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2361 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 99:
-#line 738 "ncgen.y" /* yacc.c:1646  */
+  case 100:
+#line 745 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_FLETCHER32_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2347 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2367 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 100:
-#line 740 "ncgen.y" /* yacc.c:1646  */
+  case 101:
+#line 747 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_DEFLATE_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2353 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2373 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 101:
-#line 742 "ncgen.y" /* yacc.c:1646  */
+  case 102:
+#line 749 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_SHUFFLE_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2359 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2379 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 102:
-#line 744 "ncgen.y" /* yacc.c:1646  */
+  case 103:
+#line 751 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_ENDIAN_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2365 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2385 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 103:
-#line 746 "ncgen.y" /* yacc.c:1646  */
+  case 104:
+#line 753 "ncgen.y" /* yacc.c:1646  */
+    {(yyval.sym) = makespecial(_FILTER_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
+#line 2391 "ncgeny.c" /* yacc.c:1646  */
+    break;
+
+  case 105:
+#line 755 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_NOFILL_FLAG,(yyvsp[-4].sym),NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2371 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2397 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 104:
-#line 748 "ncgen.y" /* yacc.c:1646  */
+  case 106:
+#line 757 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym) = makespecial(_FORMAT_FLAG,NULL,NULL,(void*)&(yyvsp[0].constant),1);}
-#line 2377 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2403 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 105:
-#line 753 "ncgen.y" /* yacc.c:1646  */
+  case 107:
+#line 762 "ncgen.y" /* yacc.c:1646  */
     {
 	        (yyval.sym)=(yyvsp[0].sym);
                 (yyvsp[0].sym)->ref.is_ref=1;
                 (yyvsp[0].sym)->is_prefixed=0;
                 setpathcurrent((yyvsp[0].sym));
 	    }
-#line 2388 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2414 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 106:
-#line 760 "ncgen.y" /* yacc.c:1646  */
+  case 108:
+#line 769 "ncgen.y" /* yacc.c:1646  */
     {
 	        (yyval.sym)=(yyvsp[0].sym);
                 (yyvsp[0].sym)->ref.is_ref=1;
                 (yyvsp[0].sym)->is_prefixed=1;
 	        /* path is set in ncgen.l*/
 	    }
-#line 2399 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2425 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 108:
-#line 769 "ncgen.y" /* yacc.c:1646  */
+  case 110:
+#line 778 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 2405 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2431 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 109:
-#line 770 "ncgen.y" /* yacc.c:1646  */
+  case 111:
+#line 779 "ncgen.y" /* yacc.c:1646  */
     {}
-#line 2411 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2437 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 112:
-#line 778 "ncgen.y" /* yacc.c:1646  */
+  case 114:
+#line 787 "ncgen.y" /* yacc.c:1646  */
     {(yyvsp[-2].sym)->data = (yyvsp[0].datalist);}
-#line 2417 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2443 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 113:
-#line 781 "ncgen.y" /* yacc.c:1646  */
+  case 115:
+#line 790 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist) = (yyvsp[0].datalist);}
-#line 2423 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2449 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 114:
-#line 782 "ncgen.y" /* yacc.c:1646  */
+  case 116:
+#line 791 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist) = (yyvsp[0].datalist);}
-#line 2429 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2455 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 115:
-#line 786 "ncgen.y" /* yacc.c:1646  */
+  case 117:
+#line 795 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist) = builddatalist(0);}
-#line 2435 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2461 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 116:
-#line 790 "ncgen.y" /* yacc.c:1646  */
+  case 118:
+#line 799 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[0].constant)));}
-#line 2441 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2467 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 117:
-#line 792 "ncgen.y" /* yacc.c:1646  */
+  case 119:
+#line 801 "ncgen.y" /* yacc.c:1646  */
     {datalistextend((yyvsp[-2].datalist),&((yyvsp[0].constant))); (yyval.datalist)=(yyvsp[-2].datalist);}
-#line 2447 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2473 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 118:
-#line 796 "ncgen.y" /* yacc.c:1646  */
+  case 120:
+#line 805 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=(yyvsp[0].constant);}
-#line 2453 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2479 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 119:
-#line 797 "ncgen.y" /* yacc.c:1646  */
+  case 121:
+#line 806 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=builddatasublist((yyvsp[-1].datalist));}
-#line 2459 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2485 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 120:
-#line 801 "ncgen.y" /* yacc.c:1646  */
+  case 122:
+#line 810 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=(yyvsp[0].constant);}
-#line 2465 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2491 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 121:
-#line 802 "ncgen.y" /* yacc.c:1646  */
+  case 123:
+#line 811 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_OPAQUE);}
-#line 2471 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2497 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 122:
-#line 803 "ncgen.y" /* yacc.c:1646  */
+  case 124:
+#line 812 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_FILLVALUE);}
-#line 2477 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2503 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 123:
-#line 804 "ncgen.y" /* yacc.c:1646  */
+  case 125:
+#line 813 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_NIL);}
-#line 2483 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2509 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 124:
-#line 805 "ncgen.y" /* yacc.c:1646  */
+  case 126:
+#line 814 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=(yyvsp[0].constant);}
-#line 2489 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2515 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 126:
-#line 810 "ncgen.y" /* yacc.c:1646  */
+  case 128:
+#line 819 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant) = makeenumconstref((yyvsp[0].sym));}
-#line 2495 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2521 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 127:
-#line 814 "ncgen.y" /* yacc.c:1646  */
+  case 129:
+#line 823 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=evaluate((yyvsp[-3].sym),(yyvsp[-1].datalist));}
-#line 2501 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2527 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 128:
-#line 819 "ncgen.y" /* yacc.c:1646  */
+  case 130:
+#line 828 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[0].constant)));}
-#line 2507 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2533 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 129:
-#line 821 "ncgen.y" /* yacc.c:1646  */
+  case 131:
+#line 830 "ncgen.y" /* yacc.c:1646  */
     {datalistextend((yyvsp[-2].datalist),&((yyvsp[0].constant))); (yyval.datalist)=(yyvsp[-2].datalist);}
-#line 2513 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2539 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 130:
-#line 825 "ncgen.y" /* yacc.c:1646  */
+  case 132:
+#line 834 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_CHAR);}
-#line 2519 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2545 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 131:
-#line 826 "ncgen.y" /* yacc.c:1646  */
+  case 133:
+#line 835 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_BYTE);}
-#line 2525 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2551 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 132:
-#line 827 "ncgen.y" /* yacc.c:1646  */
+  case 134:
+#line 836 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_SHORT);}
-#line 2531 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2557 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 133:
-#line 828 "ncgen.y" /* yacc.c:1646  */
+  case 135:
+#line 837 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_INT);}
-#line 2537 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2563 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 134:
-#line 829 "ncgen.y" /* yacc.c:1646  */
+  case 136:
+#line 838 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_INT64);}
-#line 2543 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2569 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 135:
-#line 830 "ncgen.y" /* yacc.c:1646  */
+  case 137:
+#line 839 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_UBYTE);}
-#line 2549 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2575 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 136:
-#line 831 "ncgen.y" /* yacc.c:1646  */
+  case 138:
+#line 840 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_USHORT);}
-#line 2555 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2581 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 137:
-#line 832 "ncgen.y" /* yacc.c:1646  */
+  case 139:
+#line 841 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_UINT);}
-#line 2561 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2587 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 138:
-#line 833 "ncgen.y" /* yacc.c:1646  */
+  case 140:
+#line 842 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_UINT64);}
-#line 2567 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2593 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 139:
-#line 834 "ncgen.y" /* yacc.c:1646  */
+  case 141:
+#line 843 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_FLOAT);}
-#line 2573 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2599 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 140:
-#line 835 "ncgen.y" /* yacc.c:1646  */
+  case 142:
+#line 844 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_DOUBLE);}
-#line 2579 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2605 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 141:
-#line 836 "ncgen.y" /* yacc.c:1646  */
+  case 143:
+#line 845 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_STRING);}
-#line 2585 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2611 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 142:
-#line 840 "ncgen.y" /* yacc.c:1646  */
+  case 144:
+#line 849 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist) = builddatalist(0); datalistextend((yyval.datalist),&((yyvsp[0].constant)));}
-#line 2591 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2617 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 143:
-#line 841 "ncgen.y" /* yacc.c:1646  */
+  case 145:
+#line 850 "ncgen.y" /* yacc.c:1646  */
     {(yyval.datalist)=(yyvsp[-2].datalist); datalistextend((yyvsp[-2].datalist),&((yyvsp[0].constant)));}
-#line 2597 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2623 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 144:
-#line 846 "ncgen.y" /* yacc.c:1646  */
+  case 146:
+#line 855 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_INT);}
-#line 2603 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2629 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 145:
-#line 848 "ncgen.y" /* yacc.c:1646  */
+  case 147:
+#line 857 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_UINT);}
-#line 2609 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2635 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 146:
-#line 850 "ncgen.y" /* yacc.c:1646  */
+  case 148:
+#line 859 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_INT64);}
-#line 2615 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2641 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 147:
-#line 852 "ncgen.y" /* yacc.c:1646  */
+  case 149:
+#line 861 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_UINT64);}
-#line 2621 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2647 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 148:
-#line 856 "ncgen.y" /* yacc.c:1646  */
+  case 150:
+#line 865 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=makeconstdata(NC_STRING);}
-#line 2627 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2653 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 149:
-#line 860 "ncgen.y" /* yacc.c:1646  */
+  case 151:
+#line 869 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=(yyvsp[0].constant);}
-#line 2633 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2659 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 150:
-#line 861 "ncgen.y" /* yacc.c:1646  */
+  case 152:
+#line 870 "ncgen.y" /* yacc.c:1646  */
     {(yyval.constant)=(yyvsp[0].constant);}
-#line 2639 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2665 "ncgeny.c" /* yacc.c:1646  */
     break;
 
-  case 151:
-#line 867 "ncgen.y" /* yacc.c:1646  */
+  case 153:
+#line 876 "ncgen.y" /* yacc.c:1646  */
     {(yyval.sym)=(yyvsp[0].sym);}
-#line 2645 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2671 "ncgeny.c" /* yacc.c:1646  */
     break;
 
 
-#line 2649 "ncgen.tab.c" /* yacc.c:1646  */
+#line 2675 "ncgeny.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -2873,7 +2899,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 870 "ncgen.y" /* yacc.c:1906  */
+#line 879 "ncgen.y" /* yacc.c:1906  */
 
 
 #ifndef NO_STDARG
@@ -3196,6 +3222,7 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
     case _STORAGE_FLAG:
     case _NCPROPS_FLAG:
     case _ENDIAN_FLAG:
+    case _FILTER_FLAG:
 	iconst.nctype = NC_STRING;
 	convert1(con,&iconst);
 	if(iconst.nctype == NC_STRING)
@@ -3325,6 +3352,11 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
                 special->flags |= _STORAGE_FLAG;
                 special->_Storage = NC_CHUNKED;
                 } break;
+          case _FILTER_FLAG:
+		/* Parse the filter spec */
+		if(parsefilterflag(sdata,special))
+                    special->flags |= _FILTER_FLAG;
+                break;
             default: PANIC1("makespecial: illegal token: %d",tag);
          }
     }
@@ -3401,15 +3433,19 @@ datalistextend(Datalist* dl, NCConstant* con)
     dlappend(dl,con);
 }
 
+/*
+Try to infer the file type from the
+kinds of constructs used in the cdl file.
+*/
 static void
 vercheck(int tid)
 {
     switch (tid) {
-    case NC_UBYTE: markcdf5("netCDF4/5 type: UBYTE"); break;
-    case NC_USHORT: markcdf5("netCDF4/5 type: USHORT"); break;
-    case NC_UINT: markcdf5("netCDF4/5 type: UINT"); break;
-    case NC_INT64: markcdf5("netCDF4/5 type: INT64"); break;
-    case NC_UINT64: markcdf5("netCDF4/5 type: UINT64"); break;
+    case NC_UBYTE: markcdf4("netCDF4/5 type: UBYTE"); break;
+    case NC_USHORT: markcdf4("netCDF4/5 type: USHORT"); break;
+    case NC_UINT: markcdf4("netCDF4/5 type: UINT"); break;
+    case NC_INT64: markcdf4("netCDF4/5 type: INT64"); break;
+    case NC_UINT64: markcdf4("netCDF4/5 type: UINT64"); break;
     case NC_STRING: markcdf4("netCDF4 type: STRING"); break;
     case NC_VLEN: markcdf4("netCDF4 type: VLEN"); break;
     case NC_OPAQUE: markcdf4("netCDF4 type: OPAQUE"); break;
@@ -3431,6 +3467,63 @@ specialname(int tag)
 }
 
 /*
+Parse a filter spec string and store it in special
+*/
+static int
+parsefilterflag(const char* sdata0, Specialdata* special)
+{
+    char* p;
+    char* sdata = NULL;
+    int stat;
+    size_t count;
+    unsigned int* ulist = NULL;
+
+    if(sdata0 == NULL || strlen(sdata0) == 0) goto fail;
+    sdata = strdup(sdata0);
+
+    /* Count number of unsigned integers and delimit */
+    p=sdata;
+    for(count=0;;count++) {
+        char* q = strchr(p,',');
+	if(q == NULL) break;
+	*q++ = '\0'; /* delimit */
+	p = q;
+    }
+    count++; /* for final piece */
+
+    /* Start by collecting the filter id */
+    p = sdata;
+    stat = sscanf(p,"%u",&special->_FilterID);
+    if(stat != 1) goto fail;
+    count--;  /* actual param count minus the id */
+
+    ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count));
+    if(ulist == NULL) goto fail;
+
+    special->nparams = count;
+    for(count=0;count < special->nparams ;) {
+        unsigned int uval;
+        p = p + strlen(p) + 1; /* move to next param */
+	stat = sscanf(p,"%u",&uval);
+	if(stat != 1) goto fail;
+	ulist[count++] = uval;
+    }
+    special->_FilterParams = ulist;
+    ulist = NULL; /* avoid duplicate free */
+
+    if(sdata) free(sdata);
+    if(ulist) free(ulist);
+    return 1;
+fail:
+    if(sdata) free(sdata);
+    if(ulist) free(ulist);
+    if(special) special->_FilterID = 0;
+    derror("Malformed filter spec: %s",sdata);
+
+    return 0;
+}
+
+/*
 Since the arguments are all simple constants,
 we can evaluate the function immediately
 and return its value.
diff --git a/ncgen/ncgeny.h b/ncgen/ncgeny.h
index a70994c..3c59b97 100644
--- a/ncgen/ncgeny.h
+++ b/ncgen/ncgeny.h
@@ -57,45 +57,47 @@ extern int ncgdebug;
     UINT_K = 267,
     INT64_K = 268,
     UINT64_K = 269,
-    IDENT = 270,
-    TERMSTRING = 271,
-    CHAR_CONST = 272,
-    BYTE_CONST = 273,
-    SHORT_CONST = 274,
-    INT_CONST = 275,
-    INT64_CONST = 276,
-    UBYTE_CONST = 277,
-    USHORT_CONST = 278,
-    UINT_CONST = 279,
-    UINT64_CONST = 280,
-    FLOAT_CONST = 281,
-    DOUBLE_CONST = 282,
-    DIMENSIONS = 283,
-    VARIABLES = 284,
-    NETCDF = 285,
-    DATA = 286,
-    TYPES = 287,
-    COMPOUND = 288,
-    ENUM = 289,
-    OPAQUE_ = 290,
-    OPAQUESTRING = 291,
-    GROUP = 292,
-    PATH = 293,
-    FILLMARKER = 294,
-    NIL = 295,
-    _FILLVALUE = 296,
-    _FORMAT = 297,
-    _STORAGE = 298,
-    _CHUNKSIZES = 299,
-    _DEFLATELEVEL = 300,
-    _SHUFFLE = 301,
-    _ENDIANNESS = 302,
-    _NOFILL = 303,
-    _FLETCHER32 = 304,
-    _NCPROPS = 305,
-    _ISNETCDF4 = 306,
-    _SUPERBLOCK = 307,
-    DATASETID = 308
+    STRING_K = 270,
+    IDENT = 271,
+    TERMSTRING = 272,
+    CHAR_CONST = 273,
+    BYTE_CONST = 274,
+    SHORT_CONST = 275,
+    INT_CONST = 276,
+    INT64_CONST = 277,
+    UBYTE_CONST = 278,
+    USHORT_CONST = 279,
+    UINT_CONST = 280,
+    UINT64_CONST = 281,
+    FLOAT_CONST = 282,
+    DOUBLE_CONST = 283,
+    DIMENSIONS = 284,
+    VARIABLES = 285,
+    NETCDF = 286,
+    DATA = 287,
+    TYPES = 288,
+    COMPOUND = 289,
+    ENUM = 290,
+    OPAQUE_ = 291,
+    OPAQUESTRING = 292,
+    GROUP = 293,
+    PATH = 294,
+    FILLMARKER = 295,
+    NIL = 296,
+    _FILLVALUE = 297,
+    _FORMAT = 298,
+    _STORAGE = 299,
+    _CHUNKSIZES = 300,
+    _DEFLATELEVEL = 301,
+    _SHUFFLE = 302,
+    _ENDIANNESS = 303,
+    _NOFILL = 304,
+    _FLETCHER32 = 305,
+    _NCPROPS = 306,
+    _ISNETCDF4 = 307,
+    _SUPERBLOCK = 308,
+    _FILTER = 309,
+    DATASETID = 310
   };
 #endif
 
@@ -104,16 +106,16 @@ extern int ncgdebug;
 
 union YYSTYPE
 {
-#line 138 "ncgen.y" /* yacc.c:1909  */
+#line 142 "ncgen.y" /* yacc.c:1909  */
 
 Symbol* sym;
 unsigned long  size; /* allow for zero size to indicate e.g. UNLIMITED*/
 long           mark; /* track indices into the sequence*/
 int            nctype; /* for tracking attribute list type*/
 Datalist*      datalist;
-NCConstant       constant;
+NCConstant     constant;
 
-#line 117 "ncgen.tab.h" /* yacc.c:1909  */
+#line 119 "ncgeny.h" /* yacc.c:1909  */
 };
 
 typedef union YYSTYPE YYSTYPE;
diff --git a/ncgen3/Makefile.in b/ncgen3/Makefile.in
index 474dbe2..e1725a5 100644
--- a/ncgen3/Makefile.in
+++ b/ncgen3/Makefile.in
@@ -104,11 +104,8 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
 bin_PROGRAMS = ncgen3$(EXEEXT)
- at USE_NETCDF4_TRUE@am__append_3 = run_nc4_tests.sh
+ at USE_NETCDF4_TRUE@am__append_2 = run_nc4_tests.sh
 subdir = ncgen3
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -407,11 +404,10 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = 
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -434,12 +430,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -465,6 +463,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -479,6 +478,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -582,7 +582,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 
@@ -601,7 +601,7 @@ EXTRA_DIST = ncgen.y ncgenyy.c ncgen.l c0.cdl run_tests.sh \
 # There is a netcdf classic and netcdf-4 test script, but don't run
 # them for DLL builds.
 #if !BUILD_DLL
-TESTS = run_tests.sh $(am__append_3)
+TESTS = run_tests.sh $(am__append_2)
 #endif # !BUILD_DLL
 CLEANFILES = c0.nc c0_64.nc c0_4.nc c0_4c.nc
 all: all-am
diff --git a/ncgen3/genlib.c b/ncgen3/genlib.c
index 177e45c..a54c066 100644
--- a/ncgen3/genlib.c
+++ b/ncgen3/genlib.c
@@ -1837,61 +1837,6 @@ grow_aarray(
   *arpp = (struct atts *) erealloc(*arpp, 2 * nar * sizeof(struct atts));
 }
 
-#ifndef HAVE_STRLCAT
-/*	$OpenBSD: strlcat.c,v 1.12 2005/03/30 20:13:52 otto Exp $	*/
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller at courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left).  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
-	char *d = dst;
-	const char *s = src;
-	size_t n = siz;
-	size_t dlen;
-
-	/* Find the end of dst and adjust bytes left but don't go past end */
-	while (n-- != 0 && *d != '\0')
-		d++;
-	dlen = d - dst;
-	n = siz - dlen;
-
-	if (n == 0)
-		return(dlen + strlen(s));
-	while (*s != '\0') {
-		if (n != 1) {
-			*d++ = *s;
-			n--;
-		}
-		s++;
-	}
-	*d = '\0';
-
-	return(dlen + (s - src));	/* count does not include NUL */
-}
-#endif /* ! HAVE_STRLCAT */
-
 
 /*
  * Replace special chars in name so it can be used in C and Fortran
diff --git a/ncgen3/genlib.h b/ncgen3/genlib.h
index 6c6f38a..45f139a 100644
--- a/ncgen3/genlib.h
+++ b/ncgen3/genlib.h
@@ -80,11 +80,6 @@ extern void nc_fill ( nc_type  type, size_t num, void* datp,
 /* reset symbol table to empty, defined in ncgen.y */
 extern void clearout(void);
 
-/* In case we are missing strlcat */
-#ifndef HAVE_STRLCAT
-extern size_t strlcat(char *dst, const char *src, size_t siz);
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/ncgen3/load.c b/ncgen3/load.c
index c02c4b4..401dd3d 100644
--- a/ncgen3/load.c
+++ b/ncgen3/load.c
@@ -15,10 +15,6 @@
 #include "ncgen.h"
 #include "genlib.h"
 
-#ifndef HAVE_STRLCAT
-extern size_t strlcat(char *dst, const char *src, size_t siz);
-#endif
-
 extern int netcdf_flag;
 extern int c_flag;
 extern int fortran_flag;
diff --git a/ncgen3/main.c b/ncgen3/main.c
index 2e035fe..c27f5ed 100644
--- a/ncgen3/main.c
+++ b/ncgen3/main.c
@@ -243,4 +243,3 @@ main(
 	return 1;
     return 0;
 }
-END_OF_MAIN()
diff --git a/nctest/CMakeLists.txt b/nctest/CMakeLists.txt
index d04126c..28a06b5 100644
--- a/nctest/CMakeLists.txt
+++ b/nctest/CMakeLists.txt
@@ -13,3 +13,5 @@ ADD_TEST(nctest ${EXECUTABLE_OUTPUT_PATH}/nctest)
 
 add_bin_test_no_prefix(tst_rename)
 add_sh_test(nctest compare_test_files)
+
+SET_TESTS_PROPERTIES(nctest_compare_test_files PROPERTIES DEPENDS nctest)
diff --git a/nctest/Makefile.am b/nctest/Makefile.am
index 4a9257c..9c8c05a 100644
--- a/nctest/Makefile.am
+++ b/nctest/Makefile.am
@@ -18,8 +18,7 @@ AM_LDFLAGS += ${top_builddir}/liblib/libnetcdf.la
 EXTRA_DIST = ref_nctest_classic.nc ref_nctest_64bit_offset.nc	\
 compare_test_files.sh run_valgrind_tests.sh CMakeLists.txt
 
-CLEANFILES = nctest_classic.nc nctest_64bit_offset.nc	\
-nctest_netcdf4.nc test2.nc temp.tmp tst_*.nc            \
+CLEANFILES = nctest_*.nc test2.nc temp.tmp tst_*.nc	\
 nctest_classic.cdl ref_nctest_classic.cdl
 
 # Run nctest and the script that compares the output with the
@@ -28,13 +27,17 @@ TESTPROGRAMS = nctest tst_rename
 check_PROGRAMS = $(TESTPROGRAMS)
 TESTS = $(TESTPROGRAMS) compare_test_files.sh
 
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
+
+# compare_test_files depends on nctest executing first.
+compare_test_files.log: nctest.log 
+
 # This will the test program with valgrind, the memory checking
 # tool. (Valgrind must be present for this to work.)
-if EXTRA_TESTS
 if USE_VALGRIND_TESTS
 TESTS += run_valgrind_tests.sh
 endif # USE_VALGRIND_TESTS
-endif # EXTRA_TESTS
 
 # These are the source files for the nctest program.
 nctest_SOURCES = add.c add.h atttests.c cdftests.c dimtests.c driver.c	\
diff --git a/nctest/Makefile.in b/nctest/Makefile.in
index 1d5ecca..38e84d7 100644
--- a/nctest/Makefile.in
+++ b/nctest/Makefile.in
@@ -102,15 +102,12 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @USE_DAP_TRUE at am__append_1 = -I${top_srcdir}/oc2
-
-# This turns on declspec magic in netcdf.h for windows DLLs.
- at BUILD_DLL_TRUE@am__append_2 = -DDLL_NETCDF
 check_PROGRAMS = $(am__EXEEXT_1)
-TESTS = $(am__EXEEXT_1) compare_test_files.sh $(am__append_3)
+TESTS = $(am__EXEEXT_1) compare_test_files.sh $(am__append_2)
 
 # This will the test program with valgrind, the memory checking
 # tool. (Valgrind must be present for this to work.)
- at EXTRA_TESTS_TRUE@@USE_VALGRIND_TESTS_TRUE at am__append_3 = run_valgrind_tests.sh
+ at USE_VALGRIND_TESTS_TRUE@am__append_2 = run_valgrind_tests.sh
 subdir = nctest
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -386,7 +383,6 @@ am__set_TESTS_bases = \
 RECHECK_LOGS = $(TEST_LOGS)
 AM_RECURSIVE_TARGETS = check recheck
 TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
 am__set_b = \
@@ -401,10 +397,9 @@ am__set_b = \
   esac
 am__test_logs1 = $(TESTS:=.log)
 am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
 	$(top_srcdir)/lib_flags.am $(top_srcdir)/test-driver README
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -412,13 +407,12 @@ ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_1)
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 
 # Put together AM_CPPFLAGS and AM_LDFLAGS.
 AM_LDFLAGS = ${top_builddir}/liblib/libnetcdf.la
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -441,12 +435,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -472,6 +468,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -486,6 +483,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -589,7 +587,7 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=${abs_top_builddir}; 
+AM_TESTS_ENVIRONMENT = export TOPSRCDIR=${abs_top_srcdir}; export TOPBUILDDIR=${abs_top_builddir}; 
 
 # Running nctest results in a file testfile.nc, which is then checked
 # to make sure it matches testfile_nc.sav, which was generated under
@@ -600,8 +598,7 @@ AM_TESTS_ENVIRONMENT = export DTOPSRCDIR=${abs_top_srcdir}; export DTOPBUILDDIR=
 EXTRA_DIST = ref_nctest_classic.nc ref_nctest_64bit_offset.nc	\
 compare_test_files.sh run_valgrind_tests.sh CMakeLists.txt
 
-CLEANFILES = nctest_classic.nc nctest_64bit_offset.nc	\
-nctest_netcdf4.nc test2.nc temp.tmp tst_*.nc            \
+CLEANFILES = nctest_*.nc test2.nc temp.tmp tst_*.nc	\
 nctest_classic.cdl ref_nctest_classic.cdl
 
 
@@ -609,6 +606,9 @@ nctest_classic.cdl ref_nctest_classic.cdl
 # reference file.
 TESTPROGRAMS = nctest tst_rename
 
+# Note which tests depend on other tests. Necessary for make -j check.
+TEST_EXTENSIONS = .sh
+
 # These are the source files for the nctest program.
 nctest_SOURCES = add.c add.h atttests.c cdftests.c dimtests.c driver.c	\
 emalloc.c emalloc.h error.c error.h misctest.c rec.c slabs.c testcdf.h	\
@@ -618,7 +618,7 @@ vartests.c vputget.c vputgetg.c
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+.SUFFIXES: .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib_flags.am $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -931,33 +931,19 @@ tst_rename.log: tst_rename$(EXEEXT)
 	--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)
-compare_test_files.sh.log: compare_test_files.sh
-	@p='compare_test_files.sh'; \
-	b='compare_test_files.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_valgrind_tests.sh.log: run_valgrind_tests.sh
-	@p='run_valgrind_tests.sh'; \
-	b='run_valgrind_tests.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)
-.test.log:
+.sh.log:
 	@p='$<'; \
 	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
- at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@.sh$(EXEEXT).log:
 @am__EXEEXT_TRUE@	@p='$<'; \
 @am__EXEEXT_TRUE@	$(am__set_b); \
- at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
- at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 distdir: $(DISTFILES)
@@ -1120,6 +1106,9 @@ uninstall-am:
 .PRECIOUS: Makefile
 
 
+# compare_test_files depends on nctest executing first.
+compare_test_files.log: nctest.log 
+
 # 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.
 .NOEXPORT:
diff --git a/nctest/driver.c b/nctest/driver.c
index 0830929..c874173 100644
--- a/nctest/driver.c
+++ b/nctest/driver.c
@@ -7,7 +7,7 @@
  * implementation of the netCDF library.  Must be invoked from a
  * directory in which the invoker has write permission.
  *
- * $Id: driver.c,v 1.32 2008/10/20 01:48:07 ed Exp $
+ * Glenn Davis, Russ Rew, Ed Hartnett
  *********************************************************************/
 
 #include <config.h>
@@ -18,118 +18,131 @@
 #include "testcdf.h"		/* defines in-memory test netcdf structure */
 #include "tests.h"
 
-/* Test everything for classic and 64-bit offsetfiles. If netcdf-4 is
- * included, that means another whole round of testing. */
+#define MAX_NUM_FORMATS 5
+
+/* Determine how many formats are available, and what they are. */
+void
+determine_test_formats(int *num_formats, int *format)
+{
+   int ind = 0;
+   int num;
+
+   /* We always have classic and 64-bit offset */
+   num = 2;
+   format[ind++] = NC_FORMAT_CLASSIC;
+   format[ind++] = NC_FORMAT_64BIT_OFFSET;
+
+   /* Do we have netCDF-4 and netCDF-4 classic? */
 #ifdef USE_NETCDF4
-#define NUM_FORMATS (3)
-#else
-#define NUM_FORMATS (2)
-#endif
+   num += 2;
+   format[ind++] = NC_FORMAT_NETCDF4_CLASSIC;
+   format[ind++] = NC_FORMAT_NETCDF4;
+#endif /* USE_NETCDF4 */
+
+   /* Do we have CDF5? */
+#ifdef ENABLE_CDF5
+   num++;
+   format[ind++] = NC_FORMAT_CDF5;
+#endif /* ENABLE_CDF5 */
+
+   *num_formats = num;
+}
 
 int
 main(int argc, char **argv)
 {
-  /*EXTERNL int ncopts;	*/	/* netCDF error options */
-    char *testfiles[] = {"nonesuch", "nctest_classic.nc", 
-			 "nctest_64bit_offset.nc", "nctest_netcdf4.nc"};
-    char *testfile = NULL;
-    int i, nerrs = 0;
-
-    ncopts &= ~NC_FATAL;	/* make errors nonfatal */
-    ncopts &= ~NC_VERBOSE;	/* turn off error messages */
-
-    fprintf(stderr, "Testing V2 API with %d different netCDF formats.\n", 
-	   NUM_FORMATS);
-
-    for (i = 1; i <= NUM_FORMATS; i++)
-    {
-       switch (i) 
-       {
-	  case NC_FORMAT_CLASSIC:
-	     nc_set_default_format(NC_FORMAT_CLASSIC, NULL);
-	     fprintf(stderr, "\n\nSwitching to netCDF classic format.\n");
-	     break;
-	  case NC_FORMAT_64BIT_OFFSET:
-	     nc_set_default_format(NC_FORMAT_64BIT_OFFSET, NULL);
-	     fprintf(stderr, "\n\nSwitching to 64-bit offset format.\n");
-	     break;
-#ifdef USE_NETCDF4 
-	  case NC_FORMAT_NETCDF4: /* actually it's _CLASSIC. */
-	     nc_set_default_format(NC_FORMAT_NETCDF4_CLASSIC, NULL);
-	     fprintf(stderr, "\n\nSwitching to netCDF-4 format (with NC_CLASSIC_MODEL).\n");
-	     break;
-#endif
-	  default:
-	     fprintf(stderr, "Unexpected format!\n");
-	     return 2;
-       }
-       testfile = testfiles[i];
-
-       /* Run all the tests for this format. */
-	   
-       nerrs += test_nccreate(testfile);
-       nerrs += test_ncopen(testfile);
-       nerrs += test_ncredef(testfile);
-       nerrs += test_ncendef(testfile);
-       nerrs += test_ncclose(testfile);
-       nerrs += test_ncinquire(testfile);
-       nerrs += test_ncsync(testfile);
-       nerrs += test_ncabort(testfile);
-       nerrs += test_ncdimdef(testfile);
-       nerrs += test_ncdimid(testfile);
-       nerrs += test_ncdiminq(testfile);
-       nerrs += test_ncdimrename(testfile);
-       nerrs += test_ncvardef(testfile);
-       nerrs += test_ncvarid(testfile);
-       nerrs += test_ncvarinq(testfile);
-	   nerrs += test_ncvarputg(testfile);
-       nerrs += test_ncvarput1(testfile);
-       nerrs += test_ncvarget1(testfile);
-       nerrs += test_ncvarput(testfile);
-       nerrs += test_ncvarget(testfile);
-       nerrs += test_ncvarputg(testfile);
-       nerrs += test_ncvargetg(testfile);
-       nerrs += test_ncrecinq(testfile);
-       nerrs += test_ncrecput(testfile);
-       nerrs += test_ncrecget(testfile);
-       nerrs += test_ncvarrename(testfile);
-       nerrs += test_ncattput(testfile);
-       nerrs += test_ncattinq(testfile);
-       nerrs += test_ncattget(testfile);
-       nerrs += test_ncattcopy(testfile, "test2.nc");
-       nerrs += test_ncattname(testfile);
-       nerrs += test_ncattrename(testfile);
-       nerrs += test_ncattdel(testfile);
-       nerrs += test_nctypelen();
-
-       /* Clean up in-memory struct. */
-       {
-	  int i;
-
-	  for (i = 0; i < test.ndims; i++)
-	     free(test.dims[i].name);
-
-	  for (i = 0; i < test.nvars; i++)
-	  {
-	     free(test.vars[i].name);
-	     free(test.vars[i].dims);
-	  }
-
-	  for (i = 0; i < test.natts; i++)
-	     free(test.atts[i].name);
-
-       }
-    }
+   /*EXTERNL int ncopts;	*/	/* netCDF error options */
+   char *format_name[MAX_NUM_FORMATS] = {"classic", "64bit_offset", "netcdf4_classic",
+                                         "netcdf4", "CDF5"};
+   char testfile[NC_MAX_NAME];
+   int format[MAX_NUM_FORMATS];
+   int num_formats;
+   int i, nerrs = 0;
+
+   ncopts &= ~NC_FATAL;	/* make errors nonfatal */
+   ncopts &= ~NC_VERBOSE;	/* turn off error messages */
+
+   /* How many formats are we testing? */
+   determine_test_formats(&num_formats, format);
+   printf("Testing V2 API with %d different netCDF formats.\n", num_formats);
+
+   for (i = 0; i < num_formats; i++)
+   {
+      /* Skip netCDF-4 - only netCDF-4 classic will work. */
+      if (format[i] == NC_FORMAT_NETCDF4)
+         continue;
+      
+      /* Come up with a test file name. */
+      sprintf(testfile, "nctest_%s.nc", format_name[i]);
+      printf("Testing %s with file %s.\n", format_name[i], testfile);      
+
+      /* Set the default format. */
+      nc_set_default_format(format[i], NULL);
+
+      /* Run all the tests for this format. */
+      nerrs += test_nccreate(testfile);
+      nerrs += test_ncopen(testfile);
+      nerrs += test_ncredef(testfile);
+      nerrs += test_ncendef(testfile);
+      nerrs += test_ncclose(testfile);
+      nerrs += test_ncinquire(testfile);
+      nerrs += test_ncsync(testfile);
+      nerrs += test_ncabort(testfile);
+      nerrs += test_ncdimdef(testfile);
+      nerrs += test_ncdimid(testfile);
+      nerrs += test_ncdiminq(testfile);
+      nerrs += test_ncdimrename(testfile);
+      nerrs += test_ncvardef(testfile);
+      nerrs += test_ncvarid(testfile);
+      nerrs += test_ncvarinq(testfile);
+      nerrs += test_ncvarputg(testfile);
+      nerrs += test_ncvarput1(testfile);
+      nerrs += test_ncvarget1(testfile);
+      nerrs += test_ncvarput(testfile);
+      nerrs += test_ncvarget(testfile);
+      nerrs += test_ncvarputg(testfile);
+      nerrs += test_ncvargetg(testfile);
+      nerrs += test_ncrecinq(testfile);
+      nerrs += test_ncrecput(testfile);
+      nerrs += test_ncrecget(testfile);
+      nerrs += test_ncvarrename(testfile);
+      nerrs += test_ncattput(testfile);
+      nerrs += test_ncattinq(testfile);
+      nerrs += test_ncattget(testfile);
+      nerrs += test_ncattcopy(testfile, "test2.nc");
+      nerrs += test_ncattname(testfile);
+      nerrs += test_ncattrename(testfile);
+      nerrs += test_ncattdel(testfile);
+      nerrs += test_nctypelen();
+
+      /* Clean up in-memory struct. */
+      {
+         int i;
+
+         for (i = 0; i < test.ndims; i++)
+            free(test.dims[i].name);
+
+         for (i = 0; i < test.nvars; i++)
+         {
+            free(test.vars[i].name);
+            free(test.vars[i].dims);
+         }
+
+         for (i = 0; i < test.natts; i++)
+            free(test.atts[i].name);
+
+      }
+   }
     
-    fprintf(stderr, "\nTotal number of failures: %d\n", nerrs);
+   fprintf(stderr, "\nTotal number of failures: %d\n", nerrs);
 
-    if (nerrs)
-    {
-       fprintf(stderr, "nctest FAILURE!!!\n");
-       return 2;
-    }
-    else
-       fprintf(stderr, "nctest SUCCESS!!!\n");
+   if (nerrs)
+   {
+      fprintf(stderr, "nctest FAILURE!!!\n");
+      return 2;
+   }
+   else
+      fprintf(stderr, "nctest SUCCESS!!!\n");
 
-    return 0;
+   return 0;
 }
diff --git a/oc2/CMakeLists.txt b/oc2/CMakeLists.txt
index 2b75aca..c0d6233 100644
--- a/oc2/CMakeLists.txt
+++ b/oc2/CMakeLists.txt
@@ -1,6 +1,7 @@
-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 occurlflags.c xxdr.c)
+SET(oc_SOURCES oc.c daplex.c dapparse.c dapy.c occompile.c occurlfunctions.c ocdata.c ocdebug.c ocdump.c ocinternal.c ocnode.c ochttp.c ocread.c ocutil.c occurlflags.c xxdr.c)
 
-add_library(oc2 OBJECT ${oc_SOURCES}) 
+
+add_library(oc2 OBJECT ${oc_SOURCES})
 
 # Apparently fails under cmake
 #set(ocprint_FILES ocprint.c )
diff --git a/oc2/Makefile.am b/oc2/Makefile.am
index aa3d65f..5a38362 100644
--- a/oc2/Makefile.am
+++ b/oc2/Makefile.am
@@ -13,17 +13,17 @@ AM_CPPFLAGS =  -I.. -I$(top_srcdir) -I$(top_srcdir)/include
 # OC Sources; include the dapy.[ch] to avoid the need for bison by user
 SRC=oc.c \
 daplex.c dapparse.c dapy.c \
-occlientparams.c occompile.c occurlfunctions.c \
+occompile.c occurlfunctions.c \
 ocdata.c ocdebug.c ocdump.c  \
 ocinternal.c ocnode.c \
 ochttp.c \
-ocrc.c ocread.c ocutil.c \
+ocread.c ocutil.c \
 occurlflags.c \
 xxdr.c
 
 HDRS=oc.h ocx.h \
 dapparselex.h dapy.h \
-occlientparams.h occompile.h occonstraints.h occurlfunctions.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 \
diff --git a/oc2/Makefile.in b/oc2/Makefile.in
index aa5bdae..fd1a45a 100644
--- a/oc2/Makefile.in
+++ b/oc2/Makefile.in
@@ -113,12 +113,11 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 liboc_la_LIBADD =
 am__objects_1 = liboc_la-oc.lo liboc_la-daplex.lo liboc_la-dapparse.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 \
-	liboc_la-ocrc.lo liboc_la-ocread.lo liboc_la-ocutil.lo \
-	liboc_la-occurlflags.lo liboc_la-xxdr.lo
+	liboc_la-dapy.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 liboc_la-ocread.lo \
+	liboc_la-ocutil.lo liboc_la-occurlflags.lo liboc_la-xxdr.lo
 am__objects_2 =
 am_liboc_la_OBJECTS = $(am__objects_1) $(am__objects_2)
 liboc_la_OBJECTS = $(am_liboc_la_OBJECTS)
@@ -198,7 +197,6 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/include
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AM_LDFLAGS = @AM_LDFLAGS@
 AR = @AR@
-AS = @AS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -221,12 +219,14 @@ DOXYGEN = @DOXYGEN@
 DOXYGEN_CSS_FILE = @DOXYGEN_CSS_FILE@
 DOXYGEN_HEADER_FILE = @DOXYGEN_HEADER_FILE@
 DOXYGEN_SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
+DOXYGEN_SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_ERANGE_FILL = @ENABLE_ERANGE_FILL@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
@@ -252,6 +252,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISCMAKE = @ISCMAKE@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
@@ -266,6 +267,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MSVC = @MSVC@
 NC_ENABLE_DOXYGEN_PDF_OUTPUT = @NC_ENABLE_DOXYGEN_PDF_OUTPUT@
 NC_HAS_CDF5 = @NC_HAS_CDF5@
 NC_HAS_DAP2 = @NC_HAS_DAP2@
@@ -373,17 +375,17 @@ top_srcdir = @top_srcdir@
 # OC Sources; include the dapy.[ch] to avoid the need for bison by user
 SRC = oc.c \
 daplex.c dapparse.c dapy.c \
-occlientparams.c occompile.c occurlfunctions.c \
+occompile.c occurlfunctions.c \
 ocdata.c ocdebug.c ocdump.c  \
 ocinternal.c ocnode.c \
 ochttp.c \
-ocrc.c ocread.c ocutil.c \
+ocread.c ocutil.c \
 occurlflags.c \
 xxdr.c
 
 HDRS = oc.h ocx.h \
 dapparselex.h dapy.h \
-occlientparams.h occompile.h occonstraints.h occurlfunctions.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 \
@@ -451,7 +453,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-dapparse.Plo at am__quote@
 @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@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-occlientparams.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-occompile.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-occurlflags.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-occurlfunctions.Plo at am__quote@
@@ -461,7 +462,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ochttp.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ocinternal.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ocnode.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ocrc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ocread.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-ocutil.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liboc_la-xxdr.Plo at am__quote@
@@ -518,13 +518,6 @@ liboc_la-dapy.lo: dapy.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-dapy.lo `test -f 'dapy.c' || echo '$(srcdir)/'`dapy.c
 
-liboc_la-occlientparams.lo: occlientparams.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-occlientparams.lo -MD -MP -MF $(DEPDIR)/liboc_la-occlientparams.Tpo -c -o liboc_la-occlientparams.lo `test -f 'occlientparams.c' || echo '$(srcdir)/'`occlientparams.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/liboc_la-occlientparams.Tpo $(DEPDIR)/liboc_la-occlientparams.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='occlientparams.c' object='liboc_la-occlientparams.lo' libtool=yes @AMDEPBACKSLASH@
- at 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-occlientparams.lo `test -f 'occlientparams.c' || echo '$(srcdir)/'`occlientparams.c
-
 liboc_la-occompile.lo: occompile.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-occompile.lo -MD -MP -MF $(DEPDIR)/liboc_la-occompile.Tpo -c -o liboc_la-occompile.lo `test -f 'occompile.c' || echo '$(srcdir)/'`occompile.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/liboc_la-occompile.Tpo $(DEPDIR)/liboc_la-occompile.Plo
@@ -581,13 +574,6 @@ liboc_la-ochttp.lo: ochttp.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-ochttp.lo `test -f 'ochttp.c' || echo '$(srcdir)/'`ochttp.c
 
-liboc_la-ocrc.lo: ocrc.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-ocrc.lo -MD -MP -MF $(DEPDIR)/liboc_la-ocrc.Tpo -c -o liboc_la-ocrc.lo `test -f 'ocrc.c' || echo '$(srcdir)/'`ocrc.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/liboc_la-ocrc.Tpo $(DEPDIR)/liboc_la-ocrc.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ocrc.c' object='liboc_la-ocrc.lo' libtool=yes @AMDEPBACKSLASH@
- at 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-ocrc.lo `test -f 'ocrc.c' || echo '$(srcdir)/'`ocrc.c
-
 liboc_la-ocread.lo: ocread.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-ocread.lo -MD -MP -MF $(DEPDIR)/liboc_la-ocread.Tpo -c -o liboc_la-ocread.lo `test -f 'ocread.c' || echo '$(srcdir)/'`ocread.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/liboc_la-ocread.Tpo $(DEPDIR)/liboc_la-ocread.Plo
diff --git a/oc2/daplex.c b/oc2/daplex.c
index cf13282..98b10fe 100644
--- a/oc2/daplex.c
+++ b/oc2/daplex.c
@@ -40,16 +40,28 @@ static char* ddsworddelims =
   "{}[]:;=,";
 
 /* Define 1 and > 1st legal characters */
+/* Note: for some reason I added # and removed !~'"
+   what was I thinking?
+*/
 static char* ddswordchars1 =
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\.*";
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+  "-+_/%\\.*!~'\"";
 static char* ddswordcharsn =
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\.*#";
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+  "-+_/%\\.*!~'\"";
+
+/* This includes sharp and colon for historical reasons */
 static char* daswordcharsn =
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\.*#:";
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+  "-+_/%\\.*#:!~'\"";
+
+/* Need to remove '.' to allow for fqns */
 static char* cewordchars1 =
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\";
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+  "-+_/%\\*!~'\"";
 static char* cewordcharsn =
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\";
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+  "-+_/%\\*!~'\"";
 
 /* Current sets of legal characters */
 /*
diff --git a/oc2/oc.c b/oc2/oc.c
index a3740c7..2040b1d 100644
--- a/oc2/oc.c
+++ b/oc2/oc.c
@@ -11,7 +11,7 @@
 #include "ocdebug.h"
 #include "ocdump.h"
 #include "nclog.h"
-#include "occlientparams.h"
+#include "ncrc.h"
 #include "occurlfunctions.h"
 #include "ochttp.h"
 #include "ncwinpath.h"
@@ -54,9 +54,8 @@ object is to be returned.
 OCerror
 oc_open(const char* url, OCobject* linkp)
 {
-    OCerror ocerr;
+	OCerror ocerr = OC_NOERR;
     OCstate* state = NULL;
-    if(!ocglobalstate.initialized) oc_initialize();
     ocerr = ocopen(&state,url);
     if(ocerr == OC_NOERR && linkp) {
       *linkp = (OCobject)(state);
@@ -1713,76 +1712,6 @@ oc_errstring(OCerror err)
     return ocerrstring(err);
 }
 
-/*!
-Each OClink object maintains a table of
-(name,value) pairs, called client parameters.
-It is initialized from any such parameters
-specified in the URL given as argument to
-oc_open().
-
-\param[in] link The link through which the server is accessed.
-\param[in] param The name of the parameter whose value is desired.
-
-\return The corresponding value, or NULL if parameter name is not in the table.
-*/
-
-const char*
-oc_clientparam_get(OCobject link, const char* param)
-{
-    OCstate* state;
-    OCVERIFYX(OC_State,link,NULL);
-    OCDEREF(OCstate*,state,link);
-
-    return ocparamlookup(state,param);
-}
-
-#ifdef OCIGNORE
-/* Delete client parameter
-   return value:
-	OC_NOERR => defined; deletion performed
-	OC_EINVAL => not already defined
-*/
-OCerror
-oc_clientparam_delete(OCobject link, const char* param)
-{
-    OCstate* state;
-    OCVERIFY(OC_State,link);
-    OCDEREF(OCstate*,state,link);
-
-    return OCTHROW(ocparamdelete(state->clientparams,param));
-}
-
-/* Insert client parameter
-   return value:
-	OC_NOERR => not already define; insertion performed
-	OC_EINVAL => already defined
-*/
-OCerror
-oc_clientparam_insert(OCobject link, const char* param, const char* value)
-{
-    OCstate* state;
-    OCVERIFY(OC_State,link);
-    OCDEREF(OCstate*,state,link);
-
-    state->clientparams = dapparaminsert(state->clientparams,param,value);
-    return OCTHROW(OC_NOERR);
-}
-
-/* Replace client parameter
-   return value:
-	OC_NOERR => already define; replacement performed
-	OC_EINVAL => not already defined
-*/
-OCerror
-oc_clientparam_replace(OCobject link, const char* param, const char* value)
-{
-    OCstate* state;
-    OCVERIFY(OC_State,link);
-    OCDEREF(OCstate*,state,link);
-
-    return dapparamreplace(state->clientparams,param,value);
-}
-#endif
 
 /**************************************************/
 
@@ -2119,44 +2048,6 @@ oc_set_useragent(OCobject link, const char* agent)
 }
 
 /*!
-Set the absolute path to use for the rc file.
-WARNING: this MUST be called before any other
-call in order for this to take effect.
-
-\param[in] rcfile The path to use. If NULL, or "",
-                  then do not use any rcfile.
-
-\retval OC_NOERR if the request succeeded.
-\retval OC_ERCFILE if the file failed to load
-*/
-
-OCerror
-oc_set_rcfile(const char* rcfile)
-{
-    OCerror stat = OC_NOERR;
-    if(rcfile != NULL && strlen(rcfile) == 0)
-	rcfile = NULL;
-
-    if(!ocglobalstate.initialized)
-	ocinternalinitialize(); /* so ocglobalstate is defined, but not triplestore */
-    if(rcfile == NULL) {
-	ocglobalstate.rc.ignore = 1;
-    } else {
-        FILE* f = NCfopen(rcfile,"r");
-        if(f == NULL) {
-	    stat = (OC_ERCFILE);
-	    goto done;
-        }
-        fclose(f);
-        ocglobalstate.rc.rcfile = strdup(rcfile);
-        /* (re) load the rcfile and esp the triplestore*/
-        stat = ocrc_load();
-    }
-done:
-    return OCTHROW(stat);
-}
-
-/*!
 Force the curl library to trace its actions.
 
 \param[in] link The link through which the server is accessed.
@@ -2174,21 +2065,4 @@ oc_trace_curl(OCobject link)
     return OCTHROW(OC_NOERR);
 }
 
-OCerror
-oc_initialize(void)
-{
-    OCerror status = OC_NOERR;
-    if(!ocglobalstate.initialized) {
-        /* Clean up before re-initializing */
-	if(ocglobalstate.tempdir != NULL) free(ocglobalstate.tempdir);
-	if(ocglobalstate.home != NULL) free(ocglobalstate.home);
-	if(ocglobalstate.rc.rcfile != NULL) free(ocglobalstate.rc.rcfile);
-    }
-    ocglobalstate.initialized = 0;
-    status = ocinternalinitialize();
-    /* (re) load the rcfile */
-    status =  ocrc_load();
-    return OCTHROW(status);
-}
-
 /**@}*/
diff --git a/oc2/occlientparams.c b/oc2/occlientparams.c
deleted file mode 100644
index d56cc75..0000000
--- a/oc2/occlientparams.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
-   See the COPYRIGHT file for more information. */
-
-#include "config.h"
-#include "ocinternal.h"
-#include "ocdebug.h"
-
-#define LBRACKET '['
-#define RBRACKET ']'
-
-const char*
-ocparamlookup(OCstate* state, const char* key)
-{
-    const char* value = NULL;
-    if(state == NULL || key == NULL || state->uri == NULL) return NULL;
-    value = ncurilookup(state->uri,key);
-    return value;
-}
-
-#if 0
-int
-ocparamset(OCstate* state, const char* params)
-{
-    int i;
-    i = ncurisetparams(state->uri,params);
-    return i?OC_NOERR:OC_EBADURL;
-}
-#endif
-
diff --git a/oc2/occlientparams.h b/oc2/occlientparams.h
deleted file mode 100644
index 22b58c7..0000000
--- a/oc2/occlientparams.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
-  See the COPYRIGHT file for more information. */
-
-#ifndef OCCLIENTPARAMS_H
-#define OCCLIENTPARAMS_H
-
-extern NClist* ocparamdecode(OCstate*);
-extern const char* ocparamlookup(OCstate*, const char*);
-extern void ocparamset(OCstate*,const char*);
-
-#endif /*OCCLIENTPARAMS_H*/
diff --git a/oc2/occurlfunctions.c b/oc2/occurlfunctions.c
index b721a3c..53cc027 100644
--- a/oc2/occurlfunctions.c
+++ b/oc2/occurlfunctions.c
@@ -2,6 +2,7 @@
    See the COPYRIGHT file for more information. */
 
 #include "config.h"
+#include "ncrc.h"
 #include "ocinternal.h"
 #include "ocdebug.h"
 #include "occurlfunctions.h"
@@ -15,10 +16,6 @@
 
 #define CHECK(state,flag,value) {if(check(state,flag,(void*)value) != OC_NOERR) {goto done;}}
 
-/* forward */
-static OCerror oc_set_curl_options(OCstate* state);
-static void* cvt(char* value, enum OCCURLFLAGTYPE type);
-
 static OCerror
 check(OCstate* state, int flag, void* value)
 {
@@ -31,39 +28,14 @@ check(OCstate* state, int flag, void* value)
     } else {
 	char show[65];
 	char* s = (char*)value;
-	strncpy(show,s,64);
-	show[64] = '\0';
+	strncpy(show,s,sizeof(show)-1);
+	show[sizeof(show)-1] = '\0';
 	OCDBG2("%s=%s",name,show);
     }
 #endif
     return stat;
 }
 
-#if 0
-static void
-showopt(int flag, void* value)
-{
-    struct OCCURLFLAG* f = occurlflagbyflag(flag);
-    if(f == NULL)  {
-	OCDBG1("Unsupported flag: %d",flag);
-    } else switch (f->type) {
-	case CF_LONG:
-	    OCDBG2("%s=%ld",f->name,(long)value);
-	    break;
-	case CF_STRING: {
-   	    char show[65];
-	    char* s = (char*)value;
-	    strncpy(show,s,64);
-	    show[64] = '\0';
-	    OCDBG2("%s=%s",f->name,show);
-            } break;
-	case CF_UNKNOWN: case CF_OTHER:
-	    OCDBG1("%s=<something>",f->name);
-	    break;
-    }
-}
-#endif
-
 /*
 Set a specific curl flag; primary wrapper for curl_easy_setopt
 */
@@ -89,41 +61,41 @@ ocset_curlflag(OCstate* state, int flag)
     switch (flag) {
 
     case CURLOPT_USERPWD: /* Does both user and pwd */
-        if(state->creds.user != NULL && state->creds.pwd != NULL) {
-	    CHECK(state, CURLOPT_USERNAME, state->creds.user);
-	    CHECK(state, CURLOPT_PASSWORD, state->creds.pwd);
+        if(state->auth.creds.user != NULL && state->auth.creds.pwd != NULL) {
+	    CHECK(state, CURLOPT_USERNAME, state->auth.creds.user);
+	    CHECK(state, CURLOPT_PASSWORD, state->auth.creds.pwd);
             CHECK(state, CURLOPT_HTTPAUTH, (OPTARG)CURLAUTH_ANY);
 	}
 	break;
 
     case CURLOPT_COOKIEJAR: case CURLOPT_COOKIEFILE:
-        if(state->curlflags.cookiejar) {
+        if(state->auth.curlflags.cookiejar) {
 	    /* Assume we will read and write cookies to same place */
-	    CHECK(state, CURLOPT_COOKIEJAR, state->curlflags.cookiejar);
-	    CHECK(state, CURLOPT_COOKIEFILE, state->curlflags.cookiejar);
+	    CHECK(state, CURLOPT_COOKIEJAR, state->auth.curlflags.cookiejar);
+	    CHECK(state, CURLOPT_COOKIEFILE, state->auth.curlflags.cookiejar);
         }
 	break;
 
     case CURLOPT_NETRC: case CURLOPT_NETRC_FILE:
-	if(state->curlflags.netrc) {
+	if(state->auth.curlflags.netrc) {
 	    CHECK(state, CURLOPT_NETRC, (OPTARG)CURL_NETRC_REQUIRED);
-	    CHECK(state, CURLOPT_NETRC_FILE, state->curlflags.netrc);
+	    CHECK(state, CURLOPT_NETRC_FILE, state->auth.curlflags.netrc);
         }
 	break;
 
     case CURLOPT_VERBOSE:
-	if(state->curlflags.verbose)
+	if(state->auth.curlflags.verbose)
 	    CHECK(state, CURLOPT_VERBOSE, (OPTARG)1L);
 	break;
 
     case CURLOPT_TIMEOUT:
-	if(state->curlflags.timeout)
-	    CHECK(state, CURLOPT_TIMEOUT, (OPTARG)((long)state->curlflags.timeout));
+	if(state->auth.curlflags.timeout)
+	    CHECK(state, CURLOPT_TIMEOUT, (OPTARG)((long)state->auth.curlflags.timeout));
 	break;
 
     case CURLOPT_USERAGENT:
-        if(state->curlflags.useragent)
-	    CHECK(state, CURLOPT_USERAGENT, state->curlflags.useragent);
+        if(state->auth.curlflags.useragent)
+	    CHECK(state, CURLOPT_USERAGENT, state->auth.curlflags.useragent);
 	break;
 
     case CURLOPT_FOLLOWLOCATION:
@@ -140,19 +112,19 @@ ocset_curlflag(OCstate* state, int flag)
 
     case CURLOPT_ENCODING:
 #ifdef CURLOPT_ENCODING
-	if(state->curlflags.compress) {
+	if(state->auth.curlflags.compress) {
 	    CHECK(state, CURLOPT_ENCODING,"deflate, gzip");
         }
 #endif
 	break;
 
     case CURLOPT_PROXY:
-	if(state->proxy.host != NULL) {
-	    CHECK(state, CURLOPT_PROXY, state->proxy.host);
-	    CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->proxy.port);
-	    if(state->proxy.user != NULL && state->proxy.pwd != NULL) {
-                CHECK(state, CURLOPT_PROXYUSERNAME, state->proxy.user);
-                CHECK(state, CURLOPT_PROXYPASSWORD, state->proxy.pwd);
+	if(state->auth.proxy.host != NULL) {
+	    CHECK(state, CURLOPT_PROXY, state->auth.proxy.host);
+	    CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->auth.proxy.port);
+	    if(state->auth.proxy.user != NULL && state->auth.proxy.pwd != NULL) {
+                CHECK(state, CURLOPT_PROXYUSERNAME, state->auth.proxy.user);
+                CHECK(state, CURLOPT_PROXYPASSWORD, state->auth.proxy.pwd);
 #ifdef CURLOPT_PROXYAUTH
 	        CHECK(state, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
 #endif
@@ -164,7 +136,7 @@ ocset_curlflag(OCstate* state, int flag)
     case CURLOPT_SSLCERT: case CURLOPT_SSLKEY:
     case CURLOPT_SSL_VERIFYPEER: case CURLOPT_SSL_VERIFYHOST:
     {
-        struct OCSSL* ssl = &state->ssl;
+        struct ssl* ssl = &state->auth.ssl;
         CHECK(state, CURLOPT_SSL_VERIFYPEER, (OPTARG)(ssl->verifypeer?1L:0L));
         CHECK(state, CURLOPT_SSL_VERIFYHOST, (OPTARG)(ssl->verifyhost?1L:0L));
         if(ssl->certificate)
@@ -222,81 +194,13 @@ ocset_flags_perlink(OCstate* state)
     if(stat == OC_NOERR) stat = ocset_curlflag(state, CURLOPT_FOLLOWLOCATION);
     if(stat == OC_NOERR) stat = ocset_curlflag(state, CURLOPT_MAXREDIRS);
     if(stat == OC_NOERR) stat = ocset_curlflag(state, CURLOPT_ERRORBUFFER);
-
-    /* Set the CURL. options */
-    if(stat == OC_NOERR) stat = oc_set_curl_options(state);
-
-    return stat;
-}
-
-/**
-Directly set any options starting with 'CURL.'
-*/
-static OCerror
-oc_set_curl_options(OCstate* state)
-{
-    OCerror stat = OC_NOERR;
-    struct OCTriplestore* store = NULL;
-    struct OCTriple* triple = NULL;
-    int i;
-    char* hostport = NULL;
-    struct OCCURLFLAG* ocflag = NULL;
-
-    hostport = occombinehostport(state->uri);
-    if(hostport == NULL) {
-      hostport = (char*)malloc(sizeof(char)*1);
-      *hostport = '\0';
-    }
-
-    store = &ocglobalstate.rc.daprc;
-    triple = store->triples;
-
-    /* Assume that the triple store has been properly sorted */
-    for(i=0;i<store->ntriples;i++,triple++) {
-        size_t hostlen = strlen(triple->host);
-        const char* flagname;
-
-        if(ocstrncmp("CURL.",triple->key,5) != 0) continue; /* not a curl flag */
-        /* do hostport prefix comparison */
-        if(hostlen > 0) {
-          int t = ocstrncmp(hostport,triple->host,hostlen);
-          if(t !=  0) continue;
-        }
-        flagname = triple->key+5; /* 5 == strlen("CURL."); */
-        ocflag = occurlflagbyname(flagname);
-        if(ocflag == NULL) {stat = OC_ECURL; goto done;}
-        stat = ocset_curlopt(state,ocflag->flag,cvt(triple->value,ocflag->type));
-    }
- done:
-    if(hostport && strlen(hostport) > 0) free(hostport);
     return stat;
 }
 
-static void*
-cvt(char* value, enum OCCURLFLAGTYPE type)
-{
-    switch (type) {
-    case CF_LONG: {
-	/* Try to convert to long value */
-	const char* p = value;
-	char* q = NULL;
-	long longvalue = strtol(p,&q,10);
-	if(*q != '\0')
-	    return NULL;
-	return (void*)longvalue;
-	}
-    case CF_STRING:
-	return (void*)value;
-    case CF_UNKNOWN: case CF_OTHER:
-	return (void*)value;
-    }
-    return NULL;
-}
-
 void
 oc_curl_debug(OCstate* state)
 {
-    state->curlflags.verbose = 1;
+    state->auth.curlflags.verbose = 1;
     ocset_curlflag(state,CURLOPT_VERBOSE);
     ocset_curlflag(state,CURLOPT_ERRORBUFFER);
 }
@@ -306,8 +210,8 @@ oc_curl_debug(OCstate* state)
 int
 ocrc_netrc_required(OCstate* state)
 {
-    char* netrcfile = ocrc_lookup(NETRCFILETAG,state->uri->uri);
-    return (netrcfile != NULL || state->curlflags.netrc != NULL ? 0 : 1);
+    char* netrcfile = NC_rclookup(NETRCFILETAG,state->uri->uri);
+    return (netrcfile != NULL || state->auth.curlflags.netrc != NULL ? 0 : 1);
 }
 
 void
@@ -316,133 +220,17 @@ oc_curl_printerror(OCstate* state)
     fprintf(stderr,"curl error details: %s\n",state->curlerror);
 }
 
-/* Determine if this version of curl supports
-       "file://..." &/or "https://..." urls.
-*/
+/* See if http: protocol is supported */
 void
-oc_curl_protocols(struct OCGLOBALSTATE* state)
+oc_curl_protocols(OCstate* state)
 {
     const char* const* proto; /*weird*/
     curl_version_info_data* curldata;
     curldata = curl_version_info(CURLVERSION_NOW);
     for(proto=curldata->protocols;*proto;proto++) {
-        if(strcmp("file",*proto)==0) {state->curl.proto_file=1;}
-        if(strcmp("http",*proto)==0) {state->curl.proto_https=1;}
-    }
-    if(ocdebug > 0) {
-        nclog(NCLOGNOTE,"Curl file:// support = %d",state->curl.proto_file);
-        nclog(NCLOGNOTE,"Curl https:// support = %d",state->curl.proto_https);
+        if(strcmp("http",*proto)==0)
+	    state->auth.curlflags.proto_https=1;
     }
 }
 
 
-#if 0
-/*
-"Inverse" of ocset_curlflag;
-Given a flag and value, it updates state.
-Update a specific flag from state->curlflags.
-*/
-OCerror
-ocset_curlstate(OCstate* state, int flag, void* value)
-{
-    OCerror stat = OC_NOERR;
-
-    switch (flag) {
-
-    case CURLOPT_USERNAME:
-        if(state->creds.user != NULL) free(state->creds.user);
-	state->creds.user = strdup((char*)value);
-	break;
-
-    case CURLOPT_PASSWORD:
-        if(state->creds.pwd != NULL) free(state->creds.pwd);
-	state->creds.pwd = strdup((char*)value);
-	break;
-
-    case CURLOPT_COOKIEJAR: case CURLOPT_COOKIEFILE:
-        if(state->curlflags.cookiejar != NULL) free(state->curlflags.cookiejar);
-	state->curlflags.cookiejar = strdup((char*)value);
-	break;
-
-    case CURLOPT_NETRC: case CURLOPT_NETRC_FILE:
-        if(state->curlflags.netrc != NULL) free(state->curlflags.netrc);
-	state->curlflags.netrc = strdup((char*)value);
-	break;
-
-    case CURLOPT_VERBOSE:
-	state->curlflags.verbose = (long)value;
-	break;
-
-    case CURLOPT_TIMEOUT:
-	state->curlflags.timeout = (long)value;
-	break;
-
-    case CURLOPT_USERAGENT:
-        if(state->curlflags.useragent != NULL) free(state->curlflags.useragent);
-        state->curlflags.useragent = strdup((char*)value);
-	break;
-
-    case CURLOPT_FOLLOWLOCATION:
-	/* no need to store; will always be set */
-	break;
-
-    case CURLOPT_MAXREDIRS:
-	/* no need to store; will always be set */
-	break;
-
-    case CURLOPT_ERRORBUFFER:
-	/* no need to store; will always be set */
-	break;
-
-    case CURLOPT_ENCODING:
-	/* no need to store; will always be set to fixed value */
-	break;
-
-    case CURLOPT_PROXY:
-	/* We assume that the value is the proxy url */
-	if(state->proxy.host != NULL) free(state->proxy.host);
-	if(state->proxy.userpwd != NULL) free(state->proxy.userpwd);
-	state->proxy.host = NULL;
-	state->proxy.userpwd = NULL;
-	if(!ocparseproxy(state,(char*)value))
-		{stat = OC_EINVAL; goto done;}
-	break;
-
-    case CURLOPT_SSLCERT:
-	if(state->ssl.certificate != NULL) free(state->ssl.certificate);
-	state->ssl.certificate = strdup((char*)value);
-	break;
-    case CURLOPT_SSLKEY:
-	if(state->ssl.key != NULL) free(state->ssl.key);
-	state->ssl.key = strdup((char*)value);
-	break;
-    case CURLOPT_KEYPASSWD:
-	if(state->ssl.keypasswd!= NULL) free(state->ssl.keypasswd);
-	state->ssl.keypasswd = strdup((char*)value);
-	break;
-    case CURLOPT_SSL_VERIFYPEER:
-      state->ssl.verifypeer = (long)value;
-      break;
-    case CURLOPT_SSL_VERIFYHOST:
-      state->ssl.verifyhost = (long)value;
-      break;
-    case CURLOPT_CAINFO:
-      if(state->ssl.cainfo != NULL) free(state->ssl.cainfo);
-      state->ssl.cainfo = strdup((char*)value);
-      break;
-    case CURLOPT_CAPATH:
-	if(state->ssl.capath != NULL) free(state->ssl.capath);
-	state->ssl.capath = strdup((char*)value);
-	break;
-
-    default: {
-	struct OCCURLFLAG* f = occurlflagbyflag(flag);
-	if(f != NULL)
-	    nclog(NCLOGWARN,"Attempt to add unexpected curl flag to state: %s",
-				f->name);
-	} break;
-    }
-done:
-    return stat;
-}
-#endif
diff --git a/oc2/occurlfunctions.h b/oc2/occurlfunctions.h
index 1be5999..6d2b0a0 100644
--- a/oc2/occurlfunctions.h
+++ b/oc2/occurlfunctions.h
@@ -32,7 +32,7 @@ extern void oc_curl_debug(OCstate* state);
 
 extern void oc_curl_printerror(OCstate* state);
 extern int ocrc_netrc_required(OCstate* state);
-extern void oc_curl_protocols(struct OCGLOBALSTATE*);
+extern void oc_curl_protocols(OCstate* state);
 
 /* From occurlflags.c */
 extern struct OCCURLFLAG* occurlflags(void);
diff --git a/oc2/ocdump.c b/oc2/ocdump.c
index 205b015..839eb93 100644
--- a/oc2/ocdump.c
+++ b/oc2/ocdump.c
@@ -232,14 +232,14 @@ ocdumpclause(OCprojectionclause* ref)
 
 
 static void
-addfield(char* field, char* line, int align)
+addfield(char* field, size_t llen, char* line, int align)
 {
     int len,rem;
-    strcat(line,"|");
-    strcat(line,field);
+    strlcat(line,"|",llen);
+    strlcat(line,field,llen);
     len = strlen(field);
     rem = (align - len);
-    while(rem-- > 0) strcat(line," ");
+    while(rem-- > 0) strlcat(line," ",llen);
 }
 
 static void
@@ -264,27 +264,27 @@ dumpfield(size_t index, char* n8, int isxdr)
 
     /* offset */
     sprintf(tmp,"%6zd",index);
-    addfield(tmp,line,5);
+    addfield(tmp,sizeof(line),line,5);
 
     memcpy(form.cv,n8,4);
 
     /* straight hex*/
     sprintf(tmp,"%08x",form.uv);
-    addfield(tmp,line,8);
+    addfield(tmp,sizeof(line),line,8);
 
     if(isxdr) {swapinline32(&form.uv);}
 
     /* unsigned integer */
     sprintf(tmp,"%12u",form.uv);
-    addfield(tmp,line,12);
+    addfield(tmp,sizeof(line),line,12);
 
     /* signed integer */
     sprintf(tmp,"%12d",form.sv);
-    addfield(tmp,line,12);
+    addfield(tmp,sizeof(line),line,12);
 
     /* float */
     sprintf(tmp,"%#g",form.fv);
-    addfield(tmp,line,12);
+    addfield(tmp,sizeof(line),line,12);
 
     /* char[4] */
     {
@@ -303,13 +303,13 @@ dumpfield(size_t index, char* n8, int isxdr)
         }
     }
 
-    addfield(tmp,line,16);
+    addfield(tmp,sizeof(line),line,16);
 
     /* double */
     memcpy(dform.cv,n8,(size_t)(2*XDRUNIT));
     if(isxdr) xxdrntohdouble(dform.cv,&dform.d);
     sprintf(tmp,"%#g",dform.d);
-    addfield(tmp,line,12);
+    addfield(tmp,sizeof(line),line,12);
 
     fprintf(stdout,"%s\n",line);
 }
@@ -326,14 +326,14 @@ typedmemorydump(char* memory, size_t len, int fromxdr)
 
     /* build the header*/
     line[0] = '\0';
-    addfield("offset",line,6);
-    addfield("hex",line,8);
-    addfield("uint",line,12);
-    addfield("int",line,12);
-    addfield("float",line,12);
-    addfield("char[4]",line,16);
-    addfield("double",line,12);
-    strcat(line,"\n");
+    addfield("offset",sizeof(line),line,6);
+    addfield("hex",sizeof(line),line,8);
+    addfield("uint",sizeof(line),line,12);
+    addfield("int",sizeof(line),line,12);
+    addfield("float",sizeof(line),line,12);
+    addfield("char[4]",sizeof(line),line,16);
+    addfield("double",sizeof(line),line,12);
+    strlcat(line,"\n",sizeof(line));
     fprintf(stdout,"%s",line);
 
     count = (len / sizeof(int));
@@ -367,9 +367,9 @@ simplememorydump(char* memory, size_t len, int fromxdr)
 
     /* build the header*/
     line[0] = '\0';
-    addfield("offset",line,6);
-    addfield("XDR (hex)",line,9);
-    addfield("!XDR (hex)",line,10);
+    addfield("offset",sizeof(line),line,6);
+    addfield("XDR (hex)",sizeof(line),line,9);
+    addfield("!XDR (hex)",sizeof(line),line,10);
     fprintf(stdout,"%s\n",line);
 
     count = (len / sizeof(int));
@@ -384,11 +384,11 @@ simplememorydump(char* memory, size_t len, int fromxdr)
 	if(!xxdr_network_order) swapinline32(&v);
         line[0] = '\0';
         sprintf(tmp,"%6d",i);
-        addfield(tmp,line,6);
+        addfield(tmp,sizeof(line),line,6);
         sprintf(tmp,"%08x",vx);
-        addfield(tmp,line,9);
+        addfield(tmp,sizeof(line),line,9);
         sprintf(tmp,"%08x",v);
-        addfield(tmp,line,10);
+        addfield(tmp,sizeof(line),line,10);
         fprintf(stdout,"%s\n",line);
     }
     fflush(stdout);
diff --git a/oc2/ochttp.c b/oc2/ochttp.c
index 4c3e850..22c3d9b 100644
--- a/oc2/ochttp.c
+++ b/oc2/ochttp.c
@@ -83,8 +83,7 @@ fail:
 }
 
 OCerror
-ocfetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime,
-           struct OCcredentials* creds)
+ocfetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime)
 {
 	OCerror stat = OC_NOERR;
 	CURLcode cstat = CURLE_OK;
@@ -95,25 +94,6 @@ ocfetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime,
 	cstat = CURLERR(CURLERR(curl_easy_setopt(curl, CURLOPT_URL, (void*)url)));
 	if (cstat != CURLE_OK)
 		goto fail;
-	
-#if 0
-	if(creds != NULL && creds->password != NULL  && creds->username != NULL) {
-	    /* Set user and password */
-#if defined (HAVE_CURLOPT_USERNAME) && defined (HAVE_CURLOPT_PASSWORD)
-	    cstat = CURLERR(curl_easy_setopt(curl, CURLOPT_USERNAME, creds->username));
-	    if (cstat != CURLE_OK)
-		goto fail;
-	    cstat = CURLERR(curl_easy_setopt(curl, CURLOPT_PASSWORD, creds->password));
-	    if (cstat != CURLE_OK)
-		goto fail;
-#else		
-		snprintf(tbuf,1023,"%s:%s",creds->username,creds->password);	
-		cstat = CURLERR(curl_easy_setopt(curl, CURLOPT_USERPWD, tbuf));
-		if (cstat != CURLE_OK)
-			goto fail;
-#endif
-	}
-#endif
 
 	/* send all data to this function  */
 	cstat = CURLERR(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback));
@@ -344,7 +324,7 @@ ocping(const char* url)
 
     /* Try to get the file */
     buf = ncbytesnew();
-    stat = ocfetchurl(curl,url,buf,NULL,NULL);
+    stat = ocfetchurl(curl,url,buf,NULL);
     if(stat == OC_NOERR) {
 	/* Don't trust curl to return an error when request gets 404 */
 	long http_code = 0;
diff --git a/oc2/ochttp.h b/oc2/ochttp.h
index c7b2371..ab720ed 100644
--- a/oc2/ochttp.h
+++ b/oc2/ochttp.h
@@ -7,7 +7,7 @@
 extern int curlopen(CURL** curlp);
 extern void curlclose(CURL*);
 
-extern OCerror ocfetchurl(CURL*, const char*, NCbytes*, long*, struct OCcredentials*);
+extern OCerror ocfetchurl(CURL*, const char*, NCbytes*, long*);
 extern OCerror ocfetchurl_file(CURL*, const char*, FILE*, off_t*, long*);
 
 extern long ocfetchhttpcode(CURL* curl);
diff --git a/oc2/ocinternal.c b/oc2/ocinternal.c
index 9ca549d..55acde1 100644
--- a/oc2/ocinternal.c
+++ b/oc2/ocinternal.c
@@ -22,9 +22,9 @@
 
 #include <errno.h>
 
+#include "ncrc.h"
 #include "ocinternal.h"
 #include "ocdebug.h"
-#include "occlientparams.h"
 #include "occurlfunctions.h"
 #include "ochttp.h"
 #include "ocread.h"
@@ -48,13 +48,16 @@ static OCerror ocset_curlproperties(OCstate*);
 
 extern OCnode* makeunlimiteddimension(void);
 
-/* Collect global state info in one place */
-struct OCGLOBALSTATE ocglobalstate;
+int ocinitialized = 0;
 
 OCerror
 ocinternalinitialize(void)
 {
     int stat = OC_NOERR;
+    CURLcode cstat = CURLE_OK;
+
+    if(ocinitialized) return OC_NOERR;
+    ocinitialized = 1;
 
 #if 0
     if(sizeof(off_t) != sizeof(void*)) {
@@ -66,81 +69,13 @@ ocinternalinitialize(void)
     }
 #endif
 
-    if(!ocglobalstate.initialized) {
-      CURLcode cstat = CURLE_OK;
-      cstat = curl_global_init(CURL_GLOBAL_ALL);
-      if(cstat != CURLE_OK)
+     cstat = curl_global_init(CURL_GLOBAL_ALL);
+     if(cstat != CURLE_OK)
 	fprintf(stderr,"curl_global_init failed!\n");
-      memset((void*)&ocglobalstate,0,sizeof(ocglobalstate));
-      ocglobalstate.initialized = 1;
-    }
-
-    /* Capture temp dir*/
-    {
-	char* tempdir;
-	char* p;
-	char* q;
-	char cwd[4096];
-#ifdef _MSC_VER
-        tempdir = getenv("TEMP");
-#else
-	tempdir = "/tmp";
-#endif
-        if(tempdir == NULL) {
-	    fprintf(stderr,"Cannot find a temp dir; using ./\n");
-	    tempdir = getcwd(cwd,sizeof(cwd));
-	    if(tempdir == NULL || *tempdir == '\0') tempdir = ".";
-	}
-        ocglobalstate.tempdir= (char*)malloc(strlen(tempdir) + 1);
-	for(p=tempdir,q=ocglobalstate.tempdir;*p;p++,q++) {
-	    if((*p == '/' && *(p+1) == '/')
-	       || (*p == '\\' && *(p+1) == '\\')) {p++;}
-	    *q = *p;
-	}
-	*q = '\0';
-#ifdef _MSC_VER
-#else
-        /* Canonicalize */
-	for(p=ocglobalstate.tempdir;*p;p++) {
-	    if(*p == '\\') {*p = '/'; };
-	}
-	*q = '\0';
-#endif
-    }
-
-    /* Capture $HOME */
-    {
-	char* p;
-	char* q;
-        char* home = getenv("HOME");
-
-        if(home == NULL) {
-	    /* use tempdir */
-	    home = ocglobalstate.tempdir;
-	}
-        ocglobalstate.home = (char*)malloc(strlen(home) + 1);
-	for(p=home,q=ocglobalstate.home;*p;p++,q++) {
-	    if((*p == '/' && *(p+1) == '/')
-	       || (*p == '\\' && *(p+1) == '\\')) {p++;}
-	    *q = *p;
-	}
-	*q = '\0';
-#ifdef _MSC_VER
-#else
-        /* Canonicalize */
-	for(p=home;*p;p++) {
-	    if(*p == '\\') {*p = '/'; };
-	}
-#endif
-    }
 
     /* Compute some xdr related flags */
     xxdr_init();
 
-    ncloginit();
-
-    oc_curl_protocols(&ocglobalstate); /* see what protocols are supported */
-
     return OCTHROW(stat);
 }
 
@@ -154,7 +89,10 @@ ocopen(OCstate** statep, const char* url)
     NCURI* tmpurl = NULL;
     CURL* curl = NULL; /* curl handle*/
 
-    if(ncuriparse(url,&tmpurl) != NCU_OK) {OCTHROWCHK(stat=OC_EBADURL); goto fail;}
+    if(ncuriparse(url,&tmpurl) != NCU_OK) {
+	OCTHROWCHK(stat=OC_EBADURL);
+	goto fail;
+    }
 
     stat = occurlopen(&curl);
     if(stat != OC_NOERR) {OCTHROWCHK(stat); goto fail;}
@@ -172,6 +110,9 @@ ocopen(OCstate** statep, const char* url)
     state->packet = ncbytesnew();
     ncbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/
 
+    /* Initialize auth info from rc file */
+    stat = NC_authsetup(&state->auth, state->uri);
+
     /* capture curl properties for this link from rc file1*/
     stat = ocset_curlproperties(state);
     if(stat != OC_NOERR) goto fail;
@@ -182,6 +123,7 @@ ocopen(OCstate** statep, const char* url)
     if((stat=ocset_flags_perfetch(state))!= OC_NOERR) goto fail;
 #endif
 
+    oc_curl_protocols(state);
     if(statep) *statep = state;
     else {
       if(state != NULL) ocfree(state);
@@ -263,7 +205,8 @@ ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCflags flags,
     state->error.httpcode = ocfetchhttpcode(state->curl);
     if(stat != OC_NOERR) {
 	if(state->error.httpcode >= 400) {
-	    nclog(NCLOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode);
+	    nclog(NCLOGWARN,"oc_open: Could not read url (%s); http error = %l",
+		  state->uri,state->error.httpcode);
 	} else {
 	    nclog(NCLOGWARN,"oc_open: Could not read url");
 	}
@@ -362,24 +305,24 @@ createtempfile(OCstate* state, OCtree* tree)
 {
     int stat = OC_NOERR;
     char* path = NULL;
-    char* name = NULL;
+    char* tmppath = NULL;
     int len;
 
     len =
-	  strlen(ocglobalstate.tempdir)
+	  strlen(ncrc_globalstate.tempdir)
 	  + 1 /* '/' */
 	  + strlen(DATADDSFILE);
     path = (char*)malloc(len+1);
     if(path == NULL) return OC_ENOMEM;
-    occopycat(path,len,3,ocglobalstate.tempdir,"/",DATADDSFILE);
-    stat = ocmktmp(path,&name);
+    occopycat(path,len,3,ncrc_globalstate.tempdir,"/",DATADDSFILE);
+    tmppath = NC_mktmp(path);
     free(path);
     if(stat != OC_NOERR) goto fail;
 #ifdef OCDEBUG
-    nclog(NCLOGNOTE,"oc_open: creating tmp file: %s",name);
+    nclog(NCLOGNOTE,"oc_open: creating tmp file: %s",tmppath);
 #endif
-    tree->data.filename = name; /* remember our tmp file name */
-    name = NULL;
+    tree->data.filename = tmppath; /* remember our tmp file name */
+    tmppath = NULL;
     tree->data.file = NCfopen(tree->data.filename,"w+");
     if(tree->data.file == NULL) return OC_EOPEN;
     /* make the temp file so it will automatically be reclaimed on close */
@@ -388,9 +331,9 @@ createtempfile(OCstate* state, OCtree* tree)
     return stat;
 
 fail:
-    if(name != NULL) {
-        nclog(NCLOGERR,"oc_open: attempt to create tmp file failed: %s",name);
-	free(name);
+    if(tmppath != NULL) {
+        nclog(NCLOGERR,"oc_open: attempt to create tmp file failed: %s",tmppath);
+	free(tmppath);
     } else {
         nclog(NCLOGERR,"oc_open: attempt to create tmp file failed: NULL");
     }
@@ -414,24 +357,8 @@ occlose(OCstate* state)
     ncbytesfree(state->packet);
     ocfree(state->error.code);
     ocfree(state->error.message);
-    ocfree(state->curlflags.useragent);
-    if(state->curlflags.cookiejar) {
-        if(state->curlflags.createdflags & COOKIECREATED)
-            ocremovefile(state->curlflags.cookiejar);
-	ocfree(state->curlflags.cookiejar);
-    }
-    ocfree(state->curlflags.netrc);
-    ocfree(state->ssl.certificate);
-    ocfree(state->ssl.key);
-    ocfree(state->ssl.keypasswd);
-    ocfree(state->ssl.cainfo);
-    ocfree(state->ssl.capath);
-    ocfree(state->proxy.host);
-    ocfree(state->proxy.user);
-    ocfree(state->proxy.pwd);
-    ocfree(state->creds.user);
-    ocfree(state->creds.pwd);
     if(state->curl != NULL) occurlclose(state->curl);
+    NC_authclear(&state->auth);
     ocfree(state);
 }
 
@@ -570,15 +497,11 @@ static OCerror
 ocset_curlproperties(OCstate* state)
 {
     OCerror stat = OC_NOERR;
-
-    /* extract the relevant triples int state */
-    ocrc_process(state);
-
-    if(state->curlflags.useragent == NULL) {
+    if(state->auth.curlflags.useragent == NULL) {
         size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1;
 	char* agent = (char*)malloc(len+1);
 	if(occopycat(agent,len,2,DFALTUSERAGENT,VERSION))
-	    state->curlflags.useragent = agent;
+	    state->auth.curlflags.useragent = agent;
 	else
 	    free(agent);
     }
@@ -586,43 +509,43 @@ ocset_curlproperties(OCstate* state)
     /* Some servers (e.g. thredds and columbia) appear to require a place
        to put cookies in order for some security functions to work
     */
-    if(state->curlflags.cookiejar != NULL
-       && strlen(state->curlflags.cookiejar) == 0) {
-	free(state->curlflags.cookiejar);
-	state->curlflags.cookiejar = NULL;
+    if(state->auth.curlflags.cookiejar != NULL
+       && strlen(state->auth.curlflags.cookiejar) == 0) {
+	free(state->auth.curlflags.cookiejar);
+	state->auth.curlflags.cookiejar = NULL;
     }
 
-    if(state->curlflags.cookiejar == NULL) {
+    if(state->auth.curlflags.cookiejar == NULL) {
 	/* If no cookie file was defined, define a default */
-        int stat;
+		int stat = NC_NOERR;
         char* path = NULL;
-        char* name = NULL;
+        char* tmppath = NULL;
         int len;
 	errno = 0;
 	/* Create the unique cookie file name */
         len =
-	  strlen(ocglobalstate.tempdir)
+	  strlen(ncrc_globalstate.tempdir)
 	  + 1 /* '/' */
 	  + strlen("occookies");
-        path = (char*)malloc(len+1);
+        path = (char*)calloc(1,len+1);
         if(path == NULL) return OC_ENOMEM;
-        occopycat(path,len,3,ocglobalstate.tempdir,"/","occookies");
-        stat = ocmktmp(path,&name);
+        occopycat(path,len,3,ncrc_globalstate.tempdir,"/","occookies");
+        tmppath = NC_mktmp(path);
         free(path);
-	state->curlflags.cookiejar = name;
-	state->curlflags.createdflags |= COOKIECREATED;
+	state->auth.curlflags.cookiejar = tmppath;
+	state->auth.curlflags.cookiejarcreated = 1;
 	if(stat != OC_NOERR && errno != EEXIST) {
 	    fprintf(stderr,"Cannot create cookie file\n");
 	    goto fail;
 	}
 	errno = 0;
     }
-    OCASSERT(state->curlflags.cookiejar != NULL);
+    OCASSERT(state->auth.curlflags.cookiejar != NULL);
 
     /* Make sure the cookie jar exists and can be read and written */
     {
 	FILE* f = NULL;
-	char* fname = state->curlflags.cookiejar;
+	char* fname = state->auth.curlflags.cookiejar;
 	/* See if the file exists already */
         f = NCfopen(fname,"r");
 	if(f == NULL) {
@@ -649,7 +572,7 @@ ocset_curlproperties(OCstate* state)
     if(ocrc_netrc_required(state)) {
 	/* WARNING: it appears that a user+pwd was specified specifically, then
            the netrc file will be completely disabled. */
-	if(state->creds.userpwd != NULL) {
+	if(state->auth.creds.userpwd != NULL) {
   	    nclog(NCLOGWARN,"The rc file specifies both netrc and user+pwd; this will cause curl to ignore the netrc file");
 	}
 	stat = oc_build_netrc(state);
@@ -719,10 +642,10 @@ OCerror
 ocset_useragent(OCstate* state, const char* agent)
 {
     OCerror stat = OC_NOERR;
-    if(state->curlflags.useragent != NULL)
-	free(state->curlflags.useragent);
-    state->curlflags.useragent = strdup(agent);
-    if(state->curlflags.useragent == NULL)
+    if(state->auth.curlflags.useragent != NULL)
+	free(state->auth.curlflags.useragent);
+    state->auth.curlflags.useragent = strdup(agent);
+    if(state->auth.curlflags.useragent == NULL)
 	return OCTHROW(OC_ENOMEM);
     stat = ocset_curlflag(state,CURLOPT_USERAGENT);
     return stat;
@@ -732,10 +655,10 @@ OCerror
 ocset_netrc(OCstate* state, const char* path)
 {
     OCerror stat = OC_NOERR;
-    if(state->curlflags.netrc != NULL)
-	free(state->curlflags.netrc);
-    state->curlflags.netrc = strdup(path);
-    if(state->curlflags.netrc == NULL)
+    if(state->auth.curlflags.netrc != NULL)
+	free(state->auth.curlflags.netrc);
+    state->auth.curlflags.netrc = strdup(path);
+    if(state->auth.curlflags.netrc == NULL)
 	return OCTHROW(OC_ENOMEM);
     stat = ocset_curlflag(state,CURLOPT_NETRC);
     return stat;
@@ -750,3 +673,4 @@ ocremovefile(const char* path)
     remove(path);
 #endif
 }
+
diff --git a/oc2/ocinternal.h b/oc2/ocinternal.h
index b4995b3..9cef372 100644
--- a/oc2/ocinternal.h
+++ b/oc2/ocinternal.h
@@ -6,8 +6,7 @@
 
 #include "config.h"
 
-
-#if defined(_WIN32) || defined(_WIN64)
+#ifdef _MSC_VER
 #include <malloc.h>
 #endif
 
@@ -41,6 +40,7 @@
 #include <curl/curl.h>
 
 #include "netcdf.h"
+#include "ncauth.h"
 #include "nclist.h"
 #include "ncbytes.h"
 #include "ncuri.h"
@@ -158,28 +158,11 @@ struct OCTriplestore {
    } triples[MAXRCLINES];
 };
 
-/* Collect global state info in one place */
-extern struct OCGLOBALSTATE {
-    int initialized;
-    struct {
-        int proto_file;
-        int proto_https;
-    } curl;
-    char* tempdir; /* track a usable temp dir */
-    char* home; /* track $HOME for use in creating $HOME/.oc dir */
-    struct {
-	int ignore; /* if 1, then do not use any rc file */
-	int loaded;
-        struct OCTriplestore daprc; /* the rc file triple store fields*/
-        char* rcfile; /* specified rcfile; overrides anything else */
-    } rc;
-} ocglobalstate;
-
 /*! Specifies the OCstate = non-opaque version of OClink */
 struct OCstate {
     OCheader header; /* class=OC_State */
     NClist* trees; /* list<OCNODE*> ; all root objects */
-    NCURI* uri; /* base URI*/
+    NCURI* uri; /* parsed base URI*/
     NCbytes* packet; /* shared by all trees during construction */
     struct OCerrdata {/* Hold info for an error return from server */
 	char* code;
@@ -189,42 +172,8 @@ struct OCstate {
     } error;
     CURL* curl; /* curl handle*/
     char curlerror[CURL_ERROR_SIZE];
-    struct OCcurlflags {
-        int proto_file; /* Is file: supported? */
-        int proto_https; /* is https: supported? */
-	int compress; /*CURLOPT_ENCODING*/
-	int verbose; /*CURLOPT_ENCODING*/
-	int timeout; /*CURLOPT_TIMEOUT*/
-	int maxredirs; /*CURLOPT_MAXREDIRS*/
-	char* useragent; /*CURLOPT_USERAGENT*/
-	/* track which of these are created by oc */
-#define COOKIECREATED 1
-	int createdflags;
-	char* cookiejar; /*CURLOPT_COOKIEJAR,CURLOPT_COOKIEFILE*/
-	char* netrc; /*CURLOPT_NETRC,CURLOPT_NETRC_FILE*/
-    } curlflags;
-    struct OCSSL {
-	int   verifypeer; /* CURLOPT_SSL_VERIFYPEER;
-                             do not do this when cert might be self-signed
-                             or temporarily incorrect */
-	int   verifyhost; /* CURLOPT_SSL_VERIFYHOST; for client-side verification */
-        char* certificate; /*CURLOPT_SSLCERT*/
-	char* key; /*CURLOPT_SSLKEY*/
-	char* keypasswd; /*CURLOPT_SSLKEYPASSWD*/
-        char* cainfo; /* CURLOPT_CAINFO; certificate authority */
-	char* capath;  /*CURLOPT_CAPATH*/
-    } ssl;
-    struct OCproxy {
-	char *host; /*CURLOPT_PROXY*/
-	int port; /*CURLOPT_PROXYPORT*/
-	char* user; /*CURLOPT_PROXYUSERNAME*/
-	char* pwd; /*CURLOPT_PROXYPASSWORD*/
-    } proxy;
-    struct OCcredentials {
-	char *user; /*CURLOPT_USERNAME*/
-	char *pwd; /*CURLOPT_PASSWORD*/
-    } creds;
     void* usercurldata;
+    NCauth auth; /* curl auth data */
     long ddslastmodified;
     long datalastmodified;
 };
@@ -263,6 +212,9 @@ extern int cedebug;
 extern NClist* CEparse(OCstate*,char* input);
 #endif
 
+extern int ocinitialized;
+
+
 extern OCerror ocopen(OCstate** statep, const char* url);
 extern void occlose(OCstate* state);
 extern OCerror ocfetch(OCstate*, const char*, OCdxd, OCflags, OCnode**);
diff --git a/oc2/ocnode.c b/oc2/ocnode.c
index e4f0e8f..4660483 100644
--- a/oc2/ocnode.c
+++ b/oc2/ocnode.c
@@ -6,8 +6,6 @@
 #include "occompile.h"
 #include "ocdebug.h"
 
-static const unsigned int MAX_UINT = 0xffffffff;
-
 static OCerror mergedas1(OCnode* dds, OCnode* das);
 static OCerror mergedods1(OCnode* dds, OCnode* das);
 static OCerror mergeother1(OCnode* root, OCnode* das);
@@ -365,14 +363,15 @@ mergedas1(OCnode* dds, OCnode* das)
     for(i=0;i<nclistlength(das->subnodes);i++) {
 	OCnode* attnode = (OCnode*)nclistget(das->subnodes,i);
 	if(attnode->octype == OC_Attribute) {
+            OCattribute* att;
 	    if(dds->octype == OC_Atomic
 		|| dds->octype == OC_Sequence
 		|| dds->octype == OC_Structure
 		|| dds->octype == OC_Grid)
 	        attnode->att.var = dds;
-	    OCattribute* att = makeattribute(attnode->name,
-						attnode->etype,
-						attnode->att.values);
+            att = makeattribute(attnode->name,
+                                attnode->etype,
+                                attnode->att.values);
             nclistpush(dds->attributes,(void*)att);
 	}
     }
@@ -399,13 +398,13 @@ mergedods1(OCnode* dds, OCnode* dods)
             */
 	    size_t len =   strlen(attnode->name)
                          + strlen(dods->name)
-			 + strlen(".")
-			 + 1; /*null*/
-	    char* newname = (char*)malloc(len);
+			 + strlen(".");
+	    len++; /*strlcat nul*/
+	    char* newname = (char*)malloc(len+1);
 	    if(newname == NULL) return OC_ENOMEM;
-	    strcpy(newname,dods->name);
-	    strcat(newname,".");
-	    strcat(newname,attnode->name);
+	    strncpy(newname,dods->name,len);
+	    strlcat(newname,".",len);
+	    strlcat(newname,attnode->name,len);
 	    att = makeattribute(newname,attnode->etype,attnode->att.values);
 	    free(newname);
             nclistpush(dds->attributes,(void*)att);
@@ -483,7 +482,7 @@ occorrelater(OCnode* dds, OCnode* dxd)
     if(dxd->name != NULL && dxd->name != NULL
        && strcmp(dxd->name,dds->name) != 0) {
 	OCTHROWCHK((ocstat = OC_EINVAL)); goto fail;
-    } else if(dxd->name != dxd->name) { /* test NULL==NULL */
+    } else if(dxd->name != dds->name) { /* test NULL==NULL */
 	OCTHROWCHK((ocstat = OC_EINVAL)); goto fail;
     }
 
diff --git a/oc2/ocrc.c b/oc2/ocrc.c
deleted file mode 100644
index d4ec4dc..0000000
--- a/oc2/ocrc.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
-   See the COPYRIGHT file for more information. */
-
-#include "config.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "netcdf.h"
-#include "ocinternal.h"
-#include "ocdebug.h"
-#include "nclog.h"
-#include "ncwinpath.h"
-
-#define OCRCFILEENV "DAPRCFILE"
-
-#define RTAG ']'
-#define LTAG '['
-
-#define TRIMCHARS " \t\r\n"
-
-static OCerror rc_search(const char* prefix, const char* rcfile, char** pathp);
-
-static int rcreadline(FILE* f, char* more, int morelen);
-static void rctrim(char* text);
-
-static void storedump(char* msg, struct OCTriple*, int ntriples);
-
-/* Define default rc files and aliases, also defines search order*/
-static char* rcfilenames[] = {".daprc",".dodsrc",NULL};
-
-/* The Username and password are in the URL if the URL is of the form:
- * http://<name>:<passwd>@<host>/....
- */
-static int
-occredentials_in_url(const char *url)
-{
-    char *pos = strstr(url, "http://");
-    if (!pos)
-        return 0;
-    pos += 7;
-    if (strchr(pos, '@') && strchr(pos, ':'))
-        return 1;
-    return 0;
-}
-
-/*
-Given form user:pwd, parse into user and pwd
-and do %xx unescaping
-*/
-static OCerror
-parsecredentials(const char* userpwd, char** userp, char** pwdp)
-{
-    char* user = NULL;
-    char* pwd = NULL;
-
-    if(userpwd == NULL)
-	return OC_EINVAL;
-    user = strdup(userpwd);
-    if(user == NULL)
-	return NC_ENOMEM;
-    pwd = strchr(user,':');
-    if(pwd == NULL)
-	return OC_EINVAL;
-    *pwd = '\0';
-    pwd++;
-    if(userp)
-	*userp = ncuridecode(user);
-    if(pwdp)
-	*pwdp = ncuridecode(pwd);
-    free(user);
-    return OC_NOERR;
-}
-
-static OCerror
-ocextract_credentials(const char *url, char **user, char** pwd, char **result_url)
-{
-    NCURI* parsed = NULL;
-
-    if(url == NULL || ncuriparse(url,&parsed) != NCU_OK)
-	return OCTHROW(OC_EBADURL);
-    if(parsed->user != NULL || parsed->password == NULL) {
-	ncurifree(parsed);
-	return OCTHROW(OC_EBADURL);
-    }
-    if(user)
-	*user = parsed->user;
-    if(pwd)
-	*pwd = parsed->password;
-    ncurifree(parsed);
-    return OC_NOERR;
-}
-
-char*
-occombinehostport(const NCURI* uri)
-{
-    char* hp;
-    int len = 0;
-
-    if(uri->host == NULL)
-	return NULL;
-    else
-	len += strlen(uri->host);
-    if(uri->port != NULL)
-	len += strlen(uri->port);
-    hp = (char*)malloc(len+1);
-    if(hp == NULL)
-	return NULL;
-    if(uri->port == NULL)
-        occopycat(hp,len+1,1,uri->host);
-    else
-        occopycat(hp,len+1,3,uri->host,":",uri->port);
-    return hp;
-}
-
-#if 0
-/*
-Combine user and pwd into the user:pwd form.
-Note that we must %xx escape the user and the pwd
-*/
-static char*
-combinecredentials(const char* user, const char* pwd)
-{
-    int userPassSize;
-    char *userPassword;
-    char *escapeduser = NULL;
-    char* escapedpwd = NULL;
-
-    if(user == NULL || pwd == NULL)
-	return NULL;	
- 
-    userPassSize = 3*strlen(user) + 3*strlen(pwd) + 2; /* times 3 for escapes */
-    userPassword = malloc(sizeof(char) * userPassSize);
-    if (!userPassword) {
-        nclog(NCLOGERR,"Out of Memory\n");
-	return NULL;
-    }
-    escapeduser = ncuriencodeuserpwd(user);
-    escapedpwd = ncuriencodeuserpwd(pwd);
-    if(escapeduser == NULL || escapedpwd == NULL) {
-        nclog(NCLOGERR,"Out of Memory\n");
-	return NULL;
-    }
-    occopycat(userPassword,userPassSize-1,3,escapeduser,":",escapedpwd);
-    free(escapeduser);
-    free(escapedpwd);
-    return userPassword;
-}
-#endif
-
-static int
-rcreadline(FILE* f, char* more, int morelen)
-{
-    int i = 0;
-    int c = getc(f);
-    if(c < 0) return 0;
-    for(;;) {
-        if(i < morelen)  /* ignore excess characters */
-            more[i++]=c;
-        c = getc(f);
-        if(c < 0) break; /* eof */
-        if(c == '\n') break; /* eol */
-    }
-    /* null terminate more */
-    more[i] = '\0';
-    return 1;
-}
-
-/* Trim TRIMCHARS from both ends of text; */
-static void
-rctrim(char* text)
-{
-    char* p = text;
-    size_t len;
-    int i;
-
-    len = strlen(text);
-    /* locate first non-trimchar */
-    for(;*p;p++) {
-       if(strchr(TRIMCHARS,*p) == NULL) break; /* hit non-trim char */
-    }
-    memmove(text,p,strlen(p)+1);
-    len = strlen(text);
-    /* locate last non-trimchar */
-    if(len > 0) {
-        for(i=(len-1);i>=0;i--) {
-            if(strchr(TRIMCHARS,text[i]) == NULL) {
-                text[i+1] = '\0'; /* elide trailing trimchars */
-                break;
-            }
-        }
-    }
-}
-
-int
-ocparseproxy(OCstate* state, char* v)
-{
-    /* Do not free these; they are pointers into v; free v instead */
-    char *host_pos = NULL;
-    char *port_pos = NULL;
-    if(v == NULL || strlen(v) == 0)
-	return OC_NOERR; /* nothing there*/
-    if (occredentials_in_url(v)) {
-        char *result_url = NULL;
-        ocextract_credentials(v, &state->proxy.user, &state->proxy.pwd, &result_url);
-        v = result_url;
-    }
-    /* allocating a bit more than likely needed ... */
-    host_pos = strstr(v, "http://");
-    if (host_pos)
-        host_pos += strlen("http://");
-    else
-        host_pos = v;
-    port_pos = strchr(host_pos, ':');
-    if (port_pos) {
-        size_t host_len;
-        char *port_sep = port_pos;
-        port_pos++;
-        *port_sep = '\0';
-        host_len = strlen(host_pos);
-        state->proxy.host = malloc(sizeof(char) * host_len + 1);
-        if (state->proxy.host == NULL)
-            return OCTHROW(OC_ENOMEM);
-        strncpy(state->proxy.host, host_pos, host_len);
-        state->proxy.host[host_len] = '\0';
-        state->proxy.port = atoi(port_pos);
-    } else {
-        size_t host_len = strlen(host_pos);
-        state->proxy.host = malloc(sizeof(char) * host_len + 1);
-        if (state->proxy.host == NULL)
-            return OCTHROW(OC_ENOMEM);
-        strncpy(state->proxy.host, host_pos, host_len);
-        state->proxy.host[host_len] = '\0';
-        state->proxy.port = 80;
-    }
-#if 0
-    state->proxy.host[v_len] = '\0';
-    state->proxy.port = atoi(v);
-    s_len = strlen(v);
-    state->proxy.user = malloc(sizeof(char) * s_len + 1);
-    if (state->proxy.user == NULL)
-        return OC_ENOMEM;
-     strncpy(state->proxy.user, v, s_len);
-     state->proxy.user[s_len] = '\0';
-     p_len = strlen(v);
-     state->proxy.password = malloc(sizeof(char) * p_len + 1);
-     if (state->proxy.password == NULL)
-         return OCTHROW(OC_ENOMEM);
-     strncpy(state->proxy.password, v, p_len);
-     state->proxy.password[p_len] = '\0';
-#endif /*0*/
-     if (ocdebug > 1) {
-         nclog(NCLOGNOTE,"host name: %s", state->proxy.host);
-#ifdef INSECURE
-         nclog(NCLOGNOTE,"user+pwd: %s+%s", state->proxy.user,state->proxy.pwd);
-#endif
-         nclog(NCLOGNOTE,"port number: %d", state->proxy.port);
-    }
-    if(v) free(v);
-    return OC_NOERR;
-}
-
-/* insertion sort the triplestore based on url */
-static void
-sorttriplestore(struct OCTriplestore* store)
-{
-    int i, nsorted;
-    struct OCTriple* sorted = NULL;
-
-    if(store == NULL) return; /* nothing to sort */
-    if(store->ntriples <= 1) return; /* nothing to sort */
-    if(ocdebug > 2)
-        storedump("initial:",store->triples,store->ntriples);
-
-    sorted = (struct OCTriple*)malloc(sizeof(struct OCTriple)*store->ntriples);
-    if(sorted == NULL) {
-        nclog(NCLOGERR,"sorttriplestore: out of memory");
-        return;
-    }
-
-    nsorted = 0;
-    while(nsorted < store->ntriples) {
-        int largest;
-        /* locate first non killed entry */
-        for(largest=0;largest<store->ntriples;largest++) {
-            if(store->triples[largest].key[0] != '\0') break;
-        }
-        OCASSERT(store->triples[largest].key[0] != '\0');
-        for(i=0;i<store->ntriples;i++) {
-            if(store->triples[i].key[0] != '\0') { /* avoid empty slots */
-                int lexorder = strcmp(store->triples[i].host,store->triples[largest].host);
-                int leni = strlen(store->triples[i].host);
-                int lenlarge = strlen(store->triples[largest].host);
-                /* this defines the ordering */
-                if(leni == 0 && lenlarge == 0) continue; /* if no urls, then leave in order */
-                if(leni != 0 && lenlarge == 0) largest = i;
-                else if(lexorder > 0) largest = i;
-            }
-        }
-        /* Move the largest entry */
-        OCASSERT(store->triples[largest].key[0] != 0);
-        sorted[nsorted] = store->triples[largest];
-        store->triples[largest].key[0] = '\0'; /* kill entry */
-        nsorted++;
-      if(ocdebug > 2)
-            storedump("pass:",sorted,nsorted);
-    }
-
-    memcpy((void*)store->triples,(void*)sorted,sizeof(struct OCTriple)*nsorted);
-    free(sorted);
-
-    if(ocdebug > 1)
-        storedump("final .rc order:",store->triples,store->ntriples);
-}
-
-/* Create a triple store from a file */
-static int
-ocrc_compile(const char* path)
-{
-    char line0[MAXRCLINESIZE+1];
-    FILE *in_file = NULL;
-    int linecount = 0;
-    struct OCTriplestore* ocrc = &ocglobalstate.rc.daprc;
-
-    ocrc->ntriples = 0; /* reset; nothing to free */
-
-    in_file = NCfopen(path, "r"); /* Open the file to read it */
-    if (in_file == NULL) {
-        nclog(NCLOGERR, "Could not open configuration file: %s",path);
-        return OC_EPERM;
-    }
-
-    for(;;) {
-        char *line,*key,*value;
-        int c;
-        if(!rcreadline(in_file,line0,sizeof(line0))) break;
-        linecount++;
-        if(linecount >= MAXRCLINES) {
-            nclog(NCLOGERR, ".rc has too many lines");
-            return 0;
-        }
-        line = line0;
-        /* check for comment */
-        c = line[0];
-        if (c == '#') continue;
-        rctrim(line);  /* trim leading and trailing blanks */
-	if(strlen(line) == 0) continue;
-        if(strlen(line) >= MAXRCLINESIZE) {
-            nclog(NCLOGERR, "%s line too long: %s",path,line0);
-            continue; /* ignore it */
-        }
-        /* setup */
-        ocrc->triples[ocrc->ntriples].host[0] = '\0';
-        ocrc->triples[ocrc->ntriples].key[0] = '\0';
-        ocrc->triples[ocrc->ntriples].value[0] = '\0';
-        if(line[0] == LTAG) {
-	    NCURI* uri;
-            char* url = ++line;
-            char* rtag = strchr(line,RTAG);
-            if(rtag == NULL) {
-                nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
-                continue;
-            }
-            line = rtag + 1;
-            *rtag = '\0';
-            /* compile the url and pull out the host */
-	    if(ncuriparse(url,&uri) != NCU_OK) {
-                nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
-		continue;
-	    }
-            strncpy(ocrc->triples[ocrc->ntriples].host,uri->host,MAXRCLINESIZE-1);
-	    if(uri->port != NULL) {
-                strncat(ocrc->triples[ocrc->ntriples].host,":",MAXRCLINESIZE-1);
-                strncat(ocrc->triples[ocrc->ntriples].host,uri->port,MAXRCLINESIZE-1);
-	    }
-	    ncurifree(uri);
-        }
-        /* split off key and value */
-        key=line;
-        value = strchr(line, '=');
-        if(value == NULL)
-            value = line + strlen(line);
-        else {
-            *value = '\0';
-            value++;
-        }
-        strncpy(ocrc->triples[ocrc->ntriples].key,key,MAXRCLINESIZE-1);
-        if(*value == '\0')
-            strcpy(ocrc->triples[ocrc->ntriples].value,"1");/*dfalt*/
-        else
-          strncpy(ocrc->triples[ocrc->ntriples].value,value,(MAXRCLINESIZE-1));
-        rctrim( ocrc->triples[ocrc->ntriples].key);
-        rctrim( ocrc->triples[ocrc->ntriples].value);
-	OCDBG2("rc: key=%s value=%s",
-		ocrc->triples[ocrc->ntriples].key,
-		ocrc->triples[ocrc->ntriples].value);
-        ocrc->ntriples++;
-    }
-    fclose(in_file);
-    sorttriplestore(&ocglobalstate.rc.daprc);
-    return 1;
-}
-
-/* read and compile the rc file, if any */
-OCerror
-ocrc_load(void)
-{
-    OCerror stat = OC_NOERR;
-    char* path = NULL;
-
-    if(ocglobalstate.rc.ignore) {
-        nclog(NCLOGDBG,"No runtime configuration file specified; continuing");
-	return OC_NOERR;
-    }
-    if(ocglobalstate.rc.loaded) return OC_NOERR;
-
-    /* locate the configuration files in the following order:
-       1. specified by set_rcfile
-       2. set by DAPRCFILE env variable
-       3. '.'/<rcfile>
-       4. $HOME/<rcfile>
-    */
-    if(ocglobalstate.rc.rcfile != NULL) { /* always use this */
-	path = strdup(ocglobalstate.rc.rcfile);
-    } else if(getenv(OCRCFILEENV) != NULL && strlen(getenv(OCRCFILEENV)) > 0) {
-        path = strdup(getenv(OCRCFILEENV));
-    } else {
-	char** rcname;
-	int found = 0;
-	for(rcname=rcfilenames;!found && *rcname;rcname++) {
-	    stat = rc_search(".",*rcname,&path);
-    	    if(stat == OC_NOERR && path == NULL)  /* try $HOME */
-	        stat = rc_search(ocglobalstate.home,*rcname,&path);
-	    if(stat != OC_NOERR)
-		goto done;
-	    if(path != NULL)
-		found = 1;
-	}
-    }
-    if(path == NULL) {
-        nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
-    } else {
-	if(ocdebug > 0)
-	    fprintf(stderr, "RC file: %s\n", path);
-        if(ocrc_compile(path) == 0) {
-	    nclog(NCLOGERR, "Error parsing %s\n",path);
-	    stat = OC_ERCFILE;
-	}
-    }
-done:
-    ocglobalstate.rc.loaded = 1; /* even if not exists */
-    if(path != NULL)
-	free(path);
-    return stat;
-}
-
-OCerror
-ocrc_process(OCstate* state)
-{
-    OCerror stat = OC_NOERR;
-    char* value = NULL;
-    NCURI* uri = state->uri;
-    char* url_hostport = NULL;
-
-    if(!ocglobalstate.initialized)
-	ocinternalinitialize();
-    if(!ocglobalstate.rc.loaded)
-	ocrc_load();
-    /* Note, we still must do this function even if
-       ocglobalstate.rc.ignore is set in order
-       to getinfo e.g. user:pwd from url
-    */
-
-    url_hostport = occombinehostport(uri);
-    if(url_hostport == NULL)
-	return OC_ENOMEM;
-
-    value = ocrc_lookup("HTTP.DEFLATE",url_hostport);
-    if(value != NULL) {
-        if(atoi(value)) state->curlflags.compress = 1;
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.DEFLATE: %ld", state->curlflags.compress);
-    }
-    if((value = ocrc_lookup("HTTP.VERBOSE",url_hostport)) != NULL) {
-        if(atoi(value)) state->curlflags.verbose = 1;
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.VERBOSE: %ld", state->curlflags.verbose);
-    }
-    if((value = ocrc_lookup("HTTP.TIMEOUT",url_hostport)) != NULL) {
-        if(atoi(value)) state->curlflags.timeout = atoi(value);
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.TIMEOUT: %ld", state->curlflags.timeout);
-    }
-    if((value = ocrc_lookup("HTTP.USERAGENT",url_hostport)) != NULL) {
-        if(atoi(value)) state->curlflags.useragent = strdup(value);
-        if(state->curlflags.useragent == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.USERAGENT: %s", state->curlflags.useragent);
-    }
-
-    if(
-          (value = ocrc_lookup("HTTP.COOKIEFILE",url_hostport))
-       || (value = ocrc_lookup("HTTP.COOKIE_FILE",url_hostport))
-       || (value = ocrc_lookup("HTTP.COOKIEJAR",url_hostport))
-       || (value = ocrc_lookup("HTTP.COOKIE_JAR",url_hostport))
-      ) {
-        state->curlflags.cookiejar = strdup(value);
-        if(state->curlflags.cookiejar == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.COOKIEJAR: %s", state->curlflags.cookiejar);
-    }
-
-    if((value = ocrc_lookup("HTTP.PROXY_SERVER",url_hostport)) != NULL) {
-        stat = ocparseproxy(state,value);
-        if(stat != OC_NOERR) goto done;
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.PROXY_SERVER: %s", value);
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.VALIDATE",url_hostport)) != NULL) {
-        if(atoi(value)) {
-	    state->ssl.verifypeer = 1;
-	    state->ssl.verifyhost = 1;
-            if(ocdebug > 0)
-                nclog(NCLOGNOTE,"HTTP.SSL.VALIDATE: %ld", 1);
-	}
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.CERTIFICATE",url_hostport)) != NULL) {
-        state->ssl.certificate = strdup(value);
-        if(state->ssl.certificate == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.SSL.CERTIFICATE: %s", state->ssl.certificate);
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.KEY",url_hostport)) != NULL) {
-        state->ssl.key = strdup(value);
-        if(state->ssl.key == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.SSL.KEY: %s", state->ssl.key);
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.KEYPASSWORD",url_hostport)) != NULL) {
-        state->ssl.keypasswd = strdup(value);
-        if(state->ssl.keypasswd == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.SSL.KEYPASSWORD: %s", state->ssl.keypasswd);
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.CAINFO",url_hostport)) != NULL) {
-        state->ssl.cainfo = strdup(value);
-        if(state->ssl.cainfo == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.SSL.CAINFO: %s", state->ssl.cainfo);
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.CAPATH",url_hostport)) != NULL) {
-        state->ssl.capath = strdup(value);
-        if(state->ssl.capath == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.SSL.CAPATH: %s", state->ssl.capath);
-    }
-
-    if((value = ocrc_lookup("HTTP.SSL.VERIFYPEER",url_hostport)) != NULL) {
-        char* s = strdup(value);
-        int tf = 0;
-        if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0)
-            tf = 0;
-        else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0)
-            tf = 1;
-        else
-            tf = 1; /* default if not null */
-        state->ssl.verifypeer = tf;
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.SSL.VERIFYPEER: %d", state->ssl.verifypeer);
-	free(s);
-    }
-
-    if((value = ocrc_lookup("HTTP.NETRC",url_hostport)) != NULL) {
-        if(state->curlflags.netrc != NULL)
-	    free(state->curlflags.netrc);
-        state->curlflags.netrc = strdup(value);
-        if(state->curlflags.netrc == NULL) {stat = OC_ENOMEM; goto done;}
-        if(ocdebug > 0)
-            nclog(NCLOGNOTE,"HTTP.NETRC: %s", state->curlflags.netrc);
-    }
-
-    { /* Handle various cases for user + password */
-	/* First, see if the user+pwd was in the original url */
-	char* user = NULL;
-	char* pwd = NULL;
-	if(uri->user != NULL && uri->password != NULL) {
-	    user = uri->user;
-	    pwd = uri->password;
-	} else {
-   	    user = ocrc_lookup("HTTP.CREDENTIALS.USER",url_hostport);
-	    pwd = ocrc_lookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
-	}
-	if(user != NULL && pwd != NULL) {
-            state->creds.user = strdup(user);
-            state->creds.pwd = strdup(pwd);
-	} else {
-	    /* Could not get user and pwd, so try USERPASSWORD */
-	    const char* userpwd = ocrc_lookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
-	    if(userpwd != NULL) {
-		stat = parsecredentials(userpwd,&user,&pwd);
-		if(stat) goto done;
-                state->creds.user = user;
-                state->creds.pwd = pwd;
-	    }
-        }
-    }
-
-done:
-    if(url_hostport != NULL) free(url_hostport);
-    return stat;
-}
-
-static struct OCTriple*
-ocrc_locate(char* key, char* hostport)
-{
-    int i,found;
-    struct OCTriplestore* ocrc = &ocglobalstate.rc.daprc;
-    struct OCTriple* triple;
-
-    if(ocglobalstate.rc.ignore)
-	return NULL;
-    if(!ocglobalstate.rc.loaded)
-	ocrc_load();
-
-    triple = ocrc->triples;
-
-    if(key == NULL || ocrc == NULL) return NULL;
-    if(hostport == NULL) hostport = "";
-    /* Assume that the triple store has been properly sorted */
-    for(found=0,i=0;i<ocrc->ntriples;i++,triple++) {
-        size_t hplen = strlen(triple->host);
-        int t;
-        if(strcmp(key,triple->key) != 0) continue; /* keys do not match */
-        /* If the triple entry has no url, then use it
-           (because we have checked all other cases)*/
-        if(hplen == 0) {found=1;break;}
-        /* do hostport match */
-        t = strcmp(hostport,triple->host);
-        if(t ==  0) {found=1; break;}
-    }
-    return (found?triple:NULL);
-}
-
-char*
-ocrc_lookup(char* key, char* hostport)
-{
-    struct OCTriple* triple = ocrc_locate(key,hostport);
-    if(triple != NULL && ocdebug > 2) {
-	fprintf(stderr,"lookup %s: [%s]%s = %s\n",hostport,triple->host,triple->key,triple->value);
-    }
-    return (triple == NULL ? NULL : triple->value);
-}
-
-
-static void
-storedump(char* msg, struct OCTriple* triples, int ntriples)
-{
-    int i;
-    struct OCTriplestore* ocrc = &ocglobalstate.rc.daprc;
-
-    if(msg != NULL) fprintf(stderr,"%s\n",msg);
-    if(ocrc == NULL) {
-        fprintf(stderr,"<EMPTY>\n");
-        return;
-    }
-    if(triples == NULL) triples= ocrc->triples;
-    if(ntriples < 0 ) ntriples= ocrc->ntriples;
-    for(i=0;i<ntriples;i++) {
-        fprintf(stderr,"\t%s\t%s\t%s\n",
-                (triples[i].host == NULL || strlen(triples[i].host)==0?"--":triples[i].host),
-                triples[i].key,
-                triples[i].value);
-    }
-}
-
-#if 0
-/*
-Lookup against all prefixes
-*/
-
-static char*
-ocrc_lookup(char* suffix, char* url)
-{
-    char* value = NULL;
-    char key[MAXRCLINESIZE+1];
-    const char** p = prefixes;
-    for(;*p;p++) {
-        if(!occopycat(key,sizeof(key),2,*p,suffix))
-            return NULL;
-	value = ocrc_lookup(key,url);
-	if(value != NULL)
-	    return value;
-    }
-    return value;
-}
-
-/* compile the rc file, if any */
-static OCerror
-ocreadrc(void)
-{
-    OCerror stat = OC_NOERR;
-    char* path = NULL;
-    /* locate the configuration files: first if specified,
-       then '.',  then $HOME */
-    if(ocglobalstate.rc.rcfile != NULL) { /* always use this */
-	path = ocglobalstate.rc.rcfile;
-    } else {
-	char** rcname;
-	int found = 0;
-	for(rcname=rcfilenames;!found && *rcname;rcname++) {
-	    stat = rc_search(".",*rcname,&path);
-    	    if(stat == OC_NOERR && path == NULL)  /* try $HOME */
-	        stat = rc_search(ocglobalstate.home,*rcname,&path);
-	    if(stat != OC_NOERR)
-		goto done;
-	    if(path != NULL)
-		found = 1;
-	}
-    }
-    if(path == NULL) {
-        nclog(NCLOGDBG,"Cannot find runtime configuration file; continuing");
-    } else {
-	if(ocdebug > 0)
-	    fprintf(stderr, "DODS RC file: %s\n", path);
-        if(ocdodsrc_read(path) == 0) {
-	    nclog(NCLOGERR, "Error parsing %s\n",path);
-	    stat = OC_ERCFILE;
-	}
-    }
-done:
-    if(path != NULL)
-	free(path);
-    return stat;
-}
-#endif
-
-/**
- * Prefix must end in '/'
- */
-static
-OCerror
-rc_search(const char* prefix, const char* rcname, char** pathp)
-{
-    char* path = NULL;
-    FILE* f = NULL;
-    int plen = strlen(prefix);
-    int rclen = strlen(rcname);
-    OCerror stat = OC_NOERR;
-
-    size_t pathlen = plen+rclen+1+1; /*+1 for '/' +1 for nul*/
-    path = (char*)malloc(pathlen);
-    if(path == NULL) {
-	stat = OC_ENOMEM;
-	goto done;
-    }
-    if(!occopycat(path,pathlen,3,prefix,"/",rcname)) {
-        stat = OC_EOVERRUN;
-	goto done;
-    }
-    /* see if file is readable */
-    f = NCfopen(path,"r");
-done:
-    if(f == NULL || stat != OC_NOERR) {
-      if(path != NULL)
-	    free(path);
-      path = NULL;
-    }
-
-    if(f != NULL)
-      fclose(f);
-    if(pathp != NULL)
-      *pathp = path;
-    else {
-      free(path);
-      path = NULL;
-    }
-
-    return OCTHROW(stat);
-}
-
-struct OCTriple*
-ocrc_triple_iterate(char* key, char* url, struct OCTriple* prev)
-{
-    struct OCTriple* next;
-    if(prev == NULL)
-      next = ocrc_locate(key,url);
-    else
-      next = prev+1;
-    if(next == NULL)
-      return NULL;
-    for(; strlen(next->key) > 0; next++) {
-      /* See if key as prefix still matches */
-      int cmp = strcmp(key,next->key);
-      if(cmp != 0) {next = NULL; break;} /* key mismatch */
-      /* compare url */
-      cmp = ocstrncmp(url,next->host,strlen(next->host));
-      if(cmp ==  0) break;
-    }
-    return next;
-}
diff --git a/oc2/ocread.c b/oc2/ocread.c
index 95d8e28..8148531 100644
--- a/oc2/ocread.c
+++ b/oc2/ocread.c
@@ -11,12 +11,13 @@
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
-#ifdef _WIN32
+#ifdef _MSC_VER
 #include <io.h>
 #ifndef O_BINARY
 #define O_BINARY _O_BINARY
 #endif
 #endif
+#include "ncrc.h"
 #include "ocinternal.h"
 #include "ocdebug.h"
 #include "ochttp.h"
@@ -92,9 +93,8 @@ readpacket(OCstate* state, NCURI* url,NCbytes* packet,OCdxd dxd,long* lastmodifi
 
    fileprotocol = (strcmp(url->protocol,"file")==0);
 
-   if(fileprotocol && !state->curlflags.proto_file) {
-        /* Short circuit file://... urls*/
-	/* We do this because the test code always needs to read files*/
+   if(fileprotocol) {
+        /* Short circuit file://... urls and read directly */
 	fetchurl = ncuribuild(url,NULL,NULL,NCURIBASE);
 	stat = readfile(fetchurl,suffix,packet);
     } else {
@@ -105,7 +105,7 @@ readpacket(OCstate* state, NCURI* url,NCbytes* packet,OCdxd dxd,long* lastmodifi
 	MEMCHECK(fetchurl,OC_ENOMEM);
 	if(ocdebug > 0)
             {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);}
-        stat = ocfetchurl(curl,fetchurl,packet,lastmodified,&state->creds);
+        stat = ocfetchurl(curl,fetchurl,packet,lastmodified);
 	if(stat)
 	    oc_curl_printerror(state);
 	if(ocdebug > 0)
@@ -143,7 +143,7 @@ fprintf(stderr,"readDATADDS:\n");
 
         fileprotocol = (strcmp(url->protocol,"file")==0);
 
-        if(fileprotocol && !state->curlflags.proto_file) {
+        if(fileprotocol) {
             readurl = ncuribuild(url,NULL,NULL,NCURIBASE);
             stat = readfiletofile(readurl, ".dods", tree->data.file, &tree->data.datasize);
         } else {
@@ -204,61 +204,12 @@ static int
 readfile(const char* path, const char* suffix, NCbytes* packet)
 {
     int stat = OC_NOERR;
-    char buf[1024];
     char filename[1024];
-    int fd = -1;
-    int flags = 0;
-    off_t filesize = 0;
-    off_t totalread = 0;
     /* check for leading file:/// */
     if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/
     if(!occopycat(filename,sizeof(filename),2,path,(suffix != NULL ? suffix : "")))
 	return OCTHROW(OC_EOVERRUN);
-    flags = O_RDONLY;
-#ifdef O_BINARY
-    flags |= O_BINARY;
-#endif
-    fd = NCopen2(filename,flags);
-    if(fd < 0) {
-	nclog(NCLOGERR,"open failed: %s file=|%s|",ocerrstring(errno),filename);
-	stat = OC_EOPEN;
-	goto done;
-    }
-    /* Get the file size */
-    filesize = lseek(fd,(off_t)0,SEEK_END);
-    if(filesize < 0) {
-	stat = OC_EIO;
-	nclog(NCLOGERR,"lseek failed: %s",filename);
-	goto done;
-    }
-    /* Move file pointer back to the beginning of the file */
-    (void)lseek(fd,(off_t)0,SEEK_SET);
-    stat = OC_NOERR;
-    for(totalread=0;;) {
-	off_t count = (off_t)read(fd,buf,sizeof(buf));
-	if(count == 0)
-	    break; /*eof*/
-	else if(count <  0) {
-	    stat = OC_EIO;
-	    nclog(NCLOGERR,"read failed: %s",filename);
-	    goto done;
-	}
-	ncbytesappendn(packet,buf,(unsigned long)count);
-	totalread += count;
-    }
-    if(totalread < filesize) {
-	stat = OC_EIO;
-	nclog(NCLOGERR,"short read: |%s|=%lu read=%lu\n",
-		filename,(unsigned long)filesize,(unsigned long)totalread);
-        goto done;
-    }
-
-done:
-#ifdef OCDEBUG
-fprintf(stderr,"readfile: filesize=%lu totalread=%lu\n",
-		(unsigned long)filesize,(unsigned long)totalread);
-#endif
-    if(fd >= 0) close(fd);
+    stat = NC_readfile(filename,packet);
     return OCTHROW(stat);
 }
 
diff --git a/oc2/ocutil.c b/oc2/ocutil.c
index bfa7143..158608f 100644
--- a/oc2/ocutil.c
+++ b/oc2/ocutil.c
@@ -13,7 +13,7 @@
 #include <fcntl.h>
 #endif
 
-#if defined(_WIN32) || defined(_WIN64)
+#ifdef _MSC_VER
 #include <io.h>
 #define mode_t int
 #endif
@@ -685,56 +685,6 @@ done:
     return status;    
 }
 
-
-/**
-Wrap mktmp and return the generated name
-*/
-
-int
-ocmktmp(const char* base, char** tmpnamep)
-{
-    int fd;
-    char tmpname[OCPATHMAX+1];
-
-    if(!occopycat(tmpname,sizeof(tmpname)-1,1,base)) {
-	return OC_EOVERRUN;
-    }
-#ifdef HAVE_MKSTEMP
-    if(!occoncat(tmpname,sizeof(tmpname)-1,1,"XXXXXX")) {
-	return OC_EOVERRUN;
-    }
-    /* Note Potential problem: old versions of this function
-       leave the file in mode 0666 instead of 0600 */
-    {
-	mode_t mask=umask(0077);
-	fd = mkstemp(tmpname);
-	(void)umask(mask);
-    }
-#else /* !HAVE_MKSTEMP */
-    /* Need to simulate by using some kind of pseudo-random number */
-    {
-	int rno = rand();
-	char spid[7];
-	if(rno < 0) rno = -rno;
-        snprintf(spid,sizeof(spid),"%06d",rno);
-	if(!occoncat(tmpname,sizeof(tmpname)-1,1,spid)) {
-	    return OC_EOVERRUN;
-        }
-#if defined(_WIN32) || defined(_WIN64)
-        fd=NCopen3(tmpname,O_RDWR|O_BINARY|O_CREAT, _S_IREAD|_S_IWRITE);
-#  else
-        fd=NCopen3(tmpname,O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
-#  endif
-    }
-#endif /* !HAVE_MKSTEMP */
-    if(fd < 0) {
-       return OC_EOPEN;
-    } else
-	close(fd);
-    if(tmpnamep) *tmpnamep = strdup(tmpname);
-    return OC_NOERR;
-}
-
 /* merge two envv style lists */
 char**
 ocmerge(const char** list1, const char** list2)
diff --git a/oc2/xxdr.c b/oc2/xxdr.c
index e333971..21439bb 100644
--- a/oc2/xxdr.c
+++ b/oc2/xxdr.c
@@ -57,7 +57,7 @@
 #include <sys/types.h>
 #endif
 
-#ifdef _WIN32
+#ifdef _MSC_VER
 #include <wchar.h>
 #include <sys/types.h>
 #endif
diff --git a/test-driver-verbose b/test-driver-verbose
index d7f96cd..2ea878f 100644
--- a/test-driver-verbose
+++ b/test-driver-verbose
@@ -1,9 +1,11 @@
 #! /bin/sh
 # test-driver - basic testsuite driver script.
 
-scriptversion=2017-04-02.20; # UTC
+DEBUGTEST="run_examples4.sh"
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+scriptversion=2018-01-15.21; # UTC
+
+# Copyright (C) 2011-2017 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
@@ -50,19 +52,6 @@ The '--test-name', '--log-file' and '--trs-file' options are mandatory.
 END
 }
 
-isshellscript()
-{
-    iss_cmd="$1"
-    iss_base=`basename ${iss_cmd}`
-    iss_sh=`basename ${iss_cmd} .sh`
-    if test "x${iss_base}" = "x${iss_sh}" ; then
-      return 1
-    else
-      return 0
-    fi
-}
-
-
 test_name= # Used for reporting.
 log_file=  # Where to save the output of the test script.
 trs_file=  # Where to save the metadata of the test run.
@@ -116,14 +105,15 @@ trap "st=130; $do_exit" 2
 trap "st=141; $do_exit" 13
 trap "st=143; $do_exit" 15
 
+set -x
+
 # Test script is run here.
-#if isshellscript $1 ; then
-#bash -x "$@" >$log_file 2>&1
-#estatus=$?
-#else
+
 "$@" >$log_file 2>&1
 estatus=$?
-#fi
+if test "x$test_name" = "x$DEBUGTEST" ; then
+cat $log_file
+fi
 
 if test $enable_hard_errors = no && test $estatus -eq 99; then
   tweaked_estatus=1
@@ -131,6 +121,8 @@ else
   tweaked_estatus=$estatus
 fi
 
+cat $log_file
+
 case $tweaked_estatus:$expect_failure in
   0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
   0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
@@ -148,7 +140,6 @@ echo "$res $test_name (exit status: $estatus)" >>$log_file
 
 # Report outcome to console.
 echo "${col}${res}${std}: $test_name"
-if test "x$res" != "x0" ; then cat $log_file ; fi
 
 # Register the test result, and other relevant metadata.
 echo ":test-result: $res" > $trs_file
@@ -162,6 +153,6 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/test_common.in b/test_common.in
index d559dd3..8e3c8a9 100644
--- a/test_common.in
+++ b/test_common.in
@@ -1,8 +1,8 @@
-set -e
-
 TOPSRCDIR=@abs_top_srcdir@
 TOPBUILDDIR=@abs_top_builddir@
 
+set -e
+
 # Figure out various locations in the src/build tree.
 # This is relatively fragile code and is essentially
 # specific to netcdf-c. It does, however, have the virtue
@@ -74,9 +74,8 @@ fi
 # We also assume we are executing in builddir
 builddir=`pwd`
 
-# execdir is an alias for builddir except
-# in the currently unsupported case of using Visual Studio
-execdir="${builddir}$VS"
+# execdir is an alias for builddir
+execdir="${builddir}"
 
 # pick off the last component as the relative name of this directory
 thisdir=`basename $srcdir`
@@ -92,19 +91,6 @@ cd $execdir; execdir=`pwd` ; cd $WD
 # If we have cygpath (which only exists under CYGWIN),
 # then try to normalize selected file paths.
 
-# So are we operating under CYGWIN? (test using uname)
-tcc=`uname | cut -d '_'  -f 1`
-if test "x$tcc_os" = xCYGWIN ; then ISCYGWIN=1; fi
-
-# Normalize selected paths
-#if test "x$ISCYGWIN" = x1; then
-#srcdir=`cygpath -mla $srcdir`
-#top_srcdir=`cygpath -mla $top_srcdir`
-#builddir=`cygpath -mla $builddir`
-#top_builddir=`cygpath -mla $top_builddir`
-#execdir=`cygpath -mla $execdir`
-#fi
-
 # For sun os
 export srcdir top_srcdir builddir top_builddir execdir
 

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