diff --git a/CMakeLists.txt b/CMakeLists.txt index bd6bb608d..d4d051323 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1039,56 +1039,87 @@ IF(ENABLE_PNETCDF) ENDIF() # Options to enable use of fill values for elements causing NC_ERANGE -SET(STATUS_ERANGE_FILL "OFF") -OPTION(ENABLE_ERANGE_FILL "Enable use of fill value when out-of-range type conversion causes NC_ERANGE error." OF) -IF(ENABLE_ERANGE_FILL) - SET(STATUS_ERANGE_FILL "ON") - ADD_DEFINITIONS(-DERANGE_FILL) -ENDIF() +SET(ENABLE_ERANGE_FILL AUTO CACHE STRING "AUTO") +OPTION(ENABLE_ERANGE_FILL "Enable use of fill value when out-of-range type conversion causes NC_ERANGE error." OFF) +IF(ENABLE_ERANGE_FILL) # enable or auto + STRING(TOUPPER ${ENABLE_ERANGE_FILL} ENABLE_ERANGE_FILL) + IF(ENABLE_ERANGE_FILL AND NOT ENABLE_ERANGE_FILL STREQUAL "AUTO") + # explicitly enabled + SET(ENABLE_ERANGE_FILL ON) + ELSE() + IF(NOT ENABLE_ERANGE_FILL STREQUAL "AUTO") + SET(ENABLE_ERANGE_FILL OFF) + ENDIF() + ENDIF() +ENDIF(ENABLE_ERANGE_FILL) +# Now ENABLE_ERANGE_FILL is either AUTO, ON, or OFF # Options to use a more relaxed coordinate argument boundary check -SET(STATUS_RELAX_COORD_BOUND "OFF") +SET(ENABLE_ZERO_LENGTH_COORD_BOUND AUTO CACHE STRING "AUTO") OPTION(ENABLE_ZERO_LENGTH_COORD_BOUND "Enable a more relaxed boundary error check NC_EINVALCOORDS to allow coordinate start argument equal to dimension size when argument count is zero." OFF) -IF(ENABLE_ZERO_LENGTH_COORD_BOUND) - SET(STATUS_RELAX_COORD_BOUND "ON") -ENDIF() +IF(ENABLE_ZERO_LENGTH_COORD_BOUND) # enable or auto + STRING(TOUPPER ${ENABLE_ZERO_LENGTH_COORD_BOUND} ENABLE_ZERO_LENGTH_COORD_BOUND) + IF(ENABLE_ZERO_LENGTH_COORD_BOUND AND NOT ENABLE_ZERO_LENGTH_COORD_BOUND STREQUAL "AUTO") + # explicitly enabled + SET(ENABLE_ZERO_LENGTH_COORD_BOUND ON) + ELSE() + IF(NOT ENABLE_ZERO_LENGTH_COORD_BOUND STREQUAL "AUTO") + SET(ENABLE_ZERO_LENGTH_COORD_BOUND OFF) + ENDIF() + ENDIF() +ENDIF(ENABLE_ZERO_LENGTH_COORD_BOUND) +# Now ENABLE_ZERO_LENGTH_COORD_BOUND is either AUTO, ON, or OFF # check and conform with PnetCDF settings on ERANGE_FILL and RELAX_COORD_BOUND IF(STATUS_PNETCDF) file(STRINGS "${pnetcdf_h}" enable_erange_fill_pnetcdf REGEX "^#define PNETCDF_ERANGE_FILL") string(REGEX REPLACE "[^0-9]" "" erange_fill_pnetcdf "${enable_erange_fill_pnetcdf}") IF("x${erange_fill_pnetcdf}" STREQUAL "x1") - IF(NOT STATUS_ERANGE_FILL) - MESSAGE(WARNING "Enable erange-fill to conform with PnetCDF setting") - SET(STATUS_ERANGE_FILL "ON") - ENDIF() + SET(erange_fill_pnetcdf "ON") ELSE() - IF(STATUS_ERANGE_FILL) - MESSAGE(WARNING "Disable erange-fill to conform with PnetCDF setting") - SET(STATUS_ERANGE_FILL "OFF") + SET(erange_fill_pnetcdf "OFF") + ENDIF() + IF(ENABLE_ERANGE_FILL STREQUAL "AUTO") # not set on command line + SET(ENABLE_ERANGE_FILL "${erange_fill_pnetcdf}") + ELSE() + # user explicitly set this option on command line + IF(NOT ENABLE_ERANGE_FILL STREQUAL "${erange_fill_pnetcdf}") + IF(ENABLE_ERANGE_FILL) + MESSAGE(FATAL_ERROR "Enabling erange-fill conflicts with PnetCDF setting") + ELSE() + MESSAGE(FATAL_ERROR "Disabling erange-fill conflicts with PnetCDF setting") + ENDIF() ENDIF() ENDIF() + file(STRINGS "${pnetcdf_h}" relax_coord_bound_pnetcdf REGEX "^#define PNETCDF_RELAX_COORD_BOUND") string(REGEX REPLACE "[^0-9]" "" relax_coord_bound "${relax_coord_bound_pnetcdf}") IF("x${relax_coord_bound}" STREQUAL "x1") - IF(NOT STATUS_RELAX_COORD_BOUND) - MESSAGE(WARNING "Enable relax-coord-bound to conform with PnetCDF setting") - SET(STATUS_RELAX_COORD_BOUND "ON") - ENDIF() + SET(relax_coord_bound_pnetcdf "ON") ELSE() - IF(STATUS_RELAX_COORD_BOUND) - MESSAGE(WARNING "Disable relax-coord-bound to conform with PnetCDF setting") - SET(STATUS_RELAX_COORD_BOUND "OFF") + SET(relax_coord_bound_pnetcdf "OFF") + ENDIF() + IF(ENABLE_ZERO_LENGTH_COORD_BOUND STREQUAL "AUTO") # not set on command line + SET(ENABLE_ZERO_LENGTH_COORD_BOUND "${relax_coord_bound_pnetcdf}") + ELSE() + # user explicitly set this option on command line + IF(NOT ENABLE_ZERO_LENGTH_COORD_BOUND STREQUAL "${relax_coord_bound_pnetcdf}") + IF(ENABLE_ZERO_LENGTH_COORD_BOUND) + MESSAGE(FATAL_ERROR "Enabling relax-coord-bound conflicts with PnetCDF setting") + ELSE() + MESSAGE(FATAL_ERROR "Disabling relax-coord-bound conflicts with PnetCDF setting") + ENDIF() ENDIF() ENDIF() ENDIF() -IF(STATUS_ERANGE_FILL) +IF(ENABLE_ERANGE_FILL) + MESSAGE(STATUS "Enabling use of fill value when NC_ERANGE") SET(M4FLAGS "-DERANGE_FILL" CACHE STRING "") ENDIF() -IF(STATUS_RELAX_COORD_BOUND) - MESSAGE(STATUS "Enabling a more relatexed check for NC_EINVALCOORDS") +IF(ENABLE_ZERO_LENGTH_COORD_BOUND) + MESSAGE(STATUS "Enabling a more relaxed check for NC_EINVALCOORDS") ADD_DEFINITIONS(-DRELAX_COORD_BOUND) ENDIF() @@ -1894,7 +1925,7 @@ is_enabled(ENABLE_DAP4 HAS_DAP4) is_enabled(ENABLE_DISKLESS HAS_DISKLESS) is_enabled(USE_MMAP HAS_MMAP) is_enabled(JNA HAS_JNA) -is_enabled(STATUS_RELAX_COORD_BOUND RELAX_COORD_BOUND) +is_enabled(ENABLE_ZERO_LENGTH_COORD_BOUND RELAX_COORD_BOUND) is_enabled(USE_CDF5 HAS_CDF5) is_enabled(ENABLE_ERANGE_FILL HAS_ERANGE_FILL) diff --git a/configure.ac b/configure.ac index d8a1e68c7..e9f57a895 100644 --- a/configure.ac +++ b/configure.ac @@ -1108,21 +1108,13 @@ if test "x$enable_pnetcdf" = xyes; then # Pnetcdf did not support utf-8 until 1.6.0 - # Save/restore CFLAGS - SAVELIBS=$LIBS - LIBS="$LIBS -lpnetcdf" - AC_RUN_IFELSE([AC_LANG_PROGRAM([#include ], - [[ - int major = PNETCDF_VERSION_MAJOR; - int minor = PNETCDF_VERSION_MINOR; - int version = major*1000 + minor; - int ok = (version >= (1*1000 + 6)); - return (ok?0:1);]])], - [pnetcdf16=yes], - [pnetcdf16=no]) - CFLAGS="$SAVECFLAGS" - LIBS="$SAVELIBS" AC_MSG_CHECKING([Is libpnetcdf version 1.6.0 or later?]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#include +#if (PNETCDF_VERSION_MAJOR*1000 + PNETCDF_VERSION_MINOR < 1006) + choke me +#endif + ]])], [pnetcdf16=yes], [pnetcdf16=no]) AC_MSG_RESULT([$pnetcdf16]) if test x$pnetcdf16 = xno; then AC_MSG_ERROR([--enable-pnetcdf requires version 1.6.0 or later]) @@ -1162,15 +1154,15 @@ AC_ARG_ENABLE([erange_fill], [AS_HELP_STRING([--enable-erange-fill], [Enable use of fill value when out-of-range type conversion causes NC_ERANGE error. @<:@default: disabled@:>@])], - [enable_erange_fill=${enableval}], [enable_erange_fill=no] + [enable_erange_fill=${enableval}], [enable_erange_fill=auto] ) AC_ARG_ENABLE([zero-length-coord-bound], - [AS_HELP_STRING([--enable-zero-length-coord-bound], - [Enable a more relaxed boundary error check NC_EINVALCOORDS + [AS_HELP_STRING([--disable-zero-length-coord-bound], + [Disable a more relaxed boundary error check NC_EINVALCOORDS to allow coordinate start argument equal to dimension size - when argument count is zero. @<:@default: disabled@:>@])], - [enable_zero_length_coord_bound=${enableval}], [enable_zero_length_coord_bound=no] + when argument count is zero. @<:@default: enabled@:>@])], + [enable_zero_length_coord_bound=${enableval}], [enable_zero_length_coord_bound=auto] ) # check PnetCDF's settings on enable_erange_fill and relax_coord_bound @@ -1178,48 +1170,46 @@ if test "x$enable_pnetcdf" = xyes; then UD_CHECK_HEADER_PATH([pnetcdf.h]) AC_MSG_CHECKING([if erange-fill is enabled in PnetCDF]) - erange_fill_pnetcdf=`grep PNETCDF_ERANGE_FILL ${ac_cv_header_path_pnetcdf_h}` - if test "x$erange_fill_pnetcdf" = x; then - erange_fill_pnetcdf=no - else - erange_fill_pnetcdf=`echo ${erange_fill_pnetcdf} | cut -d' ' -f3` - if test "x$erange_fill_pnetcdf" = x0; then - enable_erange_fill_pnetcdf=no - else - enable_erange_fill_pnetcdf=yes - fi - fi + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#include +#if !defined(PNETCDF_ERANGE_FILL) || PNETCDF_ERANGE_FILL == 0 + choke me +#endif]])], [enable_erange_fill_pnetcdf=yes], [enable_erange_fill_pnetcdf=no]) 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]) - else - AC_MSG_WARN([Disable erange-fill to conform with PnetCDF setting]) - fi + if test "x$enable_erange_fill" = xauto ; then enable_erange_fill=$enable_erange_fill_pnetcdf + elif test "$enable_erange_fill" != "$enable_erange_fill_pnetcdf"; then + if test "$enable_erange_fill" = yes; then + AC_MSG_ERROR([Enabling erange-fill conflicts with PnetCDF setting]) + else + AC_MSG_ERROR([Disabling erange-fill conflicts with PnetCDF setting]) + fi fi AC_MSG_CHECKING([if relax-coord-bound is enabled in PnetCDF]) - relax_coord_bound_pnetcdf=`grep PNETCDF_RELAX_COORD_BOUND ${ac_cv_header_path_pnetcdf_h}` - if test "x$relax_coord_bound_pnetcdf" = x; then - elax_coord_bound_pnetcdf=no - else - coord_bound_pnetcdf=`echo ${relax_coord_bound_pnetcdf} | cut -d' ' -f3` - if test "x$coord_bound_pnetcdf" = x0; then - relax_coord_bound_pnetcdf=no - else - relax_coord_bound_pnetcdf=yes - fi - fi + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#include +#if !defined(PNETCDF_RELAX_COORD_BOUND) || PNETCDF_RELAX_COORD_BOUND == 0 + choke me +#endif]])], [relax_coord_bound_pnetcdf=yes], [relax_coord_bound_pnetcdf=no]) 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]) - else - AC_MSG_WARN([Disable relax-coord-bound to conform with PnetCDF setting]) - fi + if test "x$enable_zero_length_coord_bound" = xauto ; then enable_zero_length_coord_bound=$relax_coord_bound_pnetcdf + elif test "$enable_zero_length_coord_bound" != "$relax_coord_bound_pnetcdf"; then + if test "$enable_zero_length_coord_bound" = yes; then + AC_MSG_ERROR([Enabling relax-coord-bound conflicts with PnetCDF setting]) + else + AC_MSG_ERROR([Disabling relax-coord-bound conflicts with PnetCDF setting]) + fi fi +else + # default setting + enable_erange_fill=no + enable_zero_length_coord_bound=yes +fi + +if test "x$enable_zero_length_coord_bound" = xyes; then + AC_DEFINE([RELAX_COORD_BOUND], [1], [if true, NC_EINVALCOORDS check is more relaxed]) fi if test "x$enable_erange_fill" = xyes ; then @@ -1232,10 +1222,6 @@ if test "x$enable_erange_fill" = xyes ; then fi AC_SUBST(M4FLAGS) -if test "x$enable_zero_length_coord_bound" = xyes; then - AC_DEFINE([RELAX_COORD_BOUND], [1], [if true, NC_EINVALCOORDS check is more relaxed]) -fi - # Check for downloading/building fortran via postinstall script. if test "x$enable_remote_fortran_bootstrap" = xyes; then AC_DEFINE([BUILD_FORTRAN], 1, [If true, will attempt to download and build netcdf-fortran.]) diff --git a/include/netcdf.h b/include/netcdf.h index f98e2675f..c7af86e61 100644 --- a/include/netcdf.h +++ b/include/netcdf.h @@ -897,8 +897,8 @@ nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsig EXTERNL int nc_set_fill(int ncid, int fillmode, int *old_modep); -/* Set the default nc_create format to NC_FORMAT_CLASSIC, - * NC_FORMAT_64BIT, NC_FORMAT_NETCDF4, etc */ +/* Set the default nc_create format to NC_FORMAT_CLASSIC, NC_FORMAT_64BIT, + * NC_FORMAT_CDF5, NC_FORMAT_NETCDF4, or NC_FORMAT_NETCDF4_CLASSIC */ EXTERNL int nc_set_default_format(int format, int *old_formatp); diff --git a/libdispatch/dfile.c b/libdispatch/dfile.c index 245b0a760..25914d389 100644 --- a/libdispatch/dfile.c +++ b/libdispatch/dfile.c @@ -29,6 +29,7 @@ #include "ncdispatch.h" #include "netcdf_mem.h" #include "ncwinpath.h" +#include "fbits.h" /* If Defined, then use only stdio for all magic number io; otherwise use stdio or mpio as required. @@ -2027,7 +2028,6 @@ NC_create(const char *path0, int cmode, size_t initialsz, /* Need three pieces of information for now */ int model = NC_FORMATX_UNDEFINED; /* one of the NC_FORMATX values */ int isurl = 0; /* dap or cdmremote or neither */ - int xcmode = 0; /* for implied cmode flags */ char* path = NULL; TRACE(nc_create); @@ -2073,66 +2073,49 @@ NC_create(const char *path0, int cmode, size_t initialsz, } } - /* Look to the incoming cmode for hints */ - if(model == NC_FORMATX_UNDEFINED) { + /* determine the model */ #ifdef USE_NETCDF4 - if((cmode & NC_NETCDF4) == NC_NETCDF4) - model = NC_FORMATX_NC4; - else + if (model == NC_FORMATX_UNDEFINED && ((cmode & NC_NETCDF4) == NC_NETCDF4)) + model = NC_FORMATX_NC4; #endif #ifdef USE_PNETCDF - /* pnetcdf is used for parallel io on CDF-1, CDF-2, and CDF-5 */ - if((cmode & NC_MPIIO) == NC_MPIIO) - model = NC_FORMATX_PNETCDF; - else + if (model == NC_FORMATX_UNDEFINED && ((cmode & NC_MPIIO) == NC_MPIIO)) + /* pnetcdf is used for parallel io on CDF-1, CDF-2, and CDF-5 */ + model = NC_FORMATX_PNETCDF; #endif - {} - } - if(model == NC_FORMATX_UNDEFINED) { - /* Check default format (not formatx) */ - int format = nc_get_default_format(); - switch (format) { + + /* Check default format (not formatx) */ + if (!fIsSet(cmode, NC_64BIT_OFFSET) && !fIsSet(cmode, NC_64BIT_DATA) && + !fIsSet(cmode, NC_CLASSIC_MODEL) && !fIsSet(cmode, NC_NETCDF4)) { + /* if no file format flag is set in cmode, use default */ + int format = nc_get_default_format(); + switch (format) { #ifdef USE_NETCDF4 - case NC_FORMAT_NETCDF4: - xcmode |= NC_NETCDF4; - model = NC_FORMATX_NC4; - break; - case NC_FORMAT_NETCDF4_CLASSIC: - xcmode |= NC_CLASSIC_MODEL; - model = NC_FORMATX_NC4; - break; + case NC_FORMAT_NETCDF4: + cmode |= NC_NETCDF4; + if (model == NC_FORMATX_UNDEFINED) model = NC_FORMATX_NC4; + break; + case NC_FORMAT_NETCDF4_CLASSIC: + cmode |= NC_NETCDF4 | NC_CLASSIC_MODEL; + if (model == NC_FORMATX_UNDEFINED) model = NC_FORMATX_NC4; + break; #endif #ifdef ENABLE_CDF5 - case NC_FORMAT_CDF5: - xcmode |= NC_64BIT_DATA; - model = NC_FORMATX_NC3; - break; + case NC_FORMAT_CDF5: + cmode |= NC_64BIT_DATA; + break; #endif - case NC_FORMAT_64BIT_OFFSET: - xcmode |= NC_64BIT_OFFSET; - model = NC_FORMATX_NC3; - break; - case NC_FORMAT_CLASSIC: - model = NC_FORMATX_NC3; - break; - default: - model = NC_FORMATX_NC3; - break; - } - } + case NC_FORMAT_64BIT_OFFSET: + cmode |= NC_64BIT_OFFSET; + break; + case NC_FORMAT_CLASSIC: break; + default: break; + } + } - /* Add inferred flags */ - cmode |= xcmode; - - /* Clean up illegal combinations */ - if((cmode & (NC_64BIT_OFFSET|NC_64BIT_DATA)) == (NC_64BIT_OFFSET|NC_64BIT_DATA)) - cmode &= ~(NC_64BIT_OFFSET); /*NC_64BIT_DATA=>NC_64BIT_OFFSET*/ - - if((cmode & NC_MPIIO) && (cmode & NC_MPIPOSIX)) - { - nullfree(path); - return NC_EINVAL; - } + /* default model */ + if (model == NC_FORMATX_UNDEFINED) + model = NC_FORMATX_NC3; if (dispatcher == NULL) { diff --git a/libhdf5/hdf5create.c b/libhdf5/hdf5create.c index beaaa2094..cc5194f17 100644 --- a/libhdf5/hdf5create.c +++ b/libhdf5/hdf5create.c @@ -316,18 +316,6 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe, } #endif /* USE_PARALLEL_POSIX */ - cmode |= NC_NETCDF4; - - /* Apply default create format. */ - if (nc_get_default_format() == NC_FORMAT_CDF5) - cmode |= NC_CDF5; - else if (nc_get_default_format() == NC_FORMAT_64BIT_OFFSET) - cmode |= NC_64BIT_OFFSET; - else if (nc_get_default_format() == NC_FORMAT_NETCDF4_CLASSIC) - cmode |= NC_CLASSIC_MODEL; - - LOG((2, "cmode after applying default format: 0x%x", cmode)); - nc_file->int_ncid = nc_file->ext_ncid; res = nc4_create_file(path, cmode, initialsz, parameters, nc_file); diff --git a/libnetcdf.settings.in b/libnetcdf.settings.in index 0384faca9..aa37ee0f7 100644 --- a/libnetcdf.settings.in +++ b/libnetcdf.settings.in @@ -36,3 +36,4 @@ MMap Support: @HAS_MMAP@ JNA Support: @HAS_JNA@ CDF5 Support: @HAS_CDF5@ ERANGE fill Support: @HAS_ERANGE_FILL@ +relaxed boundary check: @RELAX_COORD_BOUND@ diff --git a/libsrc/nc3internal.c b/libsrc/nc3internal.c index d3e057bf2..79c6fbb1e 100644 --- a/libsrc/nc3internal.c +++ b/libsrc/nc3internal.c @@ -1072,12 +1072,6 @@ NC3_create(const char *path, int ioflags, assert(nc3->flags == 0); - /* Apply default create format. */ - if (nc_get_default_format() == NC_FORMAT_64BIT_OFFSET) - ioflags |= NC_64BIT_OFFSET; - else if (nc_get_default_format() == NC_FORMAT_CDF5) - ioflags |= NC_64BIT_DATA; - /* Now we can set min size */ if (fIsSet(ioflags, NC_64BIT_DATA)) nc3->xsz = MIN_NC5_XSZ; /* CDF-5 has minimum 16 extra bytes */ diff --git a/libsrcp/ncpdispatch.c b/libsrcp/ncpdispatch.c index 1005db6f4..7249ade97 100644 --- a/libsrcp/ncpdispatch.c +++ b/libsrcp/ncpdispatch.c @@ -52,25 +52,6 @@ NCP_create(const char *path, int cmode, if(cmode & ~LEGAL_CREATE_FLAGS) {res = NC_EINVAL; goto done;} - /* Cannot have both MPIO flags */ - if((cmode & (NC_MPIIO|NC_MPIPOSIX)) == (NC_MPIIO|NC_MPIPOSIX)) - {res = NC_EINVAL; goto done;} - - /* Cannot have both NC_64BIT_OFFSET & NC_64BIT_DATA */ - if((cmode & (NC_64BIT_OFFSET|NC_64BIT_DATA)) == (NC_64BIT_OFFSET|NC_64BIT_DATA)) - {res = NC_EINVAL; goto done;} - - default_format = nc_get_default_format(); - /* if (default_format == NC_FORMAT_CLASSIC) then we respect the format set in cmode */ - if (default_format == NC_FORMAT_64BIT_OFFSET) { - if (! (cmode & NC_64BIT_OFFSET)) /* check if cmode has NC_64BIT_OFFSET already */ - cmode |= NC_64BIT_OFFSET; - } - else if (default_format == NC_FORMAT_CDF5) { - if (! (cmode & NC_64BIT_DATA)) /* check if cmode has NC_64BIT_DATA already */ - cmode |= NC_64BIT_DATA; - } - /* No MPI environment initialized */ if (mpidata == NULL) {res = NC_ENOPAR; goto done;} diff --git a/nc_test/CMakeLists.txt b/nc_test/CMakeLists.txt index 284c8f63e..f44476689 100644 --- a/nc_test/CMakeLists.txt +++ b/nc_test/CMakeLists.txt @@ -30,7 +30,7 @@ TARGET_LINK_LIBRARIES(nc_test ) # Some extra stand-alone tests -SET(TESTS t_nc tst_small tst_misc tst_norm tst_names tst_nofill tst_nofill2 tst_nofill3 tst_meta tst_inq_type tst_utf8_validate tst_utf8_phrases tst_global_fillval tst_max_var_dims tst_formats tst_def_var_fill tst_err_enddef) +SET(TESTS t_nc tst_small tst_misc tst_norm tst_names tst_nofill tst_nofill2 tst_nofill3 tst_meta tst_inq_type tst_utf8_validate tst_utf8_phrases tst_global_fillval tst_max_var_dims tst_formats tst_def_var_fill tst_err_enddef tst_default_format) IF(NOT HAVE_BASH) SET(TESTS ${TESTS} tst_atts3) @@ -42,6 +42,7 @@ IF(USE_PNETCDF) build_bin_test_no_prefix(tst_addvar) add_sh_test(nc_test run_pnetcdf_test) add_bin_test(nc_test tst_formatx_pnetcdf) + add_bin_test(nc_test tst_default_format_pnetcdf) ENDIF() IF(LARGE_FILE_TESTS) diff --git a/nc_test/Makefile.am b/nc_test/Makefile.am index 010bb49d5..e185faae7 100644 --- a/nc_test/Makefile.am +++ b/nc_test/Makefile.am @@ -19,10 +19,12 @@ TEST_EXTENSIONS = .sh 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 tst_def_var_fill tst_err_enddef +tst_max_var_dims tst_formats tst_def_var_fill tst_err_enddef \ +tst_default_format if USE_PNETCDF -TESTPROGRAMS += tst_parallel2 tst_pnetcdf tst_addvar tst_formatx_pnetcdf +TESTPROGRAMS += tst_parallel2 tst_pnetcdf tst_addvar tst_formatx_pnetcdf \ +tst_default_format_pnetcdf endif if TEST_PARALLEL4 diff --git a/nc_test/tst_default_format.c b/nc_test/tst_default_format.c new file mode 100644 index 000000000..a7af98e98 --- /dev/null +++ b/nc_test/tst_default_format.c @@ -0,0 +1,220 @@ +#include "config.h" +#include +#include +#include + +#define ERR { \ + if (err != NC_NOERR) { \ + printf("Error at %s line %d: %s\n", __FILE__, __LINE__, \ + nc_strerror(err)); \ + nerrs++; \ + } \ +} + +static int default_format; + +static int +create_check(char *fname, int cmode, int exp_format) +{ + int nerrs=0, err, ncid, format; + char *exp_str; + + switch (exp_format) { + case NC_FORMAT_CLASSIC: exp_str="NC_FORMAT_CLASSIC"; break; + case NC_FORMAT_64BIT_OFFSET: exp_str="NC_FORMAT_64BIT_OFFSET"; break; + case NC_FORMAT_64BIT_DATA: exp_str="NC_FORMAT_64BIT_DATA"; break; + case NC_FORMAT_NETCDF4: exp_str="NC_FORMAT_NETCDF4"; break; + case NC_FORMAT_NETCDF4_CLASSIC: + exp_str="NC_FORMAT_NETCDF4_CLASSIC";break; + default: break; + } + + /* create a file */ + cmode |= NC_CLOBBER; + err = nc_create(fname, cmode, &ncid); ERR + err = nc_close(ncid); ERR + + /* open the file and check its format */ + err = nc_open(fname, NC_NOWRITE, &ncid); ERR + err = nc_inq_format(ncid, &format); ERR + if (format != exp_format) { + char *f_str, *d_str; + switch (format) { + case NC_FORMAT_CLASSIC: f_str = "NC_FORMAT_CLASSIC"; + break; + case NC_FORMAT_64BIT_OFFSET: f_str = "NC_FORMAT_64BIT_OFFSET"; + break; + case NC_FORMAT_64BIT_DATA: f_str = "NC_FORMAT_64BIT_DATA"; + break; + case NC_FORMAT_NETCDF4: f_str = "NC_FORMAT_NETCDF4"; + break; + case NC_FORMAT_NETCDF4_CLASSIC: f_str = "NC_FORMAT_NETCDF4_CLASSIC"; + break; + default: break; + } + switch (default_format) { + case NC_FORMAT_CLASSIC: d_str = "NC_FORMAT_CLASSIC"; + break; + case NC_FORMAT_64BIT_OFFSET: d_str = "NC_FORMAT_64BIT_OFFSET"; + break; + case NC_FORMAT_64BIT_DATA: d_str = "NC_FORMAT_64BIT_DATA"; + break; + case NC_FORMAT_NETCDF4: d_str = "NC_FORMAT_NETCDF4"; + break; + case NC_FORMAT_NETCDF4_CLASSIC: d_str = "NC_FORMAT_NETCDF4_CLASSIC"; + break; + default: break; + } + + printf("Error at %s line %d: default is %s and expect %s but got %s\n", + __FILE__, __LINE__, d_str, exp_str, f_str); + nerrs++; + } + err = nc_close(ncid); ERR + return nerrs; +} + +int main(int argc, char *argv[]) +{ + char *fname="tst_default_format.nc"; + int err, nerrs=0, ncid, cmode, format; + + if (argc == 2) fname = argv[1]; + + default_format = NC_FORMAT_CLASSIC; + + /* check illegal cmode */ + cmode = NC_64BIT_OFFSET | NC_64BIT_DATA; + err = nc_create(fname, cmode, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* check illegal cmode */ + cmode = NC_NETCDF4 | NC_64BIT_OFFSET; + err = nc_create(fname, cmode, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* check illegal cmode */ + cmode = NC_MPIIO | NC_MPIPOSIX; + err = nc_create(fname, cmode, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* check illegal cmode */ + cmode = NC_MPIIO | NC_DISKLESS; + err = nc_create(fname, cmode, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* check illegal cmode */ + cmode = NC_MPIPOSIX | NC_DISKLESS; + err = nc_create(fname, cmode, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* create a file in CDF1 format */ + cmode = 0; + nerrs += create_check(fname, cmode, NC_FORMAT_CLASSIC); + + /* create a file in CDF2 format */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_OFFSET); + +#ifdef ENABLE_CDF5 + /* create a file in CDF5 format */ + cmode = NC_64BIT_DATA; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_DATA); +#endif + + /* set default file format to NC_FORMAT_64BIT_OFFSET ------------------*/ + default_format = NC_FORMAT_64BIT_OFFSET; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_OFFSET); + +#ifdef ENABLE_CDF5 + /* create a file in CDF5 format (this should ignore default) */ + cmode = NC_64BIT_DATA; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_DATA); +#endif + +#ifdef ENABLE_CDF5 + /* set default file format to NC_FORMAT_64BIT_DATA --------------------*/ + default_format = NC_FORMAT_64BIT_DATA; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_DATA); + + /* create a file in CDF2 format (this should ignore default) */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_OFFSET); +#endif + +#ifdef USE_NETCDF4 + /* set default file format to NC_FORMAT_NETCDF4 -----------------------*/ + default_format = NC_FORMAT_NETCDF4; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check(fname, cmode, NC_FORMAT_NETCDF4); + + /* create a file in CDF2 format (this should ignore default) */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_OFFSET); + + /* set default file format to NC_FORMAT_NETCDF4_CLASSIC ---------------*/ + default_format = NC_FORMAT_NETCDF4_CLASSIC; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check(fname, cmode, NC_FORMAT_NETCDF4_CLASSIC); + + /* create a file in NETCDF4 format (this should ignore default) */ + cmode = NC_NETCDF4; + nerrs += create_check(fname, cmode, NC_FORMAT_NETCDF4); + + /* create a file in CDF2 format (this should ignore default) */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_OFFSET); + + /* set default file format to NC_FORMAT_NETCDF4 -----------------------*/ + default_format = NC_FORMAT_NETCDF4; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check(fname, cmode, NC_FORMAT_NETCDF4); + + /* create a file in NETCDF4 format (this should ignore default) */ + cmode = NC_NETCDF4 | NC_CLASSIC_MODEL; + nerrs += create_check(fname, cmode, NC_FORMAT_NETCDF4_CLASSIC); + + /* create a file in CDF2 format (this should ignore default) */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check(fname, cmode, NC_FORMAT_64BIT_OFFSET); +#endif + + return (nerrs > 0); +} diff --git a/nc_test/tst_default_format_pnetcdf.c b/nc_test/tst_default_format_pnetcdf.c new file mode 100644 index 000000000..fb9f9cabe --- /dev/null +++ b/nc_test/tst_default_format_pnetcdf.c @@ -0,0 +1,180 @@ +#include "config.h" +#include +#include +#include +#include + +#define ERR { \ + if (err != NC_NOERR) { \ + printf("Error at %s line %d: %s\n", __FILE__, __LINE__, \ + nc_strerror(err)); \ + nerrs++; \ + } \ +} + +static int default_format; + +static int +create_check_pnetcdf(char *fname, int cmode, int exp_format) +{ + int nerrs=0, err, ncid, format; + char *exp_str; + + cmode |= NC_MPIIO; + + switch (exp_format) { + case NC_FORMAT_CLASSIC: exp_str="NC_FORMAT_CLASSIC"; break; + case NC_FORMAT_64BIT_OFFSET: exp_str="NC_FORMAT_64BIT_OFFSET"; break; + case NC_FORMAT_64BIT_DATA: exp_str="NC_FORMAT_64BIT_DATA"; break; + case NC_FORMAT_NETCDF4: exp_str="NC_FORMAT_NETCDF4"; break; + case NC_FORMAT_NETCDF4_CLASSIC: + exp_str="NC_FORMAT_NETCDF4_CLASSIC";break; + default: break; + } + + /* create a file */ + cmode |= NC_CLOBBER; + err = nc_create_par(fname, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); ERR + err = nc_close(ncid); ERR + + /* open the file and check its format */ + err = nc_open(fname, NC_NOWRITE, &ncid); ERR + err = nc_inq_format(ncid, &format); ERR + if (format != exp_format) { + char *f_str, *d_str; + switch (format) { + case NC_FORMAT_CLASSIC: f_str = "NC_FORMAT_CLASSIC"; + break; + case NC_FORMAT_64BIT_OFFSET: f_str = "NC_FORMAT_64BIT_OFFSET"; + break; + case NC_FORMAT_64BIT_DATA: f_str = "NC_FORMAT_64BIT_DATA"; + break; + case NC_FORMAT_NETCDF4: f_str = "NC_FORMAT_NETCDF4"; + break; + case NC_FORMAT_NETCDF4_CLASSIC: f_str = "NC_FORMAT_NETCDF4_CLASSIC"; + break; + default: break; + } + switch (default_format) { + case NC_FORMAT_CLASSIC: d_str = "NC_FORMAT_CLASSIC"; + break; + case NC_FORMAT_64BIT_OFFSET: d_str = "NC_FORMAT_64BIT_OFFSET"; + break; + case NC_FORMAT_64BIT_DATA: d_str = "NC_FORMAT_64BIT_DATA"; + break; + case NC_FORMAT_NETCDF4: d_str = "NC_FORMAT_NETCDF4"; + break; + case NC_FORMAT_NETCDF4_CLASSIC: d_str = "NC_FORMAT_NETCDF4_CLASSIC"; + break; + default: break; + } + + printf("Error at %s line %d: default is %s and expect %s but got %s\n", + __FILE__, __LINE__, d_str, exp_str, f_str); + nerrs++; + } + err = nc_close(ncid); ERR + return nerrs; +} + +int main(int argc, char *argv[]) +{ + char *fname="tst_default_format.nc"; + int err, nerrs=0, ncid, cmode, format; + + MPI_Init(&argc, &argv); + + if (argc == 2) fname = argv[1]; + + default_format = NC_FORMAT_CLASSIC; + +#ifdef ENABLE_CDF5 + /* check illegal cmode */ + cmode = NC_64BIT_OFFSET | NC_64BIT_DATA; + err = nc_create_par(fname, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } +#endif +#ifdef USE_NETCDF4 + /* check illegal cmode */ + cmode = NC_NETCDF4 | NC_64BIT_OFFSET; + err = nc_create_par(fname, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } +#endif + /* check illegal cmode */ + cmode = NC_MPIIO | NC_MPIPOSIX; + err = nc_create_par(fname, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* check illegal cmode */ + cmode = NC_MPIIO | NC_DISKLESS; + err = nc_create_par(fname, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* check illegal cmode */ + cmode = NC_MPIPOSIX | NC_DISKLESS; + err = nc_create_par(fname, cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid); + if (err != NC_EINVAL) { + printf("Error at %s line %d: expect NC_EINVAL but got %d\n", + __FILE__, __LINE__, err); + nerrs++; + } + + /* create a file in CDF1 format */ + cmode = 0; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_CLASSIC); + + /* create a file in CDF2 format */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_64BIT_OFFSET); + +#ifdef ENABLE_CDF5 + /* create a file in CDF5 format */ + cmode = NC_64BIT_DATA; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_64BIT_DATA); +#endif + + /* set default file format to NC_FORMAT_64BIT_OFFSET ------------------*/ + default_format = NC_FORMAT_64BIT_OFFSET; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_64BIT_OFFSET); + +#ifdef ENABLE_CDF5 + /* create a file in CDF5 format (this should ignore default) */ + cmode = NC_64BIT_DATA; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_64BIT_DATA); + + /* set default file format to NC_FORMAT_64BIT_DATA --------------------*/ + default_format = NC_FORMAT_64BIT_DATA; + err = nc_set_default_format(default_format, NULL); ERR + + /* create a file in default format */ + cmode = 0; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_64BIT_DATA); +#endif + + /* create a file in CDF2 format (this should ignore default) */ + cmode = NC_64BIT_OFFSET; + nerrs += create_check_pnetcdf(fname, cmode, NC_FORMAT_64BIT_OFFSET); + + MPI_Finalize(); + return (nerrs > 0); +} diff --git a/nc_test/tst_names.c b/nc_test/tst_names.c index 5f63c43e4..878ae32d9 100644 --- a/nc_test/tst_names.c +++ b/nc_test/tst_names.c @@ -241,20 +241,12 @@ main(int argc, char **argv) "classic", "64-bit offset", "64-bit data", "netCDF-4/HDF5", "netCDF-4 classic model" }; -#ifdef TEST_PNETCDF - MPI_Init(&argc, &argv); -#endif - printf("\n*** testing names with file %s...\n", testfile); for (j = 0; j < num_formats; j++) { printf("*** switching to netCDF %s format...", format_names[j]); nc_set_default_format(formats[j], NULL); -#ifdef TEST_PNETCDF - if((res = nc_create_par(testfile, NC_CLOBBER|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid))) -#else if((res = nc_create(testfile, NC_CLOBBER, &ncid))) -#endif ERROR /* Define dimensions, variables, and attributes with various @@ -302,11 +294,7 @@ main(int argc, char **argv) ERROR /* Check it out, make sure all objects with good names were defined OK */ -#ifdef TEST_PNETCDF - if ((res = nc_open_par(testfile, NC_NOWRITE|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, &ncid))) -#else if ((res = nc_open(testfile, NC_NOWRITE, &ncid))) -#endif ERROR for (i = 0; i < NUM_GOOD; i++) { size_t attlen; @@ -336,8 +324,5 @@ main(int argc, char **argv) total_err += nerrs; FINAL_RESULTS; -#ifdef TEST_PNETCDF - MPI_Finalize(); -#endif return 0; } diff --git a/nc_test/util.c b/nc_test/util.c index daee5ccd5..e26c88d64 100644 --- a/nc_test/util.c +++ b/nc_test/util.c @@ -1401,6 +1401,13 @@ char* nc_err_code_name(int err) int test_nc_against_pnetcdf(void) { + int format; + + nc_set_default_format(NC_FORMAT_CLASSIC, &format); + nc_set_default_format(format, NULL); /* restore default */ + if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC) + return 1; /* skip test for netcdf4 formats */ + #ifdef USE_PNETCDF int ncid; /* netCDF id */ int err; /* status */ diff --git a/ncdump/nccopy.c b/ncdump/nccopy.c index ec9e0d9d3..bae9930a9 100644 --- a/ncdump/nccopy.c +++ b/ncdump/nccopy.c @@ -1984,8 +1984,8 @@ usage(void) /* Don't document this flaky option until it works better */ /* [-x] use experimental computed estimates for variable-specific chunk caches\n\ */ - error("%s [-k kind] [-[3|4|6|7]] [-d n] [-s] [-c chunkspec] [-u] [-w] [-[v|V] varlist] [-[g|G] grplist] [-m n] [-h n] [-e n] [-r] infile outfile\n%s\nnetCDF library version %s", - progname, USAGE, nc_inq_libvers()); + error("[-k kind] [-[3|4|6|7]] [-d n] [-s] [-c chunkspec] [-u] [-w] [-[v|V] varlist] [-[g|G] grplist] [-m n] [-h n] [-e n] [-r] infile outfile\n%s\nnetCDF library version %s", + USAGE, nc_inq_libvers()); } int