merged ejh_notbuilt_errors

This commit is contained in:
Ed Hartnett 2017-12-04 13:23:31 -07:00
commit ea49cc1d3f
4 changed files with 132 additions and 38 deletions

View File

@ -1652,6 +1652,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 Create a file, calling the appropriate dispatch create
* call.
@ -1696,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). */

View File

@ -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
NC_NETCDF4,
NC_CLASSIC_MODEL | NC_NETCDF4};
char *formatnames[NUMFORMATS]={"CDF-1",
"CDF-2",
#ifdef USE_NETCDF4
num_formats += 2;
#endif
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;
}

View File

@ -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;
}

View File

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