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#ifdef RELAX_COORD_BOUND 1047 IF (err != NC_NOERR) /* allowed when edge[j]==0 */ 1048 EXPECT_ERR(NC_NOERR, err) 1049#else 1050 IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ 1051 EXPECT_ERR(NC_EINVALCOORDS, err) 1052#endif 1053 ELSE_NOK 1054 start[j] = var_shape[i][j]+1; /* out of boundary check */ 1055 err = PutVara(ncid, i, start, edge, buf, 1, datatype); 1056 IF (err != NC_EINVALCOORDS) 1057 EXPECT_ERR(NC_EINVALCOORDS, err) 1058 ELSE_NOK 1059 start[j] = 0; 1060 } 1061 for (j = 0; j < var_rank[i]; j++) edge[j] = 1; 1062 1063 /* Choose a random point dividing each dim into 2 parts */ 1064 /* put 2^rank (nslabs) slabs so defined */ 1065 nslabs = 1; 1066 for (j = 0; j < var_rank[i]; j++) { 1067 mid[j] = roll( var_shape[i][j] ); 1068 nslabs *= 2; 1069 } 1070 /* bits of k determine whether to put lower or upper part of dim */ 1071 for (k = 0; k < nslabs; k++) { 1072 nels = 1; 1073 for (j = 0; j < var_rank[i]; j++) { 1074 if ((k >> j) & 1) { 1075 start[j] = 0; 1076 edge[j] = mid[j]; 1077 }else{ 1078 start[j] = mid[j]; 1079 edge[j] = var_shape[i][j] - mid[j]; 1080 } 1081 nels *= edge[j]; 1082 } 1083 p = (char *) buf; 1084 for (j = 0; j < nels; j++) { 1085 err = toMixedBase(j, var_rank[i], edge, index); 1086 IF (err != 0) error("error in toMixedBase"); 1087 for (d = 0; d < var_rank[i]; d++) 1088 index[d] += start[d]; 1089 value = hash(var_type[i], var_rank[i], index); 1090 if (!inRange(value, var_type[i])) 1091 value = 0; 1092 err = dbl2nc(value, var_type[i], p); 1093 IF (err != NC_NOERR) 1094 error("error in dbl2nc"); 1095 p += nctypelen(var_type[i]); 1096 } 1097 err = PutVara(ncid, i, start, edge, buf, nels, datatype); 1098 IF (err != NC_NOERR) 1099 error("%s", APIFunc(strerror)(err)); 1100 ELSE_NOK 1101 } 1102 } 1103 1104 Check_Vars(ncid, numVars); 1105 err = APIFunc(close)(ncid); 1106 IF (err != NC_NOERR) 1107 error("close: %s", APIFunc(strerror)(err)); 1108 1109 err = FileDelete(scratch, info); 1110 IF (err != NC_NOERR) 1111 error("remove of %s failed", scratch); 1112 return nok; 1113} 1114 1115 1116/* 1117 * Test PutVars 1118 * Choose a random point dividing each dim into 2 parts 1119 * Put 2^rank (nslabs) slabs so defined 1120 * Choose random stride from 1 to edge 1121 * Redefine buffer for each put. 1122 * At end check all variables using Check_Vars 1123 */ 1124int 1125TestFunc(put_vars)(VarArgs) 1126{ 1127 int ncid, d, i, k, err, nslabs, nok=0; 1128 PTRDType nstarts; /* number of different starts */ 1129 IntType j, m, nels; 1130 IntType start[MAX_RANK]; 1131 IntType edge[MAX_RANK]; 1132 IntType index[MAX_RANK]; 1133 IntType index2[MAX_RANK]; 1134 IntType mid[MAX_RANK]; 1135 IntType count[MAX_RANK]; 1136 IntType sstride[MAX_RANK]; 1137 PTRDType stride[MAX_RANK]; 1138 double buf[MAX_NELS]; /* (void *) buffer */ 1139 char *p; /* (void *) pointer */ 1140 double value; 1141 ifdef(`PNETCDF', `MPI_Datatype datatype;') 1142 1143 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1144 IF (err != NC_NOERR) { 1145 error("create: %s", APIFunc(strerror)(err)); 1146 return nok; 1147 } 1148 1149 def_dims(ncid); 1150 Def_Vars(ncid, numVars); 1151 1152 err = APIFunc(enddef)(ncid); 1153 IF (err != NC_NOERR) 1154 error("enddef: %s", APIFunc(strerror)(err)); 1155 1156 /* check if can detect a bad file ID */ 1157 err = PutVars(BAD_ID, 0, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1158 IF (err != NC_EBADID) 1159 EXPECT_ERR(NC_EBADID, err) 1160 ELSE_NOK 1161 1162 /* check if can detect a bad variable ID */ 1163 err = PutVars(ncid, BAD_VARID, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1164 IF (err != NC_ENOTVAR) 1165 EXPECT_ERR(NC_ENOTVAR, err) 1166 ELSE_NOK 1167 1168 for (i = 0; i < numVars; i++) { 1169 assert(var_rank[i] <= MAX_RANK); 1170 assert(var_nels[i] <= MAX_NELS); 1171 1172 buf[0] = 5; /* reset to a value within bounds */ 1173 1174 /* check if can detect a bad file ID */ 1175 err = PutVars(BAD_ID, i, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); 1176 IF (err != NC_EBADID) 1177 EXPECT_ERR(NC_EBADID, err) 1178 ELSE_NOK 1179 1180 ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') 1181 1182 for (j = 0; j < var_rank[i]; j++) { 1183 start[j] = 0; 1184 edge[j] = 1; 1185 stride[j] = 1; 1186 } 1187 1188ifdef(`PNETCDF',`dnl 1189 /* for non-scalar variables, argument start cannot be NULL */ 1190 err = PutVars(ncid, i, NULL, NULL, NULL, buf, 1, datatype); 1191 if (var_rank[i] == 0) { /* scalar variable */ 1192 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1193 } 1194 else IF (err != NC_EINVALCOORDS) { 1195 EXPECT_ERR(NC_EINVALCOORDS, err) 1196 } 1197 ELSE_NOK 1198 1199 /* for non-scalar variables, argument count cannot be NULL */ 1200 err = PutVars(ncid, i, start, NULL, NULL, buf, 1, datatype); 1201 if (var_rank[i] == 0) { 1202 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1203 } 1204 else IF (err != NC_EEDGE) { 1205 EXPECT_ERR(NC_EEDGE, err) 1206 } 1207 ELSE_NOK 1208')dnl 1209 1210 /* first test when edge[*] > 0 */ 1211 for (j = 0; j < var_rank[i]; j++) { 1212 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1213 start[j] = var_shape[i][j]; 1214 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1215 IF (err != NC_EINVALCOORDS) 1216 EXPECT_ERR(NC_EINVALCOORDS, err) 1217 ELSE_NOK 1218 start[j] = 0; 1219 edge[j] = var_shape[i][j] + 1; /* edge error check */ 1220 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1221 IF (err != NC_EEDGE) 1222 EXPECT_ERR(NC_EEDG, err) 1223 ELSE_NOK 1224 edge[j] = 1; 1225 stride[j] = 0; /* strided edge error check */ 1226 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1227 IF (err != NC_ESTRIDE) 1228 EXPECT_ERR(NC_ESTRIDE, err) 1229 ELSE_NOK 1230 stride[j] = 1; 1231 } 1232 /* Check correct error returned even when nothing to put */ 1233 for (j = 0; j < var_rank[i]; j++) edge[j] = 0; 1234 1235 for (j = 0; j < var_rank[i]; j++) { 1236 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1237 start[j] = var_shape[i][j]; 1238 err = PutVars(ncid, i, start, edge, stride, buf, 0, datatype); 1239#ifdef RELAX_COORD_BOUND 1240 IF (err != NC_NOERR) /* allowed when edge[j]==0 */ 1241 EXPECT_ERR(NC_NOERR, err) 1242#else 1243 IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ 1244 EXPECT_ERR(NC_EINVALCOORDS, err) 1245#endif 1246 ELSE_NOK 1247 start[j] = var_shape[i][j]+1; /* out of boundary check */ 1248 err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); 1249 IF (err != NC_EINVALCOORDS) 1250 EXPECT_ERR(NC_EINVALCOORDS, err) 1251 ELSE_NOK 1252 start[j] = 0; 1253 } 1254 for (j = 0; j < var_rank[i]; j++) edge[j] = 1; 1255 1256 /* Choose a random point dividing each dim into 2 parts */ 1257 /* put 2^rank (nslabs) slabs so defined */ 1258 nslabs = 1; 1259 for (j = 0; j < var_rank[i]; j++) { 1260 mid[j] = roll( var_shape[i][j] ); 1261 nslabs *= 2; 1262 } 1263 /* bits of k determine whether to put lower or upper part of dim */ 1264 /* choose random stride from 1 to edge */ 1265 for (k = 0; k < nslabs; k++) { 1266 nstarts = 1; 1267 for (j = 0; j < var_rank[i]; j++) { 1268 if ((k >> j) & 1) { 1269 start[j] = 0; 1270 edge[j] = mid[j]; 1271 }else{ 1272 start[j] = mid[j]; 1273 edge[j] = var_shape[i][j] - mid[j]; 1274 } 1275 sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; 1276 stride[j] = (PTRDType)sstride[j]; 1277 nstarts *= stride[j]; 1278 } 1279 for (m = 0; m < nstarts; m++) { 1280 err = toMixedBase(m, var_rank[i], sstride, index); 1281 IF (err != 0) error("error in toMixedBase"); 1282 nels = 1; 1283 for (j = 0; j < var_rank[i]; j++) { 1284 count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; 1285 nels *= count[j]; 1286 index[j] += start[j]; 1287 } 1288 /* Random choice of forward or backward */ 1289/* TODO 1290 if ( roll(2) ) { 1291 for (j = 0; j < var_rank[i]; j++) { 1292 index[j] += (count[j] - 1) * (IntType)stride[j]; 1293 stride[j] = -stride[j]; 1294 } 1295 } 1296 */ 1297 p = (char *) buf; 1298 for (j = 0; j < nels; j++) { 1299 err = toMixedBase(j, var_rank[i], count, index2); 1300 IF (err != 0) error("error in toMixedBase"); 1301 for (d = 0; d < var_rank[i]; d++) 1302 index2[d] = index[d] + index2[d] * (IntType)stride[d]; 1303 value = hash(var_type[i], var_rank[i], index2); 1304 if (!inRange(value, var_type[i])) 1305 value = 0; 1306 err = dbl2nc(value, var_type[i], p); 1307 IF (err != NC_NOERR) 1308 error("error in dbl2nc"); 1309 p += nctypelen(var_type[i]); 1310 } 1311 err = PutVars(ncid, i, index, count, stride, buf, nels, datatype); 1312 IF (err != NC_NOERR) 1313 EXPECT_ERR(NC_NOERR, err) 1314 ELSE_NOK 1315 } 1316 } 1317 } 1318 1319 Check_Vars(ncid, numVars); 1320 err = APIFunc(close)(ncid); 1321 IF (err != NC_NOERR) 1322 error("close: %s", APIFunc(strerror)(err)); 1323 1324 err = FileDelete(scratch, info); 1325 IF (err != NC_NOERR) 1326 error("remove of %s failed", scratch); 1327 return nok; 1328} 1329 1330 1331/* 1332 * Test PutVarm 1333 * Choose a random point dividing each dim into 2 parts 1334 * Put 2^rank (nslabs) slabs so defined 1335 * Choose random stride from 1 to edge 1336 * Buffer is bit image of whole external variable. 1337 * So all puts for a variable put different elements of buffer 1338 * At end check all variables using Check_Vars 1339 */ 1340int 1341TestFunc(put_varm)(VarArgs) 1342{ 1343 int ncid, nok=0; 1344 int i; 1345 int k; 1346 int err; 1347 int nslabs; 1348 IntType j, m; 1349 PTRDType nstarts; /* number of different starts */ 1350 IntType start[MAX_RANK]; 1351 IntType edge[MAX_RANK]; 1352 IntType index[MAX_RANK]; 1353 IntType mid[MAX_RANK]; 1354 IntType count[MAX_RANK]; 1355 IntType sstride[MAX_RANK]; 1356 PTRDType stride[MAX_RANK]; 1357 PTRDType imap[MAX_RANK]; 1358 PTRDType imap2[MAX_RANK]; 1359 ifdef(`PNETCDF', `IntType bufcount;') 1360 double buf[MAX_NELS]; /* (void *) buffer */ 1361 char *p; /* (void *) pointer */ 1362 double value; 1363 ifdef(`PNETCDF', `MPI_Datatype datatype;') 1364 1365 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1366 IF (err != NC_NOERR) { 1367 error("create: %s", APIFunc(strerror)(err)); 1368 return nok; 1369 } 1370 1371 def_dims(ncid); 1372 Def_Vars(ncid, numVars); 1373 1374 err = APIFunc(enddef)(ncid); 1375 IF (err != NC_NOERR) 1376 error("enddef: %s", APIFunc(strerror)(err)); 1377 1378 /* check if can detect a bad file ID */ 1379 err = PutVarm(NC_EBADID, 0, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1380 IF (err != NC_EBADID) 1381 EXPECT_ERR(NC_EBADID, err) 1382 ELSE_NOK 1383 1384 /* check if can detect a bad variable ID */ 1385 err = PutVarm(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL, 1, MPI_DATATYPE_NULL); 1386 IF (err != NC_ENOTVAR) 1387 EXPECT_ERR(NC_ENOTVAR, err) 1388 ELSE_NOK 1389 1390 for (i = 0; i < numVars; i++) { 1391 assert(var_rank[i] <= MAX_RANK); 1392 assert(var_nels[i] <= MAX_NELS); 1393 1394 buf[0] = 5; /* reset to a value within bounds */ 1395 1396 /* check if can detect a bad file ID */ 1397 err = PutVarm(BAD_ID, i, NULL, NULL, NULL, NULL, buf, 1, MPI_DATATYPE_NULL); 1398 IF (err != NC_EBADID) 1399 EXPECT_ERR(NC_EBADID, err) 1400 ELSE_NOK 1401 1402 ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') 1403 1404 for (j = 0; j < var_rank[i]; j++) { 1405 start[j] = 0; 1406 edge[j] = 1; 1407 stride[j] = 1; 1408 imap[j] = 1; 1409 } 1410 1411ifdef(`PNETCDF',`dnl 1412 /* for non-scalar variables, argument start cannot be NULL */ 1413 err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); 1414 if (var_rank[i] == 0) { /* scalar variable */ 1415 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1416 } 1417 else IF (err != NC_EINVALCOORDS) { 1418 EXPECT_ERR(NC_EINVALCOORDS, err) 1419 } 1420 ELSE_NOK 1421 1422 /* for non-scalar variables, argument count cannot be NULL */ 1423 err = PutVarm(ncid, i, start, NULL, NULL, NULL, buf, 1, datatype); 1424 if (var_rank[i] == 0) { 1425 IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err) 1426 } 1427 else IF (err != NC_EEDGE) { 1428 EXPECT_ERR(NC_EEDGE, err) 1429 } 1430 ELSE_NOK 1431')dnl 1432 1433 /* first test when edge[*] > 0 */ 1434 for (j = 0; j < var_rank[i]; j++) { 1435 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1436 start[j] = var_shape[i][j]; 1437 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1438 IF (err != NC_EINVALCOORDS) 1439 EXPECT_ERR(NC_EINVALCOORDS, err) 1440 ELSE_NOK 1441 start[j] = 0; 1442 edge[j] = var_shape[i][j] + 1; /* edge error check */ 1443 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1444 IF (err != NC_EEDGE) 1445 EXPECT_ERR(NC_EEDG, err) 1446 ELSE_NOK 1447 edge[j] = 1; 1448 stride[j] = 0; /* strided edge error check */ 1449 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1450 IF (err != NC_ESTRIDE) 1451 EXPECT_ERR(NC_ESTRIDE, err) 1452 ELSE_NOK 1453 stride[j] = 1; 1454 } 1455 /* Check correct error returned even when nothing to put */ 1456 for (j = 0; j < var_rank[i]; j++) edge[j] = 0; 1457 1458 for (j = 0; j < var_rank[i]; j++) { 1459 if (var_dimid[i][j] == 0) continue; /* skip record dim */ 1460 start[j] = var_shape[i][j]; 1461 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype); 1462#ifdef RELAX_COORD_BOUND 1463 IF (err != NC_NOERR) /* allowed when edge[j]==0 */ 1464 EXPECT_ERR(NC_NOERR, err) 1465#else 1466 IF (err != NC_EINVALCOORDS) /* not allowed even when edge[j]==0 */ 1467 EXPECT_ERR(NC_EINVALCOORDS, err) 1468#endif 1469 ELSE_NOK 1470 start[j] = var_shape[i][j]+1; /* out of boundary check */ 1471 err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); 1472 IF (err != NC_EINVALCOORDS) 1473 EXPECT_ERR(NC_EINVALCOORDS, err) 1474 ELSE_NOK 1475 start[j] = 0; 1476 } 1477 for (j = 0; j < var_rank[i]; j++) edge[j] = 1; 1478 1479 if (var_rank[i] > 0) { 1480 int jj = var_rank[i] - 1; 1481 imap[jj] = nctypelen(var_type[i]); /* netCDF considers imap in bytes */ 1482 imap[jj] = 1; /* PnetCDF considers imap in elements */ 1483 for (; jj > 0; jj--) 1484 imap[jj-1] = imap[jj] * (PTRDType)var_shape[i][jj]; 1485 } 1486 p = (char *) buf; 1487 for (j = 0; j < var_nels[i]; j++) { 1488 err = toMixedBase(j, var_rank[i], var_shape[i], index); 1489 IF (err != 0) error("error in toMixedBase"); 1490 value = hash(var_type[i], var_rank[i], index); 1491 if (!inRange(value, var_type[i])) 1492 value = 0; 1493 err = dbl2nc(value, var_type[i], p); 1494 IF (err != NC_NOERR) 1495 error("error in dbl2nc"); 1496 p += nctypelen(var_type[i]); 1497 } 1498 1499 /* Choose a random point dividing each dim into 2 parts */ 1500 /* put 2^rank (nslabs) slabs so defined */ 1501 nslabs = 1; 1502 for (j = 0; j < var_rank[i]; j++) { 1503 mid[j] = roll( var_shape[i][j] ); 1504 nslabs *= 2; 1505 } 1506 /* bits of k determine whether to put lower or upper part of dim */ 1507 /* choose random stride from 1 to edge */ 1508 for (k = 0; k < nslabs; k++) { 1509 nstarts = 1; 1510 for (j = 0; j < var_rank[i]; j++) { 1511 if ((k >> j) & 1) { 1512 start[j] = 0; 1513 edge[j] = mid[j]; 1514 }else{ 1515 start[j] = mid[j]; 1516 edge[j] = var_shape[i][j] - mid[j]; 1517 } 1518 sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1; 1519 stride[j] = (PTRDType)sstride[j]; 1520 imap2[j] = imap[j] * (PTRDType)sstride[j]; 1521 nstarts *= stride[j]; 1522 } 1523 for (m = 0; m < nstarts; m++) { 1524 if (var_rank[i] == 0 && i%2 == 0) { 1525 err = PutVarm(ncid, i, NULL, NULL, NULL, NULL, buf, 1, datatype); 1526 } else { 1527 err = toMixedBase(m, var_rank[i], sstride, index); 1528 IF (err != 0) error("error in toMixedBase"); 1529 for (j = 0; j < var_rank[i]; j++) { 1530 count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; 1531 index[j] += start[j]; 1532 } 1533 /* Random choice of forward or backward */ 1534/* TODO 1535 if ( roll(2) ) { 1536 for (j = 0; j < var_rank[i]; j++) { 1537 index[j] += (count[j] - 1) * (IntType)stride[j]; 1538 stride[j] = -stride[j]; 1539 } 1540 } 1541 */ 1542 j = fromMixedBase(var_rank[i], index, var_shape[i]); 1543 p = (char *) buf + (int)j * nctypelen(var_type[i]); 1544 ifdef(`PNETCDF', `for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= count[j];') 1545 err = PutVarm(ncid, i, index, count, stride, imap2, p, bufcount, datatype); 1546 } 1547 IF (err != NC_NOERR) 1548 EXPECT_ERR(NC_NOERR, err) 1549 ELSE_NOK 1550 } 1551 } 1552 } 1553 1554 Check_Vars(ncid, numVars); 1555 err = APIFunc(close)(ncid); 1556 IF (err != NC_NOERR) 1557 error("close: %s", APIFunc(strerror)(err)); 1558 1559 err = FileDelete(scratch, info); 1560 IF (err != NC_NOERR) 1561 error("remove of %s failed", scratch); 1562 return nok; 1563} 1564 1565 1566/* 1567 * Test APIFunc(rename_var) 1568 * try with bad netCDF handle, check error 1569 * try with bad variable handle, check error 1570 * try renaming to existing variable name, check error 1571 * check that proper rename worked with APIFunc(inq_varid) 1572 * try in data mode, check error 1573 */ 1574int 1575TestFunc(rename_var)(VarArgs) 1576{ 1577 int ncid; 1578 int varid; 1579 int err, nok=0; 1580 int i; 1581 char name[NC_MAX_NAME]; 1582 1583 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1584 IF (err != NC_NOERR) { 1585 error("create: %s", APIFunc(strerror)(err)); 1586 return nok; 1587 } 1588 err = APIFunc(rename_var)(ncid, BAD_VARID, "newName"); 1589 IF (err != NC_ENOTVAR) 1590 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1591 ELSE_NOK 1592 def_dims(ncid); 1593 Def_Vars(ncid, numVars); 1594 1595 /* Prefix "new_" to each name */ 1596 for (i = 0; i < numVars; i++) { 1597 err = APIFunc(rename_var)(BAD_ID, i, "newName"); 1598 IF (err != NC_EBADID) 1599 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1600 ELSE_NOK 1601 err = APIFunc(rename_var)(ncid, i, var_name[numVars-1]); 1602 IF (err != NC_ENAMEINUSE) 1603 error("expecting NC_ENAMEINUSE but got %s", nc_err_code_name(err)); 1604 ELSE_NOK 1605 strcpy(name, "new_"); 1606 strcat(name, var_name[i]); 1607 err = APIFunc(rename_var)(ncid, i, name); 1608 IF (err != NC_NOERR) 1609 error("rename_var: %s", APIFunc(strerror)(err)); 1610 ELSE_NOK 1611 err = APIFunc(inq_varid)(ncid, name, &varid); 1612 IF (err != NC_NOERR) 1613 error("inq_varid: %s", APIFunc(strerror)(err)); 1614 IF (varid != i) 1615 error("Unexpected varid"); 1616 } 1617 1618 /* Change to data mode */ 1619 /* Try making names even longer. Then restore original names */ 1620 err = APIFunc(enddef)(ncid); 1621 IF (err != NC_NOERR) 1622 error("enddef: %s", APIFunc(strerror)(err)); 1623 for (i = 0; i < numVars; i++) { 1624 strcpy(name, "even_longer_"); 1625 strcat(name, var_name[i]); 1626 err = APIFunc(rename_var)(ncid, i, name); 1627 IF (err != NC_ENOTINDEFINE) 1628 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 1629 ELSE_NOK 1630 err = APIFunc(rename_var)(ncid, i, var_name[i]); 1631 IF (err != NC_NOERR) 1632 error("rename_var: %s", APIFunc(strerror)(err)); 1633 ELSE_NOK 1634 err = APIFunc(inq_varid)(ncid, var_name[i], &varid); 1635 IF (err != NC_NOERR) 1636 error("inq_varid: %s", APIFunc(strerror)(err)); 1637 IF (varid != i) 1638 error("Unexpected varid"); 1639 } 1640 1641 Put_Vars(ncid, numVars); 1642 Check_Vars(ncid, numVars); 1643 1644 err = APIFunc(close)(ncid); 1645 IF (err != NC_NOERR) 1646 error("close: %s", APIFunc(strerror)(err)); 1647 1648 err = FileDelete(scratch, info); 1649 IF (err != NC_NOERR) 1650 error("remove of %s failed", scratch); 1651 return nok; 1652} 1653 1654 1655int 1656TestFunc(put_att)(AttVarArgs) 1657{ 1658 int ncid, nok=0; 1659 int varid; 1660 int i; 1661 int j; 1662 IntType k, ndx[1]; 1663 int err; 1664 double buf[MAX_NELS]; /* (void *) buffer */ 1665 char *p; /* (void *) pointer */ 1666 char *name; /* of att */ 1667 nc_type datatype; /* of att */ 1668 IntType length; /* of att */ 1669 double value; 1670 1671 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1672 IF (err != NC_NOERR) { 1673 error("create: %s", APIFunc(strerror)(err)); 1674 return nok; 1675 } 1676 def_dims(ncid); 1677 Def_Vars(ncid, numVars); 1678 1679 for (i = -1; i < numVars; i++) { 1680 varid = VARID(i); 1681 for (j = 0; j < NATTS(i); j++) { 1682 name = ATT_NAME(i,j); 1683 datatype = ATT_TYPE(i,j); 1684 length = ATT_LEN(i,j); 1685 err = APIFunc(put_att)(BAD_ID, varid, name, datatype, length, buf); 1686 IF (err != NC_EBADID) 1687 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1688 ELSE_NOK 1689 err = APIFunc(put_att)(ncid, varid, BAD_NAME, datatype, length, buf); 1690 IF (err != NC_EBADNAME) 1691 error("expecting NC_EBADNAME but got %s", nc_err_code_name(err)); 1692 ELSE_NOK 1693 err = APIFunc(put_att)(ncid, BAD_VARID, name, datatype, length, buf); 1694 IF (err != NC_ENOTVAR) 1695 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1696 ELSE_NOK 1697 err = APIFunc(put_att)(ncid, varid, name, BAD_TYPE, length, buf); 1698 IF (err != NC_EBADTYPE) 1699 error("expecting NC_EBADTYPE but got %s", nc_err_code_name(err)); 1700 ELSE_NOK 1701 p = (char *) buf; 1702 for (k=0; k<length; k++) { 1703 ndx[0] = k; 1704 value = hash(datatype, -1, ndx); 1705 if (!inRange(value, datatype)) 1706 value = 0; 1707 err = dbl2nc(value, datatype, p); 1708 IF (err != NC_NOERR) 1709 error("error in dbl2nc"); 1710 p += nctypelen(datatype); 1711 } 1712 err = APIFunc(put_att)(ncid, varid, name, datatype, length, buf); 1713 IF (err != NC_NOERR) 1714 error("%s", APIFunc(strerror)(err)); 1715 ELSE_NOK 1716 } 1717 } 1718 1719 Check_Atts(ncid, numGatts, numVars); 1720 err = APIFunc(close)(ncid); 1721 IF (err != NC_NOERR) 1722 error("close: %s", APIFunc(strerror)(err)); 1723 1724 err = FileDelete(scratch, info); 1725 IF (err != NC_NOERR) 1726 error("remove of %s failed", scratch); 1727 return nok; 1728} 1729 1730 1731/* 1732 * Test APIFunc(copy_att) 1733 * try with bad source or target netCDF handles, check error 1734 * try with bad source or target variable handle, check error 1735 * try with nonexisting attribute, check error 1736 * check that NC_GLOBAL variable for source or target works 1737 * check that new attribute put works with target in define mode 1738 * check that old attribute put works with target in data mode 1739 * check that changing type and length of an attribute work OK 1740 * try with same ncid for source and target, different variables 1741 * try with same ncid for source and target, same variable 1742 */ 1743int 1744TestFunc(copy_att)(AttVarArgs) 1745{ 1746 int ncid_in; 1747 int ncid_out; 1748 int varid; 1749 int err, nok=0; 1750 int i; 1751 int j=0; 1752 char *name; /* of att */ 1753 nc_type datatype; /* of att */ 1754 IntType length; /* of att */ 1755 char value; 1756 1757 err = FileOpen(testfile, NC_NOWRITE, &ncid_in); 1758 IF (err != NC_NOERR) 1759 error("open: %s", APIFunc(strerror)(err)); 1760 err = FileCreate(scratch, NC_NOCLOBBER, &ncid_out); 1761 IF (err != NC_NOERR) { 1762 error("create: %s", APIFunc(strerror)(err)); 1763 return nok; 1764 } 1765 def_dims(ncid_out); 1766 Def_Vars(ncid_out, numVars); 1767 1768 for (i = -1; i < numVars; i++) { 1769 varid = VARID(i); 1770 for (j = 0; j < NATTS(i); j++) { 1771 name = ATT_NAME(i,j); 1772 err = APIFunc(copy_att)(ncid_in, BAD_VARID, name, ncid_out, varid); 1773 IF (err != NC_ENOTVAR) 1774 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1775 ELSE_NOK 1776 err = APIFunc(copy_att)(ncid_in, varid, name, ncid_out, BAD_VARID); 1777 IF (err != NC_ENOTVAR) 1778 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1779 ELSE_NOK 1780 err = APIFunc(copy_att)(BAD_ID, varid, name, ncid_out, varid); 1781 IF (err != NC_EBADID) 1782 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1783 ELSE_NOK 1784 err = APIFunc(copy_att)(ncid_in, varid, name, BAD_ID, varid); 1785 IF (err != NC_EBADID) 1786 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1787 ELSE_NOK 1788 err = APIFunc(copy_att)(ncid_in, varid, "noSuch", ncid_out, varid); 1789 IF (err != NC_ENOTATT) 1790 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 1791 ELSE_NOK 1792 err = APIFunc(copy_att)(ncid_in, varid, name, ncid_out, varid); 1793 IF (err != NC_NOERR) 1794 error("copy_att: %s", APIFunc(strerror)(err)); 1795 ELSE_NOK 1796 err = APIFunc(copy_att)(ncid_out, varid, name, ncid_out, varid); 1797 IF (err != NC_NOERR) 1798 error("source = target: %s", APIFunc(strerror)(err)); 1799 ELSE_NOK 1800 } 1801 } 1802 1803 err = APIFunc(close)(ncid_in); 1804 IF (err != NC_NOERR) 1805 error("close: %s", APIFunc(strerror)(err)); 1806 1807 /* Close scratch. Reopen & check attributes */ 1808 err = APIFunc(close)(ncid_out); 1809 IF (err != NC_NOERR) 1810 error("close: %s", APIFunc(strerror)(err)); 1811 err = FileOpen(scratch, NC_WRITE, &ncid_out); 1812 IF (err != NC_NOERR) 1813 error("open: %s", APIFunc(strerror)(err)); 1814 Check_Atts(ncid_out, numGatts, numVars); 1815 1816 /* 1817 * change to define mode 1818 * define single char. global att. ':a' with value 'A' 1819 * This will be used as source for following copies 1820 */ 1821 err = APIFunc(redef)(ncid_out); 1822 IF (err != NC_NOERR) 1823 error("redef: %s", APIFunc(strerror)(err)); 1824 err = APIFunc(put_att_text)(ncid_out, NC_GLOBAL, "a", 1, "A"); 1825 IF (err != NC_NOERR) 1826 error("put_att_text: %s", APIFunc(strerror)(err)); 1827 1828 /* 1829 * change to data mode 1830 * Use scratch as both source & dest. 1831 * try copy to existing att. change type & decrease length 1832 * rename 1st existing att of each var (if any) 'a' 1833 * if this att. exists them copy ':a' to it 1834 */ 1835 err = APIFunc(enddef)(ncid_out); 1836 IF (err != NC_NOERR) 1837 error("enddef: %s", APIFunc(strerror)(err)); 1838 for (i = 0; i < numVars; i++) { 1839 if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { 1840 err = APIFunc(rename_att)(ncid_out, i, att_name[i][0], "a"); 1841 IF (err != NC_NOERR) 1842 error("rename_att: %s", APIFunc(strerror)(err)); 1843 err = APIFunc(copy_att)(ncid_out, NC_GLOBAL, "a", ncid_out, i); 1844 IF (err != NC_NOERR) 1845 error("copy_att: %s", APIFunc(strerror)(err)); 1846 ELSE_NOK 1847 } 1848 } 1849 err = APIFunc(close)(ncid_out); 1850 IF (err != NC_NOERR) 1851 error("close: %s", APIFunc(strerror)(err)); 1852 1853 /* Reopen & check */ 1854 err = FileOpen(scratch, NC_WRITE, &ncid_out); 1855 IF (err != NC_NOERR) 1856 error("open: %s", APIFunc(strerror)(err)); 1857 for (i = 0; i < numVars; i++) { 1858 if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) { 1859 err = APIFunc(inq_att)(ncid_out, i, "a", &datatype, &length); 1860 IF (err != NC_NOERR) 1861 error("inq_att: %s", APIFunc(strerror)(err)); 1862 IF (datatype != NC_CHAR) 1863 error("Unexpected type"); 1864 IF (length != 1) 1865 error("Unexpected length"); 1866 err = APIFunc(get_att_text)(ncid_out, i, "a", &value); 1867 IF (err != NC_NOERR) 1868 error("get_att_text: %s", APIFunc(strerror)(err)); 1869 IF (value != 'A') 1870 error("Unexpected value"); 1871 } 1872 } 1873 1874 err = APIFunc(close)(ncid_out); 1875 IF (err != NC_NOERR) 1876 error("close: %s", APIFunc(strerror)(err)); 1877 err = FileDelete(scratch, info); 1878 IF (err != NC_NOERR) 1879 error("remove of %s failed", scratch); 1880 return nok; 1881} 1882 1883 1884/* 1885 * Test APIFunc(rename_att) 1886 * try with bad netCDF handle, check error 1887 * try with bad variable handle, check error 1888 * try with nonexisting att name, check error 1889 * try renaming to existing att name, check error 1890 * check that proper rename worked with APIFunc(inq_attid) 1891 * try in data mode, check error 1892 */ 1893int 1894TestFunc(rename_att)(AttVarArgs) 1895{ 1896 int ncid; 1897 int varid; 1898 int err; 1899 int i; 1900 int j; 1901 IntType k, ndx[1]; 1902 int attnum; 1903 char *attname; 1904 char name[NC_MAX_NAME]; 1905 char oldname[NC_MAX_NAME]; 1906 char newname[NC_MAX_NAME]; 1907 int nok = 0; /* count of valid comparisons */ 1908 nc_type datatype; 1909 nc_type atttype; 1910 IntType length; 1911 IntType attlength; 1912 char text[MAX_NELS]; 1913 double value[MAX_NELS]; 1914 double expect; 1915 1916 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 1917 IF (err != NC_NOERR) { 1918 error("create: %s", APIFunc(strerror)(err)); 1919 return nok; 1920 } 1921 err = APIFunc(rename_att)(ncid, BAD_VARID, "abc", "newName"); 1922 IF (err != NC_ENOTVAR) 1923 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 1924 ELSE_NOK 1925 def_dims(ncid); 1926 Def_Vars(ncid, numVars); 1927 Put_Atts(ncid, numGatts, numVars); 1928 1929 for (i = -1; i < numVars; i++) { 1930 varid = VARID(i); 1931 for (j = 0; j < NATTS(i); j++) { 1932 attname = ATT_NAME(i,j); 1933 err = APIFunc(rename_att)(BAD_ID, varid, attname, "newName"); 1934 IF (err != NC_EBADID) 1935 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 1936 ELSE_NOK 1937 err = APIFunc(rename_att)(ncid, varid, "noSuch", "newName"); 1938 IF (err != NC_ENOTATT) 1939 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 1940 ELSE_NOK 1941 strcpy(newname, "new_"); 1942 strcat(newname, attname); 1943 err = APIFunc(rename_att)(ncid, varid, attname, newname); 1944 IF (err != NC_NOERR) 1945 error("rename_att: %s", APIFunc(strerror)(err)); 1946 ELSE_NOK 1947 err = APIFunc(inq_attid)(ncid, varid, newname, &attnum); 1948 IF (err != NC_NOERR) 1949 error("inq_attid: %s", APIFunc(strerror)(err)); 1950 IF (attnum != j) 1951 error("Unexpected attnum"); 1952 } 1953 } 1954 1955 /* Close. Reopen & check */ 1956 err = APIFunc(close)(ncid); 1957 IF (err != NC_NOERR) 1958 error("close: %s", APIFunc(strerror)(err)); 1959 err = FileOpen(scratch, NC_WRITE, &ncid); 1960 IF (err != NC_NOERR) 1961 error("open: %s", APIFunc(strerror)(err)); 1962 1963 for (i = -1; i < numVars; i++) { 1964 varid = VARID(i); 1965 for (j = 0; j < NATTS(i); j++) { 1966 attname = ATT_NAME(i,j); 1967 atttype = ATT_TYPE(i,j); 1968 attlength = ATT_LEN(i,j); 1969 strcpy(newname, "new_"); 1970 strcat(newname, attname); 1971 err = APIFunc(inq_attname)(ncid, varid, j, name); 1972 IF (err != NC_NOERR) 1973 error("inq_attname: %s", APIFunc(strerror)(err)); 1974 IF (strcmp(name, newname) != 0) 1975 error("inq_attname: unexpected name"); 1976 err = APIFunc(inq_att)(ncid, varid, name, &datatype, &length); 1977 IF (err != NC_NOERR) 1978 error("inq_att: %s", APIFunc(strerror)(err)); 1979 IF (datatype != atttype) 1980 error("inq_att: unexpected type"); 1981 IF (length != attlength) 1982 error("inq_att: unexpected length"); 1983 if (datatype == NC_CHAR) { 1984 err = APIFunc(get_att_text)(ncid, varid, name, text); 1985 IF (err != NC_NOERR) 1986 error("get_att_text: %s", APIFunc(strerror)(err)); 1987 for (k = 0; k < attlength; k++) { 1988 ndx[0] = k; 1989 expect = hash(datatype, -1, ndx); 1990 IF (text[k] != (char)expect) 1991 error("get_att_text: unexpected value"); 1992 } 1993 } else { 1994 err = APIFunc(get_att_double)(ncid, varid, name, value); 1995 IF (err != NC_NOERR) 1996 error("get_att_double: %s", APIFunc(strerror)(err)); 1997 for (k = 0; k < attlength; k++) { 1998 ndx[0] = k; 1999 expect = hash(datatype, -1, ndx); 2000 if (inRange(expect, datatype)) { 2001 IF (!equal(value[k],expect,datatype,NCT_DOUBLE)) 2002 error("get_att_double: unexpected value"); 2003 } 2004 } 2005 } 2006 } 2007 } 2008 2009 /* Now in data mode */ 2010 /* Try making names even longer. Then restore original names */ 2011 2012 for (i = -1; i < numVars; i++) { 2013 varid = VARID(i); 2014 for (j = 0; j < NATTS(i); j++) { 2015 attname = ATT_NAME(i,j); 2016 strcpy(oldname, "new_"); 2017 strcat(oldname, attname); 2018 strcpy(newname, "even_longer_"); 2019 strcat(newname, attname); 2020 err = APIFunc(rename_att)(ncid, varid, oldname, newname); 2021 IF (err != NC_ENOTINDEFINE) 2022 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 2023 ELSE_NOK 2024 err = APIFunc(rename_att)(ncid, varid, oldname, attname); 2025 IF (err != NC_NOERR) 2026 error("rename_att: %s", APIFunc(strerror)(err)); 2027 ELSE_NOK 2028 err = APIFunc(inq_attid)(ncid, varid, attname, &attnum); 2029 IF (err != NC_NOERR) 2030 error("inq_attid: %s", APIFunc(strerror)(err)); 2031 IF (attnum != j) 2032 error("Unexpected attnum"); 2033 } 2034 } 2035 2036 err = APIFunc(close)(ncid); 2037 IF (err != NC_NOERR) 2038 error("close: %s", APIFunc(strerror)(err)); 2039 2040 err = FileDelete(scratch, info); 2041 IF (err != NC_NOERR) 2042 error("remove of %s failed", scratch); 2043 return nok; 2044} 2045 2046 2047/* 2048 * Test APIFunc(del_att) 2049 * try with bad netCDF handle, check error 2050 * try with bad variable handle, check error 2051 * try with nonexisting att name, check error 2052 * check that proper delete worked using: 2053 * APIFunc(inq_attid), APIFunc(inq_natts), APIFunc(inq_varnatts) 2054 */ 2055int 2056TestFunc(del_att)(AttVarArgs) 2057{ 2058 int ncid; 2059 int err, nok=0; 2060 int i; 2061 int j; 2062 int attnum; 2063 int natts; 2064 int numatts; 2065 int varid; 2066 char *name; /* of att */ 2067 2068 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 2069 IF (err != NC_NOERR) { 2070 error("create: %s", APIFunc(strerror)(err)); 2071 return nok; 2072 } 2073 err = APIFunc(del_att)(ncid, BAD_VARID, "abc"); 2074 IF (err != NC_ENOTVAR) 2075 error("expecting NC_ENOTVAR but got %s", nc_err_code_name(err)); 2076 ELSE_NOK 2077 def_dims(ncid); 2078 Def_Vars(ncid, numVars); 2079 Put_Atts(ncid, numGatts, numVars); 2080 2081 for (i = -1; i < numVars; i++) { 2082 varid = VARID(i); 2083 numatts = NATTS(i); 2084 for (j = 0; j < numatts; j++) { 2085 name = ATT_NAME(i,j); 2086 err = APIFunc(del_att)(BAD_ID, varid, name); 2087 IF (err != NC_EBADID) 2088 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 2089 ELSE_NOK 2090 err = APIFunc(del_att)(ncid, varid, "noSuch"); 2091 IF (err != NC_ENOTATT) 2092 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 2093 ELSE_NOK 2094 err = APIFunc(del_att)(ncid, varid, name); 2095 IF (err != NC_NOERR) 2096 error("del_att: %s", APIFunc(strerror)(err)); 2097 ELSE_NOK 2098 err = APIFunc(inq_attid)(ncid, varid, name, &attnum); 2099 IF (err != NC_ENOTATT) 2100 error("expecting NC_ENOTATT but got %s", nc_err_code_name(err)); 2101 if (i < 0) { 2102 err = APIFunc(inq_natts)(ncid, &natts); 2103 IF (err != NC_NOERR) 2104 error("inq_natts: %s", APIFunc(strerror)(err)); 2105 IF (natts != numatts-j-1) 2106 error("natts: expected %d, got %d", numatts-j-1, natts); 2107 } 2108 err = APIFunc(inq_varnatts)(ncid, varid, &natts); 2109 IF (err != NC_NOERR) 2110 error("inq_natts: %s", APIFunc(strerror)(err)); 2111 IF (natts != numatts-j-1) 2112 error("natts: expected %d, got %d", numatts-j-1, natts); 2113 } 2114 } 2115 2116 /* Close. Reopen & check no attributes left */ 2117 err = APIFunc(close)(ncid); 2118 IF (err != NC_NOERR) 2119 error("close: %s", APIFunc(strerror)(err)); 2120 err = FileOpen(scratch, NC_WRITE, &ncid); 2121 IF (err != NC_NOERR) 2122 error("open: %s", APIFunc(strerror)(err)); 2123 err = APIFunc(inq_natts)(ncid, &natts); 2124 IF (err != NC_NOERR) 2125 error("inq_natts: %s", APIFunc(strerror)(err)); 2126 IF (natts != 0) 2127 error("natts: expected %d, got %d", 0, natts); 2128 for (i = -1; i < numVars; i++) { 2129 varid = VARID(i); 2130 err = APIFunc(inq_varnatts)(ncid, varid, &natts); 2131 IF (err != NC_NOERR) 2132 error("inq_natts: %s", APIFunc(strerror)(err)); 2133 IF (natts != 0) 2134 error("natts: expected %d, got %d", 0, natts); 2135 } 2136 2137 /* restore attributes. change to data mode. try to delete */ 2138 err = APIFunc(redef)(ncid); 2139 IF (err != NC_NOERR) 2140 error("redef: %s", APIFunc(strerror)(err)); 2141 Put_Atts(ncid, numGatts, numVars); 2142 err = APIFunc(enddef)(ncid); 2143 IF (err != NC_NOERR) 2144 error("enddef: %s", APIFunc(strerror)(err)); 2145 2146 for (i = -1; i < numVars; i++) { 2147 varid = VARID(i); 2148 numatts = NATTS(i); 2149 for (j = 0; j < numatts; j++) { 2150 name = ATT_NAME(i,j); 2151 err = APIFunc(del_att)(ncid, varid, name); 2152 IF (err != NC_ENOTINDEFINE) 2153 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err)); 2154 ELSE_NOK 2155 } 2156 } 2157 2158 err = APIFunc(close)(ncid); 2159 IF (err != NC_NOERR) 2160 error("close: %s", APIFunc(strerror)(err)); 2161 err = FileDelete(scratch, info); 2162 IF (err != NC_NOERR) 2163 error("remove of %s failed", scratch); 2164 return nok; 2165} 2166 2167 2168/* 2169 * Test APIFunc(set_fill) 2170 * try with bad netCDF handle, check error 2171 * try in read-only mode, check error 2172 * try with bad new_fillmode, check error 2173 * try in data mode, check error 2174 * check that proper set to NC_FILL works for record & non-record variables 2175 * (note that it is not possible to test NC_NOFILL mode!) 2176 * close file & create again for test using attribute _FillValue 2177 */ 2178int 2179TestFunc(set_fill)(VarArgs) 2180{ 2181 int ncid; 2182 int varid; 2183 int err; 2184 int i; 2185 IntType j; 2186 int old_fillmode; 2187 int nok = 0; /* count of valid comparisons */ 2188 char text = 0; 2189 double value = 0; 2190 double fill; 2191 IntType index[MAX_RANK]; 2192 2193 /* bad ncid */ 2194 err = APIFunc(set_fill)(BAD_ID, NC_NOFILL, &old_fillmode); 2195 IF (err != NC_EBADID) 2196 error("expecting NC_EBADID but got %s", nc_err_code_name(err)); 2197 2198 /* try in read-only mode */ 2199 err = FileOpen(testfile, NC_NOWRITE, &ncid); 2200 IF (err != NC_NOERR) 2201 error("open: %s", APIFunc(strerror)(err)); 2202 err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode); 2203 IF (err != NC_EPERM) 2204 error("expecting NC_EPERM but got %s", nc_err_code_name(err)); 2205 err = APIFunc(close)(ncid); 2206 IF (err != NC_NOERR) 2207 error("close: %s", APIFunc(strerror)(err)); 2208 2209 /* create scratch */ 2210 err = FileCreate(scratch, NC_NOCLOBBER, &ncid); 2211 IF (err != NC_NOERR) { 2212 error("create: %s", APIFunc(strerror)(err)); 2213 return nok; 2214 } 2215 2216 /* BAD_FILLMODE */ 2217 err = APIFunc(set_fill)(ncid, BAD_FILLMODE, &old_fillmode); 2218 IF (err != NC_EINVAL) 2219 error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); 2220 2221 /* proper calls */ 2222 err = APIFunc(set_fill)(ncid, NC_NOFILL, &old_fillmode); 2223 IF (err != NC_NOERR) 2224 error("set_fill: %s", APIFunc(strerror)(err)); 2225 IF (old_fillmode != NC_NOFILL) 2226 error("Unexpected old fill mode: %d", old_fillmode); 2227 err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode); 2228 IF (err != NC_NOERR) 2229 error("set_fill: %s", APIFunc(strerror)(err)); 2230 IF (old_fillmode != NC_NOFILL) 2231 error("Unexpected old fill mode: %d", old_fillmode); 2232 2233 /* define dims & vars */ 2234 def_dims(ncid); 2235 Def_Vars(ncid, numVars); 2236 2237 /* Change to data mode. Set fillmode again */ 2238 err = APIFunc(enddef)(ncid); 2239 IF (err != NC_NOERR) 2240 error("enddef: %s", APIFunc(strerror)(err)); 2241 err = APIFunc(set_fill)(ncid, NC_FILL, &old_fillmode); 2242ifdef(`PNETCDF', 2243 `IF (err != NC_ENOTINDEFINE) 2244 error("expecting NC_ENOTINDEFINE but got %s", nc_err_code_name(err));', 2245 `IF (err) 2246 error("nc_set_fill: %s", nc_strerror(err)); 2247 IF (old_fillmode != NC_FILL) 2248 error("Unexpected old fill mode: %d", old_fillmode);')dnl 2249 2250 /* Write record number NRECS to force writing of preceding records */ 2251 /* Assumes variable cr is char vector with UNLIMITED dimension */ 2252 err = APIFunc(inq_varid)(ncid, "cr", &varid); 2253 IF (err != NC_NOERR) 2254 error("inq_varid: %s", APIFunc(strerror)(err)); 2255 index[0] = NRECS; 2256 2257ifdef(`PNETCDF', ` 2258 for (i=0; i<=index[0]; i++) 2259 err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl 2260 2261 err = PutVar1TYPE(text)(ncid, varid, index, &text); 2262 IF (err != NC_NOERR) 2263 error("put_var1_text_all: %s", APIFunc(strerror)(err)); 2264 2265 /* get all variables & check all values equal default fill */ 2266 for (i = 0; i < numVars; i++) { 2267 ifdef(`PNETCDF', `if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */') 2268 switch (var_type[i]) { 2269 case NC_CHAR: fill = (double)NC_FILL_CHAR; break; 2270 case NC_BYTE: fill = (double)NC_FILL_BYTE; break; 2271 case NC_SHORT: fill = (double)NC_FILL_SHORT; break; 2272 case NC_INT: fill = (double)NC_FILL_INT; break; 2273 case NC_FLOAT: fill = (double)NC_FILL_FLOAT; break; 2274 case NC_DOUBLE: fill = (double)NC_FILL_DOUBLE; break; 2275 case NC_UBYTE: fill = (double)NC_FILL_UBYTE; break; 2276 case NC_USHORT: fill = (double)NC_FILL_USHORT; break; 2277 case NC_UINT: fill = (double)NC_FILL_UINT; break; 2278 case NC_INT64: fill = (double)NC_FILL_INT64; break; 2279 case NC_UINT64: fill = (double)NC_FILL_UINT64; break; 2280 default: assert(0); 2281 } 2282 for (j = 0; j < var_nels[i]; j++) { 2283 err = toMixedBase(j, var_rank[i], var_shape[i], index); 2284 IF (err != 0) error("error in toMixedBase"); 2285 if (var_type[i] == NC_CHAR) { 2286 err = GetVar1TYPE(text)(ncid, i, index, &text); 2287 IF (err != NC_NOERR) 2288 error("get_var1_text_all failed: %s", APIFunc(strerror)(err)); 2289 value = text; 2290 } else { 2291 err = GetVar1TYPE(double)(ncid, i, index, &value); 2292 IF (err != NC_NOERR) 2293 error("get_var1_double_all failed: %s", APIFunc(strerror)(err)); 2294 } 2295 IF (value != fill && fabs((fill - value)/fill) > DBL_EPSILON) 2296 error("\n\t\t%s Value expected: %-23.17e,\n\t\t read: %-23.17e\n", 2297 var_name[i],fill, value); 2298 ELSE_NOK 2299 } 2300 } 2301 2302 /* close scratch & create again for test using attribute _FillValue */ 2303 err = APIFunc(close)(ncid); 2304 IF (err != NC_NOERR) 2305 error("close: %s", APIFunc(strerror)(err)); 2306 err = FileCreate(scratch, NC_CLOBBER, &ncid); 2307 IF (err != NC_NOERR) { 2308 error("create: %s", APIFunc(strerror)(err)); 2309 return nok; 2310 } 2311 def_dims(ncid); 2312 Def_Vars(ncid, numVars); 2313 2314 /* set _FillValue = 42 for all vars */ 2315 fill = 42; 2316 text = 42; 2317 for (i = 0; i < numVars; i++) { 2318 if (var_type[i] == NC_CHAR) { 2319 err = APIFunc(put_att_text)(ncid, i, "_FillValue", 1, &text); 2320 IF (err != NC_NOERR) 2321 error("put_att_text: %s", APIFunc(strerror)(err)); 2322 } else { 2323 err = APIFunc(put_att_double)(ncid, i, "_FillValue",var_type[i],1,&fill); 2324 IF (err != NC_NOERR) 2325 error("put_att_double: %s", APIFunc(strerror)(err)); 2326 } 2327 } 2328 2329 /* data mode. write records */ 2330 err = APIFunc(enddef)(ncid); 2331 IF (err != NC_NOERR) 2332 error("enddef: %s", APIFunc(strerror)(err)); 2333 index[0] = NRECS; 2334 2335ifdef(`PNETCDF', ` 2336 for (i=0; i<=index[0]; i++) 2337 err = APIFunc(fill_var_rec)(ncid, varid, i);')dnl 2338 2339 err = PutVar1TYPE(text)(ncid, varid, index, &text); 2340 IF (err != NC_NOERR) 2341 error("put_var1_text_all: %s", APIFunc(strerror)(err)); 2342 2343 /* get all variables & check all values equal 42 */ 2344 for (i = 0; i < numVars; i++) { 2345 if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */ 2346 for (j = 0; j < var_nels[i]; j++) { 2347 err = toMixedBase(j, var_rank[i], var_shape[i], index); 2348 IF (err != 0) error("error in toMixedBase"); 2349 if (var_type[i] == NC_CHAR) { 2350 err = GetVar1TYPE(text)(ncid, i, index, &text); 2351 IF (err != NC_NOERR) 2352 error("get_var1_text_all failed: %s", APIFunc(strerror)(err)); 2353 value = text; 2354 } else { 2355 err = GetVar1TYPE(double)(ncid, i, index, &value); 2356 IF (err != NC_NOERR) 2357 error("get_var1_double_all failed: %s", APIFunc(strerror)(err)); 2358 } 2359 IF (value != fill) 2360 error(" %s Value expected: %g, read: %g\n", var_name[i],fill, value); 2361 ELSE_NOK 2362 } 2363 } 2364 2365 /* enter redef mode and add a new variable, check NC_ELATEFILL */ 2366 err = APIFunc(redef)(ncid); 2367 IF (err != NC_NOERR) 2368 error("redef: %s", APIFunc(strerror)(err)); 2369 2370 /* it is not allowed to define fill value when variable already exists */ 2371 err = APIFunc(def_var_fill)(ncid, 0, 0, &value); 2372 IF (err != NC_ELATEFILL) 2373 error("redef: expect NC_ELATEFILL but got %s", nc_err_code_name(err)); 2374 err = APIFunc(def_var)(ncid, "new_var", NC_INT, 0, NULL, &varid); 2375 IF (err != NC_NOERR) 2376 error("redef: %s", APIFunc(strerror)(err)); 2377 err = APIFunc(def_var_fill)(ncid, varid, 0, &value); 2378 IF (err != NC_NOERR) 2379 error("def_var_fill: %s", APIFunc(strerror)(err)); 2380 2381 err = APIFunc(close)(ncid); 2382 IF (err != NC_NOERR) 2383 error("close: %s", APIFunc(strerror)(err)); 2384 err = FileDelete(scratch, info); 2385 IF (err != NC_NOERR) 2386 error("remove of %s failed", scratch); 2387 2388 return nok; 2389} 2390 2391 2392/* This function gets the version of a netCDF file, 1 is for netCDF 2393 classic, 2 for 64-bit offset format, (someday) 3 for HDF5 format, 2394 5 for 64-bit data format (CDF-5). 2395*/ 2396#define MAGIC_NUM_LEN 4 2397static 2398int 2399APIFunc(get_file_version)(char *path, int *version) 2400{ 2401 int fd; 2402 ssize_t read_len; 2403 char magic[MAGIC_NUM_LEN]; 2404 2405 /* Need two valid pointers - check for NULL. */ 2406 if (!version || !path) 2407 return NC_EINVAL; 2408 2409 /* Figure out if this is a netcdf or hdf5 file. */ 2410 fd = open(path, O_RDONLY, 0600); 2411 if (fd == -1) return errno; 2412 2413 read_len = read(fd, magic, MAGIC_NUM_LEN); 2414 if (-1 == close(fd)) return errno; 2415 2416 if (read_len == -1) 2417 return errno; 2418 2419 if (read_len != MAGIC_NUM_LEN) { 2420 printf("Error: reading NC magic string unexpected short read\n"); 2421 return 0; 2422 } 2423 2424 if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) { 2425 if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC || 2426 magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET 2427#ifdef ENABLE_CDF5 2428 || magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5 2429#endif 2430) 2431 *version = magic[MAGIC_NUM_LEN-1]; 2432 else 2433 return NC_ENOTNC; 2434 } 2435 /* tomorrow, tomorrow, I love you tomorrow, you're always a day 2436 away! */ 2437 /*if (magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') 2438 *version = 3;*/ 2439 return NC_NOERR; 2440} 2441 2442/* 2443 * Test APIFunc(set_default_format) 2444 * try with bad default format 2445 * try with NULL old_formatp 2446 * try in data mode, check error 2447 * check that proper set to NC_FILL works for record & non-record variables 2448 * (note that it is not possible to test NC_NOFILL mode!) 2449 * close file & create again for test using attribute _FillValue 2450 */ 2451int 2452TestFunc(set_default_format)(void) 2453{ 2454 int ncid, nok=0; 2455 int err; 2456 int i; 2457 int version=1; 2458 int old_format; 2459 2460 /* bad format */ 2461 err = APIFunc(set_default_format)(BAD_DEFAULT_FORMAT, &old_format); 2462 IF (err != NC_EINVAL) 2463 error("expecting NC_EINVAL but got %s", nc_err_code_name(err)); 2464 ELSE_NOK 2465 2466 /* NULL old_formatp */ 2467 err = APIFunc(set_default_format)(NC_FORMAT_64BIT_OFFSET, NULL); 2468 IF (err != NC_NOERR) 2469 error("null old_fortmatp: status = %d", err); 2470 ELSE_NOK 2471 2472 /* Cycle through available formats. */ 2473 2474 for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++) { 2475 if (i == NC_FORMAT_NETCDF4 || i == NC_FORMAT_NETCDF4_CLASSIC) 2476 continue; /* test classic formats only */ 2477 if ((err = APIFunc(set_default_format)(i, NULL))) 2478 error("setting classic format: status = %d", err); 2479 ELSE_NOK 2480 err = FileCreate(scratch, NC_CLOBBER, &ncid); 2481 if (err != NC_NOERR) 2482 error("bad nc_create: status = %d", err); 2483 err = APIFunc(put_att_text)(ncid, NC_GLOBAL, "testatt", sizeof("blah"), "blah"); 2484 if (err != NC_NOERR) 2485 error("bad put_att: status = %d", err); 2486 err = APIFunc(close)(ncid); 2487 if (err != NC_NOERR) 2488 error("bad close: status = %d", err); 2489 err = APIFunc(get_file_version)(scratch, &version); 2490 if (err != NC_NOERR) 2491 error("bad file version = %d", err); 2492 if (version != i) { 2493#if 0 2494 if (i == 4) { 2495 if (version == 3) continue; 2496 printf("expect version 3 but got %d (file=%s)",version,scratch); 2497 continue; 2498 } 2499#endif 2500 printf("expect version %d but got %d (file=%s)",i,version,scratch); 2501 error("bad file version = %d", version); 2502 } 2503 } 2504 2505 /* Remove the left-over file. */ 2506 err = FileDelete(scratch, info); 2507 IF (err != NC_NOERR) 2508 error("remove of %s failed", scratch); 2509 2510 return nok; 2511} 2512 2513 2514 2515 2516/* 2517 * Test FileDelete 2518 * create netcdf file 'scratch.nc' with no data, close it 2519 * delete the file 2520 */ 2521int 2522TestFunc(delete)(void) 2523{ 2524 int err, nok=0; 2525 int ncid; 2526 2527 err = FileCreate(scratch, NC_CLOBBER, &ncid); 2528 IF (err != NC_NOERR) 2529 error("error creating scratch file %s, status = %d\n", scratch,err); 2530 err = APIFunc(close)(ncid); 2531 IF (err != NC_NOERR) 2532 error("close: %s", APIFunc(strerror)(err)); 2533 err = FileDelete(scratch, info); 2534 IF (err != NC_NOERR) 2535 error("remove of %s failed", scratch); 2536 ELSE_NOK 2537 return nok; 2538} 2539