1 /*********************************************************************
2  *   Copyright 1993, UCAR/Unidata
3  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4  *   $Header: /upc/share/CVS/netcdf-3/nctest/vartests.c,v 1.19 2006/10/31 16:20:49 ed Exp $
5  *********************************************************************/
6 
7 #include <config.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>		/* for free() */
11 #include "netcdf.h"
12 #include "testcdf.h"		/* defines in-memory test cdf structure */
13 #include "emalloc.h"
14 #include "add.h"		/* functions to update in-memory netcdf */
15 #include "error.h"
16 #include "tests.h"
17 
18 #define LEN_OF(array) ((sizeof array) / (sizeof array[0]))
19 
20 
21 /*
22  * Test ncvarid
23  *    check that proper variable handle returned in both modes
24  *    try with undefined name, check error
25  *    try with bad handle, check error
26  */
27 int
test_ncvarid(path)28 test_ncvarid(path)
29      const char *path;		/* name of writable netcdf file to open */
30 {
31     static char pname[] = "test_ncvarid";
32     int cdfid;			/* netcdf id */
33     int id;
34     int varid;			/* variable id */
35     static struct cdfvar xx =	/* variable */
36       {"xx", NC_FLOAT, 1, ___, 0};
37     int nerrs = 0;
38 
39     (void) fprintf(stderr, "*** Testing %s ...\t\t", &pname[5]);
40 
41     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
42 	error("%s: ncopen failed", pname);
43 	return ++nerrs;
44     }
45     /* opened, enter define mode */
46     if (ncredef(cdfid) == -1) {
47 	error("%s: cdredef failed", pname);
48 	ncclose(cdfid); return ++nerrs;
49     }
50     /* in define mode, add a variable */
51     xx.dims = (int *) emalloc(sizeof(int) * xx.ndims);
52     for (id = 0; id < xx.ndims; id++)
53       xx.dims[id] = id;
54     if ((varid = ncvardef(cdfid,
55 			   xx.name, xx.type, xx.ndims, xx.dims)) == -1) {
56 	error("%s: ncvardef failed", pname);
57 	ncclose(cdfid); return ++nerrs;
58     }
59     add_var(&test, &xx);	/* keep in-memory netcdf in sync */
60 
61     /* check id returned for name matches id returned from definition */
62     if (ncvarid(cdfid, xx.name) != varid) {
63 	error("%s: ncvarid returned wrong value in define mode", pname);
64 	ncclose(cdfid); return ++nerrs;
65     }
66     if (ncendef (cdfid) == -1) {
67 	error("%s: ncendef failed", pname);
68 	ncclose(cdfid); return ++nerrs;
69     }
70     /* in data mode, check returned id for variable just added */
71     if (ncvarid(cdfid, xx.name) != varid) {
72 	error("%s: ncvarid returned wrong value in data mode", pname);
73 	ncclose(cdfid); return ++nerrs;
74     }
75     /* try with undefined variable, should fail */
76     if (ncvarid(cdfid, "santa-claus") != -1) {
77 	error("%s: ncvarid with bogus name should have failed ", pname);
78 	ncclose(cdfid); return ++nerrs;
79     }
80     if (ncclose (cdfid) == -1) {
81 	error("%s: ncclose failed", pname);
82 	return ++nerrs;
83     }
84     /* try on bad handle, should fail */
85     if (ncvarid(cdfid, xx.name) != -1) {
86 	error("%s: ncvarid failed to report bad netcdf handle", pname);
87 	nerrs++;
88     }
89     if (nerrs > 0)
90       (void) fprintf(stderr,"FAILED! ***\n");
91     else
92       (void) fprintf(stderr,"ok ***\n");
93 
94     free(xx.dims);
95     return nerrs;
96 }
97 
98 
99 /*
100  * Test ncvarinq
101  *    try in both modes
102  *    check returned values against defined values
103  *    try with bad variable handle, check error
104  *    try with bad netCDF handle, check error
105  */
106 int
test_ncvarinq(path)107 test_ncvarinq(path)
108      const char *path;		/* name of writable netcdf file to open */
109 {
110     int nerrs = 0;
111     static char pname[] = "test_ncvarinq";
112     int cdfid;			/* netcdf id */
113     int varid;			/* variable id */
114     struct cdfvar var;		/* variable */
115     int idim;
116 
117     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
118 
119     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
120 	error("%s: ncopen failed", pname);
121 	return ++nerrs;
122     }
123     /* opened, in data mode */
124     var.dims = (int *) emalloc(sizeof(int) * MAX_VAR_DIMS);
125     var.name = (char *) emalloc(MAX_NC_NAME);
126     for (varid = 0 ; varid < test.nvars; varid++) { /* loop on all var ids */
127 	if (ncvarinq(cdfid, varid, var.name, &var.type,
128 		      &var.ndims, var.dims, &var.natts) == -1) {
129 	    error("%s: ncvarinq in data mode failed on var id %d",
130 		  pname, varid);
131 	    ncclose(cdfid); return ++nerrs;
132 	}
133 	/* compare returned with expected values */
134 	if (strcmp(var.name, test.vars[varid].name) != 0) {
135 	    error("%s: ncvarinq (data mode), name %s, expected %s for id = %d",
136 		  pname, var.name, test.vars[varid].name, varid);
137 	    nerrs++;
138 	}
139 	if (var.type != test.vars[varid].type) {
140 	    error("%s: ncvarinq (data mode), type %d, expected %d for id = %d",
141 		  pname, var.type, test.vars[varid].type, varid);
142 	    nerrs++;
143 	}
144 	if (var.ndims != test.vars[varid].ndims) {
145 	    error("%s: ncvarinq (data mode), ndims %d, expected %d for id = %d",
146 		  pname, var.ndims, test.vars[varid].ndims, varid);
147 	    nerrs++;
148 	}
149 	else {			/* if ndims OK, compare dims */
150 	    for (idim = 0; idim < var.ndims; idim++)
151 	      if (var.dims[idim] != test.vars[varid].dims[idim]) {
152 		  error("%s: ncvarinq (data mode), dims[%d]=%d, expected %d",
153 			pname, idim, var.dims[idim],
154 			test.vars[varid].dims[idim]);
155 		  nerrs++;
156 	      }
157 	}
158     }
159     if (ncredef(cdfid) == -1) {
160 	error("%s: ncredef failed", pname);
161 	ncclose(cdfid); return ++nerrs;
162     }
163     /* in define mode, compare returned with expected values again */
164     for (varid = 0 ; varid < test.nvars; varid++) { /* loop on all var ids */
165 	if (ncvarinq(cdfid, varid, var.name, &var.type,
166 		      &var.ndims, var.dims, &var.natts) == -1) {
167 	    error("%s: ncvarinq in data mode failed on var id %d",
168 		  pname, varid);
169 	    ncclose(cdfid); return ++nerrs;
170 	}
171 	if (strcmp(var.name, test.vars[varid].name) != 0) {
172 	    error("%s: ncvarinq (define mode), name %s, expected %s for id = %d",
173 		  pname, var.name, test.vars[varid].name, varid);
174 	    nerrs++;
175 	}
176 	if (var.type != test.vars[varid].type) {
177 	    error("%s: ncvarinq (define mode), type %d, expected %d for id = %d",
178 		  pname, var.type, test.vars[varid].type, varid);
179 	    nerrs++;
180 	}
181 	if (var.ndims != test.vars[varid].ndims) {
182 	    error("%s: ncvarinq (define mode), ndims %d, expected %d for id = %d",
183 		  pname, var.ndims, test.vars[varid].ndims, varid);
184 	    nerrs++;
185 	}
186 	else {			/* if ndims OK, compare dims */
187 	    for (idim = 0; idim < var.ndims; idim++)
188 	      if (var.dims[idim] != test.vars[varid].dims[idim]) {
189 		  error("%s: ncvarinq (define mode), dims[%d]=%d, expected %d",
190 			pname, idim, var.dims[idim],
191 			test.vars[varid].dims[idim]);
192 		  nerrs++;
193 	      }
194 	}
195     }
196     /* try with bad variable handles, check for failure */
197     if (ncvarinq(cdfid, -1, var.name, &var.type,
198 		      &var.ndims, var.dims, &var.natts) != -1 ||
199 	ncvarinq(cdfid, test.nvars, var.name, &var.type,
200 		      &var.ndims, var.dims, &var.natts) != -1) {
201 	error("%s: ncvarinq should have failed on bad variable ids",
202 	      pname, varid);
203 	ncclose(cdfid); return ++nerrs;
204     }
205     if (ncendef (cdfid) == -1) {
206 	error("%s: ncendef failed", pname);
207 	ncclose(cdfid); return ++nerrs;
208     }
209     if (ncclose (cdfid) == -1) {
210 	error("%s: ncclose failed", pname);
211 	return ++nerrs;
212     }
213     /* should fail, since bad handle */
214     if (test.nvars >= 1) {	/* if any variables have been defined */
215 	if (ncvarinq(cdfid, varid, var.name, &var.type,
216 		      &var.ndims, var.dims, &var.natts) != -1) {
217 	    error("%s: ncvarinq failed to report bad netcdf handle ", pname);
218 	    nerrs++;
219 	}
220     }
221     if(var.dims != NULL) free(var.dims);
222     if(var.name != NULL) free(var.name);
223     if (nerrs > 0)
224       (void) fprintf(stderr,"FAILED! ***\n");
225     else
226       (void) fprintf(stderr,"ok ***\n");
227 
228     return nerrs;
229 }
230 
231 
232 struct cdfelm {			/* coordinates and generic value */
233     long coords[MAX_NC_DIMS];
234     union generic {
235 	char by;
236 	char ch;
237 	short sh;
238 	nclong lo;
239 	float fl;
240 	double db;
241     } val;
242 };
243 
244 
245 /*
246  * Test both ncvarput1 and ncvarget1 with all types of data
247  *    use points in "lower-left", "middle", and "upper-right"
248  *    for each existing variable, put values of its type at each point
249  *    get values and compare with put values
250  */
251 static int
test_varputget1(cdfid)252 test_varputget1(cdfid)
253      int cdfid;			/* handle of netcdf open and in data mode */
254 {
255     int nerrs = 0;
256     static char pname[] = "test_varputget1";
257     int id, ie, iv;
258     int ne = 3;			/* number of test points */
259     struct cdfelm elm[3];	/* coordinates and values of test points */
260     static long edges[] = {1};
261     void *voidp;
262     void *tmpp;
263     char chval;
264     short shval;
265     nclong loval;
266     float flval;
267     double dbval;
268 
269     for (iv = 0; iv < test.nvars; iv++)	{ /* for each var in netcdf */
270 	for (id = 0; id < test.vars[iv].ndims; id++) { /* set corners */
271 	    int dsize;		/* max dimension size, used for u-r corner */
272 	    /* "lower-left" corner */
273 	    elm[0].coords[id] = 0;
274 	    /* if unlimited dimension, choose record 3 for max, arbitrarily */
275 	    dsize = (int) test.dims[test.vars[iv].dims[id]].size;
276 	    if (dsize == NC_UNLIMITED)
277 	      dsize = 3;
278 	    /* middle */
279 	    elm[1].coords[id] = dsize / 2;
280 	    /* "upper-right" corner */
281 	    elm[2].coords[id] = dsize - 1;
282 	}
283 	for (ie = 0; ie < ne; ie++) { /* for each of ne points */
284 	    switch (test.vars[iv].type) { /* get values of right type to put */
285 	      case NC_BYTE:
286 	      case NC_CHAR:
287 		elm[ie].val.by = (char) (ie+1);
288 		voidp = (void *) &elm[ie].val.by;
289 		tmpp = (void *) &chval;
290 		break;
291 	      case NC_SHORT:
292 		elm[ie].val.sh = (short) (ie-1);
293 		voidp = (void *) &elm[ie].val.sh;
294 		tmpp = (void *) &shval;
295 		break;
296 	      case NC_LONG:
297 		elm[ie].val.lo = (nclong) (ie-3);
298 		voidp = (void *) &elm[ie].val.lo;
299 		tmpp = (void *) &loval;
300 		break;
301 	      case NC_FLOAT:
302 		elm[ie].val.fl = (float) (ie+1);
303 		voidp = (void *) &elm[ie].val.fl;
304 		tmpp = (void *) &flval;
305 		break;
306 	      case NC_DOUBLE:
307 		elm[ie].val.db = (double) (ie-1);
308 		voidp = (void *) &elm[ie].val.db;
309 		tmpp = (void *) &dbval;
310 		break;
311 	      default:
312 		error("%s: bad type, test program error", pname);
313 	    }
314 	    if(ncvarput1 (cdfid, iv, elm[ie].coords, voidp) == -1) {
315 		error("%s: ncvarput1 failed for point %d, variable %s",
316 		      pname, ie, test.vars[iv].name);
317 		ncclose(cdfid); return 1;
318 	    }
319 	    add_data(&test, iv, elm[ie].coords, edges); /* keep test in sync */
320 
321 	    if(ncvarget1 (cdfid, iv, elm[ie].coords, tmpp) == -1) {
322 		error("%s: ncvarget1 failed for point %d, variable %s",
323 		      pname, ie, test.vars[iv].name);
324 		ncclose(cdfid); return 1;
325 	    }
326 	    switch (test.vars[iv].type) { /* compare values of right type */
327 	      case NC_BYTE:
328 	      case NC_CHAR:
329 		if (elm[ie].val.by != chval) {
330 		    error("%s: ncvarget1 returned char %d, expected %d",
331 			  pname, chval, elm[ie].val.by);
332 		    nerrs++;
333 		}
334 		break;
335 	      case NC_SHORT:
336 		if (elm[ie].val.sh != shval) {
337 		    error("%s: ncvarget1 returned short %d, expected %d",
338 			  pname, shval, elm[ie].val.sh);
339 		    nerrs++;
340 		}
341 		break;
342 	      case NC_LONG:
343 		if (elm[ie].val.lo != loval) {
344 		    error("%s: ncvarget1 returned long %ld, expected %ld",
345 			  pname, (long)loval, (long)elm[ie].val.lo);
346 		    nerrs++;
347 		}
348 		break;
349 	      case NC_FLOAT:
350 		if (elm[ie].val.fl != flval) {
351 		    error("%s: ncvarget1 returned float %g, expected %g",
352 			  pname, flval, elm[ie].val.fl);
353 		    nerrs++;
354 		}
355 		break;
356 	      case NC_DOUBLE:
357 		if (elm[ie].val.db != dbval) {
358 		    error("%s: ncvarget1 returned double %g, expected %g",
359 			  pname, dbval, elm[ie].val.db);
360 		    nerrs++;
361 		}
362 		break;
363 	      default:
364 		error("%s: bad type, test program error", pname);
365 	    }
366 	}
367     }
368 
369     return nerrs;
370 }
371 
372 
373 /*
374  * Test ncvarput1
375  *    check that proper call worked with ncvarget1
376  *    try with negative coords, check error
377  *    try with too-large coords, check error
378  *    try with bad variable handle, check error
379  *    try in define mode, check error
380  *    try with bad netCDF handle, check error
381  */
382 int
test_ncvarput1(path)383 test_ncvarput1(path)
384      const char *path;		/* name of writable netcdf file to open */
385 {
386     int nerrs = 0;
387     static char pname[] = "test_ncvarput1";
388     int cdfid;			/* netcdf id */
389     int iv;			/* variable id */
390     struct cdfelm elm;		/* coordinates and value of test point */
391 
392     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
393 
394     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
395 	error("%s: ncopen failed", pname);
396 	return ++nerrs;
397     }
398     /* opened in data mode, try putting and getting values of each type */
399     nerrs += test_varputget1 (cdfid);	/* tests ncvarput1 and ncvarget1 */
400 
401     /* find a variable with at least one dimension */
402     iv = 0;
403     while (test.vars[iv].ndims <= 0 && iv < test.nvars)
404       iv++;
405     if (iv < test.nvars) {	/* iv is varid of variable with dimensions */
406 	/* set coords */
407 	int id;			/* dimension id */
408 	for (id = 0; id < test.vars[iv].ndims; id++)
409 	  elm.coords[id] = 0;
410 	/* try invalid coordinates, should fail */
411 	elm.coords[test.vars[iv].ndims/2] = -1;
412 	if(ncvarput1 (cdfid, iv, elm.coords, (void *) &elm.val) != -1) {
413 	    error("%s: ncvarput1 should fail for negative coordinate", pname);
414 	    ncclose(cdfid); return ++nerrs;
415 	}
416 	elm.coords[test.vars[iv].ndims/2] =
417 	  test.dims[test.vars[iv].dims[test.vars[iv].ndims/2]].size;
418 	if(ncvarput1 (cdfid, iv, elm.coords, (void *) &elm.val) != -1) {
419 	    error("%s: ncvarput1 should fail for too-high coordinate", pname);
420 	    ncclose(cdfid); return ++nerrs;
421 	}
422     }
423     /* try with bad variable handle, should fail */
424     if(ncvarput1 (cdfid, -1, elm.coords, (void *) &elm.val) != -1 ||
425        ncvarput1 (cdfid, test.nvars, elm.coords, (void *) &elm.val) != -1) {
426 	error("%s: ncvarput1 should fail for bad variable handle", pname);
427 	ncclose(cdfid); return ++nerrs;
428     }
429     if (ncredef(cdfid) == -1) {
430 	error("%s: ncredef failed", pname);
431 	ncclose(cdfid); return ++nerrs;
432     }
433     /* try in define mode, should fail */
434     if (test.nvars > 0)
435       if(ncvarput1 (cdfid, 0, elm.coords, (void *) &elm.val) != -1) {
436 	  error("%s: ncvarput1 should fail in define mode", pname);
437 	  ncclose(cdfid); return ++nerrs;
438       }
439     if (ncendef (cdfid) == -1) {
440 	error("%s: ncendef failed", pname);
441 	ncclose(cdfid); return ++nerrs;
442     }
443     if (ncclose (cdfid) == -1) {
444 	error("%s: ncclose failed", pname);
445 	return ++nerrs;
446     }
447     /* try with bad netCDF handle, should fail */
448     if(ncvarput1 (cdfid, 0, elm.coords, (void *) &elm.val) != -1) {
449 	error("%s: ncvarput1 failed to report bad netcdf handle", pname);
450 	nerrs++;
451     }
452     if (nerrs > 0)
453       (void) fprintf(stderr,"FAILED! ***\n");
454     else
455       (void) fprintf(stderr,"ok ***\n");
456 
457     return nerrs;
458 }
459 
460 
461 /*
462  * Test ncvarget1
463  *    check that proper call worked after ncvarput1
464  *    try with negative coords, check error
465  *    try with too-large coords, check error
466  *    try with bad variable handle, check error
467  *    try in define mode, check error
468  *    try with bad netCDF handle, check error
469  */
470 int
test_ncvarget1(path)471 test_ncvarget1(path)
472      const char *path;		/* name of writable netcdf file to open */
473 {
474     int nerrs = 0;
475     static char pname[] = "test_ncvarget1";
476     int cdfid;			/* netcdf id */
477     int iv;			/* variable id */
478     struct cdfelm elm;		/* coordinates and value of test point */
479 
480     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
481 
482     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
483 	error("%s: ncopen failed", pname);
484 	return ++nerrs;
485     }
486     /* opened in data mode, try putting and getting values of each type */
487     nerrs += test_varputget1 (cdfid);	/* tests ncvarput1 and ncvarget1 */
488 
489     /* find a variable with at least one dimension */
490     iv = 0;
491     while (test.vars[iv].ndims <= 0 && iv < test.nvars)
492       iv++;
493     if (iv < test.nvars) {	/* iv is varid of variable with dimensions */
494 	/* set coords */
495 	int id;			/* dimension id */
496 	for (id = 0; id < test.vars[iv].ndims; id++)
497 	  elm.coords[id] = 0;
498 	/* try invalid coordinates, should fail */
499 	elm.coords[test.vars[iv].ndims/2] = -1;
500 	if(ncvarget1 (cdfid, iv, elm.coords, (void *) &elm.val) != -1) {
501 	    error("%s: ncvarget1 should fail for negative coordinate", pname);
502 	    ncclose(cdfid); return ++nerrs;
503 	}
504 	elm.coords[test.vars[iv].ndims/2] =
505 	  test.dims[test.vars[iv].dims[test.vars[iv].ndims/2]].size;
506 	if(ncvarget1 (cdfid, iv, elm.coords, (void *) &elm.val) != -1) {
507 	    error("%s: ncvarget1 should fail for too-high coordinate", pname);
508 	    ncclose(cdfid); return ++nerrs;
509 	}
510     }
511     /* try with bad variable handle, should fail */
512     if(ncvarget1 (cdfid, -1, elm.coords, (void *) &elm.val) != -1 ||
513        ncvarget1 (cdfid, test.nvars, elm.coords, (void *) &elm.val) != -1) {
514 	error("%s: ncvarget1 should fail for bad variable handle", pname);
515 	ncclose(cdfid); return ++nerrs;
516     }
517     if (ncredef(cdfid) == -1) {
518 	error("%s: ncredef failed", pname);
519 	ncclose(cdfid); return ++nerrs;
520     }
521     /* try in define mode, should fail */
522     if (test.nvars > 0)
523       if(ncvarget1 (cdfid, 0, elm.coords, (void *) &elm.val) != -1) {
524 	  error("%s: ncvarget1 should fail in define mode",
525 		pname);
526 	  ncclose(cdfid); return ++nerrs;
527       }
528     if (ncendef (cdfid) == -1) {
529 	error("%s: ncendef failed", pname);
530 	ncclose(cdfid); return ++nerrs;
531     }
532     if (ncclose (cdfid) == -1) {
533 	error("%s: ncclose failed", pname);
534 	return ++nerrs;
535     }
536     /* try with bad netCDF handle, should fail */
537     if(ncvarget1 (cdfid, 0, elm.coords, (void *) &elm.val) != -1) {
538 	error("%s: ncvarget1 failed to report bad netcdf handle", pname);
539 	nerrs++;
540     }
541     if (nerrs > 0)
542       (void) fprintf(stderr,"FAILED! ***\n");
543     else
544       (void) fprintf(stderr,"ok ***\n");
545 
546     return nerrs;
547 }
548 
549 
550 /*
551  * Test ncvarrename
552  *    check that proper rename worked with ncvarinq
553  *    try with bad netCDF handle, check error
554  *    try in data mode, check error
555  *    try with bad variable handle, check error
556  *    try renaming to existing variable name, check error
557  */
558 int
test_ncvarrename(path)559 test_ncvarrename(path)
560      const char *path;		/* name of writable netcdf file to open */
561 {
562     int nerrs = 0;
563     static char pname[] = "test_ncvarrename";
564     int cdfid;			/* netcdf id */
565     int id;			/* dimension id */
566     int yy_id;			/* variable id */
567     static struct cdfvar yy =	/* variable */
568       {"old_name", NC_SHORT, 1, ___, 0};
569     static char newname[] = "yyy"; /* variable name */
570     static char shortname[] = "yy"; /* variable name */
571     struct cdfvar var;		/* variable */
572     static struct cdfvar zz =	/* variable */
573       {"zz", NC_BYTE, 2, ___, 0};
574 
575     (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);
576 
577     if ((cdfid = ncopen(path, NC_WRITE)) == -1) {
578 	error("%s: ncopen failed", pname);
579 	return ++nerrs;
580     }
581     /* opened */
582     if (ncredef(cdfid) == -1) {
583 	error("%s: ncredef failed", pname);
584 	ncclose(cdfid); return ++nerrs;
585     }
586     /* in define mode, add two variables */
587     yy.dims = (int *) emalloc(sizeof(int) * yy.ndims);
588     for (id = 0; id < yy.ndims; id++)
589       yy.dims[id] = id;
590     if ((yy_id = ncvardef(cdfid,
591 			   yy.name, yy.type, yy.ndims, yy.dims)) == -1) {
592 	error("%s: ncvardef failed", pname);
593 	ncclose(cdfid); return ++nerrs;
594     }
595     add_var(&test, &yy);	/* keep in-memory netcdf in sync */
596     zz.dims = (int *) emalloc(sizeof(int) * zz.ndims);
597     for (id = 0; id < zz.ndims; id++)
598       zz.dims[id] = id;
599     if (ncvardef(cdfid, zz.name, zz.type, zz.ndims, zz.dims) == -1) {
600 	error("%s: ncvardef failed", pname);
601 	ncclose(cdfid); return ++nerrs;
602     }
603     add_var(&test, &zz);	/* keep in-memory netcdf in sync */
604 
605     /* rename first variable */
606     if (ncvarrename(cdfid, yy_id, newname) == -1) {
607 	error("%s: ncvarrename failed", pname);
608 	ncclose(cdfid); return ++nerrs;
609     }
610     /* check new name with ncvarid, ncvarinq */
611     if (yy_id != ncvarid(cdfid, newname)) {
612         error("%s: lookup by name failed after ncvarrename", pname);
613     }
614     var.dims = (int *) emalloc(sizeof(int) * MAX_VAR_DIMS);
615     var.name = (char *) emalloc(MAX_NC_NAME);
616     if (ncvarinq(cdfid, yy_id, var.name,
617 		  &var.type, &var.ndims, var.dims, &var.natts) == -1) {
618 	error("%s: ncvarinq failed", pname);
619 	ncclose(cdfid); return ++nerrs;
620     }
621     if (strcmp(var.name,yy.name) == 0) {
622 	error("%s: ncvarrename failed to change name", pname);
623 	ncclose(cdfid); return ++nerrs;
624     }
625     if (strcmp(var.name,newname) != 0) {
626 	error("%s: ncvarrename changed name to %s instead of %s",
627 	      pname, var.name, newname);
628 	ncclose(cdfid); return ++nerrs;
629     }
630     (void) strcpy(test.vars[yy_id].name, newname); /* keep test consistent */
631     /* try to rename second variable same as first, should fail */
632     if (ncvarrename(cdfid, yy_id, zz.name) != -1) {
633 	error("%s: ncvarrename should have failed with used name", pname);
634 	ncclose(cdfid); return ++nerrs;
635     }
636     /* try with bad variable handles, check for failure */
637     if (ncvarrename(cdfid, -1, var.name) != -1 ||
638 	ncvarrename(cdfid, test.nvars, var.name) != -1) {
639 	error("%s: ncvarrename should have failed on bad variable ids",
640 	      pname);
641 	ncclose(cdfid); return ++nerrs;
642     }
643     if (ncendef (cdfid) == -1) {
644 	error("%s: ncendef failed", pname);
645 	ncclose(cdfid); return ++nerrs;
646     }
647     /* in data mode */
648     if (ncvarrename(cdfid, yy_id, "a_longer_name") != -1) {
649 	error("%s: ncvarrename to longer should fail in data mode", pname);
650 	ncclose(cdfid); return ++nerrs;
651     }
652     if (ncvarrename(cdfid, yy_id, shortname) == -1) {
653 	error("%s: ncvarrename to shorter should succeed in data mode", pname);
654 	ncclose(cdfid); return ++nerrs;
655     }
656     (void) strcpy(test.vars[yy_id].name, shortname); /* keep test consistent */
657     /* check new name with ncvarid, ncvarinq */
658     if (yy_id != ncvarid(cdfid, shortname)) {
659         error("%s: lookup by name in data mode failed after ncvarrename",
660 	      pname);
661     }
662     if (ncclose (cdfid) == -1) {
663 	error("%s: ncclose failed", pname);
664 	return ++nerrs;
665     }
666     /* should fail, since bad handle */
667     if (ncvarrename (cdfid, 0, var.name) != -1) {
668 	error("%s: ncvarrename failed to report bad netcdf handle ", pname);
669 	nerrs++;
670     }
671     free(yy.dims);
672     free(zz.dims);
673     free(var.name);
674     free(var.dims);
675     if (nerrs > 0)
676       (void) fprintf(stderr,"FAILED! ***\n");
677     else
678       (void) fprintf(stderr,"ok ***\n");
679 
680     return nerrs;
681 }
682