1dnl This is m4 source. 2dnl Process using m4 to produce 'C' language file. 3dnl 4dnl This file is supposed to be the same as PnetCDF's test_write.m4 5dnl 6dnl If you see this line, you can ignore the next one. 7/* Do not edit this file. It is produced from the corresponding .m4 source */ 8dnl 9/* 10 * Copyright (C) 2003, Northwestern University and Argonne National Laboratory 11 * See COPYRIGHT notice in top-level directory. 12 */ 13/* $Id: test_write.m4 2687 2016-12-08 18:32:13Z wkliao $ */ 14 15dnl 16dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF 17dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types 18dnl (MPI_Offset vs. size_t), and function name substrings for external data 19dnl types. 20dnl 21 22#if defined (_WIN32) || defined (_WIN64) 23#include <io.h> 24#endif 25 26#include <sys/types.h> /* open() */ 27#include <sys/stat.h> /* open() */ 28#include <fcntl.h> /* open() */ 29#ifdef _MSC_VER 30#include <io.h> 31#else 32#include <unistd.h> /* read() */ 33#endif 34 35#include "tests.h" 36#include "config.h" 37#include "math.h" 38 39define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl 40 41define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl 42define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl 43define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_$1',`test_nc_$1')')dnl 44define(`APIFunc', `ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl 45 46define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, $3)', `file_open($1, $2, $3)')')dnl 47define(`FileCreate',`ifdef(`PNETCDF',`ncmpi_create(comm, $1, $2, info, $3)', `file_create($1, $2, $3)')')dnl 48define(`FileDelete',`ifdef(`PNETCDF',`ncmpi_delete($1,$2)',`nc_delete($1)')')dnl 49 50define(`Def_Vars', `ifdef(`PNETCDF',`def_vars($1,$2)',`def_vars($1)')')dnl 51define(`Put_Atts', `ifdef(`PNETCDF',`put_atts($1,$2,$3)',`put_atts($1)')')dnl 52define(`Put_Vars', `ifdef(`PNETCDF',`put_vars($1,$2)',`put_vars($1)')')dnl 53define(`Check_File',`ifdef(`PNETCDF',`check_file($1,$2,$3)',`check_file($1)')')dnl 54define(`Check_Atts',`ifdef(`PNETCDF',`check_atts($1,$2,$3)',`check_atts($1)')')dnl 55define(`Check_Vars',`ifdef(`PNETCDF',`check_vars($1,$2)',`check_vars($1)')')dnl 56define(`VarArgs', `ifdef(`PNETCDF',`int numVars',`void')')dnl 57define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts, int numVars',`void')')dnl 58 59define(`GetVar1TYPE',`ifdef(`PNETCDF',`ncmpi_get_var1_$1_all',`nc_get_var1_$1')')dnl 60define(`PutVar1TYPE',`ifdef(`PNETCDF',`ncmpi_put_var1_$1_all',`nc_put_var1_$1')')dnl 61 62define(`PutVar1', `ifdef(`PNETCDF',`ncmpi_put_var1_all($1,$2,$3,$4,$5,$6)', `nc_put_var1($1,$2,$3,$4)')')dnl 63define(`PutVar', `ifdef(`PNETCDF',`ncmpi_put_var_all( $1,$2,$3,$4,$5)', `nc_put_var( $1,$2,$3)')')dnl 64define(`PutVara', `ifdef(`PNETCDF',`ncmpi_put_vara_all($1,$2,$3,$4,$5,$6,$7)', `nc_put_vara($1,$2,$3,$4,$5)')')dnl 65define(`PutVars', `ifdef(`PNETCDF',`ncmpi_put_vars_all($1,$2,$3,$4,$5,$6,$7,$8)', `nc_put_vars($1,$2,$3,$4,$5,$6)')')dnl 66define(`PutVarm', `ifdef(`PNETCDF',`ncmpi_put_varm_all($1,$2,$3,$4,$5,$6,$7,$8,$9)', `nc_put_varm($1,$2,$3,$4,$5,$6,$7)')')dnl 67 68 69/* 70 * Test APIFunc(create) 71 * For mode in NC_NOCLOBBER, NC_CLOBBER do: 72 * create netcdf file 'scratch.nc' with no data, close it 73 * test that it can be opened, do APIFunc(inq) to check nvars = 0, etc. 74 * Try again in NC_NOCLOBBER mode, check error return 75 * On exit, delete this file 76 */ 77int 78TestFunc(create)(void) 79{ 80 int clobber; /* 0 for NC_NOCLOBBER, 1 for NC_CLOBBER */ 81 int err; 82 int ncid; 83 int ndims; /* number of dimensions */ 84 int nvars; /* number of variables */ 85 int ngatts; /* number of global attributes */ 86 int recdim; /* id of unlimited dimension */ 87 int nok=0; 88 89 for (clobber = 0; clobber < 2; clobber++) { 90 err = FileCreate(scratch, clobber ? NC_CLOBBER : NC_NOCLOBBER, &ncid); 91 IF (err != NC_NOERR) 92 error("create: %s", APIFunc(strerror)(err)); 93 ELSE_NOK 94 err = APIFunc(close)(ncid); 95 IF (err != NC_NOERR) 96 error("close: %s", APIFunc(strerror)(err)); 97 err = FileOpen(scratch, NC_NOWRITE, &ncid); 98 IF (err != NC_NOERR) 99 error("open: %s", APIFunc(strerror)(err)); 100 err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, &recdim); 101 IF (err != NC_NOERR) 102 error("inq: %s", APIFunc(strerror)(err)); 103 else IF (ndims != 0) 104 error("inq: wrong number of dimensions returned, %d", ndims); 105 else IF (nvars != 0) 106 error("inq: wrong number of variables returned, %d", nvars); 107 else IF (ngatts != 0) 108 error("inq: wrong number of global atts returned, %d", ngatts); 109 else IF (recdim != -1) 110 error("inq: wrong record dimension ID returned, %d", recdim); 111 ELSE_NOK 112 err = APIFunc(close)(ncid); 113 IF (err != NC_NOERR) 114 error("close: %s", APIFunc(strerror)(err)); 115 } 116 117 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 118 IF (err != NC_EEXIST) 119 error("expecting NC_EEXIST but got %s", nc_err_code_name(err)); 120 ELSE_NOK 121 122 err = FileDelete(scratch, info); 123 IF (err != NC_NOERR) 124 error("remove of %s failed", scratch); 125 return nok; 126} 127 128 129/* 130 * Test APIFunc(redef) 131 * (In fact also tests APIFunc(enddef) - called from TestFunc(enddef)) 132 * BAD_ID 133 * attempt redef (error) & enddef on read-only file 134 * create file, define dims & vars. 135 * attempt put var (error) 136 * attempt redef (error) & enddef. 137 * put vars 138 * attempt def new dims (error) 139 * redef 140 * def new dims, vars. 141 * put atts 142 * enddef 143 * put vars 144 * close 145 * check file: vars & atts 146 * check reopening with NC_WRITE and adding new dims, atts, vars 147 */ 148int 149TestFunc(redef)(AttVarArgs) 150{ 151 int ncid; /* netcdf id */ 152 /* used to force effective test of ncio->move() in redef */ 153 IntType sizehint = 8192; 154 int dimid; /* dimension id */ 155 int varid; /* variable id */ 156 int varid1; /* variable id */ 157 int nok=0, err; 158 const char * title = "Not funny"; 159 double var; 160 char name[NC_MAX_NAME]; 161 IntType length; 162 int fmt_variant1, fmt_variant2; 163 164 /* BAD_ID tests */ 165 err = APIFunc(redef)(BAD_ID); 166 IF (err != NC_EBADID) 167 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 168 ELSE_NOK 169 err = APIFunc(enddef)(BAD_ID); 170 IF (err != NC_EBADID) 171 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 172 ELSE_NOK 173 174 /* read-only tests */ 175 err = FileOpen(testfile, NC_NOWRITE, &ncid); 176 IF (err != NC_NOERR) 177 error("open: %s", APIFunc(strerror)(err)); 178 err = APIFunc(redef)(ncid); 179 IF (err != NC_EPERM) 180 error("expecting NC_EPERM but got %s", nc_err_code_name(err)); 181 ELSE_NOK 182 err = APIFunc(enddef)(ncid); 183 IF (err != NC_ENOTINDEFINE) 184 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 185 ELSE_NOK 186 err = APIFunc(close)(ncid); 187 IF (err != NC_NOERR) 188 error("close: %s", APIFunc(strerror)(err)); 189 190 /* tests using scratch file */ 191ifdef(`PNETCDF',`dnl 192 err = FileCreate(scratch, NC_NOCLOBBER, &ncid);',`dnl 193 err = file__create(scratch, NC_NOCLOBBER, 0, &sizehint, &ncid);') 194 IF (err != NC_NOERR) { 195 error("create: %s", APIFunc(strerror)(err)); 196 return nok; 197 } 198ifdef(`PNETCDF',,`dnl 199 /* limit for ncio implementations which have infinite chunksize */ 200 if(sizehint > 32768) sizehint = 16384;') 201 def_dims(ncid); 202 Def_Vars(ncid, numVars); 203 Put_Atts(ncid, numGatts, numVars); 204 err = APIFunc(inq_varid)(ncid, "d", &varid); 205 IF (err != NC_NOERR) 206 error("inq_varid: %s", APIFunc(strerror)(err)); 207 var = 1.0; 208 209ifdef(`PNETCDF', ` 210 err = ncmpi_begin_indep_data(ncid); 211 IF (err != NC_EINDEFINE) 212 error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err));')dnl 213 214 err = PutVar1TYPE(double)(ncid, varid, NULL, &var); 215 IF (err != NC_EINDEFINE) 216 error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err)); 217 218ifdef(`PNETCDF', ` 219 err = ncmpi_end_indep_data(ncid); 220 IF (err != NC_ENOTINDEP) 221 error("expecting NC_ENOTINDEP but got %s", nc_err_code_name(err));')dnl 222 223 err = APIFunc(redef)(ncid); 224 IF (err != NC_EINDEFINE) 225 error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err)); 226 ELSE_NOK 227 err = APIFunc(enddef)(ncid); 228 IF (err != NC_NOERR) 229 error("enddef: %s", APIFunc(strerror)(err)); 230 ELSE_NOK 231 Put_Vars(ncid, numVars); 232 err = APIFunc(def_dim)(ncid, "abc", sizehint, &dimid); 233 IF (err != NC_ENOTINDEFINE) 234 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 235 err = APIFunc(redef)(ncid); 236 IF (err != NC_NOERR) 237 error("redef: %s", APIFunc(strerror)(err)); 238 ELSE_NOK 239 240 err = APIFunc(set_fill)(ncid, NC_NOFILL, NULL); 241 IF (err != NC_NOERR) 242 error("set_fill: %s", APIFunc(strerror)(err)); 243 244 err = APIFunc(def_dim)(ncid, "abc", sizehint, &dimid); 245 IF (err != NC_NOERR) 246 error("def_dim: %s", APIFunc(strerror)(err)); 247 err = APIFunc(def_var)(ncid, "abcScalar", NC_INT, 0, NULL, &varid); 248 IF (err != NC_NOERR) 249 error("def_var: %s", APIFunc(strerror)(err)); 250 err = APIFunc(def_var)(ncid, "abc", NC_INT, 1, &dimid, &varid1); 251 IF (err != NC_NOERR) 252 error("def_var: %s", APIFunc(strerror)(err)); 253 { 254 int dimids[NDIMS +1]; 255 int ii = 0; 256 for(ii = 0; ii < NDIMS; ii++) dimids[ii] = ii; 257 dimids[NDIMS] = dimid; 258 err = APIFunc(def_var)(ncid, "abcRec", NC_INT, NDIMS, dimids, &varid1); 259 IF (err != NC_NOERR) 260 error("def_var: %s", APIFunc(strerror)(err)); 261 } 262 err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "title", 1+strlen(title), title); 263 IF (err != NC_NOERR) 264 error("put_att_text: %s", APIFunc(strerror)(err)); 265 err = APIFunc(enddef)(ncid); 266 IF (err != NC_NOERR) 267 error("enddef: %s", APIFunc(strerror)(err)); 268 ELSE_NOK 269 var = 1.0; 270 271ifdef(`PNETCDF', ` 272 err = ncmpi_end_indep_data(ncid); 273 IF (err != NC_ENOTINDEP) 274 error("expecting NC_ENOTINDEP but got %s", nc_err_code_name(err));')dnl 275 276 err = PutVar1TYPE(double)(ncid, varid, NULL, &var); 277 IF (err != NC_NOERR) 278 error("put_var1_double: %s", APIFunc(strerror)(err)); 279 err = APIFunc(inq_format)(ncid, &fmt_variant1); 280 IF (err) 281 error("inq_format: %s", APIFunc(strerror)(err)); 282 err = APIFunc(close)(ncid); 283 IF (err != NC_NOERR) 284 error("close: %s", APIFunc(strerror)(err)); 285 286 /* check scratch file written as expected */ 287 Check_File(scratch, numGatts, numVars); /* checks all except "abc" stuff added above */ 288 289 IF ((err = FileOpen(scratch, NC_NOWRITE, &ncid))) 290 error("open: %s", APIFunc(strerror)(err)); 291 IF ((err = APIFunc(inq_dim)(ncid, dimid, name, &length))) 292 error("inq_dim: %s", APIFunc(strerror)(err)); 293 IF (strcmp(name, "abc") != 0) 294 error("Unexpected dim name"); 295 IF (length != sizehint) 296 error("Unexpected dim length"); 297 IF ((err = GetVar1TYPE(double)(ncid, varid, NULL, &var))) 298 error("get_var1_double: %s", APIFunc(strerror)(err)); 299 IF (var != 1.0) 300 error("get_var1_double: unexpected value"); 301 IF ((err = APIFunc(close)(ncid))) 302 error("close: %s", APIFunc(strerror)(err)); 303 304 /* open scratch file for writing, add another dim, var, att, then check */ 305 IF ((err = FileOpen(scratch, NC_WRITE, &ncid))) 306 error("open: %s", APIFunc(strerror)(err)); 307 IF ((err = APIFunc(redef)(ncid))) 308 error("redef: %s", APIFunc(strerror)(err)); 309 IF ((err = APIFunc(def_dim)(ncid, "def", sizehint, &dimid))) 310 error("def_dim: %s", APIFunc(strerror)(err)); 311 IF ((err = APIFunc(def_var)(ncid, "defScalar", NC_INT, 0, NULL, &varid))) 312 error("def_var: %s", APIFunc(strerror)(err)); 313 IF ((err = APIFunc(def_var)(ncid, "def", NC_INT, 1, &dimid, &varid1))) 314 error("def_var: %s", APIFunc(strerror)(err)); 315 IF ((err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "Credits", 1+strlen("Thanks!"), "Thanks!"))) 316 error("put_att_text: %s", APIFunc(strerror)(err)); 317 IF ((err = APIFunc(enddef)(ncid))) 318 error("enddef: %s", APIFunc(strerror)(err)); 319 var = 2.0; 320 IF ((err = PutVar1TYPE(double)(ncid, varid, NULL, &var))) 321 error("put_var1_double: %s", APIFunc(strerror)(err)); 322 IF ((err = APIFunc(close)(ncid))) 323 error("close: %s", APIFunc(strerror)(err)); 324 325 /* check scratch file written as expected */ 326 Check_File(scratch, numGatts, numVars); 327 328 err = FileOpen(scratch, NC_NOWRITE, &ncid); 329 IF (err) 330 error("open: %s", APIFunc(strerror)(err)); 331 err = APIFunc(inq_dim)(ncid, dimid, name, &length); 332 IF (err) 333 error("inq_dim: %s", APIFunc(strerror)(err)); 334 IF (strcmp(name, "def") != 0) 335 error("Unexpected dim name"); 336 IF (length != sizehint) 337 error("Unexpected dim length"); 338 err = GetVar1TYPE(double)(ncid, varid, NULL, &var); 339 IF (err) 340 error("get_var1_double: %s", APIFunc(strerror)(err)); 341 IF (var != 2.0) 342 error("get_var1_double: unexpected value"); 343 /* make sure format variant hasn't changed from when created */ 344 err = APIFunc(inq_format)(ncid, &fmt_variant2); 345 IF (err) 346 error("inq_format: %s", APIFunc(strerror)(err)); 347 IF (fmt_variant1 != fmt_variant2) 348 error("enddef changed format variant"); 349 err = APIFunc(close)(ncid); 350 IF (err) 351 error("close: %s", APIFunc(strerror)(err)); 352 353 err = FileDelete(scratch, info); 354 IF (err != NC_NOERR) 355 error("remove of %s failed", scratch); 356 return nok; 357} 358 359 360/* 361 * Test APIFunc(enddef) 362 * Simply calls TestFunc(redef) which tests both APIFunc(redef) & APIFunc(enddef) 363 */ 364int 365TestFunc(enddef)(AttVarArgs) 366{ 367 ifdef(`PNETCDF', 368 `return test_ncmpi_redef(numGatts, numVars);', 369 `return test_nc_redef();') 370} 371 372 373/* 374 * Test APIFunc(sync) 375 * try with bad handle, check error 376 * try in define mode, check error 377 * try writing with one handle, reading with another on same netCDF 378 */ 379int 380TestFunc(sync)(AttVarArgs) 381{ 382 int ncidw; /* netcdf id for writing */ 383 int ncidr; /* netcdf id for reading */ 384 int nok=0, err; 385 386 /* BAD_ID test */ 387 err = APIFunc(sync)(BAD_ID); 388 IF (err != NC_EBADID) 389 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 390 ELSE_NOK 391 392 /* create scratch file & try APIFunc(sync) in define mode */ 393 err = FileCreate(scratch, NC_NOCLOBBER, &ncidw); 394 IF (err != NC_NOERR) { 395 error("create: %s", APIFunc(strerror)(err)); 396 return nok; 397 } 398 err = APIFunc(sync)(ncidw); 399 IF (err != NC_EINDEFINE) 400 error("expecting NC_EINDEFINE but got %s", nc_err_code_name(err)); 401 ELSE_NOK 402 403 /* write using same handle */ 404 def_dims(ncidw); 405 Def_Vars(ncidw, numVars); 406 Put_Atts(ncidw, numGatts, numVars); 407 err = APIFunc(enddef)(ncidw); 408 IF (err != NC_NOERR) 409 error("enddef: %s", APIFunc(strerror)(err)); 410 Put_Vars(ncidw, numVars); 411 err = APIFunc(sync)(ncidw); 412 IF (err != NC_NOERR) 413 error("sync of ncidw failed: %s", APIFunc(strerror)(err)); 414 ELSE_NOK 415 416 /* open another handle, APIFunc(sync), read (check) */ 417 err = FileOpen(scratch, NC_NOWRITE, &ncidr); 418 IF (err != NC_NOERR) 419 error("open: %s", APIFunc(strerror)(err)); 420 err = APIFunc(sync)(ncidr); 421 IF (err != NC_NOERR) 422 error("sync of ncidr failed: %s", APIFunc(strerror)(err)); 423 ELSE_NOK 424 check_dims(ncidr); 425 Check_Atts(ncidr, numGatts, numVars); 426 Check_Vars(ncidr, numVars); 427 428 /* close both handles */ 429 err = APIFunc(close)(ncidr); 430 IF (err != NC_NOERR) 431 error("close: %s", APIFunc(strerror)(err)); 432 err = APIFunc(close)(ncidw); 433 IF (err != NC_NOERR) 434 error("close: %s", APIFunc(strerror)(err)); 435 436 err = FileDelete(scratch, info); 437 IF (err != NC_NOERR) 438 error("remove of %s failed", scratch); 439 return nok; 440} 441 442 443/* 444 * Test APIFunc(abort) 445 * try with bad handle, check error 446 * try in define mode before anything written, check that file was deleted 447 * try after APIFunc(enddef), APIFunc(redef), define new dims, vars, atts 448 * try after writing variable 449 */ 450int 451TestFunc(abort)(AttVarArgs) 452{ 453 int ncid; /* netcdf id */ 454 int err; 455 int ndims; 456 int nvars; 457 int ngatts; 458 int nok=0; 459 460 /* BAD_ID test */ 461 err = APIFunc(abort)(BAD_ID); 462 IF (err != NC_EBADID) 463 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 464 ELSE_NOK 465 466 /* create scratch file & try APIFunc(abort) in define mode */ 467 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 468 IF (err != NC_NOERR) { 469 error("create: %s", APIFunc(strerror)(err)); 470 return nok; 471 } 472 def_dims(ncid); 473 Def_Vars(ncid, numVars); 474 Put_Atts(ncid, numGatts, numVars); 475 err = APIFunc(abort)(ncid); 476 IF (err != NC_NOERR) 477 error("abort of ncid failed: %s", APIFunc(strerror)(err)); 478 ELSE_NOK 479 err = APIFunc(close)(ncid); /* should already be closed */ 480 IF (err != NC_EBADID) 481 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 482 err = FileDelete(scratch, info); /* should already be deleted */ 483ifdef(`PNETCDF', 484 `IF (err != NC_ENOENT && err != NC_EFILE) 485 error("expecting NC_ENOENT or NC_EFILE but got %s", nc_err_code_name(err));', 486 `IF (err != ENOENT && err != NC_EIO) 487 error("expecting ENOENT or NC_EIO but got %s", nc_err_code_name(err));')dnl 488 489 /* 490 * create scratch file 491 * do APIFunc(enddef) & APIFunc(redef) 492 * define new dims, vars, atts 493 * try APIFunc(abort): should restore previous state (no dims, vars, atts) 494 */ 495 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 496 IF (err != NC_NOERR) { 497 error("create: %s", APIFunc(strerror)(err)); 498 return nok; 499 } 500 err = APIFunc(enddef)(ncid); 501 IF (err != NC_NOERR) 502 error("enddef: %s", APIFunc(strerror)(err)); 503 err = APIFunc(redef)(ncid); 504 IF (err != NC_NOERR) 505 error("redef: %s", APIFunc(strerror)(err)); 506 def_dims(ncid); 507 Def_Vars(ncid, numVars); 508 Put_Atts(ncid, numGatts, numVars); 509 err = APIFunc(abort)(ncid); 510 IF (err != NC_NOERR) 511 error("abort of ncid failed: %s", APIFunc(strerror)(err)); 512 ELSE_NOK 513 err = APIFunc(close)(ncid); /* should already be closed */ 514 IF (err != NC_EBADID) 515 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 516 err = FileOpen(scratch, NC_NOWRITE, &ncid); 517 IF (err != NC_NOERR) 518 error("open: %s", APIFunc(strerror)(err)); 519 err = APIFunc(inq)(ncid, &ndims, &nvars, &ngatts, NULL); 520 IF (err != NC_NOERR) 521 error("inq: %s", APIFunc(strerror)(err)); 522 IF (ndims != 0) 523 error("ndims should be 0"); 524 IF (nvars != 0) 525 error("nvars should be 0"); 526 IF (ngatts != 0) 527 error("ngatts should be 0"); 528 err = APIFunc(close)(ncid); 529 IF (err != NC_NOERR) 530 error("close: %s", APIFunc(strerror)(err)); 531 532 /* try APIFunc(abort) in data mode - should just close */ 533 err = FileCreate(scratch, NC_CLOBBER, &ncid); 534 IF (err != NC_NOERR) { 535 error("create: %s", APIFunc(strerror)(err)); 536 return nok; 537 } 538 def_dims(ncid); 539 Def_Vars(ncid, numVars); 540 Put_Atts(ncid, numGatts, numVars); 541 err = APIFunc(enddef)(ncid); 542 IF (err != NC_NOERR) 543 error("enddef: %s", APIFunc(strerror)(err)); 544 Put_Vars(ncid, numVars); 545 err = APIFunc(abort)(ncid); 546 IF (err != NC_NOERR) 547 error("abort of ncid failed: %s", APIFunc(strerror)(err)); 548 ELSE_NOK 549 err = APIFunc(close)(ncid); /* should already be closed */ 550 IF (err != NC_EBADID) 551 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 552 Check_File(scratch, numGatts, numVars); 553 err = FileDelete(scratch, info); 554 IF (err != NC_NOERR) 555 error("remove of %s failed", scratch); 556 return nok; 557} 558 559 560/* 561 * Test APIFunc(def_dim) 562 * try with bad netCDF handle, check error 563 * try in data mode, check error 564 * check that returned id is one more than previous id 565 * try adding same dimension twice, check error 566 * try with illegal sizes, check error 567 * make sure unlimited size works, shows up in APIFunc(inq_unlimdim) 568 * try to define a second unlimited dimension, check error 569 */ 570int 571TestFunc(def_dim)(VarArgs) 572{ 573 int ncid; 574 int err; /* status */ 575 int i, nok=0; 576 int dimid; /* dimension id */ 577 IntType length; 578 579 /* BAD_ID test */ 580 err = APIFunc(def_dim)(BAD_ID, "abc", 8, &dimid); 581 IF (err != NC_EBADID) 582 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 583 ELSE_NOK 584 585 /* data mode test */ 586 err = FileCreate(scratch, NC_CLOBBER, &ncid); 587 IF (err != NC_NOERR) { 588 error("create: %s", APIFunc(strerror)(err)); 589 return nok; 590 } 591 err = APIFunc(enddef)(ncid); 592 IF (err != NC_NOERR) 593 error("enddef: %s", APIFunc(strerror)(err)); 594 err = APIFunc(def_dim)(ncid, "abc", 8, &dimid); 595 IF (err != NC_ENOTINDEFINE) 596 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 597 ELSE_NOK 598 599 /* define-mode tests: unlimited dim */ 600 err = APIFunc(redef)(ncid); 601 IF (err != NC_NOERR) 602 error("redef: %s", APIFunc(strerror)(err)); 603 err = APIFunc(def_dim)(ncid, dim_name[0], NC_UNLIMITED, &dimid); 604 IF (err != NC_NOERR) 605 error("def_dim: %s", APIFunc(strerror)(err)); 606 ELSE_NOK 607 IF (dimid != 0) 608 error("Unexpected dimid"); 609 ELSE_NOK 610 err = APIFunc(inq_unlimdim)(ncid, &dimid); 611 IF (err != NC_NOERR) 612 error("inq_unlimdim: %s", APIFunc(strerror)(err)); 613 IF (dimid != 0) 614 error("Unexpected recdim"); 615 err = APIFunc(inq_dimlen)(ncid, dimid, &length); 616 IF (length != 0) 617 error("Unexpected length"); 618 err = APIFunc(def_dim)(ncid, "abc", NC_UNLIMITED, &dimid); 619 IF (err != NC_EUNLIMIT) 620 error("expecting NC_EUNLIMIT but got %s", nc_err_code_name(err)); 621 ELSE_NOK 622 623 /* define-mode tests: remaining dims */ 624 for (i = 1; i < NDIMS; i++) { 625 err = APIFunc(def_dim)(ncid, dim_name[i-1], dim_len[i], &dimid); 626 IF (err != NC_ENAMEINUSE) 627 error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); 628 ELSE_NOK 629 err = APIFunc(def_dim)(ncid, BAD_NAME, dim_len[i], &dimid); 630 IF (err != NC_EBADNAME) 631 error("expecting NC_EBADNAME but got %s", nc_err_code_name(err)); 632 ELSE_NOK 633ifdef(`PNETCDF', ,`if(sizeof(long) > 4) /* Fix: dmh 11/4/2011: works only if sizeof(long) > 4 */') 634 { 635 err = APIFunc(def_dim)(ncid, dim_name[i], (IntType)(NC_UNLIMITED-1), &dimid); 636 IF (err != NC_EDIMSIZE) 637 error("expecting NC_EDIMSIZE but got %s", nc_err_code_name(err)); 638 ELSE_NOK 639 } 640 err = APIFunc(def_dim)(ncid, dim_name[i], dim_len[i], &dimid); 641 IF (err != NC_NOERR) 642 error("def_dim: %s", APIFunc(strerror)(err)); 643 ELSE_NOK 644 IF (dimid != i) 645 error("Unexpected dimid"); 646 } 647 648 /* Following just to expand unlimited dim */ 649 Def_Vars(ncid, numVars); 650 err = APIFunc(enddef)(ncid); 651 IF (err != NC_NOERR) 652 error("enddef: %s", APIFunc(strerror)(err)); 653 Put_Vars(ncid, numVars); 654 655 /* Check all dims */ 656 check_dims(ncid); 657 658 err = APIFunc(close)(ncid); 659 IF (err != NC_NOERR) 660 error("close: %s", APIFunc(strerror)(err)); 661 err = FileDelete(scratch, info); 662 IF (err != NC_NOERR) 663 error("remove of %s failed", scratch); 664 return nok; 665} 666 667 668/* 669 * Test APIFunc(rename_dim) 670 * try with bad netCDF handle, check error 671 * check that proper rename worked with APIFunc(inq_dim) 672 * try renaming to existing dimension name, check error 673 * try with bad dimension handle, check error 674 */ 675int 676TestFunc(rename_dim)(void) 677{ 678 int ncid; 679 int err, nok=0; /* status */ 680 char name[NC_MAX_NAME]; 681 682 /* BAD_ID test */ 683 err = APIFunc(rename_dim)(BAD_ID, 0, "abc"); 684 IF (err != NC_EBADID) 685 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 686 ELSE_NOK 687 688 /* main tests */ 689 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 690 IF (err != NC_NOERR) { 691 error("create: %s", APIFunc(strerror)(err)); 692 return nok; 693 } 694 def_dims(ncid); 695 err = APIFunc(rename_dim)(ncid, BAD_DIMID, "abc"); 696 IF (err != NC_EBADDIM) 697 error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); 698 ELSE_NOK 699 err = APIFunc(rename_dim)(ncid, 2, "abc"); 700 IF (err != NC_NOERR) 701 error("rename_dim: %s", APIFunc(strerror)(err)); 702 ELSE_NOK 703 err = APIFunc(inq_dimname)(ncid, 2, name); 704 IF (strcmp(name, "abc") != 0) 705 error("Unexpected name: %s", name); 706 err = APIFunc(rename_dim)(ncid, 0, "abc"); 707 IF (err != NC_ENAMEINUSE) 708 error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); 709 ELSE_NOK 710 711 err = APIFunc(close)(ncid); 712 IF (err != NC_NOERR) 713 error("close: %s", APIFunc(strerror)(err)); 714 err = FileDelete(scratch, info); 715 IF (err != NC_NOERR) 716 error("remove of %s failed", scratch); 717 return nok; 718} 719 720 721/* 722 * Test APIFunc(def_var) 723 * try with bad netCDF handle, check error 724 * try with bad name, check error 725 * scalar tests: 726 * check that proper define worked with APIFunc(inq_var) 727 * try redefining an existing variable, check error 728 * try with bad datatype, check error 729 * try with bad number of dimensions, check error 730 * try in data mode, check error 731 * check that returned id is one more than previous id 732 * try with bad dimension ids, check error 733 */ 734int 735TestFunc(def_var)(VarArgs) 736{ 737 int ncid; 738 int varid; 739 int err, nok=0; /* status */ 740 int i; 741 int ndims; 742 int natts; 743 char name[NC_MAX_NAME]; 744 int dimids[MAX_RANK]; 745 nc_type datatype; 746 747 /* BAD_ID test */ 748 err = APIFunc(def_var)(BAD_ID, "abc", NC_SHORT, 0, NULL, &varid); 749 IF (err != NC_EBADID) 750 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 751 ELSE_NOK 752 753 /* scalar tests */ 754 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 755 IF (err != NC_NOERR) { 756 error("create: %s", APIFunc(strerror)(err)); 757 return nok; 758 } 759 err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 0, NULL, &varid); 760 IF (err != NC_NOERR) 761 error("def_var: %s", APIFunc(strerror)(err)); 762 ELSE_NOK 763 err = APIFunc(inq_var)(ncid, varid, name, &datatype, &ndims, dimids, &natts); 764 IF (err != NC_NOERR) 765 error("inq_var: %s", APIFunc(strerror)(err)); 766 IF (strcmp(name, "abc") != 0) 767 error("Unexpected name: %s", name); 768 IF (datatype != NC_SHORT) 769 error("Unexpected datatype"); 770 IF (ndims != 0) 771 error("Unexpected rank"); 772 err = APIFunc(def_var)(ncid, BAD_NAME, NC_SHORT, 0, NULL, &varid); 773 IF (err != NC_EBADNAME) 774 error("expecting NC_EBADNAME but got %s", nc_err_code_name(err)); 775 ELSE_NOK 776 err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 0, NULL, &varid); 777 IF (err != NC_ENAMEINUSE) 778 error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); 779 ELSE_NOK 780 err = APIFunc(def_var)(ncid, "ABC", BAD_TYPE, -1, dimids, &varid); 781 IF (err != NC_EBADTYPE) 782 error("expecting NC_EBADTYPE but got %s", nc_err_code_name(err)); 783 ELSE_NOK 784 err = APIFunc(def_var)(ncid, "ABC", NC_SHORT, -1, dimids, &varid); 785 IF (err != NC_EINVAL) 786 error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); 787 ELSE_NOK 788 err = APIFunc(enddef)(ncid); 789 IF (err != NC_NOERR) 790 error("enddef: %s", APIFunc(strerror)(err)); 791 err = APIFunc(def_var)(ncid, "ABC", NC_SHORT, 0, dimids, &varid); 792 IF (err != NC_ENOTINDEFINE) 793 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 794 ELSE_NOK 795 err = APIFunc(close)(ncid); 796 IF (err != NC_NOERR) 797 error("close: %s", APIFunc(strerror)(err)); 798 err = FileDelete(scratch, info); 799 IF (err != NC_NOERR) 800 error("remove of %s failed", scratch); 801 802 /* general tests using global vars */ 803 err = FileCreate(scratch, NC_CLOBBER, &ncid); 804 IF (err != NC_NOERR) { 805 error("create: %s", APIFunc(strerror)(err)); 806 return nok; 807 } 808 def_dims(ncid); 809 for (i = 0; i < numVars; i++) { 810 err = APIFunc(def_var)(ncid, var_name[i], var_type[i], var_rank[i], 811 var_dimid[i], &varid); 812 IF (err != NC_NOERR) 813 error("def_var: %s", APIFunc(strerror)(err)); 814 ELSE_NOK 815 IF (varid != i) 816 error("Unexpected varid"); 817 ELSE_NOK 818 } 819 820 /* try bad dim ids */ 821 dimids[0] = BAD_DIMID; 822 err = APIFunc(def_var)(ncid, "abc", NC_SHORT, 1, dimids, &varid); 823 IF (err != NC_EBADDIM) 824 error("expecting NC_EBADDIM but got %s", nc_err_code_name(err)); 825 ELSE_NOK 826 err = APIFunc(close)(ncid); 827 IF (err != NC_NOERR) 828 error("close: %s", APIFunc(strerror)(err)); 829 830 err = FileDelete(scratch, info); 831 IF (err != NC_NOERR) 832 error("remove of %s failed", scratch); 833 return nok; 834} 835 836 837/* 838 * Test PutVar1 839 */ 840int 841TestFunc(put_var1)(VarArgs) 842{ 843 int i, err, ncid, nok=0; 844 IntType j, index[MAX_RANK]; 845 double value[1]; 846 double buf[1]; /* (void *) buffer */ 847 ifdef(`PNETCDF', `MPI_Datatype datatype;') 848 849 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 850 IF (err != NC_NOERR) { 851 error("create: %s", APIFunc(strerror)(err)); 852 return nok; 853 } 854 855 def_dims(ncid); 856 Def_Vars(ncid, numVars); 857 858 err = APIFunc(enddef)(ncid); 859 IF (err != NC_NOERR) 860 error("enddef: %s", APIFunc(strerror)(err)); 861 862 /* check if can detect a bad file ID */ 863 err = PutVar1(BAD_ID, 0, NULL, NULL, 1, MPI_DATATYPE_NULL); 864 IF (err != NC_EBADID) 865 EXPECT_ERR(NC_EBADID, err) 866 ELSE_NOK 867 868 /* check if can detect a bad variable ID */ 869 err = PutVar1(ncid, BAD_VARID, NULL, NULL, 1, MPI_DATATYPE_NULL); 870 IF (err != NC_ENOTVAR) 871 EXPECT_ERR(NC_ENOTVAR, err) 872 ELSE_NOK 873 874 for (i = 0; i < numVars; i++) { 875 assert(var_rank[i] <= MAX_RANK); 876 assert(var_nels[i] <= MAX_NELS); 877 878 value[0] = 5; /* reset to a value within bounds */ 879 880 ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') 881 882ifdef(`PNETCDF',`dnl 883 /* for non-scalar variables, argument start cannot be NULL */ 884 err = PutVar1(ncid, i, NULL, value, 1, datatype); 885 if (var_rank[i] == 0) { /* scalar variable */ 886 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 887 } 888 else IF (err != NC_EINVALCOORDS) { 889 EXPECT_ERR(NC_EINVALCOORDS, err) 890 } 891 ELSE_NOK 892')dnl 893 894 /* test NC_EINVALCOORDS */ 895 for (j = 0; j < var_rank[i]; j++) index[j] = 0; 896 897 for (j = 0; j < var_rank[i]; j++) { 898 if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ 899 index[j] = var_shape[i][j]; /* out of boundary check */ 900 err = PutVar1(ncid, i, index, value, 1, datatype); 901 IF (err != NC_EINVALCOORDS) 902 EXPECT_ERR(NC_EINVALCOORDS, err) 903 ELSE_NOK 904 index[j] = 0; 905 } 906 907 for (j = 0; j < var_nels[i]; j++) { 908 err = toMixedBase(j, var_rank[i], var_shape[i], index); 909 IF (err != 0) error("error in toMixedBase"); 910 value[0] = hash(var_type[i], var_rank[i], index); 911 if (inRange(value[0], var_type[i])) { 912 err = dbl2nc(value[0], var_type[i], buf); 913 IF (err != NC_NOERR) 914 error("error in dbl2nc var:%s type:%s", 915 var_name[i],s_nc_type(var_type[i])); 916 err = PutVar1(ncid, i, index, buf, 1, datatype); 917 IF (err != NC_NOERR) 918 EXPECT_ERR(NC_NOERR, err) 919 ELSE_NOK 920 } 921 } 922 } 923 924 Check_Vars(ncid, numVars); 925 err = APIFunc(close)(ncid); 926 IF (err != NC_NOERR) 927 error("close: %s", APIFunc(strerror)(err)); 928 929 err = FileDelete(scratch, info); 930 IF (err != NC_NOERR) 931 error("remove of %s failed", scratch); 932 return nok; 933} 934 935 936/* 937 * Test PutVara 938 * Choose a random point dividing each dim into 2 parts 939 * Put 2^rank (nslabs) slabs so defined 940 * Redefine buffer for each put. 941 * At end check all variables using Check_Vars 942 */ 943int 944TestFunc(put_vara)(VarArgs) 945{ 946 int d, i, k, err, nslabs, ncid, nok=0; 947 IntType j, nels; 948 IntType start[MAX_RANK]; 949 IntType edge[MAX_RANK]; 950 IntType index[MAX_RANK]; 951 IntType mid[MAX_RANK]; 952 double buf[MAX_NELS]; /* (void *) buffer */ 953 char *p; /* (void *) pointer */ 954 double value; 955 ifdef(`PNETCDF', `MPI_Datatype datatype;') 956 957 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 958 IF (err != NC_NOERR) { 959 error("create: %s", APIFunc(strerror)(err)); 960 return nok; 961 } 962 963 def_dims(ncid); 964 Def_Vars(ncid, numVars); 965 966 err = APIFunc(enddef)(ncid); 967 IF (err != NC_NOERR) 968 error("enddef: %s", APIFunc(strerror)(err)); 969 970 /* check if can detect a bad file ID */ 971 err = PutVara(BAD_ID, 0, start, edge, buf, 1, MPI_DATATYPE_NULL); 972 IF (err != NC_EBADID) 973 EXPECT_ERR(NC_EBADID, err) 974 ELSE_NOK 975 976 /* check if can detect a bad variable ID */ 977 err = PutVara(ncid, BAD_VARID, start, edge, buf, 1, MPI_DATATYPE_NULL); 978 IF (err != NC_ENOTVAR) 979 EXPECT_ERR(NC_ENOTVAR, err) 980 ELSE_NOK 981 982 for (i = 0; i < numVars; i++) { 983 assert(var_rank[i] <= MAX_RANK); 984 assert(var_nels[i] <= MAX_NELS); 985 986 buf[0] = 5; /* reset to a value within bounds */ 987 988 /* check if can detect a bad file ID */ 989 err = PutVara(BAD_ID, i, start, edge, buf, 1, MPI_DATATYPE_NULL); 990 IF (err != NC_EBADID) 991 EXPECT_ERR(NC_EBADID, err) 992 ELSE_NOK 993 994 ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') 995 996 for (j = 0; j < var_rank[i]; j++) { 997 start[j] = 0; 998 edge[j] = 1; 999 } 1000 1001ifdef(`PNETCDF',`dnl 1002 /* for non-scalar variables, argument start cannot be NULL */ 1003 err = PutVara(ncid, i, NULL, NULL, buf, 1, datatype); 1004 if (var_rank[i] == 0) { /* scalar variable */ 1005 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1006 } 1007 else IF (err != NC_EINVALCOORDS) { 1008 EXPECT_ERR(NC_EINVALCOORDS, err) 1009 } 1010 ELSE_NOK 1011 1012 /* for non-scalar variables, argument count cannot be NULL */ 1013 err = PutVara(ncid, i, start, NULL, buf, 1, datatype); 1014 if (var_rank[i] == 0) { 1015 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1016 } 1017 else IF (err != NC_EEDGE) { 1018 EXPECT_ERR(NC_EEDGE, err) 1019 } 1020 ELSE_NOK 1021')dnl 1022 1023 /* first test when edge[*] > 0 */ 1024 for (j = 0; j < var_rank[i]; j++) { 1025 if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ 1026 start[j] = var_shape[i][j]; 1027 err = PutVara(ncid, i, start, edge, buf, 1, datatype); 1028 IF (err != NC_EINVALCOORDS) 1029 EXPECT_ERR(NC_EINVALCOORDS, err) 1030 ELSE_NOK 1031 start[j] = 0; 1032 edge[j] = var_shape[i][j] + 1; 1033 err = PutVara(ncid, i, start, edge, buf, 1, datatype); 1034 IF (err != NC_EEDGE) 1035 EXPECT_ERR(NC_EEDG, err) 1036 ELSE_NOK 1037 edge[j] = 1; 1038 } 1039 /* Check correct error returned when nothing to put, when edge[*]==0 */ 1040 for (j = 0; j < var_rank[i]; j++) edge[j] = 0; 1041 1042 for (j = 0; j < var_rank[i]; j++) { 1043 if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ 1044 start[j] = var_shape[i][j]; 1045 err = PutVara(ncid, i, start, edge, buf, 0, datatype); 1046 IF (err != NC_NOERR) /* allowed when edge[j]==0 */ 1047 EXPECT_ERR(NC_NOERR, err) 1048 ELSE_NOK 1049 start[j] = var_shape[i][j]+1; /* out of boundary check */ 1050 err = PutVara(ncid, i, start, edge, buf, 1, datatype); 1051 IF (err != NC_EINVALCOORDS) 1052 EXPECT_ERR(NC_EINVALCOORDS, err) 1053 ELSE_NOK 1054 start[j] = 0; 1055 } 1056 for (j = 0; j < var_rank[i]; j++) edge[j] = 1; 1057 1058 /* Choose a random point dividing each dim into 2 parts */ 1059 /* put 2^rank (nslabs) slabs so defined */ 1060 nslabs = 1; 1061 for (j = 0; j < var_rank[i]; j++) { 1062 mid[j] = roll( var_shape[i][j] ); 1063 nslabs *= 2; 1064 } 1065 /* bits of k determine whether to put lower or upper part of dim */ 1066 for (k = 0; k < nslabs; k++) { 1067 nels = 1; 1068 for (j = 0; j < var_rank[i]; j++) { 1069 if ((k >> j) & 1) { 1070 start[j] = 0; 1071 edge[j] = mid[j]; 1072 }else{ 1073 start[j] = mid[j]; 1074 edge[j] = var_shape[i][j] - mid[j]; 1075 } 1076 nels *= edge[j]; 1077 } 1078 p = (char *) buf; 1079 for (j = 0; j < nels; j++) { 1080 err = toMixedBase(j, var_rank[i], edge, index); 1081 IF (err != 0) error("error in toMixedBase"); 1082 for (d = 0; d < var_rank[i]; d++) 1083 index[d] += start[d]; 1084 value = hash(var_type[i], var_rank[i], index); 1085 if (!inRange(value, var_type[i])) 1086 value = 0; 1087 err = dbl2nc(value, var_type[i], p); 1088 IF (err != NC_NOERR) 1089 error("error in dbl2nc"); 1090 p += nctypelen(var_type[i]); 1091 } 1092 err = PutVara(ncid, i, start, edge, buf, nels, datatype); 1093 IF (err != NC_NOERR) 1094 error("%s", APIFunc(strerror)(err)); 1095 ELSE_NOK 1096 } 1097 } 1098 1099 Check_Vars(ncid, numVars); 1100 err = APIFunc(close)(ncid); 1101 IF (err != NC_NOERR) 1102 error("close: %s", APIFunc(strerror)(err)); 1103 1104 err = FileDelete(scratch, info); 1105 IF (err != NC_NOERR) 1106 error("remove of %s failed", scratch); 1107 return nok; 1108} 1109 1110 1111/* 1112 * Test PutVars 1113 * Choose a random point dividing each dim into 2 parts 1114 * Put 2^rank (nslabs) slabs so defined 1115 * Choose random stride from 1 to edge 1116 * Redefine buffer for each put. 1117 * At end check all variables using Check_Vars 1118 */ 1119int 1120TestFunc(put_vars)(VarArgs) 1121{ 1122 int ncid, d, i, k, err, nslabs, nok=0; 1123 PTRDType nstarts; /* number of different starts */ 1124 IntType j, m, nels; 1125 IntType start[MAX_RANK]; 1126 IntType edge[MAX_RANK]; 1127 IntType index[MAX_RANK]; 1128 IntType index2[MAX_RANK]; 1129 IntType mid[MAX_RANK]; 1130 IntType count[MAX_RANK]; 1131 IntType sstride[MAX_RANK]; 1132 PTRDType stride[MAX_RANK]; 1133 double buf[MAX_NELS]; /* (void *) buffer */ 1134 char *p; /* (void *) pointer */ 1135 double value; 1136 ifdef(`PNETCDF', `MPI_Datatype datatype;') 1137 1138 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1139 IF (err != NC_NOERR) { 1140 error("create: %s", APIFunc(strerror)(err)); 1141 return nok; 1142 } 1143 1144 def_dims(ncid); 1145 Def_Vars(ncid, numVars); 1146 1147 err = APIFunc(enddef)(ncid); 1148 IF (err != NC_NOERR) 1149 error("enddef: %s", APIFunc(strerror)(err)); 1150 1151 /* check if can detect a bad file ID */ 1152 err = PutVars(BAD_ID, 0, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1153 IF (err != NC_EBADID) 1154 EXPECT_ERR(NC_EBADID, err) 1155 ELSE_NOK 1156 1157 /* check if can detect a bad variable ID */ 1158 err = PutVars(ncid, BAD_VARID, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1159 IF (err != NC_ENOTVAR) 1160 EXPECT_ERR(NC_ENOTVAR, err) 1161 ELSE_NOK 1162 1163 for (i = 0; i < numVars; i++) { 1164 assert(var_rank[i] <= MAX_RANK); 1165 assert(var_nels[i] <= MAX_NELS); 1166 1167 buf[0] = 5; /* reset to a value within bounds */ 1168 1169 /* check if can detect a bad file ID */ 1170 err = PutVars(BAD_ID, i, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); 1171 IF (err != NC_EBADID) 1172 EXPECT_ERR(NC_EBADID, err) 1173 ELSE_NOK 1174 1175 ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') 1176 1177 for (j = 0; j < var_rank[i]; j++) { 1178 start[j] = 0; 1179 edge[j] = 1; 1180 stride[j] = 1; 1181 } 1182 1183ifdef(`PNETCDF',`dnl 1184 /* for non-scalar variables, argument start cannot be NULL */ 1185 err = PutVars(ncid, i, NULL, NULL, NULL, buf, 1, datatype); 1186 if (var_rank[i] == 0) { /* scalar variable */ 1187 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1188 } 1189 else IF (err != NC_EINVALCOORDS) { 1190 EXPECT_ERR(NC_EINVALCOORDS, err) 1191 } 1192 ELSE_NOK 1193 1194 /* for non-scalar variables, argument count cannot be NULL */ 1195 err = PutVars(ncid, i, start, NULL, NULL, buf, 1, datatype); 1196 if (var_rank[i] == 0) { 1197 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1198 } 1199 else IF (err != NC_EEDGE) { 1200 EXPECT_ERR(NC_EEDGE, err) 1201 } 1202 ELSE_NOK 1203')dnl 1204 1205 /* first test when edge[*] > 0 */ 1206 for (j = 0; j < var_rank[i]; j++) { 1207 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1208 start[j] = var_shape[i][j]; 1209 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1210 IF (err != NC_EINVALCOORDS) 1211 EXPECT_ERR(NC_EINVALCOORDS, err) 1212 ELSE_NOK 1213 start[j] = 0; 1214 edge[j] = var_shape[i][j] + 1; /* edge error check */ 1215 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1216 IF (err != NC_EEDGE) 1217 EXPECT_ERR(NC_EEDG, err) 1218 ELSE_NOK 1219 edge[j] = 1; 1220 stride[j] = 0; /* strided edge error check */ 1221 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1222 IF (err != NC_ESTRIDE) 1223 EXPECT_ERR(NC_ESTRIDE, err) 1224 ELSE_NOK 1225 stride[j] = 1; 1226 } 1227 /* Check correct error returned even when nothing to put */ 1228 for (j = 0; j < var_rank[i]; j++) edge[j] = 0; 1229 1230 for (j = 0; j < var_rank[i]; j++) { 1231 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1232 start[j] = var_shape[i][j]; 1233 err = PutVars(ncid, i, start, edge, stride, buf, 0, datatype); 1234 IF (err != NC_NOERR) /* allowed when edge[j]==0 */ 1235 EXPECT_ERR(NC_NOERR, err) 1236 ELSE_NOK 1237 start[j] = var_shape[i][j]+1; /* out of boundary check */ 1238 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1239 IF (err != NC_EINVALCOORDS) 1240 EXPECT_ERR(NC_EINVALCOORDS, err) 1241 ELSE_NOK 1242 start[j] = 0; 1243 } 1244 for (j = 0; j < var_rank[i]; j++) edge[j] = 1; 1245 1246 /* Choose a random point dividing each dim into 2 parts */ 1247 /* put 2^rank (nslabs) slabs so defined */ 1248 nslabs = 1; 1249 for (j = 0; j < var_rank[i]; j++) { 1250 mid[j] = roll( var_shape[i][j] ); 1251 nslabs *= 2; 1252 } 1253 /* bits of k determine whether to put lower or upper part of dim */ 1254 /* choose random stride from 1 to edge */ 1255 for (k = 0; k < nslabs; k++) { 1256 nstarts = 1; 1257 for (j = 0; j < var_rank[i]; j++) { 1258 if ((k >> j) & 1) { 1259 start[j] = 0; 1260 edge[j] = mid[j]; 1261 }else{ 1262 start[j] = mid[j]; 1263 edge[j] = var_shape[i][j] - mid[j]; 1264 } 1265 sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; 1266 stride[j] = (PTRDType)sstride[j]; 1267 nstarts *= stride[j]; 1268 } 1269 for (m = 0; m < nstarts; m++) { 1270 err = toMixedBase(m, var_rank[i], sstride, index); 1271 IF (err != 0) error("error in toMixedBase"); 1272 nels = 1; 1273 for (j = 0; j < var_rank[i]; j++) { 1274 count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; 1275 nels *= count[j]; 1276 index[j] += start[j]; 1277 } 1278 /* Random choice of forward or backward */ 1279/* TODO 1280 if ( roll(2) ) { 1281 for (j = 0; j < var_rank[i]; j++) { 1282 index[j] += (count[j] - 1) * (IntType)stride[j]; 1283 stride[j] = -stride[j]; 1284 } 1285 } 1286 */ 1287 p = (char *) buf; 1288 for (j = 0; j < nels; j++) { 1289 err = toMixedBase(j, var_rank[i], count, index2); 1290 IF (err != 0) error("error in toMixedBase"); 1291 for (d = 0; d < var_rank[i]; d++) 1292 index2[d] = index[d] + index2[d] * (IntType)stride[d]; 1293 value = hash(var_type[i], var_rank[i], index2); 1294 if (!inRange(value, var_type[i])) 1295 value = 0; 1296 err = dbl2nc(value, var_type[i], p); 1297 IF (err != NC_NOERR) 1298 error("error in dbl2nc"); 1299 p += nctypelen(var_type[i]); 1300 } 1301 err = PutVars(ncid, i, index, count, stride, buf, nels, datatype); 1302 IF (err != NC_NOERR) 1303 EXPECT_ERR(NC_NOERR, err) 1304 ELSE_NOK 1305 } 1306 } 1307 } 1308 1309 Check_Vars(ncid, numVars); 1310 err = APIFunc(close)(ncid); 1311 IF (err != NC_NOERR) 1312 error("close: %s", APIFunc(strerror)(err)); 1313 1314 err = FileDelete(scratch, info); 1315 IF (err != NC_NOERR) 1316 error("remove of %s failed", scratch); 1317 return nok; 1318} 1319 1320 1321/* 1322 * Test PutVarm 1323 * Choose a random point dividing each dim into 2 parts 1324 * Put 2^rank (nslabs) slabs so defined 1325 * Choose random stride from 1 to edge 1326 * Buffer is bit image of whole external variable. 1327 * So all puts for a variable put different elements of buffer 1328 * At end check all variables using Check_Vars 1329 */ 1330int 1331TestFunc(put_varm)(VarArgs) 1332{ 1333 int ncid, nok=0; 1334 int i; 1335 int k; 1336 int err; 1337 int nslabs; 1338 IntType j, m; 1339 PTRDType nstarts; /* number of different starts */ 1340 IntType start[MAX_RANK]; 1341 IntType edge[MAX_RANK]; 1342 IntType index[MAX_RANK]; 1343 IntType mid[MAX_RANK]; 1344 IntType count[MAX_RANK]; 1345 IntType sstride[MAX_RANK]; 1346 PTRDType stride[MAX_RANK]; 1347 PTRDType imap[MAX_RANK]; 1348 PTRDType imap2[MAX_RANK]; 1349 ifdef(`PNETCDF', `IntType bufcount;') 1350 double buf[MAX_NELS]; /* (void *) buffer */ 1351 char *p; /* (void *) pointer */ 1352 double value; 1353 ifdef(`PNETCDF', `MPI_Datatype datatype;') 1354 1355 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1356 IF (err != NC_NOERR) { 1357 error("create: %s", APIFunc(strerror)(err)); 1358 return nok; 1359 } 1360 1361 def_dims(ncid); 1362 Def_Vars(ncid, numVars); 1363 1364 err = APIFunc(enddef)(ncid); 1365 IF (err != NC_NOERR) 1366 error("enddef: %s", APIFunc(strerror)(err)); 1367 1368 /* check if can detect a bad file ID */ 1369 err = PutVarm(NC_EBADID, 0, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1370 IF (err != NC_EBADID) 1371 EXPECT_ERR(NC_EBADID, err) 1372 ELSE_NOK 1373 1374 /* check if can detect a bad variable ID */ 1375 err = PutVarm(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1376 IF (err != NC_ENOTVAR) 1377 EXPECT_ERR(NC_ENOTVAR, err) 1378 ELSE_NOK 1379 1380 for (i = 0; i < numVars; i++) { 1381 assert(var_rank[i] <= MAX_RANK); 1382 assert(var_nels[i] <= MAX_NELS); 1383 1384 buf[0] = 5; /* reset to a value within bounds */ 1385 1386 /* check if can detect a bad file ID */ 1387 err = PutVarm(BAD_ID, i, NULL, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); 1388 IF (err != NC_EBADID) 1389 EXPECT_ERR(NC_EBADID, err) 1390 ELSE_NOK 1391 1392 ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') 1393 1394 for (j = 0; j < var_rank[i]; j++) { 1395 start[j] = 0; 1396 edge[j] = 1; 1397 stride[j] = 1; 1398 imap[j] = 1; 1399 } 1400 1401ifdef(`PNETCDF',`dnl 1402 /* for non-scalar variables, argument start cannot be NULL */ 1403 err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); 1404 if (var_rank[i] == 0) { /* scalar variable */ 1405 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1406 } 1407 else IF (err != NC_EINVALCOORDS) { 1408 EXPECT_ERR(NC_EINVALCOORDS, err) 1409 } 1410 ELSE_NOK 1411 1412 /* for non-scalar variables, argument count cannot be NULL */ 1413 err = PutVarm(ncid, i, start, NULL, NULL, NULL, buf, 1, datatype); 1414 if (var_rank[i] == 0) { 1415 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1416 } 1417 else IF (err != NC_EEDGE) { 1418 EXPECT_ERR(NC_EEDGE, err) 1419 } 1420 ELSE_NOK 1421')dnl 1422 1423 /* first test when edge[*] > 0 */ 1424 for (j = 0; j < var_rank[i]; j++) { 1425 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1426 start[j] = var_shape[i][j]; 1427 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1428 IF (err != NC_EINVALCOORDS) 1429 EXPECT_ERR(NC_EINVALCOORDS, err) 1430 ELSE_NOK 1431 start[j] = 0; 1432 edge[j] = var_shape[i][j] + 1; /* edge error check */ 1433 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1434 IF (err != NC_EEDGE) 1435 EXPECT_ERR(NC_EEDG, err) 1436 ELSE_NOK 1437 edge[j] = 1; 1438 stride[j] = 0; /* strided edge error check */ 1439 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1440 IF (err != NC_ESTRIDE) 1441 EXPECT_ERR(NC_ESTRIDE, err) 1442 ELSE_NOK 1443 stride[j] = 1; 1444 } 1445 /* Check correct error returned even when nothing to put */ 1446 for (j = 0; j < var_rank[i]; j++) edge[j] = 0; 1447 1448 for (j = 0; j < var_rank[i]; j++) { 1449 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1450 start[j] = var_shape[i][j]; 1451 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype); 1452 IF (err != NC_NOERR) /* allowed when edge[j]==0 */ 1453 EXPECT_ERR(NC_NOERR, err) 1454 ELSE_NOK 1455 start[j] = var_shape[i][j]+1; /* out of boundary check */ 1456 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1457 IF (err != NC_EINVALCOORDS) 1458 EXPECT_ERR(NC_EINVALCOORDS, err) 1459 ELSE_NOK 1460 start[j] = 0; 1461 } 1462 for (j = 0; j < var_rank[i]; j++) edge[j] = 1; 1463 1464 if (var_rank[i] > 0) { 1465 int jj = var_rank[i] - 1; 1466 imap[jj] = nctypelen(var_type[i]); /* netCDF considers imap in bytes */ 1467 imap[jj] = 1; /* PnetCDF considers imap in elements */ 1468 for (; jj > 0; jj--) 1469 imap[jj-1] = imap[jj] * (PTRDType)var_shape[i][jj]; 1470 } 1471 p = (char *) buf; 1472 for (j = 0; j < var_nels[i]; j++) { 1473 err = toMixedBase(j, var_rank[i], var_shape[i], index); 1474 IF (err != 0) error("error in toMixedBase"); 1475 value = hash(var_type[i], var_rank[i], index); 1476 if (!inRange(value, var_type[i])) 1477 value = 0; 1478 err = dbl2nc(value, var_type[i], p); 1479 IF (err != NC_NOERR) 1480 error("error in dbl2nc"); 1481 p += nctypelen(var_type[i]); 1482 } 1483 1484 /* Choose a random point dividing each dim into 2 parts */ 1485 /* put 2^rank (nslabs) slabs so defined */ 1486 nslabs = 1; 1487 for (j = 0; j < var_rank[i]; j++) { 1488 mid[j] = roll( var_shape[i][j] ); 1489 nslabs *= 2; 1490 } 1491 /* bits of k determine whether to put lower or upper part of dim */ 1492 /* choose random stride from 1 to edge */ 1493 for (k = 0; k < nslabs; k++) { 1494 nstarts = 1; 1495 for (j = 0; j < var_rank[i]; j++) { 1496 if ((k >> j) & 1) { 1497 start[j] = 0; 1498 edge[j] = mid[j]; 1499 }else{ 1500 start[j] = mid[j]; 1501 edge[j] = var_shape[i][j] - mid[j]; 1502 } 1503 sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; 1504 stride[j] = (PTRDType)sstride[j]; 1505 imap2[j] = imap[j] * (PTRDType)sstride[j]; 1506 nstarts *= stride[j]; 1507 } 1508 for (m = 0; m < nstarts; m++) { 1509 if (var_rank[i] == 0 && i%2 == 0) { 1510 err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); 1511 } else { 1512 err = toMixedBase(m, var_rank[i], sstride, index); 1513 IF (err != 0) error("error in toMixedBase"); 1514 for (j = 0; j < var_rank[i]; j++) { 1515 count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; 1516 index[j] += start[j]; 1517 } 1518 /* Random choice of forward or backward */ 1519/* TODO 1520 if ( roll(2) ) { 1521 for (j = 0; j < var_rank[i]; j++) { 1522 index[j] += (count[j] - 1) * (IntType)stride[j]; 1523 stride[j] = -stride[j]; 1524 } 1525 } 1526 */ 1527 j = fromMixedBase(var_rank[i], index, var_shape[i]); 1528 p = (char *) buf + (int)j * nctypelen(var_type[i]); 1529 ifdef(`PNETCDF', `for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= count[j];') 1530 err = PutVarm(ncid, i, index, count, stride, imap2, p, bufcount, datatype); 1531 } 1532 IF (err != NC_NOERR) 1533 EXPECT_ERR(NC_NOERR, err) 1534 ELSE_NOK 1535 } 1536 } 1537 } 1538 1539 Check_Vars(ncid, numVars); 1540 err = APIFunc(close)(ncid); 1541 IF (err != NC_NOERR) 1542 error("close: %s", APIFunc(strerror)(err)); 1543 1544 err = FileDelete(scratch, info); 1545 IF (err != NC_NOERR) 1546 error("remove of %s failed", scratch); 1547 return nok; 1548} 1549 1550 1551/* 1552 * Test APIFunc(rename_var) 1553 * try with bad netCDF handle, check error 1554 * try with bad variable handle, check error 1555 * try renaming to existing variable name, check error 1556 * check that proper rename worked with APIFunc(inq_varid) 1557 * try in data mode, check error 1558 */ 1559int 1560TestFunc(rename_var)(VarArgs) 1561{ 1562 int ncid; 1563 int varid; 1564 int err, nok=0; 1565 int i; 1566 char name[NC_MAX_NAME]; 1567 1568 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1569 IF (err != NC_NOERR) { 1570 error("create: %s", APIFunc(strerror)(err)); 1571 return nok; 1572 } 1573 err = APIFunc(rename_var)(ncid, BAD_VARID, "newName"); 1574 IF (err != NC_ENOTVAR) 1575 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1576 ELSE_NOK 1577 def_dims(ncid); 1578 Def_Vars(ncid, numVars); 1579 1580 /* Prefix "new_" to each name */ 1581 for (i = 0; i < numVars; i++) { 1582 err = APIFunc(rename_var)(BAD_ID, i, "newName"); 1583 IF (err != NC_EBADID) 1584 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1585 ELSE_NOK 1586 err = APIFunc(rename_var)(ncid, i, var_name[numVars-1]); 1587 IF (err != NC_ENAMEINUSE) 1588 error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); 1589 ELSE_NOK 1590 strcpy(name, "new_"); 1591 strcat(name, var_name[i]); 1592 err = APIFunc(rename_var)(ncid, i, name); 1593 IF (err != NC_NOERR) 1594 error("rename_var: %s", APIFunc(strerror)(err)); 1595 ELSE_NOK 1596 err = APIFunc(inq_varid)(ncid, name, &varid); 1597 IF (err != NC_NOERR) 1598 error("inq_varid: %s", APIFunc(strerror)(err)); 1599 IF (varid != i) 1600 error("Unexpected varid"); 1601 } 1602 1603 /* Change to data mode */ 1604 /* Try making names even longer. Then restore original names */ 1605 err = APIFunc(enddef)(ncid); 1606 IF (err != NC_NOERR) 1607 error("enddef: %s", APIFunc(strerror)(err)); 1608 for (i = 0; i < numVars; i++) { 1609 strcpy(name, "even_longer_"); 1610 strcat(name, var_name[i]); 1611 err = APIFunc(rename_var)(ncid, i, name); 1612 IF (err != NC_ENOTINDEFINE) 1613 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 1614 ELSE_NOK 1615 err = APIFunc(rename_var)(ncid, i, var_name[i]); 1616 IF (err != NC_NOERR) 1617 error("rename_var: %s", APIFunc(strerror)(err)); 1618 ELSE_NOK 1619 err = APIFunc(inq_varid)(ncid, var_name[i], &varid); 1620 IF (err != NC_NOERR) 1621 error("inq_varid: %s", APIFunc(strerror)(err)); 1622 IF (varid != i) 1623 error("Unexpected varid"); 1624 } 1625 1626 Put_Vars(ncid, numVars); 1627 Check_Vars(ncid, numVars); 1628 1629 err = APIFunc(close)(ncid); 1630 IF (err != NC_NOERR) 1631 error("close: %s", APIFunc(strerror)(err)); 1632 1633 err = FileDelete(scratch, info); 1634 IF (err != NC_NOERR) 1635 error("remove of %s failed", scratch); 1636 return nok; 1637} 1638 1639 1640int 1641TestFunc(put_att)(AttVarArgs) 1642{ 1643 int ncid, nok=0; 1644 int varid; 1645 int i; 1646 int j; 1647 IntType k, ndx[1]; 1648 int err; 1649 double buf[MAX_NELS]; /* (void *) buffer */ 1650 char *p; /* (void *) pointer */ 1651 char *name; /* of att */ 1652 nc_type datatype; /* of att */ 1653 IntType length; /* of att */ 1654 double value; 1655 1656 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1657 IF (err != NC_NOERR) { 1658 error("create: %s", APIFunc(strerror)(err)); 1659 return nok; 1660 } 1661 def_dims(ncid); 1662 Def_Vars(ncid, numVars); 1663 1664 for (i = -1; i < numVars; i++) { 1665 varid = VARID(i); 1666 for (j = 0; j < NATTS(i); j++) { 1667 name = ATT_NAME(i,j); 1668 datatype = ATT_TYPE(i,j); 1669 length = ATT_LEN(i,j); 1670 err = APIFunc(put_att)(BAD_ID, varid, name, datatype, length, buf); 1671 IF (err != NC_EBADID) 1672 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1673 ELSE_NOK 1674 err = APIFunc(put_att)(ncid, varid, BAD_NAME, datatype, length, buf); 1675 IF (err != NC_EBADNAME) 1676 error("expecting NC_EBADNAME but got %s", nc_err_code_name(err)); 1677 ELSE_NOK 1678 err = APIFunc(put_att)(ncid, BAD_VARID, name, datatype, length, buf); 1679 IF (err != NC_ENOTVAR) 1680 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1681 ELSE_NOK 1682 err = APIFunc(put_att)(ncid, varid, name, BAD_TYPE, length, buf); 1683 IF (err != NC_EBADTYPE) 1684 error("expecting NC_EBADTYPE but got %s", nc_err_code_name(err)); 1685 ELSE_NOK 1686 p = (char *) buf; 1687 for (k=0; k<length; k++) { 1688 ndx[0] = k; 1689 value = hash(datatype, -1, ndx); 1690 if (!inRange(value, datatype)) 1691 value = 0; 1692 err = dbl2nc(value, datatype, p); 1693 IF (err != NC_NOERR) 1694 error("error in dbl2nc"); 1695 p += nctypelen(datatype); 1696 } 1697 err = APIFunc(put_att)(ncid, varid, name, datatype, length, buf); 1698 IF (err != NC_NOERR) 1699 error("%s", APIFunc(strerror)(err)); 1700 ELSE_NOK 1701 } 1702 } 1703 1704 Check_Atts(ncid, numGatts, numVars); 1705 err = APIFunc(close)(ncid); 1706 IF (err != NC_NOERR) 1707 error("close: %s", APIFunc(strerror)(err)); 1708 1709 err = FileDelete(scratch, info); 1710 IF (err != NC_NOERR) 1711 error("remove of %s failed", scratch); 1712 return nok; 1713} 1714 1715 1716/* 1717 * Test APIFunc(copy_att) 1718 * try with bad source or target netCDF handles, check error 1719 * try with bad source or target variable handle, check error 1720 * try with nonexisting attribute, check error 1721 * check that NC_GLOBAL variable for source or target works 1722 * check that new attribute put works with target in define mode 1723 * check that old attribute put works with target in data mode 1724 * check that changing type and length of an attribute work OK 1725 * try with same ncid for source and target, different variables 1726 * try with same ncid for source and target, same variable 1727 */ 1728int 1729TestFunc(copy_att)(AttVarArgs) 1730{ 1731 int ncid_in; 1732 int ncid_out; 1733 int varid; 1734 int err, nok=0; 1735 int i; 1736 int j=0; 1737 char *name; /* of att */ 1738 nc_type datatype; /* of att */ 1739 IntType length; /* of att */ 1740 char value; 1741 1742 err = FileOpen(testfile, NC_NOWRITE, &ncid_in); 1743 IF (err != NC_NOERR) 1744 error("open: %s", APIFunc(strerror)(err)); 1745 err = FileCreate(scratch, NC_NOCLOBBER, &ncid_out); 1746 IF (err != NC_NOERR) { 1747 error("create: %s", APIFunc(strerror)(err)); 1748 return nok; 1749 } 1750 def_dims(ncid_out); 1751 Def_Vars(ncid_out, numVars); 1752 1753 for (i = -1; i < numVars; i++) { 1754 varid = VARID(i); 1755 for (j = 0; j < NATTS(i); j++) { 1756 name = ATT_NAME(i,j); 1757 err = APIFunc(copy_att)(ncid_in, BAD_VARID, name, ncid_out, varid); 1758 IF (err != NC_ENOTVAR) 1759 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1760 ELSE_NOK 1761 err = APIFunc(copy_att)(ncid_in, varid, name, ncid_out, BAD_VARID); 1762 IF (err != NC_ENOTVAR) 1763 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1764 ELSE_NOK 1765 err = APIFunc(copy_att)(BAD_ID, varid, name, ncid_out, varid); 1766 IF (err != NC_EBADID) 1767 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1768 ELSE_NOK 1769 err = APIFunc(copy_att)(ncid_in, varid, name, BAD_ID, varid); 1770 IF (err != NC_EBADID) 1771 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1772 ELSE_NOK 1773 err = APIFunc(copy_att)(ncid_in, varid, "noSuch", ncid_out, varid); 1774 IF (err != NC_ENOTATT) 1775 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 1776 ELSE_NOK 1777 err = APIFunc(copy_att)(ncid_in, varid, name, ncid_out, varid); 1778 IF (err != NC_NOERR) 1779 error("copy_att: %s", APIFunc(strerror)(err)); 1780 ELSE_NOK 1781 err = APIFunc(copy_att)(ncid_out, varid, name, ncid_out, varid); 1782 IF (err != NC_NOERR) 1783 error("source = target: %s", APIFunc(strerror)(err)); 1784 ELSE_NOK 1785 } 1786 } 1787 1788 err = APIFunc(close)(ncid_in); 1789 IF (err != NC_NOERR) 1790 error("close: %s", APIFunc(strerror)(err)); 1791 1792 /* Close scratch. Reopen & check attributes */ 1793 err = APIFunc(close)(ncid_out); 1794 IF (err != NC_NOERR) 1795 error("close: %s", APIFunc(strerror)(err)); 1796 err = FileOpen(scratch, NC_WRITE, &ncid_out); 1797 IF (err != NC_NOERR) 1798 error("open: %s", APIFunc(strerror)(err)); 1799 Check_Atts(ncid_out, numGatts, numVars); 1800 1801 /* 1802 * change to define mode 1803 * define single char. global att. ':a' with value 'A' 1804 * This will be used as source for following copies 1805 */ 1806 err = APIFunc(redef)(ncid_out); 1807 IF (err != NC_NOERR) 1808 error("redef: %s", APIFunc(strerror)(err)); 1809 err = APIFunc(put_att_text)(ncid_out, NC_GLOBAL, "a", 1, "A"); 1810 IF (err != NC_NOERR) 1811 error("put_att_text: %s", APIFunc(strerror)(err)); 1812 1813 /* 1814 * change to data mode 1815 * Use scratch as both source & dest. 1816 * try copy to existing att. change type & decrease length 1817 * rename 1st existing att of each var (if any) 'a' 1818 * if this att. exists them copy ':a' to it 1819 */ 1820 err = APIFunc(enddef)(ncid_out); 1821 IF (err != NC_NOERR) 1822 error("enddef: %s", APIFunc(strerror)(err)); 1823 for (i = 0; i < numVars; i++) { 1824 if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { 1825 err = APIFunc(rename_att)(ncid_out, i, att_name[i][0], "a"); 1826 IF (err != NC_NOERR) 1827 error("rename_att: %s", APIFunc(strerror)(err)); 1828 err = APIFunc(copy_att)(ncid_out, NC_GLOBAL, "a", ncid_out, i); 1829 IF (err != NC_NOERR) 1830 error("copy_att: %s", APIFunc(strerror)(err)); 1831 ELSE_NOK 1832 } 1833 } 1834 err = APIFunc(close)(ncid_out); 1835 IF (err != NC_NOERR) 1836 error("close: %s", APIFunc(strerror)(err)); 1837 1838 /* Reopen & check */ 1839 err = FileOpen(scratch, NC_WRITE, &ncid_out); 1840 IF (err != NC_NOERR) 1841 error("open: %s", APIFunc(strerror)(err)); 1842 for (i = 0; i < numVars; i++) { 1843 if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { 1844 err = APIFunc(inq_att)(ncid_out, i, "a", &datatype, &length); 1845 IF (err != NC_NOERR) 1846 error("inq_att: %s", APIFunc(strerror)(err)); 1847 IF (datatype != NC_CHAR) 1848 error("Unexpected type"); 1849 IF (length != 1) 1850 error("Unexpected length"); 1851 err = APIFunc(get_att_text)(ncid_out, i, "a", &value); 1852 IF (err != NC_NOERR) 1853 error("get_att_text: %s", APIFunc(strerror)(err)); 1854 IF (value != 'A') 1855 error("Unexpected value"); 1856 } 1857 } 1858 1859 err = APIFunc(close)(ncid_out); 1860 IF (err != NC_NOERR) 1861 error("close: %s", APIFunc(strerror)(err)); 1862 err = FileDelete(scratch, info); 1863 IF (err != NC_NOERR) 1864 error("remove of %s failed", scratch); 1865 return nok; 1866} 1867 1868 1869/* 1870 * Test APIFunc(rename_att) 1871 * try with bad netCDF handle, check error 1872 * try with bad variable handle, check error 1873 * try with nonexisting att name, check error 1874 * try renaming to existing att name, check error 1875 * check that proper rename worked with APIFunc(inq_attid) 1876 * try in data mode, check error 1877 */ 1878int 1879TestFunc(rename_att)(AttVarArgs) 1880{ 1881 int ncid; 1882 int varid; 1883 int err; 1884 int i; 1885 int j; 1886 IntType k, ndx[1]; 1887 int attnum; 1888 char *attname; 1889 char name[NC_MAX_NAME]; 1890 char oldname[NC_MAX_NAME]; 1891 char newname[NC_MAX_NAME]; 1892 int nok = 0; /* count of valid comparisons */ 1893 nc_type datatype; 1894 nc_type atttype; 1895 IntType length; 1896 IntType attlength; 1897 char text[MAX_NELS]; 1898 double value[MAX_NELS]; 1899 double expect; 1900 1901 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1902 IF (err != NC_NOERR) { 1903 error("create: %s", APIFunc(strerror)(err)); 1904 return nok; 1905 } 1906 err = APIFunc(rename_att)(ncid, BAD_VARID, "abc", "newName"); 1907 IF (err != NC_ENOTVAR) 1908 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1909 ELSE_NOK 1910 def_dims(ncid); 1911 Def_Vars(ncid, numVars); 1912 Put_Atts(ncid, numGatts, numVars); 1913 1914 for (i = -1; i < numVars; i++) { 1915 varid = VARID(i); 1916 for (j = 0; j < NATTS(i); j++) { 1917 attname = ATT_NAME(i,j); 1918 err = APIFunc(rename_att)(BAD_ID, varid, attname, "newName"); 1919 IF (err != NC_EBADID) 1920 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1921 ELSE_NOK 1922 err = APIFunc(rename_att)(ncid, varid, "noSuch", "newName"); 1923 IF (err != NC_ENOTATT) 1924 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 1925 ELSE_NOK 1926 strcpy(newname, "new_"); 1927 strcat(newname, attname); 1928 err = APIFunc(rename_att)(ncid, varid, attname, newname); 1929 IF (err != NC_NOERR) 1930 error("rename_att: %s", APIFunc(strerror)(err)); 1931 ELSE_NOK 1932 err = APIFunc(inq_attid)(ncid, varid, newname, &attnum); 1933 IF (err != NC_NOERR) 1934 error("inq_attid: %s", APIFunc(strerror)(err)); 1935 IF (attnum != j) 1936 error("Unexpected attnum"); 1937 } 1938 } 1939 1940 /* Close. Reopen & check */ 1941 err = APIFunc(close)(ncid); 1942 IF (err != NC_NOERR) 1943 error("close: %s", APIFunc(strerror)(err)); 1944 err = FileOpen(scratch, NC_WRITE, &ncid); 1945 IF (err != NC_NOERR) 1946 error("open: %s", APIFunc(strerror)(err)); 1947 1948 for (i = -1; i < numVars; i++) { 1949 varid = VARID(i); 1950 for (j = 0; j < NATTS(i); j++) { 1951 attname = ATT_NAME(i,j); 1952 atttype = ATT_TYPE(i,j); 1953 attlength = ATT_LEN(i,j); 1954 strcpy(newname, "new_"); 1955 strcat(newname, attname); 1956 err = APIFunc(inq_attname)(ncid, varid, j, name); 1957 IF (err != NC_NOERR) 1958 error("inq_attname: %s", APIFunc(strerror)(err)); 1959 IF (strcmp(name, newname) != 0) 1960 error("inq_attname: unexpected name"); 1961 err = APIFunc(inq_att)(ncid, varid, name, &datatype, &length); 1962 IF (err != NC_NOERR) 1963 error("inq_att: %s", APIFunc(strerror)(err)); 1964 IF (datatype != atttype) 1965 error("inq_att: unexpected type"); 1966 IF (length != attlength) 1967 error("inq_att: unexpected length"); 1968 if (datatype == NC_CHAR) { 1969 err = APIFunc(get_att_text)(ncid, varid, name, text); 1970 IF (err != NC_NOERR) 1971 error("get_att_text: %s", APIFunc(strerror)(err)); 1972 for (k = 0; k < attlength; k++) { 1973 ndx[0] = k; 1974 expect = hash(datatype, -1, ndx); 1975 IF (text[k] != (char)expect) 1976 error("get_att_text: unexpected value"); 1977 } 1978 } else { 1979 err = APIFunc(get_att_double)(ncid, varid, name, value); 1980 IF (err != NC_NOERR) 1981 error("get_att_double: %s", APIFunc(strerror)(err)); 1982 for (k = 0; k < attlength; k++) { 1983 ndx[0] = k; 1984 expect = hash(datatype, -1, ndx); 1985 if (inRange(expect, datatype)) { 1986 IF (!equal(value[k],expect,datatype,NCT_DOUBLE)) 1987 error("get_att_double: unexpected value"); 1988 } 1989 } 1990 } 1991 } 1992 } 1993 1994 /* Now in data mode */ 1995 /* Try making names even longer. Then restore original names */ 1996 1997 for (i = -1; i < numVars; i++) { 1998 varid = VARID(i); 1999 for (j = 0; j < NATTS(i); j++) { 2000 attname = ATT_NAME(i,j); 2001 strcpy(oldname, "new_"); 2002 strcat(oldname, attname); 2003 strcpy(newname, "even_longer_"); 2004 strcat(newname, attname); 2005 err = APIFunc(rename_att)(ncid, varid, oldname, newname); 2006 IF (err != NC_ENOTINDEFINE) 2007 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 2008 ELSE_NOK 2009 err = APIFunc(rename_att)(ncid, varid, oldname, attname); 2010 IF (err != NC_NOERR) 2011 error("rename_att: %s", APIFunc(strerror)(err)); 2012 ELSE_NOK 2013 err = APIFunc(inq_attid)(ncid, varid, attname, &attnum); 2014 IF (err != NC_NOERR) 2015 error("inq_attid: %s", APIFunc(strerror)(err)); 2016 IF (attnum != j) 2017 error("Unexpected attnum"); 2018 } 2019 } 2020 2021 err = APIFunc(close)(ncid); 2022 IF (err != NC_NOERR) 2023 error("close: %s", APIFunc(strerror)(err)); 2024 2025 err = FileDelete(scratch, info); 2026 IF (err != NC_NOERR) 2027 error("remove of %s failed", scratch); 2028 return nok; 2029} 2030 2031 2032/* 2033 * Test APIFunc(del_att) 2034 * try with bad netCDF handle, check error 2035 * try with bad variable handle, check error 2036 * try with nonexisting att name, check error 2037 * check that proper delete worked using: 2038 * APIFunc(inq_attid), APIFunc(inq_natts), APIFunc(inq_varnatts) 2039 */ 2040int 2041TestFunc(del_att)(AttVarArgs) 2042{ 2043 int ncid; 2044 int err, nok=0; 2045 int i; 2046 int j; 2047 int attnum; 2048 int natts; 2049 int numatts; 2050 int varid; 2051 char *name; /* of att */ 2052 2053 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 2054 IF (err != NC_NOERR) { 2055 error("create: %s", APIFunc(strerror)(err)); 2056 return nok; 2057 } 2058 err = APIFunc(del_att)(ncid, BAD_VARID, "abc"); 2059 IF (err != NC_ENOTVAR) 2060 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 2061 ELSE_NOK 2062 def_dims(ncid); 2063 Def_Vars(ncid, numVars); 2064 Put_Atts(ncid, numGatts, numVars); 2065 2066 for (i = -1; i < numVars; i++) { 2067 varid = VARID(i); 2068 numatts = NATTS(i); 2069 for (j = 0; j < numatts; j++) { 2070 name = ATT_NAME(i,j); 2071 err = APIFunc(del_att)(BAD_ID, varid, name); 2072 IF (err != NC_EBADID) 2073 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 2074 ELSE_NOK 2075 err = APIFunc(del_att)(ncid, varid, "noSuch"); 2076 IF (err != NC_ENOTATT) 2077 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 2078 ELSE_NOK 2079 err = APIFunc(del_att)(ncid, varid, name); 2080 IF (err != NC_NOERR) 2081 error("del_att: %s", APIFunc(strerror)(err)); 2082 ELSE_NOK 2083 err = APIFunc(inq_attid)(ncid, varid, name, &attnum); 2084 IF (err != NC_ENOTATT) 2085 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 2086 if (i < 0) { 2087 err = APIFunc(inq_natts)(ncid, &natts); 2088 IF (err != NC_NOERR) 2089 error("inq_natts: %s", APIFunc(strerror)(err)); 2090 IF (natts != numatts-j-1) 2091 error("natts: expected %d, got %d", numatts-j-1, natts); 2092 } 2093 err = APIFunc(inq_varnatts)(ncid, varid, &natts); 2094 IF (err != NC_NOERR) 2095 error("inq_natts: %s", APIFunc(strerror)(err)); 2096 IF (natts != numatts-j-1) 2097 error("natts: expected %d, got %d", numatts-j-1, natts); 2098 } 2099 } 2100 2101 /* Close. Reopen & check no attributes left */ 2102 err = APIFunc(close)(ncid); 2103 IF (err != NC_NOERR) 2104 error("close: %s", APIFunc(strerror)(err)); 2105 err = FileOpen(scratch, NC_WRITE, &ncid); 2106 IF (err != NC_NOERR) 2107 error("open: %s", APIFunc(strerror)(err)); 2108 err = APIFunc(inq_natts)(ncid, &natts); 2109 IF (err != NC_NOERR) 2110 error("inq_natts: %s", APIFunc(strerror)(err)); 2111 IF (natts != 0) 2112 error("natts: expected %d, got %d", 0, natts); 2113 for (i = -1; i < numVars; i++) { 2114 varid = VARID(i); 2115 err = APIFunc(inq_varnatts)(ncid, varid, &natts); 2116 IF (err != NC_NOERR) 2117 error("inq_natts: %s", APIFunc(strerror)(err)); 2118 IF (natts != 0) 2119 error("natts: expected %d, got %d", 0, natts); 2120 } 2121 2122 /* restore attributes. change to data mode. try to delete */ 2123 err = APIFunc(redef)(ncid); 2124 IF (err != NC_NOERR) 2125 error("redef: %s", APIFunc(strerror)(err)); 2126 Put_Atts(ncid, numGatts, numVars); 2127 err = APIFunc(enddef)(ncid); 2128 IF (err != NC_NOERR) 2129 error("enddef: %s", APIFunc(strerror)(err)); 2130 2131 for (i = -1; i < numVars; i++) { 2132 varid = VARID(i); 2133 numatts = NATTS(i); 2134 for (j = 0; j < numatts; j++) { 2135 name = ATT_NAME(i,j); 2136 err = APIFunc(del_att)(ncid, varid, name); 2137 IF (err != NC_ENOTINDEFINE) 2138 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 2139 ELSE_NOK 2140 } 2141 } 2142 2143 err = APIFunc(close)(ncid); 2144 IF (err != NC_NOERR) 2145 error("close: %s", APIFunc(strerror)(err)); 2146 err = FileDelete(scratch, info); 2147 IF (err != NC_NOERR) 2148 error("remove of %s failed", scratch); 2149 return nok; 2150} 2151 2152 2153/* 2154 * Test APIFunc(set_fill) 2155 * try with bad netCDF handle, check error 2156 * try in read-only mode, check error 2157 * try with bad new_fillmode, check error 2158 * try in data mode, check error 2159 * check that proper set to NC_FILL works for record & non-record variables 2160 * (note that it is not possible to test NC_NOFILL mode!) 2161 * close file & create again for test using attribute _FillValue 2162 */ 2163int 2164TestFunc(set_fill)(VarArgs) 2165{ 2166 int ncid; 2167 int varid; 2168 int err; 2169 int i; 2170 IntType j; 2171 int old_fillmode; 2172 int nok = 0; /* count of valid comparisons */ 2173 char text = 0; 2174 double value = 0; 2175 double fill; 2176 IntType index[MAX_RANK]; 2177 2178 /* bad ncid */ 2179 err = APIFunc(set_fill)(BAD_ID, NC_NOFILL, &old_fillmode); 2180 IF (err != NC_EBADID) 2181 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 2182 2183 /* try in read-only mode */ 2184 err = FileOpen(testfile, NC_NOWRITE, &ncid); 2185 IF (err != NC_NOERR) 2186 error("open: %s", APIFunc(strerror)(err)); 2187 err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode); 2188 IF (err != NC_EPERM) 2189 error("expecting NC_EPERM but got %s", nc_err_code_name(err)); 2190 err = APIFunc(close)(ncid); 2191 IF (err != NC_NOERR) 2192 error("close: %s", APIFunc(strerror)(err)); 2193 2194 /* create scratch */ 2195 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 2196 IF (err != NC_NOERR) { 2197 error("create: %s", APIFunc(strerror)(err)); 2198 return nok; 2199 } 2200 2201 /* BAD_FILLMODE */ 2202 err = APIFunc(set_fill)(ncid, BAD_FILLMODE, &old_fillmode); 2203 IF (err != NC_EINVAL) 2204 error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); 2205 2206 /* proper calls */ 2207 err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode); 2208 IF (err != NC_NOERR) 2209 error("set_fill: %s", APIFunc(strerror)(err)); 2210 IF (old_fillmode != NC_NOFILL) 2211 error("Unexpected old fill mode: %d", old_fillmode); 2212 err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode); 2213 IF (err != NC_NOERR) 2214 error("set_fill: %s", APIFunc(strerror)(err)); 2215 IF (old_fillmode != NC_NOFILL) 2216 error("Unexpected old fill mode: %d", old_fillmode); 2217 2218 /* define dims & vars */ 2219 def_dims(ncid); 2220 Def_Vars(ncid, numVars); 2221 2222 /* Change to data mode. Set fillmode again */ 2223 err = APIFunc(enddef)(ncid); 2224 IF (err != NC_NOERR) 2225 error("enddef: %s", APIFunc(strerror)(err)); 2226 err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode); 2227ifdef(`PNETCDF', 2228 `IF (err != NC_ENOTINDEFINE) 2229 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));', 2230 `IF (err) 2231 error("nc_set_fill: %s", nc_strerror(err)); 2232 IF (old_fillmode != NC_FILL) 2233 error("Unexpected old fill mode: %d", old_fillmode);')dnl 2234 2235 /* Write record number NRECS to force writing of preceding records */ 2236 /* Assumes variable cr is char vector with UNLIMITED dimension */ 2237 err = APIFunc(inq_varid)(ncid, "cr", &varid); 2238 IF (err != NC_NOERR) 2239 error("inq_varid: %s", APIFunc(strerror)(err)); 2240 index[0] = NRECS; 2241 2242ifdef(`PNETCDF', ` 2243 for (i=0; i<=index[0]; i++) 2244 err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl 2245 2246 err = PutVar1TYPE(text)(ncid, varid, index, &text); 2247 IF (err != NC_NOERR) 2248 error("put_var1_text_all: %s", APIFunc(strerror)(err)); 2249 2250 /* get all variables & check all values equal default fill */ 2251 for (i = 0; i < numVars; i++) { 2252 ifdef(`PNETCDF', `if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */') 2253 switch (var_type[i]) { 2254 case NC_CHAR: fill = (double)NC_FILL_CHAR; break; 2255 case NC_BYTE: fill = (double)NC_FILL_BYTE; break; 2256 case NC_SHORT: fill = (double)NC_FILL_SHORT; break; 2257 case NC_INT: fill = (double)NC_FILL_INT; break; 2258 case NC_FLOAT: fill = (double)NC_FILL_FLOAT; break; 2259 case NC_DOUBLE: fill = (double)NC_FILL_DOUBLE; break; 2260 case NC_UBYTE: fill = (double)NC_FILL_UBYTE; break; 2261 case NC_USHORT: fill = (double)NC_FILL_USHORT; break; 2262 case NC_UINT: fill = (double)NC_FILL_UINT; break; 2263 case NC_INT64: fill = (double)NC_FILL_INT64; break; 2264 case NC_UINT64: fill = (double)NC_FILL_UINT64; break; 2265 default: assert(0); 2266 } 2267 for (j = 0; j < var_nels[i]; j++) { 2268 err = toMixedBase(j, var_rank[i], var_shape[i], index); 2269 IF (err != 0) error("error in toMixedBase"); 2270 if (var_type[i] == NC_CHAR) { 2271 err = GetVar1TYPE(text)(ncid, i, index, &text); 2272 IF (err != NC_NOERR) 2273 error("get_var1_text_all failed: %s", APIFunc(strerror)(err)); 2274 value = text; 2275 } else { 2276 err = GetVar1TYPE(double)(ncid, i, index, &value); 2277 IF (err != NC_NOERR) 2278 error("get_var1_double_all failed: %s", APIFunc(strerror)(err)); 2279 } 2280 IF (value != fill && fabs((fill - value)/fill) > DBL_EPSILON) 2281 error("\n\t\t%s Value expected: %-23.17e,\n\t\t read: %-23.17e\n", 2282 var_name[i],fill, value); 2283 ELSE_NOK 2284 } 2285 } 2286 2287 /* close scratch & create again for test using attribute _FillValue */ 2288 err = APIFunc(close)(ncid); 2289 IF (err != NC_NOERR) 2290 error("close: %s", APIFunc(strerror)(err)); 2291 err = FileCreate(scratch, NC_CLOBBER, &ncid); 2292 IF (err != NC_NOERR) { 2293 error("create: %s", APIFunc(strerror)(err)); 2294 return nok; 2295 } 2296 def_dims(ncid); 2297 Def_Vars(ncid, numVars); 2298 2299 /* set _FillValue = 42 for all vars */ 2300 fill = 42; 2301 text = 42; 2302 for (i = 0; i < numVars; i++) { 2303 if (var_type[i] == NC_CHAR) { 2304 err = APIFunc(put_att_text)(ncid, i, "_FillValue", 1, &text); 2305 IF (err != NC_NOERR) 2306 error("put_att_text: %s", APIFunc(strerror)(err)); 2307 } else { 2308 err = APIFunc(put_att_double)(ncid, i, "_FillValue",var_type[i],1,&fill); 2309 IF (err != NC_NOERR) 2310 error("put_att_double: %s", APIFunc(strerror)(err)); 2311 } 2312 } 2313 2314 /* data mode. write records */ 2315 err = APIFunc(enddef)(ncid); 2316 IF (err != NC_NOERR) 2317 error("enddef: %s", APIFunc(strerror)(err)); 2318 index[0] = NRECS; 2319 2320ifdef(`PNETCDF', ` 2321 for (i=0; i<=index[0]; i++) 2322 err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl 2323 2324 err = PutVar1TYPE(text)(ncid, varid, index, &text); 2325 IF (err != NC_NOERR) 2326 error("put_var1_text_all: %s", APIFunc(strerror)(err)); 2327 2328 /* get all variables & check all values equal 42 */ 2329 for (i = 0; i < numVars; i++) { 2330 if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */ 2331 for (j = 0; j < var_nels[i]; j++) { 2332 err = toMixedBase(j, var_rank[i], var_shape[i], index); 2333 IF (err != 0) error("error in toMixedBase"); 2334 if (var_type[i] == NC_CHAR) { 2335 err = GetVar1TYPE(text)(ncid, i, index, &text); 2336 IF (err != NC_NOERR) 2337 error("get_var1_text_all failed: %s", APIFunc(strerror)(err)); 2338 value = text; 2339 } else { 2340 err = GetVar1TYPE(double)(ncid, i, index, &value); 2341 IF (err != NC_NOERR) 2342 error("get_var1_double_all failed: %s", APIFunc(strerror)(err)); 2343 } 2344 IF (value != fill) 2345 error(" %s Value expected: %g, read: %g\n", var_name[i],fill, value); 2346 ELSE_NOK 2347 } 2348 } 2349 2350 /* enter redef mode and add a new variable, check NC_ELATEFILL */ 2351 err = APIFunc(redef)(ncid); 2352 IF (err != NC_NOERR) 2353 error("redef: %s", APIFunc(strerror)(err)); 2354 2355 /* it is not allowed to define fill value when variable already exists */ 2356 err = APIFunc(def_var_fill)(ncid, 0, 0, &value); 2357 IF (err != NC_ELATEFILL) 2358 error("redef: expect NC_ELATEFILL but got %s", nc_err_code_name(err)); 2359 err = APIFunc(def_var)(ncid, "new_var", NC_INT, 0, NULL, &varid); 2360 IF (err != NC_NOERR) 2361 error("redef: %s", APIFunc(strerror)(err)); 2362 err = APIFunc(def_var_fill)(ncid, varid, 0, &value); 2363 IF (err != NC_NOERR) 2364 error("def_var_fill: %s", APIFunc(strerror)(err)); 2365 2366 err = APIFunc(close)(ncid); 2367 IF (err != NC_NOERR) 2368 error("close: %s", APIFunc(strerror)(err)); 2369 err = FileDelete(scratch, info); 2370 IF (err != NC_NOERR) 2371 error("remove of %s failed", scratch); 2372 2373 return nok; 2374} 2375 2376 2377/* This function gets the version of a netCDF file, 1 is for netCDF 2378 classic, 2 for 64-bit offset format, (someday) 3 for HDF5 format, 2379 5 for 64-bit data format (CDF-5). 2380*/ 2381#define MAGIC_NUM_LEN 4 2382static 2383int 2384APIFunc(get_file_version)(char *path, int *version) 2385{ 2386 int fd; 2387 ssize_t read_len; 2388 char magic[MAGIC_NUM_LEN]; 2389 2390 /* Need two valid pointers - check for NULL. */ 2391 if (!version || !path) 2392 return NC_EINVAL; 2393 2394 /* Figure out if this is a netcdf or hdf5 file. */ 2395 fd = open(path, O_RDONLY, 0600); 2396 if (fd == -1) return errno; 2397 2398 read_len = read(fd, magic, MAGIC_NUM_LEN); 2399 if (-1 == close(fd)) return errno; 2400 2401 if (read_len == -1) 2402 return errno; 2403 2404 if (read_len != MAGIC_NUM_LEN) { 2405 printf("Error: reading NC magic string unexpected short read\n"); 2406 return 0; 2407 } 2408 2409 if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) { 2410 if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC || 2411 magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET 2412#ifdef ENABLE_CDF5 2413 || magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5 2414#endif 2415) 2416 *version = magic[MAGIC_NUM_LEN-1]; 2417 else 2418 return NC_ENOTNC; 2419 } 2420 /* tomorrow, tomorrow, I love you tomorrow, you're always a day 2421 away! */ 2422 /*if (magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') 2423 *version = 3;*/ 2424 return NC_NOERR; 2425} 2426 2427/* 2428 * Test APIFunc(set_default_format) 2429 * try with bad default format 2430 * try with NULL old_formatp 2431 * try in data mode, check error 2432 * check that proper set to NC_FILL works for record & non-record variables 2433 * (note that it is not possible to test NC_NOFILL mode!) 2434 * close file & create again for test using attribute _FillValue 2435 */ 2436int 2437TestFunc(set_default_format)(void) 2438{ 2439 int ncid, nok=0; 2440 int err; 2441 int i; 2442 int version=1; 2443 int old_format; 2444 2445 /* bad format */ 2446 err = APIFunc(set_default_format)(BAD_DEFAULT_FORMAT, &old_format); 2447 IF (err != NC_EINVAL) 2448 error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); 2449 ELSE_NOK 2450 2451 /* NULL old_formatp */ 2452 err = APIFunc(set_default_format)(NC_FORMAT_64BIT_OFFSET, NULL); 2453 IF (err != NC_NOERR) 2454 error("null old_fortmatp: status = %d", err); 2455 ELSE_NOK 2456 2457 /* Cycle through available formats. */ 2458 2459 for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++) { 2460 if (i == NC_FORMAT_NETCDF4 || i == NC_FORMAT_NETCDF4_CLASSIC) 2461 continue; /* test classic formats only */ 2462 if ((err = APIFunc(set_default_format)(i, NULL))) 2463 error("setting classic format: status = %d", err); 2464 ELSE_NOK 2465 err = FileCreate(scratch, NC_CLOBBER, &ncid); 2466 if (err != NC_NOERR) 2467 error("bad nc_create: status = %d", err); 2468 err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "testatt", sizeof("blah"), "blah"); 2469 if (err != NC_NOERR) 2470 error("bad put_att: status = %d", err); 2471 err = APIFunc(close)(ncid); 2472 if (err != NC_NOERR) 2473 error("bad close: status = %d", err); 2474 err = APIFunc(get_file_version)(scratch, &version); 2475 if (err != NC_NOERR) 2476 error("bad file version = %d", err); 2477 if (version != i) { 2478#if 0 2479 if (i == 4) { 2480 if (version == 3) continue; 2481 printf("expect version 3 but got %d (file=%s)",version,scratch); 2482 continue; 2483 } 2484#endif 2485 printf("expect version %d but got %d (file=%s)",i,version,scratch); 2486 error("bad file version = %d", version); 2487 } 2488 } 2489 2490 /* Remove the left-over file. */ 2491 err = FileDelete(scratch, info); 2492 IF (err != NC_NOERR) 2493 error("remove of %s failed", scratch); 2494 2495 return nok; 2496} 2497 2498 2499 2500 2501/* 2502 * Test FileDelete 2503 * create netcdf file 'scratch.nc' with no data, close it 2504 * delete the file 2505 */ 2506int 2507TestFunc(delete)(void) 2508{ 2509 int err, nok=0; 2510 int ncid; 2511 2512 err = FileCreate(scratch, NC_CLOBBER, &ncid); 2513 IF (err != NC_NOERR) 2514 error("error creating scratch file %s, status = %d\n", scratch,err); 2515 err = APIFunc(close)(ncid); 2516 IF (err != NC_NOERR) 2517 error("close: %s", APIFunc(strerror)(err)); 2518 err = FileDelete(scratch, info); 2519 IF (err != NC_NOERR) 2520 error("remove of %s failed", scratch); 2521 ELSE_NOK 2522 return nok; 2523} 2524