1/*
2 *    Copyright 1990, University Corporation for Atmospheric Research
3 *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 */
5/* $Id: jackets-linux.c 4772 2006-11-01 16:53:11Z epourmal $ */
6/*
7 * OVERVIEW
8 *
9 * This file contains jacket routines written in C for interfacing Fortran
10 * netCDF function calls to the actual C binding for the NetCDF.  This code
11 * is written explicitly for Sun.  In general, these functions handle
12 * character-string parameter conventions, convert between
13 * column-major-order arrays and row-major-order arrays, and map between
14 * array indices beginning at one and array indices beginning at zero.
15 *
16 */
17
18/* LINTLIBRARY */
19#include    <ctype.h>
20#include        <string.h>
21#include    <stdlib.h>
22#include    <stdio.h>
23#ifdef HDF
24#include        "local_nc.h"
25#else /* HDF */
26#include    "netcdf.h"
27#endif /* HDF */
28
29
30
31
32
33#if !NC_OLD_FILLVALUES
34
35struct ncfils {            /* This will be a common block from Fortran */
36    double dd;
37#if defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
38    int ll;
39#else
40    long ll;
41#endif
42    float ff;
43    short ss;
44    char cc;
45    char bb;
46} ncfils_ = {
47    FILL_DOUBLE,
48    FILL_LONG,
49    FILL_FLOAT,
50    FILL_SHORT,
51    FILL_CHAR,
52    FILL_BYTE
53};
54
55#else    /* NC_OLD_FILLVALUES below */
56
57/*
58 * This section is provided for backward compatibility only.  Using
59 * XDR infinities for floating-point fill values has caused more problems
60 * than it has solved.  We encourage you to define your own data-specific
61 * fill values rather than use default ones.
62 * If, however, you *must* use default fill values, then you should use
63 * the above fill values rather than the ones in this section.
64 */
65
66struct ncfils {            /* This will be a common block from Fortran */
67    double dd;
68#if defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
69    int ll;
70#else
71    long ll;
72#endif
73    float ff;
74    short ss;
75    char cc;
76    char bb;
77} ncfils_ = {
78    XDR_D_INFINITY,        /* You may have to insert a constant here */
79    FILL_LONG,
80    XDR_F_INFINITY,        /* You may have to insert a constant here */
81    FILL_SHORT,
82    FILL_CHAR,
83    FILL_BYTE
84};
85
86#endif    /* NC_OLD_FILLVALUES above */
87
88/* blank fill C string to make FORTRAN string */
89static void
90fcdcpy (fstring, fslen, sstring)
91    char *fstring;        /* output string to be blank-filled */
92    int fslen;            /* length of output string */
93    char *sstring;        /* input string, null-terminated */
94{
95    int i, len = strlen(sstring);
96
97    for (i = 0; i < len; i++)
98    *(fstring + i) = *(sstring + i);
99    for (i = len; i < fslen; i++)
100    *(fstring + i) = ' ';
101}
102
103
104static void
105reverse (array, length)
106    int array[];        /* array to be reversed */
107    int length;            /* length of array */
108{
109    int temp, i, j;
110
111    for (i = 0, j = length - 1; i < j; i++, j--) {
112    temp = array[i];
113    array[i] = array[j];
114    array[j] = temp;
115    }
116}
117
118
119static void
120revlongs (array, length)
121    long array[];        /* array to be reversed */
122    int length;            /* length of array */
123{
124    int i, j;
125    long temp;
126
127    for (i = 0, j = length - 1; i < j; i++, j--) {
128    temp = array[i];
129    array[i] = array[j];
130    array[j] = temp;
131    }
132}
133
134
135/* error handling function */
136static void
137handle_err (pname, rcode)
138    char *pname;        /* procedure name */
139    int rcode;            /* error return */
140{
141    cdf_routine_name = pname;
142    NCadvise(rcode, "string won't fit in CHARACTER variable provided");
143}
144
145/* copy function used to copy strings with embedded blanks */
146static void
147fstrncpy (target, source, maxlen)
148    char *target;        /* space to be copied into */
149    char *source;        /* string to be copied */
150    int maxlen;            /* maximum length of *source */
151{
152    while (maxlen-- && *source != '\0')
153    *target++ = *source++;
154    *target = '\0';
155}
156#ifdef WE_COULDNT_READ_NAMES_WITH_SPACES
157/* copy function used to copy strings terminated with blanks */
158static void
159nstrncpy (target, source, maxlen)
160    char *target;        /* space to be copied into */
161    char *source;        /* string to be copied */
162    int maxlen;            /* maximum length of *source */
163{
164    while (maxlen-- && *source != ' ')
165    *target++ = *source++;
166    *target = '\0';
167}
168#endif
169
170/* copy function used to copy strings with embeded blanks and
171   terminated with blanks */
172static void
173nstrncpy (target, source, maxlen)
174    char *target;        /* space to be copied into */
175    char *source;        /* string to be copied */
176    int maxlen;            /* maximum length of *source */
177{
178/* Copy all string */
179    while (maxlen--)
180        *target++ = *source++;
181    *target -- = '\0';
182/* Disregard all trailing spaces  */
183     while (*target == ' ')
184         *target-- = '\0';
185
186}
187
188/*
189 * Compute product of dimensions.
190 */
191static long
192dimprod (dims, ndims)
193     long *dims;            /* list of dimensions */
194     int ndims;            /* number of dimensions in list */
195{
196    long *ip;
197    long prod = 1;
198
199    for (ip = dims; ip < &dims[ndims]; ip++)
200      prod *= *ip;
201    return prod;
202}
203
204
205#ifdef FORTRAN_HAS_NO_BYTE
206/*
207 * Convert multi-dimensional array of bytes stored in ints to packed array of
208 * bytes, in malloc'ed space.  Returns pointer to bytes or NULL if malloc
209 * failed.
210 */
211static char *
212itob(ints, dims, ndims)
213     int *ints;            /* multi-dimensional array of integers */
214     long *dims;            /* list of dimensions */
215     int ndims;            /* number of dimensions in list */
216{
217    long iocount = dimprod (dims, ndims);    /* product of dimensions */
218    char *bytes = (char *) malloc (iocount * sizeof (char));
219    int *ip;
220    char *bp = bytes;
221
222    if (bytes != NULL)
223      for (ip = ints; iocount > 0; iocount--)
224    *bp++ = (char) *ip++;
225    return bytes;
226}
227
228/*
229 * Convert a generalized multi-dimensional array of bytes stored in ints to
230 * packed array of bytes, in malloc'ed space.  Returns pointer to bytes or
231 * NULL if malloc failed.
232 */
233static char *
234itobg(ints, dims, basis, ndims)
235     int *ints;            /* multi-dimensional array of integers */
236     long *dims;            /* list of dimensions */
237     long *basis;            /* memory access basis vector */
238     int ndims;            /* number of dimensions in list */
239{
240    long iocount = dimprod (dims, ndims);    /* product of dimensions */
241    char *bytes = (char *) malloc (iocount * sizeof (char));
242
243    if (bytes != NULL && iocount > 0) {
244    int    idim;
245    char    *bp    = bytes;
246    char    *ip    = (char*)ints;
247    long    length[MAX_NC_DIMS];
248    long    coords[MAX_NC_DIMS];
249
250    for (idim = 0; idim < ndims; ++idim) {
251        length[idim]    = dims[idim]*basis[idim];
252        coords[idim]    = 0;
253    }
254
255    for (;;) {
256        *bp++    = (char)*(int*)ip;
257        idim    = ndims - 1;
258    carry:
259        ip    += basis[idim];
260        if (++coords[idim] >= dims[idim]) {
261        coords[idim]    = 0;
262        ip        -= length[idim];
263        if (--idim < 0)
264            break;
265        goto carry;
266        }
267        }
268    }
269
270    return bytes;
271}
272
273/*
274 * Convert a packed array of bytes into a generalized multi-dimensional array
275 * of ints.
276 */
277static void
278btoig(bytes, ints, dims, basis, ndims)
279     char *bytes;        /* packed array of bytes */
280     int *ints;            /* multi-dimensional array of integers */
281     long *dims;        /* list of dimensions */
282     long *basis;        /* memory access basis vector */
283     int ndims;            /* number of dimensions in list */
284{
285    if (dimprod (dims, ndims) > 0) {
286    int    idim;
287    char    *bp    = bytes;
288    char    *ip    = (char*)ints;
289    long    length[MAX_NC_DIMS];
290    long    coords[MAX_NC_DIMS];
291
292    for (idim = 0; idim < ndims; ++idim) {
293        length[idim]    = dims[idim]*basis[idim];
294        coords[idim]    = 0;
295    }
296
297    for (;;) {
298        *(int*)ip    = *bp++;
299        idim    = ndims - 1;
300    carry:
301        ip    += basis[idim];
302        if (++coords[idim] >= dims[idim]) {
303        coords[idim]    = 0;
304        ip        -= length[idim];
305        if (--idim < 0)
306            break;
307        goto carry;
308        }
309        }
310    }
311}
312#endif /* FORTRAN_HAS_NO_BYTE */
313
314#ifdef FORTRAN_HAS_NO_SHORT
315/*
316 * Convert multi-dimensional array of shorts stored in ints to packed array of
317 * shorts, in malloc'ed space.  Returns pointer to shorts or NULL if malloc
318 * failed.
319 */
320static short *
321itos(ints, dims, ndims)
322     int *ints;        /* multi-dimensional array of ints */
323     long *dims;            /* list of dimensions */
324     int ndims;            /* number of dimensions in list */
325{
326    long iocount = dimprod (dims, ndims);    /* product of dimensions */
327    short *shorts = (short *) malloc (iocount * sizeof (short));
328    int *ip;
329    short *sp = shorts;
330
331    if (shorts != NULL)
332      for (ip = ints; iocount > 0; iocount--)
333    *sp++ = (short) *ip++;
334    return shorts;
335}
336
337/*
338 * Convert a generalized multi-dimensional array of shorts stored in ints to
339 * packed array of shorts, in malloc'ed space.  Returns pointer to shorts or
340 * NULL if malloc failed.
341 */
342static short *
343itosg(ints, dims, basis, ndims)
344     int *ints;            /* multi-dimensional array of integers */
345     long *dims;            /* list of dimensions */
346     long *basis;            /* memory access basis vector */
347     int ndims;            /* number of dimensions in list */
348{
349    long iocount = dimprod (dims, ndims);    /* product of dimensions */
350    short *shorts = (short *) malloc (iocount * sizeof (short));
351
352    if (shorts != NULL && iocount > 0) {
353    int    idim;
354    char    *ip    = (char*)ints;
355    short    *sp    = shorts;
356    long    length[MAX_NC_DIMS];
357    long    coords[MAX_NC_DIMS];
358
359    for (idim = 0; idim < ndims; ++idim) {
360        length[idim]    = dims[idim]*basis[idim];
361        coords[idim]    = 0;
362    }
363
364    for (;;) {
365        *sp++    = (short)*(int*)ip;
366        idim    = ndims - 1;
367    carry:
368        ip    += basis[idim];
369        if (++coords[idim] >= dims[idim]) {
370        coords[idim]    = 0;
371        ip        -= length[idim];
372        if (--idim < 0)
373            break;
374        goto carry;
375        }
376        }
377    }
378
379    return shorts;
380}
381
382/*
383 * Convert a packed array of shorts into a generalized multi-dimensional array
384 * of ints.
385 */
386static void
387stoig(shorts, ints, dims, basis, ndims)
388     short *shorts;        /* packed array of shorts */
389     int *ints;            /* multi-dimensional array of integers */
390     long *dims;        /* list of dimensions */
391     long *basis;        /* memory access basis vector */
392     int ndims;            /* number of dimensions in list */
393{
394    if (dimprod (dims, ndims) > 0) {
395    int    idim;
396    short    *sp    = shorts;
397    char    *ip    = (char*)ints;
398    long    length[MAX_NC_DIMS];
399    long    coords[MAX_NC_DIMS];
400
401    for (idim = 0; idim < ndims; ++idim) {
402        length[idim]    = dims[idim]*basis[idim];
403        coords[idim]    = 0;
404    }
405
406    for (;;) {
407        *(int*)ip    = *sp++;
408        idim    = ndims - 1;
409    carry:
410        ip    += basis[idim];
411        if (++coords[idim] >= dims[idim]) {
412        coords[idim]    = 0;
413        ip        -= length[idim];
414        if (--idim < 0)
415            break;
416        goto carry;
417        }
418        }
419    }
420}
421#endif /* FORTRAN_HAS_NO_SHORT */
422
423#if defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
424/*
425 * Convert multi-dimensional array of NCLONGs stored in ints to packed
426 * array of longs, in malloc'ed space.  Returns pointer to longs or NULL
427 * if malloc failed.
428 */
429static long *
430itol(ints, dims, ndims)
431    int        *ints;        /* multi-dimensional array of ints */
432    long    *dims;        /* list of dimensions */
433    int        ndims;        /* number of dimensions in list */
434{
435    long    iocount = dimprod (dims, ndims);
436    long    *longs = (long *) malloc (iocount * sizeof (long));
437    int        *ip;
438    long    *lp = longs;
439
440    if (longs != NULL)
441    for (ip = ints; iocount > 0; iocount--)
442        *lp++ = (long) *ip++;
443    return longs;
444}
445
446/*
447 * Convert a generalized multi-dimensional array of longs stored in ints to
448 * packed array of longs, in malloc'ed space.  Returns pointer to longs or
449 * NULL if malloc failed.
450 */
451static long *
452itolg(ints, dims, imap, ndims)
453    int        *ints;        /* multi-dimensional array of integers */
454    long    *dims;        /* list of dimensions */
455    long    *imap;        /* memory access index mapping vector */
456    int        ndims;        /* number of dimensions in list */
457{
458    long    iocount = dimprod (dims, ndims);
459    long    *longs = (long *) malloc (iocount * sizeof (long));
460
461    if (longs != NULL && iocount > 0) {
462    int    idim;
463    char    *ip    = (char*)ints;
464    long    *lp    = longs;
465    long    length[MAX_NC_DIMS];
466    long    coords[MAX_NC_DIMS];
467
468    for (idim = 0; idim < ndims; ++idim) {
469        length[idim]    = dims[idim]*imap[idim];
470        coords[idim]    = 0;
471    }
472
473    for (;;) {
474        *lp++    = (long)*(int*)ip;
475        idim    = ndims - 1;
476    carry:
477        ip    += imap[idim];
478        if (++coords[idim] >= dims[idim]) {
479        coords[idim]    = 0;
480        ip        -= length[idim];
481        if (--idim < 0)
482            break;
483        goto carry;
484        }
485        }
486    }
487
488    return longs;
489}
490
491/*
492 * Convert a packed array of longs into a generalized multi-dimensional array
493 * of ints.
494 */
495static void
496ltoig(longs, ints, dims, imap, ndims)
497    long    *longs;        /* packed array of longs */
498    int        *ints;        /* multi-dimensional array of integers */
499    long    *dims;        /* list of dimensions */
500    long    *imap;        /* memory access index mapping vector */
501    int        ndims;        /* number of dimensions in list */
502{
503    if (dimprod (dims, ndims) > 0) {
504    int    idim;
505    long    *lp    = longs;
506    char    *ip    = (char*)ints;
507    long    length[MAX_NC_DIMS];
508    long    coords[MAX_NC_DIMS];
509
510    for (idim = 0; idim < ndims; ++idim) {
511        length[idim]    = dims[idim]*imap[idim];
512        coords[idim]    = 0;
513    }
514
515    for (;;) {
516        *(int*)ip    = *lp++;
517        idim    = ndims - 1;
518    carry:
519        ip    += imap[idim];
520        if (++coords[idim] >= dims[idim]) {
521        coords[idim]    = 0;
522        ip        -= length[idim];
523        if (--idim < 0)
524            break;
525        goto carry;
526        }
527        }
528    }
529}
530#endif    /* Alpha platform above */
531
532/* ------------ Linux FORTRAN jackets for netCDF Functions ------------ */
533
534/* used to set the C global variable ncopts from Fortran */
535void
536nncpopt(val)
537    int        *val;
538{
539    ncopts = *val;
540}
541
542
543/* used to get the C global variable ncopts from Fortran */
544void
545nncgopt(val)
546    int        *val;
547{
548    *val = ncopts;
549}
550
551/*
552 * creates a new netCDF file, returning a netCDF ID.  New netCDF
553 * file is placed in define mode.
554 */
555int
556nnccre(pathname, clobmode, rcode, pathnamelen)
557    char    *pathname;
558    int        pathnamelen;
559    int        *clobmode;
560    int        *rcode;
561{
562    char name[MAX_NC_NAME + 1];
563    int cdfid;
564
565    nstrncpy (name, pathname, pathnamelen);
566    if ((cdfid = nccreate (name, *clobmode)) != -1) {
567    *rcode = 0;
568    return (cdfid);
569    }
570    *rcode = ncerr;
571    return (-1);
572}
573
574
575/* opens an existing netCDF file for access */
576int
577nncopn(pathname, rwmode, rcode, pathnamelen)
578    char    *pathname;
579    int        pathnamelen;
580    int        *rwmode;
581    int        *rcode;
582{
583    char name[MAX_NC_NAME + 1];
584    int cdfid;
585
586    nstrncpy (name, pathname, pathnamelen);
587    if ((cdfid = ncopen (name, *rwmode)) != -1) {
588    *rcode = 0;
589    return (cdfid);
590    }
591    *rcode = ncerr;
592    return (-1);
593}
594
595
596/* adds a new dimension to an open netCDF file in define mode */
597int
598nncddef(cdfid, dimname, dimlen, rcode, dimnamelen)
599    int        *cdfid;
600    char    *dimname;
601    int        dimnamelen;
602    int        *dimlen;
603    int        *rcode;
604{
605    char name[MAX_NC_NAME + 1];
606    int dimid;
607
608    nstrncpy (name, dimname, dimnamelen);
609    if ((dimid = ncdimdef (*cdfid, name, (long)*dimlen)) != -1) {
610    *rcode = 0;
611    return (dimid + 1);
612    }
613    *rcode = ncerr;
614    return (-1);
615}
616
617
618/*
619 * returns the ID of a netCDF dimension, given the name of the
620 * dimension
621 */
622int
623nncdid(cdfid, dimname, rcode, dimnamelen)
624    int        *cdfid;
625    char    *dimname;
626    int        dimnamelen;
627    int        *rcode;
628{
629    char name[MAX_NC_NAME + 1];
630    int dimid;
631
632    nstrncpy (name, dimname, dimnamelen);
633    if ((dimid = ncdimid (*cdfid, name)) != -1) {
634    *rcode = 0;
635    return (dimid + 1);
636    }
637    *rcode = ncerr;
638    return (-1);
639}
640
641
642/* adds a new variable to an open netCDF file in define mode */
643int
644nncvdef(cdfid, varname, datatype, ndims, dimarray, rcode, varnamelen)
645    int        *cdfid;
646    char    *varname;
647    int        varnamelen;
648    int        *datatype;
649    int        *ndims;
650    int        *dimarray;
651    int        *rcode;
652{
653    int varid, i, dimid[MAX_VAR_DIMS];
654    char name[MAX_NC_NAME + 1];
655
656    nstrncpy (name, varname, varnamelen);
657    for (i = 0; i < *ndims; i++)
658    dimid[i] = dimarray[i] - 1;
659    reverse (dimid, *ndims);
660    if ((varid = ncvardef (*cdfid, name, (nc_type) *datatype, *ndims,
661            dimid)) != -1) {
662    *rcode = 0;
663    return (varid + 1);
664    }
665    *rcode = ncerr;
666    return (-1);
667}
668
669
670/* returns the ID of a netCDF variable given its name */
671int
672nncvid(cdfid, varname, rcode, varnamelen)
673    int        *cdfid;
674    char    *varname;
675    int        varnamelen;
676    int        *rcode;
677{
678    int varid;
679    char name[MAX_NC_NAME + 1];
680
681    nstrncpy (name, varname, varnamelen);
682    if ((varid = ncvarid (*cdfid, name)) != -1) {
683    *rcode = 0;
684    return (varid + 1);
685    }
686    *rcode = ncerr;
687    return (-1);
688}
689
690
691/* returns number of bytes per netCDF data type */
692int
693nnctlen(datatype, rcode)
694    int        *datatype;
695    int        *rcode;
696{
697    int itype;
698
699    if ((itype = nctypelen ((nc_type) *datatype)) != -1) {
700    *rcode = 0;
701    return (itype);
702    }
703    *rcode = ncerr;
704    return (-1);
705}
706
707/* closes an open netCDF file */
708void
709nncclos(cdfid, rcode)
710    int        *cdfid;
711    int        *rcode;
712{
713    *rcode = 0;
714    if (ncclose (*cdfid) == -1)
715    *rcode = ncerr;
716}
717
718/* puts an open netCDF into define mode */
719void
720nncredf(cdfid, rcode)
721    int        *cdfid;
722    int        *rcode;
723{
724    *rcode = 0;
725    if (ncredef (*cdfid) == -1)
726    *rcode = ncerr;
727}
728
729/* takes an open netCDF out of define mode */
730void
731nncendf(cdfid, rcode)
732    int        *cdfid;
733    int        *rcode;
734{
735    *rcode = 0;
736    if (ncendef (*cdfid) == -1)
737    *rcode = ncerr;
738}
739
740/* returns information about an open netCDF file given its netCDF ID */
741void
742nncinq(cdfid, ndims, nvars, natts, recdim, rcode)
743    int        *cdfid;
744    int        *ndims;
745    int        *nvars;
746    int        *natts;
747    int        *recdim;
748    int        *rcode;
749{
750    *rcode = 0;
751    if (ncinquire (*cdfid, ndims, nvars, natts, recdim) == -1) {
752    *rcode = ncerr;
753    return;
754    }
755    if (*recdim != -1)
756    (*recdim)++;
757}
758
759/*
760 * makes sure that the disk copy of a netCDF file open for writing
761 * is current
762 */
763void
764nncsnc(cdfid, rcode)
765    int        *cdfid;
766    int        *rcode;
767{
768    *rcode = 0;
769    if (ncsync (*cdfid) == -1)
770    *rcode = ncerr;
771}
772
773/*
774 * restores the netCDF to a known consistent state in case anything
775 * goes wrong during the definition of new dimensions, variables
776 * or attributes
777 */
778void
779nncabor(cdfid, rcode)
780    int        *cdfid;
781    int        *rcode;
782{
783    *rcode = 0;
784    if (ncabort (*cdfid) == -1)
785    *rcode = ncerr;
786}
787
788/* returns the name and size of a dimension, given its ID */
789void
790nncdinq(cdfid, dimid, dimname, size, rcode, dimnamelen)
791    int        *cdfid;
792    int        *dimid;
793    char    *dimname;
794    int        dimnamelen;
795    int        *size;
796    int        *rcode;
797{
798    long siz;
799    char name[MAX_NC_NAME + 1];
800
801    *rcode = 0;
802    if (ncdiminq (*cdfid, *dimid - 1, name, &siz) == -1) {
803    *rcode = ncerr;
804    return;
805    }
806    *size = siz;
807    if (strlen (name) > dimnamelen) {
808    *rcode = NC_ESTS;
809    handle_err ("NCDINQ", *rcode);
810    return;
811    }
812    /* blank fill the input character string */
813    fcdcpy (dimname, dimnamelen, name);
814}
815
816/* renames an existing dimension in a netCDF open for writing */
817void
818nncdren(cdfid, dimid, dimname, rcode, dimnamelen)
819    int        *cdfid;
820    int        *dimid;
821    char    *dimname;
822    int        dimnamelen;
823    int        *rcode;
824{
825    char name[MAX_NC_NAME + 1];
826
827    nstrncpy (name, dimname, dimnamelen);
828    *rcode = 0;
829    if (ncdimrename (*cdfid, *dimid - 1, name) == -1)
830    *rcode = ncerr;
831}
832
833/* returns information about a netCDF variable, given its ID */
834void
835nncvinq(cdfid, varid, varname, datatype, ndims, dimarray, natts, rcode, varnamelen)
836    int        *cdfid;
837    int        *varid;
838    char    *varname;
839    int        varnamelen;
840    int        *datatype;
841    int        *ndims;
842    int        *dimarray;
843    int        *natts;
844    int        *rcode;
845{
846    char name[MAX_NC_NAME + 1];
847    int dimid[MAX_VAR_DIMS], i;
848
849    *rcode = 0;
850    if (ncvarinq (*cdfid, *varid - 1, name, (nc_type *) datatype, ndims, dimid,
851        natts) == -1) {
852    *rcode = ncerr;
853    return;
854    }
855    for (i = 0; i < *ndims; i++)
856    dimarray[i] = dimid[i] + 1;
857    reverse (dimarray, *ndims);
858    if (strlen (name) > varnamelen) {
859    *rcode = NC_ESTS;
860    handle_err ("NCVINQ", *rcode);
861    return;
862    }
863    fcdcpy (varname, varnamelen, name);
864}
865
866/* puts a single numeric data value into a variable of an open netCDF */
867void
868nncvpt1(cdfid, varid, indices, value, rcode)
869
870    int        *cdfid;
871    int        *varid;
872    int        *indices;
873    void    *value;
874    int        *rcode;
875{
876    int datatype, ndims, natts, i;
877    long nindices[MAX_VAR_DIMS];
878    int dimid[MAX_VAR_DIMS];
879#ifdef HDF
880    NC *handle=NC_check_id(*cdfid);
881#endif /* HDF */
882
883    if (ncvarinq (*cdfid, *varid - 1, (char *) 0,
884        (nc_type *) & datatype, &ndims, dimid, &natts) == -1) {
885    *rcode = ncerr;
886    return;
887    }
888    for (i = 0; i < ndims; i++)
889    nindices[i] = indices[i] - 1;
890    revlongs (nindices, ndims);
891    *rcode = 0;
892#ifdef FORTRAN_HAS_NO_BYTE
893    if ((nc_type) datatype == NC_BYTE) {    /* pack ints into bytes */
894    char           bytes = *(int *) value;
895    if (ncvarput1(*cdfid, *varid - 1, nindices,
896            (ncvoid *) &bytes) == -1) {
897        *rcode = ncerr;
898    }
899    return;
900    }                /* else */
901#endif                /* FORTRAN_HAS_NO_BYTE */
902#ifdef FORTRAN_HAS_NO_SHORT
903    if ((nc_type) datatype == NC_SHORT) {    /* pack ints into shorts */
904    short          shorts = *(int *)value;
905    if (ncvarput1(*cdfid, *varid - 1, nindices, (ncvoid *) &shorts) == -1) {
906        *rcode = ncerr;
907    }
908    return;
909    }                /* else */
910#endif                /* FORTRAN_HAS_NO_SHORT */
911#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
912#ifdef HDF
913    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
914    long          longs = *(int *)value;
915    if (ncvarput1(*cdfid, *varid - 1, nindices, (ncvoid *) &longs) == -1) {
916        *rcode = ncerr;
917    }
918    return;
919    }                /* else */
920#else /* HDF */
921    if ((nc_type) datatype == NC_LONG) {
922    long          longs = *(int *)value;
923    if (ncvarput1(*cdfid, *varid - 1, nindices, (ncvoid *) &longs) == -1) {
924        *rcode = ncerr;
925    }
926    return;
927    }                /* else */
928#endif /* HDF */
929#endif
930    if (ncvarput1 (*cdfid, *varid - 1, nindices, value) == -1) {
931    *rcode = ncerr;
932    }
933}
934
935/* puts a single character into an open netCDF file */
936void
937nncvp1c(cdfid, varid, indices, chval, rcode, chvallen)
938    int        *cdfid;
939    int        *varid;
940    int        *indices;
941    char    *chval;
942    int        chvallen;
943    int        *rcode;
944{
945    int datatype, ndims, natts, i;
946    long nindices[MAX_VAR_DIMS];
947    int dimid[MAX_VAR_DIMS];
948
949    if (ncvarinq (*cdfid, *varid - 1, (char *) 0,
950        (nc_type *) & datatype, &ndims, dimid, &natts) == -1) {
951    *rcode = ncerr;
952    return;
953    }
954    for (i = 0; i < ndims; i++)
955    nindices[i] = indices[i] - 1;
956    revlongs (nindices, ndims);
957    *rcode = 0;
958    if (ncvarput1 (*cdfid, *varid - 1, nindices, (ncvoid *) chval) == -1) {
959    *rcode = ncerr;
960    }
961}
962
963/*
964 * writes a hypercube of numeric values into a netCDF variable of an open
965 * netCDF file
966 */
967void
968nncvpt(cdfid, varid, start, count, value, rcode)
969    int        *cdfid;
970    int        *varid;
971    int        *start;
972    int        *count;
973    void    *value;
974    int        *rcode;
975{
976    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS], i;
977    int ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
978#ifdef HDF
979    NC *handle=NC_check_id(*cdfid);
980#endif /* HDF */
981
982    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
983        &ndims, dimarray, &natts) == -1) {
984    *rcode = ncerr;
985    return;
986    }
987    for (i = 0; i < ndims; i++) {
988    ncount[i] = count[i];
989    nstart[i] = start[i] - 1;
990    }
991    revlongs (ncount, ndims);
992    revlongs (nstart, ndims);
993
994    *rcode = 0;
995#ifdef FORTRAN_HAS_NO_BYTE
996    if ((nc_type) datatype == NC_BYTE) {    /* pack ints into bytes */
997    char *bytes = itob (value, ncount, ndims);
998    if (bytes == NULL) {
999        *rcode = NC_SYSERR;
1000        return;
1001        }
1002    if (ncvarput (*cdfid, *varid - 1, nstart, ncount,
1003                (ncvoid *) bytes) == -1) {
1004        *rcode = ncerr;
1005    }
1006    free (bytes);
1007    return;
1008    }                /* else */
1009#endif                /* FORTRAN_HAS_NO_BYTE */
1010#ifdef FORTRAN_HAS_NO_SHORT
1011    if ((nc_type) datatype == NC_SHORT) { /* pack ints into shorts */
1012    short *shorts = itos (value, ncount, ndims);
1013    if (shorts == NULL) {
1014        *rcode = NC_SYSERR;
1015        return;
1016        }
1017    if (ncvarput (*cdfid, *varid - 1, nstart, ncount,
1018            (ncvoid *) shorts) == -1) {
1019        *rcode = ncerr;
1020    }
1021    free (shorts);
1022    return;
1023    }                /* else */
1024#endif                /* FORTRAN_HAS_NO_SHORT */
1025#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1026#ifdef HDF
1027    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
1028    long *longs = itol (value, ncount, ndims);
1029    if (longs == NULL) {
1030        *rcode = NC_SYSERR;
1031        return;
1032        }
1033    if (ncvarput (*cdfid, *varid - 1, nstart, ncount,
1034                (ncvoid *) longs) == -1) {
1035        *rcode = ncerr;
1036    }
1037    free (longs);
1038    return;
1039    }                /* else */
1040#else /* HDF */
1041    if ((nc_type) datatype == NC_LONG) {
1042    long *longs = itol (value, ncount, ndims);
1043    if (longs == NULL) {
1044        *rcode = NC_SYSERR;
1045        return;
1046        }
1047    if (ncvarput (*cdfid, *varid - 1, nstart, ncount,
1048                (ncvoid *) longs) == -1) {
1049        *rcode = ncerr;
1050    }
1051    free (longs);
1052    return;
1053    }                /* else */
1054#endif /* HDF */
1055#endif
1056    if (ncvarput (*cdfid, *varid - 1, nstart, ncount, value) == -1) {
1057    *rcode = ncerr;
1058    }
1059}
1060
1061/* writes a hypercube of character values into an open netCDF file */
1062void
1063nncvptc(cdfid, varid, start, count, string, lenstr, rcode, stringlen)
1064    int        *cdfid;
1065    int        *varid;
1066    int        *start;
1067    int        *count;
1068    char    *string;
1069    int        stringlen;
1070    int        *lenstr;
1071    int        *rcode;
1072{
1073    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS], i;
1074    int ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1075
1076    if (ncvarinq (*cdfid, *varid - 1, (char *) 0,
1077        (nc_type *) & datatype, &ndims, dimarray, &natts) == -1) {
1078    *rcode = ncerr;
1079    return;
1080    }
1081    for (i = 0; i < ndims; i++) {
1082    ncount[i] = count[i];
1083    nstart[i] = start[i] - 1;
1084    }
1085    revlongs (ncount, ndims);
1086    revlongs (nstart, ndims);
1087    if (dimprod(ncount,ndims) > *lenstr) {
1088    *rcode = NC_ESTS;
1089    handle_err ("NCVPTC", *rcode);
1090    return;
1091    }
1092    *rcode = 0;
1093    if (ncvarput (*cdfid, *varid - 1, nstart, ncount, (ncvoid *) string) == -1) {
1094    *rcode = ncerr;
1095    }
1096}
1097
1098/*
1099 * writes a generalized hypercube of numeric values into a netCDF variable of
1100 * an open netCDF file
1101 */
1102void
1103nncvptg(cdfid, varid, start, count, stride, basis, value, rcode)
1104    int        *cdfid;
1105    int        *varid;
1106    int        *start;
1107    int        *count;
1108    int        *stride;
1109    int        *basis;
1110    void    *value;
1111    int        *rcode;
1112{
1113    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS], i;
1114    long nstride[MAX_VAR_DIMS], nbasis[MAX_VAR_DIMS];
1115    long tmpbasis;
1116    int ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1117#ifdef HDF
1118    NC *handle=NC_check_id(*cdfid);
1119#endif /* HDF */
1120
1121    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
1122        &ndims, dimarray, &natts) == -1) {
1123    *rcode = ncerr;
1124    return;
1125    }
1126#ifdef FORTRAN_HAS_NO_BYTE
1127    if (datatype == NC_CHAR || datatype == NC_BYTE)
1128    tmpbasis    = nctypelen(NC_LONG);
1129    else
1130#endif
1131#ifdef FORTRAN_HAS_NO_SHORT
1132    if (datatype == NC_SHORT)
1133    tmpbasis    = nctypelen(NC_LONG);
1134    else
1135#endif
1136#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1137    if (datatype == NC_LONG)
1138    tmpbasis    = sizeof(int);
1139    else
1140#endif
1141    tmpbasis    = nctypelen(datatype);
1142    for (i = 0; i < ndims; i++) {
1143    ncount[i] = count[i];
1144    nstart[i] = start[i] - 1;
1145    nstride[i] = stride[0] == 0 ? 1 : stride[i];
1146    nbasis[i] = basis[0] == 0 ? tmpbasis : basis[i];
1147    tmpbasis *= count[i];
1148    }
1149    revlongs (ncount, ndims);
1150    revlongs (nstart, ndims);
1151    revlongs (nstride, ndims);
1152    revlongs (nbasis, ndims);
1153
1154    *rcode = 0;
1155#ifdef FORTRAN_HAS_NO_BYTE
1156    if ((nc_type) datatype == NC_BYTE) {    /* pack ints into bytes */
1157    /*
1158    * Release 2.3.1 had a bug in the following line: it used count
1159    * rather than ncount.
1160    */
1161    char *bytes = itobg (value, ncount, nbasis, ndims);
1162    if (bytes == NULL) {
1163        *rcode = NC_SYSERR;
1164        return;
1165        }
1166    if (ncvarputg (*cdfid, *varid - 1, nstart, ncount, nstride,
1167            (long*)NULL, (ncvoid *) bytes) == -1) {
1168        *rcode = ncerr;
1169    }
1170    free (bytes);
1171    return;
1172    }                /* else */
1173#endif                /* FORTRAN_HAS_NO_BYTE */
1174#ifdef FORTRAN_HAS_NO_SHORT
1175    if ((nc_type) datatype == NC_SHORT) { /* pack ints into shorts */
1176    /*
1177    * Release 2.3.1 had a bug in the following line: it used count
1178    * rather than ncount.
1179    */
1180    short *shorts = itosg (value, ncount, nbasis, ndims);
1181    if (shorts == NULL) {
1182        *rcode = NC_SYSERR;
1183        return;
1184        }
1185    if (ncvarputg (*cdfid, *varid - 1, nstart, ncount, nstride,
1186            (long*)NULL, (ncvoid *) shorts) == -1) {
1187        *rcode = ncerr;
1188    }
1189    free (shorts);
1190    return;
1191    }                /* else */
1192#endif                /* FORTRAN_HAS_NO_SHORT */
1193#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1194#ifdef HDF
1195    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
1196    long *longs = itolg (value, ncount, nbasis, ndims);
1197    if (longs == NULL) {
1198        *rcode = NC_SYSERR;
1199        return;
1200        }
1201    if (ncvarputg (*cdfid, *varid - 1, nstart, ncount, nstride,
1202            (long*)NULL, (ncvoid *) longs) == -1) {
1203        *rcode = ncerr;
1204    }
1205    free (longs);
1206    return;
1207    }                /* else */
1208#else /* HDF */
1209    if ((nc_type) datatype == NC_LONG) {
1210    long *longs = itolg (value, ncount, nbasis, ndims);
1211    if (longs == NULL) {
1212        *rcode = NC_SYSERR;
1213        return;
1214        }
1215    if (ncvarputg (*cdfid, *varid - 1, nstart, ncount, nstride,
1216            (long*)NULL, (ncvoid *) longs) == -1) {
1217        *rcode = ncerr;
1218    }
1219    free (longs);
1220    return;
1221    }                /* else */
1222#endif /* HDF */
1223#endif
1224    if (ncvarputg (*cdfid, *varid - 1, nstart, ncount, nstride, nbasis,
1225        value) == -1) {
1226    *rcode = ncerr;
1227    }
1228}
1229
1230/*
1231 * writes a generalized hypercube of character values into a netCDF variable of
1232 * an open netCDF file
1233 */
1234void
1235nncvpgc(cdfid, varid, start, count, stride, basis, string, rcode, stringlen)
1236    int        *cdfid;
1237    int        *varid;
1238    int        *start;
1239    int        *count;
1240    int        *stride;
1241    int        *basis;
1242    char    *string;
1243    int        stringlen;
1244    int        *rcode;
1245{
1246    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS], i;
1247    long nstride[MAX_VAR_DIMS], nbasis[MAX_VAR_DIMS];
1248    long tmpbasis;
1249    int ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1250
1251    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
1252        &ndims, dimarray, &natts) == -1) {
1253    *rcode = ncerr;
1254    return;
1255    }
1256    tmpbasis    = nctypelen(datatype);
1257    for (i = 0; i < ndims; i++) {
1258    ncount[i] = count[i];
1259    nstart[i] = start[i] - 1;
1260    nstride[i] = stride[0] == 0 ? 1 : stride[i];
1261    nbasis[i] = basis[0] == 0 ? tmpbasis : basis[i];
1262    tmpbasis *= count[i];
1263    }
1264    revlongs (ncount, ndims);
1265    revlongs (nstart, ndims);
1266    revlongs (nstride, ndims);
1267    revlongs (nbasis, ndims);
1268
1269    *rcode = 0;
1270    if (ncvarputg (*cdfid, *varid - 1, nstart, ncount, nstride, nbasis,
1271        (ncvoid*)string) == -1) {
1272    *rcode = ncerr;
1273    }
1274}
1275
1276/* gets a single numeric value from a variable of an open netCDF file */
1277void
1278nncvgt1(cdfid, varid, indices, value, rcode)
1279    int        *cdfid;
1280    int        *varid;
1281    int        *indices;
1282    void    *value;
1283    int        *rcode;
1284{
1285    long nindices[MAX_VAR_DIMS], i;
1286    int datatype, ndims, dimarray[MAX_VAR_DIMS], natts;
1287#ifdef HDF
1288    NC *handle=NC_check_id(*cdfid);
1289#endif /* HDF */
1290
1291    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
1292        &ndims, dimarray, &natts) == -1) {
1293    *rcode = ncerr;
1294    return;
1295    }
1296    for (i = 0; i < ndims; i++) {
1297    nindices[i] = indices[i] - 1;
1298    }
1299    revlongs (nindices, ndims);
1300    *rcode = 0;
1301#ifdef FORTRAN_HAS_NO_BYTE
1302    if ((nc_type) datatype == NC_BYTE) {
1303    char           bytes;
1304    int            *ip = (int *) value;
1305    char           *bp = &bytes;
1306
1307    if (ncvarget1(*cdfid, *varid - 1, nindices, (ncvoid *) &bytes) == -1) {
1308        *rcode = ncerr;
1309        return;
1310    }
1311    *ip = *bp;
1312    return;
1313    }                /* else */
1314#endif                /* FORTRAN_HAS_NO_BYTE */
1315#ifdef FORTRAN_HAS_NO_SHORT
1316    if ((nc_type) datatype == NC_SHORT) {
1317    short          shorts;
1318    int            *ip = (int *) value;
1319    short          *sp = &shorts;
1320
1321    if (ncvarget1(*cdfid, *varid - 1, nindices, (ncvoid *) &shorts) == -1) {
1322        *rcode = ncerr;
1323        return;
1324    }
1325    *ip = *sp;
1326    return;
1327    }                /* else */
1328#endif                /* FORTRAN_HAS_NO_SHORT */
1329#if defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1330#ifdef HDF
1331    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
1332    long          longs;
1333    int           *ip = (int *) value;
1334
1335    if (ncvarget1(*cdfid, *varid - 1, nindices, (ncvoid *) &longs) == -1) {
1336        *rcode = ncerr;
1337        return;
1338    }
1339    *ip = longs;
1340    return;
1341    }                /* else */
1342#else /* HDF */
1343    if ((nc_type) datatype == NC_LONG) {
1344    long          longs;
1345    int           *ip = (int *) value;
1346
1347    if (ncvarget1(*cdfid, *varid - 1, nindices, (ncvoid *) &longs) == -1) {
1348        *rcode = ncerr;
1349        return;
1350    }
1351    *ip = longs;
1352    return;
1353    }                /* else */
1354#endif /* HDF */
1355#endif
1356    if (ncvarget1 (*cdfid, *varid - 1, nindices, value) == -1) {
1357    *rcode = ncerr;
1358    }
1359}
1360
1361/*
1362 * gets a single character data value from a variable of an open
1363 * netCDF file
1364 */
1365void
1366nncvg1c(cdfid, varid, indices, chval, rcode, chvallen)
1367    int        *cdfid;
1368    int        *varid;
1369    int        *indices;
1370    char    *chval;
1371    int        chvallen;
1372    int        *rcode;
1373{
1374    long nindices[MAX_VAR_DIMS];
1375    int i, datatype, ndims, dimarray[MAX_VAR_DIMS], natts;
1376
1377    if (ncvarinq (*cdfid, *varid - 1, (char *) 0,
1378        (nc_type *) & datatype, &ndims, dimarray, &natts) == -1) {
1379    *rcode = ncerr;
1380    return;
1381    }
1382
1383    for (i = 0; i < ndims; i++) {
1384    nindices[i] = indices[i] - 1;
1385    }
1386    revlongs (nindices, ndims);
1387    *rcode = 0;
1388    if (ncvarget1 (*cdfid, *varid - 1, nindices, (ncvoid *) chval) == -1) {
1389    *rcode = ncerr;
1390    }
1391}
1392
1393/*
1394 * reads a hypercube of numeric values from a netCDF variable of an open
1395 * netCDF file
1396 */
1397void
1398nncvgt(cdfid, varid, start, count, value, rcode)
1399    int        *cdfid;
1400    int        *varid;
1401    int        *start;
1402    int        *count;
1403    void    *value;
1404    int        *rcode;
1405{
1406    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS];
1407    int i, ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1408#ifdef HDF
1409    NC *handle=NC_check_id(*cdfid);
1410#endif /* HDF */
1411
1412    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
1413        &ndims, dimarray, &natts) == -1) {
1414    *rcode = ncerr;
1415    return;
1416    }
1417    for (i = 0; i < ndims; i++) {
1418    ncount[i] = count[i];
1419    nstart[i] = start[i] - 1;
1420    }
1421    revlongs (ncount, ndims);
1422    revlongs (nstart, ndims);
1423
1424    *rcode = 0;
1425#ifdef FORTRAN_HAS_NO_BYTE
1426    if ((nc_type) datatype == NC_BYTE) {
1427    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1428    char *bytes = (char *) malloc (iocount * sizeof (char));
1429    int *ip;
1430    char *bp = bytes;
1431
1432    if (bytes == NULL) {
1433        *rcode = NC_SYSERR;
1434        return;
1435    }
1436    if (ncvarget (*cdfid, *varid - 1, nstart, ncount,
1437            (ncvoid *) bytes) == -1) {
1438        *rcode = ncerr;
1439        free (bytes);
1440        return;
1441    }
1442    for (ip = (int *) value; iocount > 0; iocount--)
1443    *ip++ = *bp++;
1444    free (bytes);
1445    return;
1446    }                /* else */
1447#endif                /* FORTRAN_HAS_NO_BYTE */
1448#ifdef FORTRAN_HAS_NO_SHORT
1449    if ((nc_type) datatype == NC_SHORT) {
1450    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1451    short *shorts = (short *) malloc (iocount * sizeof (short));
1452    int *ip;
1453    short *sp = shorts;
1454
1455    if (shorts == NULL) {
1456        *rcode = NC_SYSERR;
1457        return;
1458    }
1459    if (ncvarget (*cdfid, *varid - 1, nstart, ncount,
1460            (ncvoid *) shorts) == -1) {
1461        *rcode = ncerr;
1462        free (shorts);
1463        return;
1464    }
1465    for (ip = (int *) value; iocount > 0; iocount--)
1466        *ip++ = *sp++;
1467    free (shorts);
1468    return;
1469    }                /* else */
1470#endif                /* FORTRAN_HAS_NO_SHORT */
1471#if defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1472#ifdef HDF
1473    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
1474    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1475/* EIP   We need int buffer to read data in on the platforms where long is 8 bytes
1476    long *longs = (long *) malloc (iocount * sizeof (long));
1477    int *ip;
1478    long *lp = longs;
1479*/
1480    int *longs = (int *) malloc (iocount * sizeof (int));
1481    int *ip;
1482    int *lp = longs;
1483
1484    if (longs == NULL) {
1485        *rcode = NC_SYSERR;
1486        return;
1487    }
1488    if (ncvarget (*cdfid, *varid - 1, nstart, ncount,
1489            (ncvoid *) longs) == -1) {
1490        *rcode = ncerr;
1491        free (longs);
1492        return;
1493    }
1494    for (ip = (int *) value; iocount > 0; iocount--)
1495        *ip++ = *lp++;
1496    free (longs);
1497    return;
1498    }                /* else */
1499#else /* HDF */
1500    if ((nc_type) datatype == NC_LONG) {
1501    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1502    long *longs = (long *) malloc (iocount * sizeof (long));
1503    int *ip;
1504    long *lp = longs;
1505
1506    if (longs == NULL) {
1507        *rcode = NC_SYSERR;
1508        return;
1509    }
1510    if (ncvarget (*cdfid, *varid - 1, nstart, ncount,
1511            (ncvoid *) longs) == -1) {
1512        *rcode = ncerr;
1513        free (longs);
1514        return;
1515    }
1516    for (ip = (int *) value; iocount > 0; iocount--)
1517        *ip++ = *lp++;
1518    free (longs);
1519    return;
1520    }                /* else */
1521#endif /* HDF */
1522#endif
1523    if (ncvarget (*cdfid, *varid - 1, nstart, ncount, value) == -1) {
1524    *rcode = ncerr;
1525    }
1526}
1527
1528/* reads a hypercube of character values from a netCDF variable */
1529void
1530nncvgtc(cdfid, varid, start, count, string, lenstr, rcode, stringlen)
1531    int        *cdfid;
1532    int        *varid;
1533    int        *start;
1534    int        *count;
1535    char    *string;
1536    int        stringlen;
1537    int        *lenstr;
1538    int        *rcode;
1539{
1540    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS];
1541    int i, ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1542    int prod = 1;
1543
1544    if (ncvarinq (*cdfid, *varid - 1, (char *) 0,
1545        (nc_type *) & datatype, &ndims, dimarray, &natts) == -1) {
1546    *rcode = ncerr;
1547    return;
1548    }
1549    for (i = 0; i < ndims; i++) {
1550    ncount[i] = count[i];
1551    nstart[i] = start[i] - 1;
1552    prod *= count[i];
1553    }
1554    if (prod > *lenstr) {
1555    *rcode = NC_ESTS;
1556    handle_err ("NCVGTC", *rcode);
1557    return;
1558    }
1559    revlongs (ncount, ndims);
1560    revlongs (nstart, ndims);
1561    *rcode = 0;
1562    if (ncvarget (*cdfid, *varid - 1, nstart, ncount, (ncvoid *) string) == -1) {
1563    *rcode = ncerr;
1564    return;
1565    }
1566
1567    for (i = prod; i < *lenstr; i++)
1568    string[i] = ' ';
1569}
1570
1571/*
1572 * reads a generalized hypercube of numeric values from a netCDF variable of an
1573 * open netCDF file
1574 */
1575void
1576nncvgtg(cdfid, varid, start, count, stride, basis, value, rcode)
1577    int        *cdfid;
1578    int        *varid;
1579    int        *start;
1580    int        *count;
1581    int        *stride;
1582    int        *basis;
1583    void    *value;
1584    int        *rcode;
1585{
1586    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS];
1587    long nstride[MAX_VAR_DIMS], nbasis[MAX_VAR_DIMS];
1588    long tmpbasis;
1589    int i, ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1590#ifdef HDF
1591    NC *handle=NC_check_id(*cdfid);
1592#endif /* HDF */
1593
1594    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
1595        &ndims, dimarray, &natts) == -1) {
1596    *rcode = ncerr;
1597    return;
1598    }
1599#ifdef FORTRAN_HAS_NO_BYTE
1600    if (datatype == NC_CHAR || datatype == NC_BYTE)
1601    tmpbasis    = nctypelen(NC_LONG);
1602    else
1603#endif
1604#ifdef FORTRAN_HAS_NO_SHORT
1605    if (datatype == NC_SHORT)
1606    tmpbasis    = nctypelen(NC_LONG);
1607    else
1608#endif
1609#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1610    if (datatype == NC_LONG)
1611    tmpbasis    = sizeof(int);
1612    else
1613#endif
1614    tmpbasis    = nctypelen(datatype);
1615    for (i = 0; i < ndims; i++) {
1616    ncount[i] = count[i];
1617    nstart[i] = start[i] - 1;
1618    nstride[i] = stride[0] == 0 ? 1 : stride[i];
1619    nbasis[i] = basis[0] == 0 ? tmpbasis : basis[i];
1620    tmpbasis *= count[i];
1621    }
1622    revlongs (ncount, ndims);
1623    revlongs (nstart, ndims);
1624    revlongs (nstride, ndims);
1625    revlongs (nbasis, ndims);
1626
1627    *rcode = 0;
1628#ifdef FORTRAN_HAS_NO_BYTE
1629    if ((nc_type) datatype == NC_BYTE) {
1630    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1631    char *bytes = (char *) malloc (iocount * sizeof (char));
1632    int *ip;
1633    char *bp = bytes;
1634
1635    if (bytes == NULL) {
1636        *rcode = NC_SYSERR;
1637        return;
1638    }
1639    if (ncvargetg (*cdfid, *varid - 1, nstart, ncount, nstride,
1640            (long*)NULL, (ncvoid *) bytes) == -1) {
1641        *rcode = ncerr;
1642        free (bytes);
1643        return;
1644    }
1645    /*
1646    * Release 2.3.1 had a bug in the following line: it used basis
1647    * rather than nbasis.
1648    */
1649    btoig(bytes, (int*)value, ncount, nbasis, ndims);
1650    free (bytes);
1651    return;
1652    }                /* else */
1653#endif                /* FORTRAN_HAS_NO_BYTE */
1654#ifdef FORTRAN_HAS_NO_SHORT
1655    if ((nc_type) datatype == NC_SHORT) {
1656    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1657    short *shorts = (short *) malloc (iocount * sizeof (short));
1658    int *ip;
1659    short *sp = shorts;
1660
1661    if (shorts == NULL) {
1662        *rcode = NC_SYSERR;
1663        return;
1664    }
1665    if (ncvargetg (*cdfid, *varid - 1, nstart, ncount, nstride,
1666            (long*)NULL, (ncvoid *) shorts) == -1) {
1667        *rcode = ncerr;
1668        free (shorts);
1669        return;
1670    }
1671    /*
1672    * Release 2.3.1 had a bug in the following line: it used basis
1673    * rather than nbasis.
1674    */
1675    stoig(shorts, (int*)value, ncount, nbasis, ndims);
1676    free (shorts);
1677    return;
1678    }                /* else */
1679#endif                /* FORTRAN_HAS_NO_SHORT */
1680#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1681#ifdef HDF
1682    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
1683    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1684    long *longs = (long *) malloc (iocount * sizeof (long));
1685
1686    if (longs == NULL) {
1687        *rcode = NC_SYSERR;
1688        return;
1689    }
1690    if (ncvargetg (*cdfid, *varid - 1, nstart, ncount, nstride,
1691            (long*)NULL, (ncvoid *) longs) == -1) {
1692        *rcode = ncerr;
1693        free (longs);
1694        return;
1695    }
1696    ltoig(longs, (int*)value, ncount, nbasis, ndims);
1697    free (longs);
1698    return;
1699    }                /* else */
1700#else /* HDF */
1701    if ((nc_type) datatype == NC_LONG) {
1702    long iocount = dimprod (ncount, ndims);    /* product of dimensions */
1703    long *longs = (long *) malloc (iocount * sizeof (long));
1704
1705    if (longs == NULL) {
1706        *rcode = NC_SYSERR;
1707        return;
1708    }
1709    if (ncvargetg (*cdfid, *varid - 1, nstart, ncount, nstride,
1710            (long*)NULL, (ncvoid *) longs) == -1) {
1711        *rcode = ncerr;
1712        free (longs);
1713        return;
1714    }
1715    ltoig(longs, (int*)value, ncount, nbasis, ndims);
1716    free (longs);
1717    return;
1718    }                /* else */
1719#endif /* HDF */
1720#endif
1721    if (ncvargetg (*cdfid, *varid - 1, nstart, ncount, nstride,
1722        nbasis, value) == -1) {
1723    *rcode = ncerr;
1724    }
1725}
1726
1727/*
1728 * reads a generalized hypercube of character values from a netCDF variable
1729 * of an open netCDF file
1730 */
1731void
1732nncvggc(cdfid, varid, start, count, stride, basis, string, rcode, stringlen)
1733    int        *cdfid;
1734    int        *varid;
1735    int        *start;
1736    int        *count;
1737    int        *stride;
1738    int        *basis;
1739    char    *string;
1740    int        stringlen;
1741    int        *rcode;
1742{
1743    long ncount[MAX_VAR_DIMS], nstart[MAX_VAR_DIMS];
1744    long nstride[MAX_VAR_DIMS], nbasis[MAX_VAR_DIMS];
1745    long tmpbasis;
1746    int i, ndims, datatype, dimarray[MAX_VAR_DIMS], natts;
1747
1748    if (ncvarinq (*cdfid, *varid - 1, (char *) 0, (nc_type *) & datatype,
1749        &ndims, dimarray, &natts) == -1) {
1750    *rcode = ncerr;
1751    return;
1752    }
1753    tmpbasis    = nctypelen(datatype);
1754    for (i = 0; i < ndims; i++) {
1755    ncount[i] = count[i];
1756    nstart[i] = start[i] - 1;
1757    nstride[i] = stride[0] == 0 ? 1 : stride[i];
1758    nbasis[i] = basis[0] == 0 ? tmpbasis : basis[i];
1759    tmpbasis *= count[i];
1760    }
1761    revlongs (ncount, ndims);
1762    revlongs (nstart, ndims);
1763    revlongs (nstride, ndims);
1764    revlongs (nbasis, ndims);
1765
1766    *rcode = 0;
1767    if (ncvargetg (*cdfid, *varid - 1, nstart, ncount, nstride,
1768        nbasis, (ncvoid*)string) == -1) {
1769    *rcode = ncerr;
1770    }
1771}
1772
1773/* changes the name of a netCDF variable in an open netCDF file */
1774void
1775nncvren(cdfid, varid, varname, rcode, varnamelen)
1776    int        *cdfid;
1777    int        *varid;
1778    char    *varname;
1779    int        varnamelen;
1780    int        *rcode;
1781{
1782    char name[MAX_NC_NAME + 1];
1783
1784    nstrncpy (name, varname, varnamelen);
1785    *rcode = 0;
1786    if (ncvarrename (*cdfid, *varid - 1, name) == -1) {
1787    *rcode = ncerr;
1788    }
1789}
1790
1791/*
1792 * adds or changes a numeric variable or global attribute of an open
1793 * netCDF file
1794 */
1795void
1796nncapt(cdfid, varid, attname, datatype, attlen, value, rcode, attnamelen)
1797    int        *cdfid;
1798    int        *varid;
1799    char    *attname;
1800    int        attnamelen;
1801    int        *datatype;
1802    int        *attlen;
1803    void    *value;
1804    int        *rcode;
1805{
1806    char name[MAX_NC_NAME + 1];
1807#ifdef HDF
1808    NC *handle=NC_check_id(*cdfid);
1809#endif /* HDF */
1810
1811    nstrncpy (name, attname, attnamelen);
1812
1813    *rcode = 0;
1814#ifdef FORTRAN_HAS_NO_BYTE
1815    if ((nc_type) *datatype == NC_BYTE) {    /* pack ints into bytes */
1816    char *bytes = itob (value, attlen, 1);
1817
1818    if (bytes == NULL) {
1819        *rcode = NC_SYSERR;
1820        return;
1821    }
1822    if (ncattput (*cdfid, *varid - 1, name, (nc_type) *datatype, *attlen,
1823            (ncvoid *) bytes) == -1) {
1824        *rcode = ncerr;
1825    }
1826    free (bytes);
1827    return;
1828    }                /* else */
1829#endif                /* FORTRAN_HAS_NO_BYTE */
1830#ifdef FORTRAN_HAS_NO_SHORT
1831    if ((nc_type) *datatype == NC_SHORT) {    /* pack ints into shorts */
1832    short *shorts = itos (value, attlen, 1);
1833
1834    if (shorts == NULL) {
1835        *rcode = NC_SYSERR;
1836        return;
1837    }
1838    if (ncattput (*cdfid, *varid - 1, name, (nc_type) *datatype, *attlen,
1839            (ncvoid *) shorts) == -1) {
1840        *rcode = ncerr;
1841    }
1842    free (shorts);
1843    return;
1844    }                /* else */
1845#endif                /* FORTRAN_HAS_NO_SHORT */
1846#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
1847#ifdef HDF
1848    if ((nc_type) *datatype == NC_LONG && handle->file_type!=HDF_FILE) {
1849    long *longs = itol (value, attlen, 1);
1850
1851    if (longs == NULL) {
1852        *rcode = NC_SYSERR;
1853        return;
1854    }
1855    if (ncattput (*cdfid, *varid - 1, name, (nc_type) *datatype, *attlen,
1856            (ncvoid *) longs) == -1) {
1857        *rcode = ncerr;
1858    }
1859    free (longs);
1860    return;
1861    }                /* else */
1862#else /* HDF */
1863    if ((nc_type) *datatype == NC_LONG) {
1864    long *longs = itol (value, attlen, 1);
1865
1866    if (longs == NULL) {
1867        *rcode = NC_SYSERR;
1868        return;
1869    }
1870    if (ncattput (*cdfid, *varid - 1, name, (nc_type) *datatype, *attlen,
1871            (ncvoid *) longs) == -1) {
1872        *rcode = ncerr;
1873    }
1874    free (longs);
1875    return;
1876    }                /* else */
1877#endif /* HDF */
1878#endif
1879    if (ncattput (*cdfid, *varid - 1, name, (nc_type) *datatype, *attlen,
1880        value) == -1) {
1881    *rcode = ncerr;
1882    }
1883}
1884
1885/*
1886 * adds or changes a character variable or global attribute
1887 * of an open netCDF file
1888 */
1889void
1890nncaptc(cdfid, varid, attname, datatype, lenstr, string, rcode, attnamelen, stringlen)
1891    int        *cdfid;
1892    int        *varid;
1893    char    *attname;
1894    int        attnamelen;
1895    int        *datatype;
1896    int        *lenstr;
1897    char    *string;
1898    int        stringlen;
1899    int        *rcode;
1900{
1901    char name[MAX_NC_NAME + 1];
1902    char *value;
1903
1904    nstrncpy (name, attname, attnamelen);
1905    if (((value = malloc ((unsigned) *lenstr + 1)) == NULL) || (*lenstr == 0)) {
1906    *rcode = NC_ESTS;
1907    handle_err ("NCAPTC", *rcode);
1908    return;
1909    }
1910    (void) fstrncpy (value, string, *lenstr);
1911    *rcode = 0;
1912    if (ncattput (*cdfid, *varid - 1, name, (nc_type) *datatype, *lenstr,
1913        (ncvoid *) value) == -1) {
1914    *rcode = ncerr;
1915    }
1916    free (value);
1917}
1918
1919/*
1920 * returns information about a netCDF attribute given its variable
1921 * ID and name
1922 */
1923void
1924nncainq(cdfid, varid, attname, datatype, attlen, rcode, attnamelen)
1925    int        *cdfid;
1926    int        *varid;
1927    char    *attname;
1928    int        attnamelen;
1929    int        *datatype;
1930    int        *attlen;
1931    int        *rcode;
1932{
1933    char name[MAX_NC_NAME + 1];
1934
1935    nstrncpy (name, attname, attnamelen);
1936    *rcode = 0;
1937    if (ncattinq (*cdfid, *varid - 1, name, (nc_type *) datatype, attlen) == -1) {
1938    *rcode = ncerr;
1939    }
1940}
1941
1942/*
1943 * gets the value of a netCDF attribute given its variable ID
1944 * and name
1945 */
1946void
1947nncagt(cdfid, varid, attname, value, rcode, attnamelen)
1948    int        *cdfid;
1949    int        *varid;
1950    char    *attname;
1951    int        attnamelen;
1952    void    *value;
1953    int        *rcode;
1954{
1955    char name[MAX_NC_NAME + 1];
1956    int datatype;
1957    int attlen;
1958#ifdef HDF
1959    NC *handle=NC_check_id(*cdfid);
1960#endif /* HDF */
1961
1962    nstrncpy (name, attname, attnamelen);
1963    *rcode = 0;
1964    if (ncattinq (*cdfid, *varid - 1, name, (nc_type *) &datatype, &attlen)
1965        == -1) {
1966    *rcode = ncerr;
1967    return;
1968    }
1969#ifdef FORTRAN_HAS_NO_BYTE
1970    if ((nc_type) datatype == NC_BYTE) {
1971    char *bytes = (char *) malloc (attlen);
1972    int *ip;
1973    char *bp = bytes;
1974
1975    if (bytes == NULL) {
1976        *rcode = NC_SYSERR;
1977        return;
1978    }
1979    if (ncattget (*cdfid, *varid - 1, name, (ncvoid *) bytes) == -1) {
1980        *rcode = ncerr;
1981        free (bytes);
1982        return;
1983    }
1984    for (ip = (int *) value; attlen > 0; attlen--)
1985        *ip++ = *bp++;
1986    free (bytes);
1987    return;
1988    }                /* else */
1989#endif                /* FORTRAN_HAS_NO_BYTE */
1990#ifdef FORTRAN_HAS_NO_SHORT
1991    if ((nc_type) datatype == NC_SHORT) {
1992    short *shorts = (short *) malloc (attlen * sizeof (short));
1993    int *ip;
1994    short *sp = shorts;
1995
1996    if (shorts == NULL) {
1997        *rcode = NC_SYSERR;
1998        return;
1999    }
2000    if (ncattget (*cdfid, *varid - 1, name, (ncvoid *) shorts) == -1) {
2001        *rcode = ncerr;
2002        free (shorts);
2003        return;
2004    }
2005    for (ip = (int *) value; attlen > 0; attlen--)
2006        *ip++ = *sp++;
2007    free (shorts);
2008    return;
2009    }                /* else */
2010#endif                /* FORTRAN_HAS_NO_SHORT */
2011#if  defined __alpha || (_MIPS_SZLONG == 64) || defined __ia64 || (defined __sun && defined _LP64) || defined AIX5L64 || defined __x86_64__
2012#ifdef HDF
2013    if ((nc_type) datatype == NC_LONG && handle->file_type!=HDF_FILE) {
2014/* EIP  We need to use int buffer to read data in on the platforms where long is 8 bytes
2015    long *longs = (long *) malloc (attlen * sizeof (long));
2016    int *ip;
2017    long *lp = longs;
2018*/
2019    int *longs = (int *) malloc (attlen * sizeof (int));
2020    int *ip;
2021    int *lp = longs;
2022
2023    if (longs == NULL) {
2024        *rcode = NC_SYSERR;
2025        return;
2026    }
2027    if (ncattget (*cdfid, *varid - 1, name, (ncvoid *) longs) == -1) {
2028        *rcode = ncerr;
2029        free (longs);
2030        return;
2031    }
2032    for (ip = (int *) value; attlen > 0; attlen--)
2033        *ip++ = *lp++;
2034    free (longs);
2035    return;
2036    }                /* else */
2037#else /* HDF */
2038    if ((nc_type) datatype == NC_LONG) {
2039    long *longs = (long *) malloc (attlen * sizeof (long));
2040    int *ip;
2041    long *lp = longs;
2042
2043    if (longs == NULL) {
2044        *rcode = NC_SYSERR;
2045        return;
2046    }
2047    if (ncattget (*cdfid, *varid - 1, name, (ncvoid *) longs) == -1) {
2048        *rcode = ncerr;
2049        free (longs);
2050        return;
2051    }
2052    for (ip = (int *) value; attlen > 0; attlen--)
2053        *ip++ = *lp++;
2054    free (longs);
2055    return;
2056    }                /* else */
2057#endif /* HDF */
2058#endif
2059    if (ncattget (*cdfid, *varid - 1, name, value) == -1) {
2060    *rcode = ncerr;
2061    }
2062}
2063
2064/*
2065 * gets the value of a netCDF character attribute given its variable
2066 * ID and name
2067 */
2068void
2069nncagtc(cdfid, varid, attname, string, lenstr, rcode, attnamelen, stringlen)
2070    int        *cdfid;
2071    int        *varid;
2072    char    *attname;
2073    int        attnamelen;
2074    char    *string;
2075    int        stringlen;
2076    int        *lenstr;
2077    int        *rcode;
2078{
2079    char name[MAX_NC_NAME + 1];
2080    int datatype;
2081    int attlen;
2082    int i;
2083
2084    nstrncpy (name, attname, attnamelen);
2085    *rcode = 0;
2086    if (ncattinq (*cdfid, *varid - 1, name, (nc_type *) &datatype, &attlen) == -1) {
2087    *rcode = ncerr;
2088    return;
2089    }
2090    if (attlen > *lenstr) {
2091    *rcode = NC_ESTS;
2092    handle_err ("NCAGTC", *rcode);
2093    return;
2094    }
2095    if (ncattget (*cdfid, *varid - 1, name, (ncvoid *) string) == -1) {
2096    *rcode = ncerr;
2097    return;
2098    }
2099
2100    for (i = attlen; i < *lenstr; i++)
2101    string[i] = ' ';
2102}
2103
2104/* copies an attribute from one open netCDF file to another */
2105void
2106nncacpy(incdfid, invarid, attname, outcdfid, outvarid, rcode, attnamelen)
2107    int        *incdfid;
2108    int        *invarid;
2109    char    *attname;
2110    int        attnamelen;
2111    int        *outcdfid;
2112    int        *outvarid;
2113    int        *rcode;
2114{
2115    char name[MAX_NC_NAME + 1];
2116
2117    nstrncpy (name, attname, attnamelen);
2118    *rcode = 0;
2119    if (ncattcopy (*incdfid, *invarid - 1, name,
2120        *outcdfid, *outvarid - 1) == -1) {
2121    *rcode = ncerr;
2122    }
2123}
2124
2125/*
2126 * gets the name of an attribute given its variable ID and number
2127 * as an attribute of that variable
2128 */
2129void
2130nncanam(cdfid, varid, attnum, attname, rcode, attnamelen)
2131    int        *cdfid;
2132    int        *varid;
2133    int        *attnum;
2134    char    *attname;
2135    int        attnamelen;
2136    int        *rcode;
2137{
2138    char name[MAX_NC_NAME + 1];
2139
2140    *rcode = 0;
2141    if (ncattname (*cdfid, *varid - 1, *attnum - 1, name) == -1) {
2142    *rcode = ncerr;
2143    return;
2144    }
2145    if (strlen (name) > attnamelen) {
2146    *rcode = NC_ESTS;
2147    handle_err ("NCANAM", *rcode);
2148    return;
2149    }
2150    fcdcpy (attname, attnamelen, name);
2151}
2152
2153
2154/* renames an attribute in an open netCDF file */
2155void
2156nncaren(cdfid, varid, attname, newname, rcode, attnamelen, newnamelen)
2157    int        *cdfid;
2158    int        *varid;
2159    char    *attname;
2160    int        attnamelen;
2161    char    *newname;
2162    int        newnamelen;
2163    int        *rcode;
2164{
2165    char name[MAX_NC_NAME + 1], nname[MAX_NC_NAME + 1];
2166
2167    nstrncpy (name, attname, attnamelen);
2168    nstrncpy (nname, newname, newnamelen);
2169    *rcode = 0;
2170    if (ncattrename (*cdfid, *varid - 1, name, nname) == -1) {
2171    *rcode = ncerr;
2172    }
2173}
2174
2175/*
2176 * deletes an attribute from an open netCDF file given the attribute
2177 * name
2178 */
2179void
2180nncadel(cdfid, varid, attname, rcode, attnamelen)
2181    int        *cdfid;
2182    int        *varid;
2183    char    *attname;
2184    int        attnamelen;
2185    int        *rcode;
2186{
2187    char name[MAX_NC_NAME + 1];
2188
2189    nstrncpy (name, attname, attnamelen);
2190    *rcode = 0;
2191    if (ncattdel (*cdfid, *varid - 1, name) == -1) {
2192    *rcode = ncerr;
2193    }
2194}
2195
2196
2197/*
2198 * sets the fill mode of a netCDF file open for writing
2199 */
2200int
2201nncsfil(cdfid, fillmode, rcode)
2202    int        *cdfid;
2203    int        *fillmode;
2204    int        *rcode;
2205{
2206    int retval;
2207
2208    if ((retval = ncsetfill (*cdfid, *fillmode)) != -1) {
2209    *rcode = 0;
2210    return retval;
2211    }
2212    *rcode = ncerr;
2213    return (-1);
2214}
2215
2216