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