Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cause nc_create() to return NC_ENOTBUILT if user requests un-built feature like netCDF4 or CDF5 #658

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions libdispatch/dfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,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
Expand Down Expand Up @@ -1646,6 +1710,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,
Expand All @@ -1664,6 +1730,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). */
Expand Down
70 changes: 35 additions & 35 deletions nc_test/tst_global_fillval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <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 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<NUMFORMATS; i++) {
cmode = NC_CLOBBER | formats[i];
err = nc_create(FILE_NAME, cmode, &ncid); ERR

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;
for (int i = 0; i < num_formats; i++)
{
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;

}
}
printf("Total errors: %d\n",toterrs);
return toterrs;
SUMMARIZE_ERR;
FINAL_RESULTS;
}
22 changes: 22 additions & 0 deletions nc_test/tst_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
9 changes: 6 additions & 3 deletions nc_test4/tst_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand Down