sync m4 files with PnetCDF

This commit is contained in:
Wei-keng Liao 2016-10-25 15:11:16 -05:00
parent 39ea0963e1
commit f19e4ce81e
4 changed files with 330 additions and 167 deletions

View File

@ -10,7 +10,7 @@ dnl
* Copyright (C) 2003, Northwestern University and Argonne National Laboratory
* See COPYRIGHT notice in top-level directory.
*/
/* $Id: test_get.m4 2542 2016-10-12 21:14:00Z wkliao $ */
/* $Id: test_get.m4 2559 2016-10-16 20:47:09Z wkliao $ */
dnl
dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF
@ -111,6 +111,18 @@ TestFunc(var1)_$1(VarArgs)
index[j] = 0;
}
ifdef(`PNETCDF',`dnl
err = GetVar1($1)(ncid, i, NULL, &value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
/* check if the contents are supposed to be */
for (j = 0; j < var_nels[i]; j++) {
err = toMixedBase(j, var_rank[i], var_shape[i], index);
@ -342,6 +354,29 @@ TestFunc(vara)_$1(VarArgs)
start[j] = 0;
edge[j] = 1;
}
ifdef(`PNETCDF',`dnl
err = GetVara($1)(ncid, i, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
err = GetVara($1)(ncid, i, start, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLCOUNT)
error("expecting NC_ENULLCOUNT, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_rank[i]; j++) {
start[j] = var_shape[i][j]; /* causes NC_EINVALCOORDS */
err = GetVara($1)(ncid, i, start, edge, value);
@ -530,6 +565,29 @@ TestFunc(vars)_$1(VarArgs)
edge[j] = 1;
stride[j] = 1;
}
ifdef(`PNETCDF',`dnl
err = GetVars($1)(ncid, i, NULL, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
err = GetVars($1)(ncid, i, start, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLCOUNT)
error("expecting NC_ENULLCOUNT, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_rank[i]; j++) {
start[j] = var_shape[i][j];
err = GetVars($1)(ncid, i, start, edge, stride, value);
@ -727,6 +785,29 @@ TestFunc(varm)_$1(VarArgs)
stride[j] = 1;
imap[j] = 1;
}
ifdef(`PNETCDF',`dnl
err = GetVarm($1)(ncid, i, NULL, NULL, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
err = GetVarm($1)(ncid, i, start, NULL, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLCOUNT)
error("expecting NC_ENULLCOUNT, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_rank[i]; j++) {
start[j] = var_shape[i][j];
err = GetVarm($1)(ncid, i, start, edge, stride, imap, value);

View File

@ -10,7 +10,7 @@ dnl
* Copyright (C) 2003, Northwestern University and Argonne National Laboratory
* See COPYRIGHT notice in top-level directory.
*/
/* $Id: test_put.m4 2542 2016-10-12 21:14:00Z wkliao $ */
/* $Id: test_put.m4 2573 2016-10-23 16:37:07Z wkliao $ */
dnl
dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF
@ -136,7 +136,7 @@ check_vars_$1(const char *filename, int numVars)
double expect;
$1 value;
err = FileOpen(testfile, NC_NOWRITE);
err = FileOpen(filename, NC_NOWRITE);
IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err));
err = APIFunc(inq_format)(ncid, &cdf_format);
@ -384,6 +384,19 @@ TestFunc(var1)_$1(VarArgs)
}
}
}
ifdef(`PNETCDF',`dnl
err = PutVar1($1)(ncid, i, NULL, &value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_nels[i]; j++) {
err = toMixedBase(j, var_rank[i], var_shape[i], index);
IF (err != NC_NOERR)
@ -654,10 +667,36 @@ TestFunc(vara)_$1(VarArgs)
edge[j] = 1;
}
ifdef(`PNETCDF',`dnl
err = PutVara($1)(ncid, i, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
for (j=0; j<var_rank[i]; j++) start[j] = 0;
err = PutVara($1)(ncid, i, start, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLCOUNT)
error("expecting NC_ENULLCOUNT, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_rank[i]; j++) {
if (var_dimid[i][j] > 0) { /* skip record dim */
start[j] = var_shape[i][j]; /* out of boundary check */
err = PutVara($1)(ncid, i, start, edge, value);
IF (!canConvert && err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
IF (canConvert && err != NC_EINVALCOORDS)
error("expecting NC_EINVALCOORDS, but got %s", nc_err_code_name(err));
ELSE_NOK
@ -840,6 +879,29 @@ TestFunc(vars)_$1(VarArgs)
stride[j] = 1;
}
ifdef(`PNETCDF',`dnl
err = PutVars($1)(ncid, i, NULL, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
for (j=0; j<var_rank[i]; j++) start[j] = 0;
err = PutVars($1)(ncid, i, start, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLCOUNT)
error("expecting NC_ENULLCOUNT, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_rank[i]; j++) {
if (var_dimid[i][j] > 0) { /* skip record dim */
start[j] = var_shape[i][j]; /* out of boundary check */
@ -1028,6 +1090,29 @@ TestFunc(varm)_$1(VarArgs)
imap[j] = 1;
}
ifdef(`PNETCDF',`dnl
err = PutVarm($1)(ncid, i, NULL, NULL, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLSTART)
error("expecting NC_ENULLSTART, but got %s", nc_err_code_name(err));
ELSE_NOK
for (j=0; j<var_rank[i]; j++) start[j] = 0;
err = PutVarm($1)(ncid, i, start, NULL, NULL, NULL, value);
if (!canConvert) {
IF (err != NC_ECHAR)
error("expecting NC_ECHAR, but got %s", nc_err_code_name(err));
ELSE_NOK
}
else IF (var_rank[i] > 0 && err != NC_ENULLCOUNT)
error("expecting NC_ENULLCOUNT, but got %s", nc_err_code_name(err));
ELSE_NOK
')dnl
for (j = 0; j < var_rank[i]; j++) {
if (var_dimid[i][j] > 0) { /* skip record dim */
start[j] = var_shape[i][j]; /* out of boundary check */

View File

@ -10,7 +10,7 @@ dnl
* Copyright (C) 2003, Northwestern University and Argonne National Laboratory
* See COPYRIGHT notice in top-level directory.
*/
/* $Id: test_write.m4 2550 2016-10-13 18:24:04Z wkliao $ */
/* $Id: test_write.m4 2563 2016-10-18 02:43:48Z wkliao $ */
dnl
dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF
@ -467,8 +467,11 @@ TestFunc(abort)(AttVarArgs)
IF (err != NC_EBADID)
error("expecting NC_EBADID but got %s", nc_err_code_name(err));
err = FileDelete(scratch, info); /* should already be deleted */
IF (!err) /* err is expected to be NC_ENOENT */
error("file %s should not exist", scratch);
ifdef(`PNETCDF',
`IF (err != NC_ENOENT && err != NC_EFILE)
error("expecting NC_ENOENT or NC_EFILE but got %s", nc_err_code_name(err));',
`IF (err != ENOENT && err != NC_EIO)
error("expecting ENOENT or NC_EIO but got %s", nc_err_code_name(err));')dnl
/*
* create scratch file
@ -2275,8 +2278,10 @@ TestFunc(set_default_format)(void)
}
/* Remove the left-over file. */
if ((err = FileDelete(scratch, info)))
err = FileDelete(scratch, info);
IF (err != NC_NOERR)
error("remove of %s failed", scratch);
return nok;
}

View File

@ -4,8 +4,9 @@
* $Id: util.c 2792 2014-10-27 06:02:59Z wkliao $
*********************************************************************/
#include <math.h> /* floor() */
#include "tests.h"
#include <math.h>
void
print_nok(int nok)
{
@ -19,8 +20,6 @@ print_nok(int nok)
int
inRange(const double value, const nc_type xtype)
{
double min, max;
switch (xtype) {
case NC_CHAR: return value >= X_CHAR_MIN && value <= X_CHAR_MAX;
case NC_BYTE: return value >= X_BYTE_MIN && value <= X_BYTE_MAX;
@ -34,8 +33,8 @@ inRange(const double value, const nc_type xtype)
case NC_INT64: return value >= X_INT64_MIN && value <= X_INT64_MAX;
case NC_UINT64: return value >= 0 && value <= X_UINT64_MAX;
default: assert(0);
return(0);
}
return value >= min && value <= max;
}
static int
@ -57,32 +56,16 @@ inRange_uchar(const int cdf_format,
return inRange(value, xtype);
}
static int
inRange_schar(const double value, const nc_type xtype)
{
/* check value of type xtype if within schar range */
if (xtype == NC_UBYTE) {
/* netCDF specification make a special case for type conversion between
* uchar and schar: do not check for range error. See
* http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
*/
return(value >= X_CHAR_MIN && value <= X_CHAR_MAX);
}
/* else */
return inRange(value, xtype);
}
static int
inRange_float(const double value, const nc_type xtype)
{
double min, max;
switch (xtype) {
case NC_CHAR: min = X_CHAR_MIN; max = X_CHAR_MAX; break;
case NC_BYTE: min = X_BYTE_MIN; max = X_BYTE_MAX; break;
case NC_CHAR: min = X_CHAR_MIN; max = X_CHAR_MAX; break;
case NC_BYTE: min = X_BYTE_MIN; max = X_BYTE_MAX; break;
case NC_SHORT: min = X_SHORT_MIN; max = X_SHORT_MAX; break;
case NC_INT: min = X_INT_MIN; max = X_INT_MAX; break;
case NC_INT: min = X_INT_MIN; max = X_INT_MAX; break;
case NC_FLOAT:
if(FLT_MAX < X_FLOAT_MAX) {
min = (-FLT_MAX);
@ -122,7 +105,7 @@ inRange_float(const double value, const nc_type xtype)
#if FLT_MANT_DIG != DBL_MANT_DIG
/* else */
{
const float fvalue = value;
const float fvalue = (float)value;
return fvalue >= min && fvalue <= max;
}
#else
@ -131,25 +114,35 @@ inRange_float(const double value, const nc_type xtype)
}
/* wrapper for inRange to handle special NC_BYTE/uchar adjustment */
/* this function checks whether "value" to be casted to type "itype" is
* within the range of external "xtype".
*/
int
inRange3(
const int cdf_format,
const double value,
const nc_type xtype,
const nct_itype itype)
inRange3(const int cdf_format,
const double value,
const nc_type xtype,
const nct_itype itype)
{
/* netCDF specification make a special case for type conversion between
* uchar and NC_BYTE: do not check for range error. See
* http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
* The _uchar and _schar functions were introduced in netCDF-3 to eliminate
* an ambiguity, and support both signed and unsigned byte data. In
* netCDF-2, whether the external NC_BYTE type represented signed or
* unsigned values was left up to the user. In netcdf-3, we treat NC_BYTE
* as signed for the purposes of conversion to short, int, long, float, or
* double. (Of course, no conversion takes place when the internal type is
* signed char.) In the _uchar functions, we treat NC_BYTE as if it were
* unsigned. Thus, no NC_ERANGE error can occur converting between NC_BYTE
* and unsigned char.
*/
switch (itype) {
/*
case NCT_SCHAR:
case NCT_CHAR:
return inRange_schar(value, xtype);
*/
case NCT_UCHAR:
return inRange_uchar(cdf_format, value, xtype);
case NCT_FLOAT:
return inRange_float(value, xtype);
default:
break;
case NCT_UCHAR:
return inRange_uchar(cdf_format, value, xtype);
case NCT_FLOAT:
return inRange_float(value, xtype);
default:
break;
}
return inRange(value, xtype);
}
@ -160,11 +153,10 @@ inRange3(
* Use tolerant comparison based on IEEE FLT_EPSILON or DBL_EPSILON.
*/
int
equal(
const double x,
const double y,
nc_type xtype, /* external data type */
nct_itype itype)
equal(const double x,
const double y,
nc_type xtype, /* external data type */
nct_itype itype)
{
const double flt_epsilon = 1.19209290E-07;
const double dbl_epsilon = 2.2204460492503131E-16;
@ -187,10 +179,9 @@ equal(
/* this function is for the APIs without itype, i.e. xtype == itype */
int
equal2(
const double x,
const double y,
nc_type xtype) /* external data type */
equal2(const double x,
const double y,
nc_type xtype) /* external data type */
{
const double flt_epsilon = 1.19209290E-07;
const double dbl_epsilon = 2.2204460492503131E-16;
@ -237,7 +228,7 @@ int roll( int n )
* We don't use RAND_MAX here because not all compilation
* environments define it (e.g. gcc(1) under SunOS 4.1.4).
*/
r = ((rand() % 32768) / 32767.0) * (n - 1) + 0.5;
r = (int)(((rand() % 32768) / 32767.0) * (n - 1) + 0.5);
while (r >= n);
return r;
@ -257,16 +248,15 @@ int roll( int n )
int
toMixedBase(
size_t number, /* number to be converted to mixed base */
size_t length,
int length,
const size_t base[], /* dimensioned [length], base[0] ignored */
size_t result[]) /* dimensioned [length] */
{
size_t i;
int i;
if (length > 0) {
for (i = length - 1; i > 0; i--) {
if (base[i] == 0)
return 1;
if (base[i] == 0) return 1;
result[i] = number % base[i];
number = number / base[i];
}
@ -286,10 +276,9 @@ toMixedBase(
* Author: Harvey Davies, Unidata/UCAR, Boulder, Colorado
*/
size_t
fromMixedBase(
size_t length,
size_t number[], /* dimensioned [length] */
size_t base[]) /* dimensioned [length], base[0] ignored */
fromMixedBase(size_t length,
size_t number[], /* dimensioned [length] */
size_t base[]) /* dimensioned [length], base[0] ignored */
{
size_t i;
size_t result = 0;
@ -310,25 +299,25 @@ int nc2dbl ( const nc_type xtype, const void *p, double *result)
if ( ! p ) return 2;
if ( ! result ) return 3;
switch (xtype) {
case NC_BYTE: *result = *((signed char *) p); break;
case NC_CHAR: *result = *((signed char *) p); break;
case NC_SHORT: *result = *((short *) p); break;
case NC_CHAR: *result = *((signed char *) p); break;
case NC_BYTE: *result = *((signed char *) p); break;
case NC_UBYTE: *result = *((unsigned char *) p); break;
case NC_SHORT: *result = *((short *) p); break;
case NC_USHORT: *result = *((unsigned short *) p); break;
case NC_INT:
#if INT_MAX >= X_INT_MAX
*result = *((int *) p); break;
#else
*result = *((long *) p); break;
#endif
case NC_FLOAT: *result = *((float *) p); break;
case NC_DOUBLE: *result = *((double *) p); break;
case NC_UBYTE: *result = *((unsigned char *) p); break;
case NC_USHORT: *result = *((unsigned short *) p); break;
case NC_UINT:
#if UINT_MAX >= X_UINT_MAX
*result = *((unsigned int *) p); break;
#else
*result = *((unsigned long *) p); break;
#endif
case NC_FLOAT: *result = *((float *) p); break;
case NC_DOUBLE: *result = *((double *) p); break;
case NC_INT64: *result = *((long long *) p); break;
case NC_UINT64: *result = *((unsigned long long *) p); break;
default: return 1;
@ -342,59 +331,52 @@ int dbl2nc ( const double d, const nc_type xtype, void *p)
{
double r; /* rounded value */
if (p) {
switch (xtype) {
case NC_BYTE:
r = floor(0.5+d);
if ( r < schar_min || r > schar_max ) return 2;
*((signed char *) p) = r;
break;
case NC_CHAR:
r = floor(0.5+d);
/* d is obtained from hash() which may be set to X_CHAR_MIN (0)
* or X_CHAR_MAX (255). When in-memory data type char is signed
* (i.e. ranged from -128 to 127), we should still allow a type
* cast a unsigned value > 127 to a signed char without
* reporting it as a range error.
*/
if ( r < X_CHAR_MIN || r > X_CHAR_MAX ) return 2;
if (p == NULL) return 1;
switch (xtype) {
case NC_CHAR:
r = floor(0.5+d);
/* d is obtained from hash() which may be set to X_CHAR_MIN (0)
* or X_CHAR_MAX (255). When in-memory data type char is signed
* (i.e. ranged from -128 to 127), we should still allow a type
* cast a unsigned value > 127 to a signed char without
* reporting it as a range error.
*/
if ( r < X_CHAR_MIN || r > X_CHAR_MAX ) return 2;
#if defined(__CHAR_UNSIGNED__) && __CHAR_UNSIGNED__ != 0
*((signed char*) p) = r;
*((signed char*) p) = r;
#else
*((char *) p) = r;
*((char *) p) = r;
#endif
break;
case NC_SHORT:
r = floor(0.5+d);
if ( r < short_min || r > short_max ) return 2;
*((short *) p) = r;
break;
case NC_INT:
r = floor(0.5+d);
if ( r < long_min || r > long_max ) return 2;
#if INT_MAX >= X_INT_MAX
*((int *) p) = r;
#else
*((long *) p) = r;
#endif
break;
case NC_FLOAT:
if ( fabs(d) > float_max ) return 2;
*((float *) p) = d;
break;
case NC_DOUBLE:
*((double *) p) = d;
break;
break;
case NC_BYTE:
r = floor(0.5+d);
if ( r < schar_min || r > schar_max ) return 2;
*((signed char *) p) = r;
break;
case NC_UBYTE:
r = floor(0.5+d);
if ( r < 0.0 || r > uchar_max ) return 2;
*((unsigned char *) p) = r;
break;
case NC_SHORT:
r = floor(0.5+d);
if ( r < short_min || r > short_max ) return 2;
*((short *) p) = r;
break;
case NC_USHORT:
r = floor(0.5+d);
if ( r < 0.0 || r > ushort_max ) return 2;
*((unsigned short *) p) = r;
break;
case NC_INT:
r = floor(0.5+d);
if ( r < long_min || r > long_max ) return 2;
#if INT_MAX >= X_INT_MAX
*((int *) p) = r;
#else
*((long *) p) = r;
#endif
break;
case NC_UINT:
r = floor(0.5+d);
if ( r < 0.0 || r > uint_max ) return 2;
@ -404,6 +386,13 @@ int dbl2nc ( const double d, const nc_type xtype, void *p)
*((unsigned long *) p) = r;
#endif
break;
case NC_FLOAT:
if ( fabs(d) > float_max ) return 2;
*((float *) p) = d;
break;
case NC_DOUBLE:
*((double *) p) = d;
break;
case NC_INT64:
r = floor(0.5+d);
if ( r < int64_min || r > int64_max ) return 2;
@ -414,13 +403,10 @@ int dbl2nc ( const double d, const nc_type xtype, void *p)
if ( r < 0.0 || r > uint64_max ) return 2;
*((unsigned long long *) p) = r;
break;
default:
return 1;
}
return 0;
} else {
return 1;
default:
return 1;
}
return 0;
}
#define FUZZ (1.19209290E-07)
@ -443,7 +429,7 @@ hash( const nc_type xtype, const int rank, const size_t *index )
case NC_CHAR: return X_CHAR_MIN;
case NC_BYTE: return X_BYTE_MIN;
case NC_SHORT: return X_SHORT_MIN;
case NC_INT: return X_INT_MIN;
case NC_INT: return X_INT_MIN;
case NC_FLOAT: return X_FLOAT_MIN;
case NC_DOUBLE: return X_DOUBLE_MIN;
case NC_UBYTE: return 0;
@ -459,7 +445,7 @@ hash( const nc_type xtype, const int rank, const size_t *index )
case NC_CHAR: return X_CHAR_MAX;
case NC_BYTE: return X_BYTE_MAX;
case NC_SHORT: return X_SHORT_MAX;
case NC_INT: return X_INT_MAX;
case NC_INT: return X_INT_MAX;
case NC_FLOAT: return X_FLOAT_MAX;
case NC_DOUBLE: return X_DOUBLE_MAX;
case NC_UBYTE: return X_UCHAR_MAX;
@ -476,7 +462,7 @@ hash( const nc_type xtype, const int rank, const size_t *index )
case NC_CHAR: return 'A';
case NC_BYTE: return X_BYTE_MIN-1.0;
case NC_SHORT: return X_SHORT_MIN-1.0;
case NC_INT: return X_INT_MIN-1.0;
case NC_INT: return X_INT_MIN-1.0;
case NC_FLOAT: return X_FLOAT_MIN * (1.0 + FUZZ);
case NC_DOUBLE: return -1.0;
case NC_UBYTE: return -1.0;
@ -491,7 +477,7 @@ hash( const nc_type xtype, const int rank, const size_t *index )
case NC_CHAR: return 'Z';
case NC_BYTE: return X_BYTE_MAX+1.0;
case NC_SHORT: return X_SHORT_MAX+1.0;
case NC_INT: return X_INT_MAX+1.0;
case NC_INT: return X_INT_MAX+1.0;
case NC_FLOAT: return X_FLOAT_MAX * (1.0 + FUZZ);
case NC_DOUBLE: return 1.0;
case NC_UBYTE: return X_UCHAR_MAX +1.0;
@ -504,11 +490,11 @@ hash( const nc_type xtype, const int rank, const size_t *index )
}
} else {
switch (xtype) {
case NC_CHAR: base = 2; break;
case NC_BYTE: base = -2; break;
case NC_SHORT: base = -5; break;
case NC_INT: base = -20; break;
case NC_FLOAT: base = -9; break;
case NC_CHAR: base = 2; break;
case NC_BYTE: base = -2; break;
case NC_SHORT: base = -5; break;
case NC_INT: base = -20; break;
case NC_FLOAT: base = -9; break;
case NC_DOUBLE: base = -10; break;
/* not sure what right values are */
@ -633,23 +619,32 @@ hash( const nc_type xtype, const int rank, const size_t *index )
#endif
/* wrapper for hash to handle special NC_BYTE/uchar adjustment */
double
hash4(
const int cdf_format,
const nc_type xtype,
const int rank,
const size_t *index,
const nct_itype itype)
hash4(const int cdf_format,
const nc_type xtype,
const int rank,
const size_t *index,
const nct_itype itype)
{
double result;
result = hash( xtype, rank, index );
/* netCDF specification make a special case for type conversion between
* uchar and NC_BYTE: do not check for range error. See
* http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
* The _uchar and _schar functions were introduced in netCDF-3 to eliminate
* an ambiguity, and support both signed and unsigned byte data. In
* netCDF-2, whether the external NC_BYTE type represented signed or
* unsigned values was left up to the user. In netcdf-3, we treat NC_BYTE
* as signed for the purposes of conversion to short, int, long, float, or
* double. (Of course, no conversion takes place when the internal type is
* signed char.) In the _uchar functions, we treat NC_BYTE as if it were
* unsigned. Thus, no NC_ERANGE error can occur converting between NC_BYTE
* and unsigned char.
*/
if (cdf_format < NC_FORMAT_CDF5 &&
itype == NCT_UCHAR && xtype == NC_BYTE && result >= -128 && result < 0)
/* netCDF specification make a special case for type conversion between
* uchar and scahr: do not check for range error. See
* http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
*/
itype == NCT_UCHAR && xtype == NC_BYTE &&
result >= -128 && result < 0)
result += 256;
return result;
@ -703,7 +698,7 @@ init_gatts(const char *type_letter)
}
static size_t
product(size_t nn, const size_t *sp)
product(int nn, const size_t *sp)
{
size_t result = 1;
while(nn-- > 0)
@ -731,7 +726,7 @@ init_gvars (void)
*/
const char digit[] = "r123456789";
size_t rank;
int rank;
int vn; /* var number */
int xtype; /* index of type */
int an; /* attribute number */
@ -747,7 +742,7 @@ init_gvars (void)
{
/* number variables of a type and rank */
const size_t nvars = product(rank, max_dim_len);
int jj;
size_t jj;
for (jj = 0; jj < nvars; jj++)
{
@ -849,7 +844,7 @@ put_atts(int ncid)
for (j = 0; j < NATTS(i); j++) {
if (ATT_TYPE(i,j) == NC_CHAR) {
for (k = 0; k < ATT_LEN(i,j); k++) {
catt[k] = hash(ATT_TYPE(i,j), -1, &k);
catt[k] = (char) hash(ATT_TYPE(i,j), -1, &k);
}
err = nc_put_att_text(ncid, i, ATT_NAME(i,j),
ATT_LEN(i,j), catt);
@ -894,7 +889,7 @@ put_vars(int ncid)
err = toMixedBase(j, var_rank[i], var_shape[i], index);
IF (err) error("toMixedBase");
if (var_name[i][0] == 'c') {
text[j] = hash(var_type[i], var_rank[i], index);
text[j] = (char) hash(var_type[i], var_rank[i], index);
} else {
value[j] = hash(var_type[i], var_rank[i], index);
allInRange = allInRange && inRange(value[j], var_type[i]);
@ -984,19 +979,14 @@ void
check_vars(int ncid)
{
size_t index[MAX_RANK];
int err; /* status */
int i;
char text, name[NC_MAX_NAME];
int i, err; /* status */
size_t j;
char text;
double value;
nc_type xtype;
int ndims;
int dimids[MAX_RANK];
int isChar;
double expect;
char name[NC_MAX_NAME];
size_t length;
int nok = 0; /* count of valid comparisons */
int isChar, ndims, dimids[MAX_RANK];
double value, expect;
nc_type xtype;
size_t length;
for (i = 0; i < numVars; i++) {
isChar = var_type[i] == NC_CHAR;
@ -1022,18 +1012,14 @@ check_vars(int ncid)
error("error in toMixedBase 2");
expect = hash( var_type[i], var_rank[i], index );
if (isChar) {
err = nc_get_var1_text(ncid, i, index, &text);
IF (err)
err = nc_get_var1_text(ncid, i, index, &text);
IF (err)
error("nc_get_var1_text: %s", nc_strerror(err));
IF (text != (char)expect) {
error("Var %s value read 0x%02x not that expected 0x%02x ",
var_name[i], text, (char)expect);
print_n_size_t(var_rank[i], index);
} else {
#if 0
print("\nOk %s ", var_name[i]);
print_n_size_t(var_rank[i], index);
#endif
nok++;
}
} else {
@ -1049,10 +1035,6 @@ check_vars(int ncid)
var_name[i], value, expect);
print_n_size_t(var_rank[i], index);
} else {
#if 0
print("\nOk %s ", var_name[i]);
print_n_size_t(var_rank[i], index);
#endif
nok++;
}
}
@ -1104,9 +1086,9 @@ check_atts(int ncid)
expect = hash(xtype, -1, &k);
IF (text[k] != (char)expect) {
error("nc_get_att_text: unexpected value");
} else {
nok++;
}
} else {
nok++;
}
}
} else {
err = nc_get_att_double(ncid, i, name, value);
@ -1222,6 +1204,16 @@ int file_open(const char *filename, int omode, int *ncid)
char* nc_err_code_name(int err)
{
static char unknown_str[32];
if (err > 0) { /* system error */
const char *cp = (const char *) strerror(err);
if (cp == NULL)
sprintf(unknown_str,"Unknown error code %d",err);
else
sprintf(unknown_str,"Error code %d (%s)",err,cp);
return unknown_str;
}
switch (err) {
case (NC_NOERR): return "NC_NOERR";
case (NC_EBADID): return "NC_EBADID";