From 03753c0344dec920751671ac1e15ed7feaedba94 Mon Sep 17 00:00:00 2001 From: Ed Hartnett Date: Mon, 13 Nov 2017 08:09:15 -0700 Subject: [PATCH] now return NC_ENOTBUILT for not built library features --- libdispatch/dfile.c | 71 ++++++++++++++++++++++++++++++++++++ nc_test/tst_global_fillval.c | 70 +++++++++++++++++------------------ nc_test/tst_misc.c | 22 +++++++++++ nc_test4/tst_files.c | 9 +++-- 4 files changed, 134 insertions(+), 38 deletions(-) diff --git a/libdispatch/dfile.c b/libdispatch/dfile.c index 27112f9d49..0f95a19faf 100644 --- a/libdispatch/dfile.c +++ b/libdispatch/dfile.c @@ -1610,6 +1610,70 @@ nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size) return ncp->dispatch->inq_type(ncid,xtype,name,size); } +/** +Check the create mode parameter for sanity. + +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 cmode The creation mode flag. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTBUILT Requested feature not built into library +\returns ::NC_NINVAL 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; + +#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 */ + + /* Well I guess there is some sanity in the world after all. */ + return NC_NOERR; +} + /** \internal \ingroup dispatch @@ -1642,6 +1706,8 @@ file. stored. \returns ::NC_NOERR No error. +\returns ::NC_EINVAL invalid parameters +\returns ::NC_ENOTBUILT requesting library feature that was not built. */ int NC_create(const char *path0, int cmode, size_t initialsz, @@ -1660,6 +1726,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). */ diff --git a/nc_test/tst_global_fillval.c b/nc_test/tst_global_fillval.c index b2bd99770b..e4dcaabf94 100644 --- a/nc_test/tst_global_fillval.c +++ b/nc_test/tst_global_fillval.c @@ -9,55 +9,55 @@ * https://github.com/Unidata/netcdf-c/issues/388 * https://github.com/Unidata/netcdf-c/pull/389 -*/ + + Modified by Ed Hartnett, see: + https://github.com/Unidata/netcdf-c/issues/392 + */ #include "config.h" #include -#include -#include - -#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 num_formats = 2; + int n = 0; + + /* Determine how many formats are in use. */ #ifdef USE_CDF5 - NC_64BIT_DATA, + num_formats++; +#endif +#ifdef USE_NETCDF4 + num_formats += 2; #endif - NC_NETCDF4, - NC_CLASSIC_MODEL | NC_NETCDF4}; - char *formatnames[NUMFORMATS]={"CDF-1", - "CDF-2", + + int formats[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 -#include "netcdf.h" #include #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;