1dnl This is m4 source.
2dnl Process using m4 to produce 'C' language file.
3dnl
4dnl This file is supposed to be the same as PnetCDF's test_put.m4
5dnl
6dnl If you see this line, you can ignore the next one.
7/* Do not edit this file. It is produced from the corresponding .m4 source */
8dnl
9/*
10 *  Copyright (C) 2003, Northwestern University and Argonne National Laboratory
11 *  See COPYRIGHT notice in top-level directory.
12 */
13/* $Id: test_put.m4 2672 2016-12-03 19:23:53Z wkliao $ */
14
15dnl
16dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF
17dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types
18dnl (MPI_Offset vs. size_t), and function name substrings for external data
19dnl types.
20dnl
21
22#include "tests.h"
23
24ifdef(`PNETCDF',,`dnl
25#ifdef USE_PNETCDF
26#include <pnetcdf.h>
27#ifndef PNETCDF_VERSION_MAJOR
28#error("PNETCDF_VERSION_MAJOR is not defined in pnetcdf.h")
29#endif
30#ifndef PNETCDF_VERSION_MINOR
31#error("PNETCDF_VERSION_MAJOR is not defined in pnetcdf.h")
32#endif
33#endif')
34
35define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl
36
37define(`IntType', `ifdef(`PNETCDF',`MPI_Offset',`size_t')')dnl
38define(`PTRDType',`ifdef(`PNETCDF',`MPI_Offset',`ptrdiff_t')')dnl
39define(`TestFunc',`ifdef(`PNETCDF',`test_ncmpi_put_$1',`test_nc_put_$1')')dnl
40define(`APIFunc',` ifdef(`PNETCDF',`ncmpi_$1',`nc_$1')')dnl
41
42define(`FileOpen', `ifdef(`PNETCDF',`ncmpi_open(comm, $1, $2, info, &ncid)', `file_open($1, $2, &ncid)')')dnl
43define(`FileCreate',`ifdef(`PNETCDF',`ncmpi_create(comm, $1, $2, info, &ncid)', `file_create($1, $2, &ncid)')')dnl
44define(`FileDelete',`ifdef(`PNETCDF',`ncmpi_delete($1,$2)',`nc_delete($1)')')dnl
45
46define(`VarArgs',   `ifdef(`PNETCDF',`int numVars',`void')')dnl
47define(`AttVarArgs',`ifdef(`PNETCDF',`int numGatts,int numVars',`void')')dnl
48
49define(`PutVar1',`ifdef(`PNETCDF',`ncmpi_put_var1_$1_all',`nc_put_var1_$1')')dnl
50define(`PutVar', `ifdef(`PNETCDF',`ncmpi_put_var_$1_all', `nc_put_var_$1')')dnl
51define(`PutVara',`ifdef(`PNETCDF',`ncmpi_put_vara_$1_all',`nc_put_vara_$1')')dnl
52define(`PutVars',`ifdef(`PNETCDF',`ncmpi_put_vars_$1_all',`nc_put_vars_$1')')dnl
53define(`PutVarm',`ifdef(`PNETCDF',`ncmpi_put_varm_$1_all',`nc_put_varm_$1')')dnl
54define(`PutAtt', `ifdef(`PNETCDF',`ncmpi_put_att_$1',`nc_put_att_$1')')dnl
55define(`GetVar1',`ifdef(`PNETCDF',`ncmpi_get_var1_$1_all',`nc_get_var1_$1')')dnl
56define(`DefVars',`ifdef(`PNETCDF',`def_vars($1,$2)',`def_vars($1)')')dnl
57
58define(`PNETCDF_CHECK_ERANGE',`dnl
59ifelse(`$1',`uchar',`ifdef(`PNETCDF',,`
60`#'if !defined(USE_PNETCDF) || (PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR>=8)')',
61       `$1',`schar',`ifdef(`PNETCDF',,`
62`#'if defined(USE_PNETCDF) && PNETCDF_VERSION_MAJOR==1 && PNETCDF_VERSION_MINOR<7
63                    else if (cdf_format < NC_FORMAT_CDF5) {
64`#'else')')
65                    else {
66ifelse(`$1',`schar',`ifdef(`PNETCDF',,``#'endif')')
67                        IF (err != NC_ERANGE)
68                            EXPECT_ERR(NC_ERANGE, err)
69                        ELSE_NOK
70                    }
71ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')')'
72)dnl
73
74undefine(`index')dnl
75dnl dnl dnl
76dnl
77dnl Macros
78dnl
79dnl dnl dnl
80dnl
81dnl Upcase(str)
82dnl
83define(`Upcase',dnl
84`dnl
85translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
86dnl dnl dnl
87dnl
88dnl NCT_ITYPE(type)
89dnl
90define(`NCT_ITYPE',    ``NCT_'Upcase($1)')dnl
91define(`NC_TYPE',      ``NC_'Upcase($1)')dnl
92define(`X_MIN',        ``X_'Upcase($1)_MIN')dnl
93define(`X_MAX',        ``X_'Upcase($1)_MAX')dnl
94dnl
95
96define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl
97define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl
98define(`CheckNumRange',
99       `ifelse(`$1',`text', `1',
100               `inRange3(cdf_format, (double)$2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl
101define(`CheckRange',
102       `ifelse(`$1',`text', `0', `($2 >= $1_min && $2 <= $1_max)')')dnl
103define(`CheckRange3',
104       `ifelse(`$1',`text', `1',
105               `inRange3(cdf_format, (double)$2,$3,NCT_ITYPE($1))')')dnl
106
107dnl HASH(TYPE)
108dnl
109define(`HASH',dnl
110`dnl
111/*
112 *  ensure hash value within range for internal TYPE
113 */
114$1
115hash_$1(const int       cdf_format,
116        const nc_type   type,
117        const int       rank,
118        const IntType  *index,
119        const nct_itype itype)
120{
121    double value;
122
123    value = hash4(cdf_format, type, rank, index, itype);
124    ifelse(`$1',`text',`return (text)value;',`
125    if (value > $1_max) return $1_max;
126    else if (value < $1_min) return $1_min;
127    else return ($1)value;')
128}
129')dnl
130
131HASH(text)
132HASH(uchar)
133HASH(schar)
134HASH(short)
135HASH(int)
136HASH(long)
137HASH(float)
138HASH(double)
139HASH(ushort)
140HASH(uint)
141HASH(longlong)
142HASH(ulonglong)
143
144
145dnl CHECK_VARS(TYPE)
146dnl
147define(`CHECK_VARS',dnl
148`dnl
149/*
150 *  check all vars in file which are (text/numeric) compatible with TYPE
151 */
152int
153check_vars_$1(const char *filename, int numVars)
154{
155    int i, d, err, ncid, cdf_format, ndims;
156    int canConvert;   /* Both text or both numeric */
157    int nok = 0;      /* count of valid comparisons */
158    int dimids[MAX_RANK];
159    nc_type datatype;
160    char name[NC_MAX_NAME];
161    IntType j, length, index[MAX_RANK];
162    double expect;
163    $1 value;
164
165    err = FileOpen(filename, NC_NOWRITE);
166    IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err));
167
168    err = APIFunc(inq_format)(ncid, &cdf_format);
169    IF (err != NC_NOERR) error("inq_format: %s", APIFunc(strerror)(err));
170
171    for (i = 0; i < numVars; i++) {
172        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
173        if (!canConvert) continue;
174
175        err = APIFunc(inq_var)(ncid, i, name, &datatype, &ndims, dimids, NULL);
176        IF (err != NC_NOERR)
177            error("inq_var: %s", APIFunc(strerror)(err));
178        IF (strcmp(name, var_name[i]) != 0)
179            error("Unexpected var_name");
180        IF (datatype != var_type[i])
181            error("Unexpected type");
182        IF (ndims != var_rank[i])
183            error("Unexpected rank");
184        for (j = 0; j < ndims; j++) {
185            err = APIFunc(inq_dim)(ncid, dimids[j], 0, &length);
186            IF (err != NC_NOERR)
187                error("inq_dim: %s", APIFunc(strerror)(err));
188            IF (length != var_shape[i][j])
189                error("Unexpected shape");
190        }
191        for (j = 0; j < var_nels[i]; j++) {
192            err = toMixedBase(j, var_rank[i], var_shape[i], index);
193            IF (err != 0) error("error in toMixedBase");
194            expect = hash4(cdf_format, var_type[i], var_rank[i], index,
195                           NCT_ITYPE($1));
196            err = GetVar1($1)(ncid, i, index, &value);
197            if (CheckNumRange($1, expect, datatype)) {
198                IF (err != NC_NOERR) {
199                    error("GetVar1($1): %s", APIFunc(strerror)(err));
200                } else {
201                    ifelse(`$1', `uchar', `
202                    /* In put_vars(), PutVara(double)() is used to write
203                     * variables of type NC_BYTE to files. For uchar APIs,
204                     * NC_BYTE variables are treated as unsigned for CDF-1 and 2
205                     * formats. Thus, we skip the equal test for out-of-bound
206                     * values below for uchar APIs.
207                     */
208                    if (cdf_format < NC_FORMAT_CDF5 &&
209                        var_type[i] == NC_BYTE && expect > schar_max)
210                        continue;')
211                    IF (!equal((double)value,expect,var_type[i],NCT_ITYPE($1))){
212                        error("Var value read not that expected");
213                        if (verbose) {
214                            error("\n");
215                            error("varid: %d, ", i);
216                            error("var_name: %s, ", var_name[i]);
217                            error("var_type: %s, ", s_nc_type(var_type[i]));
218                            error("index:");
219                            for (d = 0; d < var_rank[i]; d++)
220                                error(" %d", index[d]);
221                            error(", expect: %g, ", expect);
222                            error("got: %g", (double) value);
223                        }
224                    } else {
225                        ++nok;
226                    }
227                }
228            }
229        }
230    }
231    err = APIFunc(close)(ncid);
232    IF (err != NC_NOERR)
233        error("close: %s", APIFunc(strerror)(err));
234    return nok;
235}
236')dnl
237
238CHECK_VARS(text)
239CHECK_VARS(uchar)
240CHECK_VARS(schar)
241CHECK_VARS(short)
242CHECK_VARS(int)
243CHECK_VARS(long)
244CHECK_VARS(float)
245CHECK_VARS(double)
246CHECK_VARS(ushort)
247CHECK_VARS(uint)
248CHECK_VARS(longlong)
249CHECK_VARS(ulonglong)
250
251
252dnl CHECK_ATTS(TYPE)
253dnl
254define(`CHECK_ATTS',dnl
255`dnl
256/*
257 *  for _text tests, check all attributes in file which are of text type
258 *  Note no NC_ERANGE check for text attributes as text is not convertible to
259 *  any other numerical data types (i.e. NC_ECHAR)
260 *
261 *  for other tests, check all numerical attributes in file against values
262 *  outside range of type $1
263 */
264int
265check_atts_$1(int ncid, int numGatts, int numVars)
266{
267    int i, j, cdf_format, err;
268    int canConvert;      /* Both text or both numeric */
269    int nok = 0;         /* count of valid comparisons */
270    IntType k, length, ndx[1];
271    nc_type datatype;
272    IntType nInExtRange;  /* number values within external range */
273    IntType nInIntRange;  /* number values within internal range */
274    double expect[MAX_NELS];
275    $1 value[MAX_NELS];
276
277    err = APIFunc(inq_format)(ncid, &cdf_format);
278    IF (err != NC_NOERR)
279        error("inq_format: %s", APIFunc(strerror)(err));
280
281    for (i = -1; i < numVars; i++) {
282        for (j = 0; j < NATTS(i); j++) {
283            canConvert = (ATT_TYPE(i,j) == NC_CHAR) CheckText($1);
284            if (!canConvert) continue;
285
286            err = APIFunc(inq_att)(ncid, i, ATT_NAME(i,j), &datatype, &length);
287            IF (err != NC_NOERR)
288                error("inq_att: %s", APIFunc(strerror)(err));
289            IF (datatype != ATT_TYPE(i,j))
290                error("inq_att: unexpected type");
291            IF (length != ATT_LEN(i,j))
292                error("inq_att: unexpected length");
293            assert(length <= MAX_NELS);
294            nInIntRange = nInExtRange = 0;
295            for (k = 0; k < length; k++) {
296                ndx[0] = k;
297                expect[k] = hash4(cdf_format, datatype, -1, ndx, NCT_ITYPE($1));
298                if (inRange3(cdf_format, expect[k], datatype, NCT_ITYPE($1))) {
299                    ++nInExtRange;
300                    if (CheckRange($1, expect[k]))
301                        ++nInIntRange;
302                }
303            }
304            err = APIFunc(get_att_$1)(ncid, i, ATT_NAME(i,j), value);
305            if (nInExtRange == length && nInIntRange == length) {
306                IF (err != NC_NOERR)
307                    EXPECT_ERR(NC_NOERR, err)
308            } else {
309                IF (err != NC_NOERR && err != NC_ERANGE)
310                    EXPECT_ERR(NC_NOERR or NC_ERANGE, err)
311            }
312            for (k = 0; k < length; k++) {
313                if (CheckNumRange($1, expect[k], datatype)) {
314                    ifelse(`$1', `uchar', `
315                    /* In put_vars(), PutVara(double)() is used to write
316                     * variables of type NC_BYTE to files. For uchar APIs,
317                     * NC_BYTE variables are treated as unsigned for CDF-1 and 2
318                     * formats. Thus, we skip the equal test for out-of-bound
319                     * values below for uchar APIs.
320                     */
321                    if (cdf_format < NC_FORMAT_CDF5 &&
322                        ATT_TYPE(i,j) == NC_BYTE && expect[k] > schar_max)
323                        continue;')
324                    IF (!equal((double)value[k],expect[k],datatype,NCT_ITYPE($1))) {
325                        error("att. value read not that expected");
326                        if (verbose) {
327                            error("\n");
328                            error("varid: %d, ", i);
329                            error("att_name: %s, ", ATT_NAME(i,j));
330                            error("att_type: %s, ", s_nc_type(ATT_TYPE(i,j)));
331                            error("element number: %d ", k);
332                            error("expect: %g, ", expect[k]);
333                            error("got: %g", (double) value[k]);
334                        }
335                    } else {
336                        nok++;
337                    }
338                }
339            }
340        }
341    }
342    return nok;
343}
344')dnl
345
346CHECK_ATTS(text)
347CHECK_ATTS(uchar)
348CHECK_ATTS(schar)
349CHECK_ATTS(short)
350CHECK_ATTS(int)
351CHECK_ATTS(long)
352CHECK_ATTS(float)
353CHECK_ATTS(double)
354CHECK_ATTS(ushort)
355CHECK_ATTS(uint)
356CHECK_ATTS(longlong)
357CHECK_ATTS(ulonglong)
358
359
360dnl TEST_NC_PUT_VAR1(TYPE)
361dnl
362define(`TEST_NC_PUT_VAR1',dnl
363`dnl
364int
365TestFunc(var1)_$1(VarArgs)
366{
367    int i, err, ncid, cdf_format, nok=0;
368    int canConvert;      /* Both text or both numeric */
369    IntType j, index[MAX_RANK];
370    $1 value[1];
371
372    err = FileCreate(scratch, NC_CLOBBER);
373    IF (err != NC_NOERR) {
374        error("create: %s", APIFunc(strerror)(err));
375        return nok;
376    }
377
378    err = APIFunc(inq_format)(ncid, &cdf_format);
379    IF (err != NC_NOERR)
380        error("inq_format: %s", APIFunc(strerror)(err));
381
382    def_dims(ncid);
383    DefVars(ncid, numVars);
384
385    err = APIFunc(enddef)(ncid);
386    IF (err != NC_NOERR)
387        error("enddef: %s", APIFunc(strerror)(err));
388
389    /* check if can detect a bad file ID */
390    err = PutVar1($1)(BAD_ID, 0, NULL, NULL);
391    IF (err != NC_EBADID)
392        EXPECT_ERR(NC_EBADID, err)
393    ELSE_NOK
394
395    /* check if can detect a bad variable ID */
396    err = PutVar1($1)(ncid, BAD_VARID, NULL, NULL);
397    IF (err != NC_ENOTVAR)
398        EXPECT_ERR(NC_ENOTVAR, err)
399    ELSE_NOK
400
401    for (i = 0; i < numVars; i++) {
402        assert(var_rank[i] <= MAX_RANK);
403        assert(var_nels[i] <= MAX_NELS);
404
405        value[0] = 5;  /* reset to a value within bounds */
406
407        /* check if can detect a bad file ID */
408        err = PutVar1($1)(BAD_ID, i, NULL, value);
409        IF (err != NC_EBADID)
410            EXPECT_ERR(NC_EBADID, err)
411        ELSE_NOK
412
413        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
414
415ifdef(`PNETCDF',`dnl
416        /* for non-scalar variables, argument start cannot be NULL */
417        err = PutVar1($1)(ncid, i, NULL, value);
418        if (!canConvert) {
419            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
420        }
421        else if (var_rank[i] == 0) {
422            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
423        }
424        else IF (err != NC_EINVALCOORDS) {
425            EXPECT_ERR(NC_EINVALCOORDS, err)
426        }
427        ELSE_NOK
428')dnl
429
430        /* test NC_EINVALCOORDS */
431        for (j = 0; j < var_rank[i]; j++) index[j] = 0;
432
433        for (j = 0; j < var_rank[i]; j++) {
434            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
435            index[j] = var_shape[i][j];     /* out of boundary check */
436            err = PutVar1($1)(ncid, i, index, value);
437            if (!canConvert) {
438                IF (err != NC_ECHAR)
439                    EXPECT_ERR(NC_ECHAR, err)
440                ELSE_NOK
441                index[j] = 0;
442                continue;
443            }
444            IF (err != NC_EINVALCOORDS)
445                EXPECT_ERR(NC_EINVALCOORDS, err)
446            ELSE_NOK
447            index[j] = 0;
448        }
449
450        for (j = 0; j < var_nels[i]; j++) {
451            err = toMixedBase(j, var_rank[i], var_shape[i], index);
452            IF (err != 0) error("error in toMixedBase");
453            value[0] = hash_$1(cdf_format, var_type[i], var_rank[i], index,
454                               NCT_ITYPE($1));
455            err = PutVar1($1)(ncid, i, index, value);
456            if (canConvert) {
457                if (CheckRange3($1, value[0], var_type[i])) {
458                    IF (err != NC_NOERR)
459                        EXPECT_ERR(NC_NOERR, err)
460                    ELSE_NOK
461                }
462                PNETCDF_CHECK_ERANGE($1)
463            } else {
464                IF (err != NC_ECHAR)
465                    EXPECT_ERR(NC_ECHAR, err)
466                ELSE_NOK
467            }
468        }
469    }
470
471    err = APIFunc(close)(ncid);
472    IF (err != NC_NOERR)
473        error("close: %s", APIFunc(strerror)(err));
474
475    nok += check_vars_$1(scratch, numVars);
476
477    err = FileDelete(scratch, info);
478    IF (err != NC_NOERR)
479        error("delete file %s failed", scratch);
480    return nok;
481}
482')dnl
483
484TEST_NC_PUT_VAR1(text)
485TEST_NC_PUT_VAR1(uchar)
486TEST_NC_PUT_VAR1(schar)
487TEST_NC_PUT_VAR1(short)
488TEST_NC_PUT_VAR1(int)
489TEST_NC_PUT_VAR1(long)
490TEST_NC_PUT_VAR1(float)
491TEST_NC_PUT_VAR1(double)
492TEST_NC_PUT_VAR1(ushort)
493TEST_NC_PUT_VAR1(uint)
494TEST_NC_PUT_VAR1(longlong)
495TEST_NC_PUT_VAR1(ulonglong)
496
497
498dnl TEST_NC_PUT_VAR(TYPE)
499dnl
500define(`TEST_NC_PUT_VAR',dnl
501`dnl
502int
503TestFunc(var)_$1(VarArgs)
504{
505    int i, err, ncid, varid, cdf_format, nok=0;
506    int canConvert;        /* Both text or both numeric */
507    int allInExtRange;     /* all values within external range? */
508    IntType j, index[MAX_RANK];
509    $1 value[MAX_NELS];
510
511    err = FileCreate(scratch, NC_CLOBBER);
512    IF (err != NC_NOERR) {
513        error("create: %s", APIFunc(strerror)(err));
514        return nok;
515    }
516
517    err = APIFunc(inq_format)(ncid, &cdf_format);
518    IF (err != NC_NOERR)
519        error("inq_format: %s", APIFunc(strerror)(err));
520
521    def_dims(ncid);
522    DefVars(ncid, numVars);
523
524    err = APIFunc(enddef)(ncid);
525    IF (err != NC_NOERR)
526        error("enddef: %s", APIFunc(strerror)(err));
527
528    /* check if can detect a bad file ID */
529    err = PutVar($1)(BAD_ID, 0, NULL);
530    IF (err != NC_EBADID)
531        EXPECT_ERR(NC_EBADID, err)
532    ELSE_NOK
533
534    /* check if can detect a bad variable ID */
535    err = PutVar($1)(ncid, BAD_VARID, NULL);
536    IF (err != NC_ENOTVAR)
537        EXPECT_ERR(NC_ENOTVAR, err)
538    ELSE_NOK
539
540    for (i = 0; i < numVars; i++) {
541        assert(var_rank[i] <= MAX_RANK);
542        assert(var_nels[i] <= MAX_NELS);
543
544        if (var_dimid[i][0] == RECDIM) continue; /* fixed-size variables only */
545
546        value[0] = 5;  /* reset to a value within bounds */
547
548        /* check if can detect a bad file ID */
549        err = PutVar($1)(BAD_ID, i, value);
550        IF (err != NC_EBADID)
551            EXPECT_ERR(NC_EBADID, err)
552        ELSE_NOK
553
554        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
555
556        for (allInExtRange = 1, j = 0; j < var_nels[i]; j++) {
557            err = toMixedBase(j, var_rank[i], var_shape[i], index);
558            IF (err != 0) error("error in toMixedBase");
559            value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index,
560                              NCT_ITYPE($1));
561            IfCheckTextChar($1, var_type[i])
562                allInExtRange &= inRange3(cdf_format, (double)value[j],
563                                          var_type[i], NCT_ITYPE($1));
564        }
565        err = PutVar($1)(ncid, i, value);
566        if (canConvert) {
567            if (allInExtRange) {
568                IF (err != NC_NOERR)
569                    EXPECT_ERR(NC_NOERR, err)
570                ELSE_NOK
571            }
572            PNETCDF_CHECK_ERANGE($1)
573        } else { /* should flag wrong type even if nothing to write */
574            IF (err != NC_ECHAR)
575                EXPECT_ERR(NC_ECHAR, err)
576            ELSE_NOK
577        }
578    }
579
580    /* Preceding has written nothing for record variables, now try */
581    /* again with more than 0 records */
582
583    /* Write record number NRECS to force writing of preceding records */
584    /* Assumes variable cr is char vector with UNLIMITED dimension */
585    err = APIFunc(inq_varid)(ncid, "cr", &varid);
586    IF (err != NC_NOERR)
587        error("inq_varid: %s", APIFunc(strerror)(err));
588    index[0] = NRECS-1;
589    err = PutVar1(text)(ncid, varid, index, "x");
590    IF (err != NC_NOERR)
591        error("put_var1_text: %s", APIFunc(strerror)(err));
592
593    for (i = 0; i < numVars; i++) {
594        if (var_dimid[i][0] != RECDIM) continue; /* only record variables here */
595
596        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
597
598        for (allInExtRange = 1, j = 0; j < var_nels[i]; j++) {
599            err = toMixedBase(j, var_rank[i], var_shape[i], index);
600            IF (err != 0) error("error in toMixedBase");
601            value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index,
602                              NCT_ITYPE($1));
603            IfCheckTextChar($1, var_type[i])
604                allInExtRange &= inRange3(cdf_format, (double)value[j],
605                                          var_type[i], NCT_ITYPE($1));
606        }
607        err = PutVar($1)(ncid, i, value);
608        if (canConvert) {
609            if (allInExtRange) {
610                IF (err != NC_NOERR)
611                    EXPECT_ERR(NC_NOERR, err)
612                ELSE_NOK
613            } else {
614                IF (err != NC_ERANGE)
615                    EXPECT_ERR(NC_ERANGE, err)
616                ELSE_NOK
617            }
618        } else {
619            IF (err != NC_ECHAR)
620                EXPECT_ERR(NC_ECHAR, err)
621            ELSE_NOK
622        }
623    }
624
625    err = APIFunc(close)(ncid);
626    IF (err != NC_NOERR)
627        error("close: %s", APIFunc(strerror)(err));
628
629    nok += check_vars_$1(scratch, numVars);
630
631    err = FileDelete(scratch, info);
632    IF (err != NC_NOERR)
633        error("delete file %s failed", scratch);
634    return nok;
635}
636')dnl
637
638TEST_NC_PUT_VAR(text)
639TEST_NC_PUT_VAR(uchar)
640TEST_NC_PUT_VAR(schar)
641TEST_NC_PUT_VAR(short)
642TEST_NC_PUT_VAR(int)
643TEST_NC_PUT_VAR(long)
644TEST_NC_PUT_VAR(float)
645TEST_NC_PUT_VAR(double)
646TEST_NC_PUT_VAR(ushort)
647TEST_NC_PUT_VAR(uint)
648TEST_NC_PUT_VAR(longlong)
649TEST_NC_PUT_VAR(ulonglong)
650
651
652dnl TEST_NC_PUT_VARA(TYPE)
653dnl
654define(`TEST_NC_PUT_VARA',dnl
655`dnl
656int
657TestFunc(vara)_$1(VarArgs)
658{
659    int i, k, d, err, nslabs, ncid, cdf_format, nok=0;
660    int canConvert;        /* Both text or both numeric */
661    int allInExtRange;     /* all values within external range? */
662    IntType j, nels;
663    IntType start[MAX_RANK], edge[MAX_RANK];
664    IntType mid[MAX_RANK], index[MAX_RANK];
665    $1 value[MAX_NELS];
666
667    err = FileCreate(scratch, NC_CLOBBER);
668    IF (err != NC_NOERR) {
669        error("create: %s", APIFunc(strerror)(err));
670        return nok;
671    }
672
673    err = APIFunc(inq_format)(ncid, &cdf_format);
674    IF (err != NC_NOERR)
675        error("inq_format: %s", APIFunc(strerror)(err));
676
677    def_dims(ncid);
678    DefVars(ncid, numVars);
679
680    err = APIFunc(enddef)(ncid);
681    IF (err != NC_NOERR)
682        error("enddef: %s", APIFunc(strerror)(err));
683
684    /* check if can detect a bad file ID */
685    err = PutVara($1)(BAD_ID, 0, NULL, NULL, NULL);
686    IF (err != NC_EBADID)
687        EXPECT_ERR(NC_EBADID, err)
688    ELSE_NOK
689
690    /* check if can detect a bad variable ID */
691    err = PutVara($1)(ncid, BAD_VARID, NULL, NULL, NULL);
692    IF (err != NC_ENOTVAR)
693        EXPECT_ERR(NC_ENOTVAR, err)
694    ELSE_NOK
695
696    for (i = 0; i < numVars; i++) {
697        assert(var_rank[i] <= MAX_RANK);
698        assert(var_nels[i] <= MAX_NELS);
699
700        value[0] = 5; /* reset to a value within bounds */
701
702        /* check if can detect a bad file ID */
703        err = PutVara($1)(BAD_ID, i, NULL, NULL, value);
704        IF (err != NC_EBADID)
705            EXPECT_ERR(NC_EBADID, err)
706        ELSE_NOK
707
708        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
709
710        for (j = 0; j < var_rank[i]; j++) {
711            start[j] = 0;
712            edge[j] = 1;
713        }
714
715ifdef(`PNETCDF',`dnl
716        /* for non-scalar variables, argument start cannot be NULL */
717        err = PutVara($1)(ncid, i, NULL, NULL, value);
718        if (!canConvert) {
719            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
720        }
721        else if (var_rank[i] == 0) {
722            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
723        }
724        else IF (err != NC_EINVALCOORDS) {
725            EXPECT_ERR(NC_EINVALCOORDS, err)
726        }
727        ELSE_NOK
728
729        /* for non-scalar variables, argument count cannot be NULL */
730        err = PutVara($1)(ncid, i, start, NULL, value);
731        if (!canConvert) {
732            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
733        }
734        else if (var_rank[i] == 0) {
735            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
736        }
737        else IF (err != NC_EEDGE) {
738            EXPECT_ERR(NC_EEDGE, err)
739        }
740        ELSE_NOK
741')dnl
742
743        /* first test when edge[*] > 0 */
744        for (j = 0; j < var_rank[i]; j++) {
745            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
746            start[j] = var_shape[i][j];
747            err = PutVara($1)(ncid, i, start, edge, value);
748            if (!canConvert) {
749                IF (err != NC_ECHAR)
750                    EXPECT_ERR(NC_ECHAR, err)
751                ELSE_NOK
752                start[j] = 0;
753                continue;
754            }
755            IF (err != NC_EINVALCOORDS)
756                EXPECT_ERR(NC_EINVALCOORDS, err)
757            ELSE_NOK
758            start[j] = 0;
759            edge[j] = var_shape[i][j] + 1;
760            err = PutVara($1)(ncid, i, start, edge, value);
761            IF (err != NC_EEDGE)
762                EXPECT_ERR(NC_EEDG, err)
763            ELSE_NOK
764            edge[j] = 1;
765        }
766
767        /* Check correct error returned when nothing to put, when edge[*]==0 */
768        for (j = 0; j < var_rank[i]; j++) edge[j] = 0;
769
770        for (j = 0; j < var_rank[i]; j++) {
771            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
772            start[j] = var_shape[i][j];
773            err = PutVara($1)(ncid, i, start, edge, value);
774            if (!canConvert) {
775                IF (err != NC_ECHAR)
776                    EXPECT_ERR(NC_ECHAR, err)
777                ELSE_NOK
778                start[j] = 0;
779                continue;
780            }
781            IF (err != NC_NOERR) /* allowed when edge[j]==0 */
782                EXPECT_ERR(NC_NOERR, err)
783            ELSE_NOK
784            start[j] = var_shape[i][j]+1; /* out of boundary check */
785            err = PutVara($1)(ncid, i, start, edge, value);
786            IF (err != NC_EINVALCOORDS)
787                EXPECT_ERR(NC_EINVALCOORDS, err)
788            ELSE_NOK
789            start[j] = 0;
790        }
791        for (j = 0; j < var_rank[i]; j++) edge[j] = 1;
792
793        /* Choose a random point dividing each dim into 2 parts */
794        /* Put 2^rank (nslabs) slabs so defined */
795        nslabs = 1;
796        for (j = 0; j < var_rank[i]; j++) {
797            mid[j] = roll( var_shape[i][j] );
798            nslabs *= 2;
799        }
800        /* bits of k determine whether to put lower or upper part of dim */
801        for (k = 0; k < nslabs; k++) {
802            nels = 1;
803            for (j = 0; j < var_rank[i]; j++) {
804                if ((k >> j) & 1) {
805                    start[j] = 0;
806                    edge[j] = mid[j];
807                } else {
808                    start[j] = mid[j];
809                    edge[j] = var_shape[i][j] - mid[j];
810                }
811                nels *= edge[j];
812            }
813
814            for (allInExtRange = 1, j = 0; j < nels; j++) {
815                err = toMixedBase(j, var_rank[i], edge, index);
816                IF (err != 0) error("error in toMixedBase");
817                for (d = 0; d < var_rank[i]; d++)
818                    index[d] += start[d];
819                value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index,
820                                  NCT_ITYPE($1));
821                IfCheckTextChar($1, var_type[i])
822                    allInExtRange &= inRange3(cdf_format, (double)value[j],
823                                              var_type[i], NCT_ITYPE($1));
824            }
825            err = PutVara($1)(ncid, i, start, edge, value);
826            if (canConvert) {
827                if (allInExtRange) {
828                    IF (err != NC_NOERR)
829                        EXPECT_ERR(NC_NOERR, err)
830                    ELSE_NOK
831                }
832                PNETCDF_CHECK_ERANGE($1)
833            } else {
834                IF (err != NC_ECHAR)
835                    EXPECT_ERR(NC_ECHAR, err)
836                ELSE_NOK
837            }
838        }
839    }
840
841    err = APIFunc(close)(ncid);
842    IF (err != NC_NOERR)
843        error("close: %s", APIFunc(strerror)(err));
844
845    nok += check_vars_$1(scratch, numVars);
846
847    err = FileDelete(scratch, info);
848    IF (err != NC_NOERR)
849        error("delete file %s failed", scratch);
850    return nok;
851}
852')dnl
853
854TEST_NC_PUT_VARA(text)
855TEST_NC_PUT_VARA(uchar)
856TEST_NC_PUT_VARA(schar)
857TEST_NC_PUT_VARA(short)
858TEST_NC_PUT_VARA(int)
859TEST_NC_PUT_VARA(long)
860TEST_NC_PUT_VARA(float)
861TEST_NC_PUT_VARA(double)
862TEST_NC_PUT_VARA(ushort)
863TEST_NC_PUT_VARA(uint)
864TEST_NC_PUT_VARA(longlong)
865TEST_NC_PUT_VARA(ulonglong)
866
867
868dnl TEST_NC_PUT_VARS(TYPE)
869dnl
870define(`TEST_NC_PUT_VARS',dnl
871`dnl
872int
873TestFunc(vars)_$1(VarArgs)
874{
875    int i, k, d, err, nslabs, ncid, cdf_format, nok=0;
876    int canConvert;     /* Both text or both numeric */
877    int allInExtRange;  /* all values within external range? */
878    IntType j, m, nels;
879    IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK];
880    IntType index2[MAX_RANK], mid[MAX_RANK], count[MAX_RANK];
881    IntType sstride[MAX_RANK];
882    PTRDType nstarts;   /* number of different starts */
883    PTRDType stride[MAX_RANK];
884    $1 value[MAX_NELS];
885
886    err = FileCreate(scratch, NC_CLOBBER);
887    IF (err != NC_NOERR) {
888        error("create: %s", APIFunc(strerror)(err));
889        return nok;
890    }
891
892    err = APIFunc(inq_format)(ncid, &cdf_format);
893    IF (err != NC_NOERR)
894        error("inq_format: %s", APIFunc(strerror)(err));
895
896    def_dims(ncid);
897    DefVars(ncid, numVars);
898
899    err = APIFunc(enddef)(ncid);
900    IF (err != NC_NOERR)
901        error("enddef: %s", APIFunc(strerror)(err));
902
903    /* check if can detect a bad file ID */
904    err = PutVars($1)(BAD_ID, 0, NULL, NULL, NULL, NULL);
905    IF (err != NC_EBADID)
906        EXPECT_ERR(NC_EBADID, err)
907    ELSE_NOK
908
909    /* check if can detect a bad variable ID */
910    err = PutVars($1)(ncid, BAD_VARID, NULL, NULL, NULL, NULL);
911    IF (err != NC_ENOTVAR)
912        EXPECT_ERR(NC_ENOTVAR, err)
913    ELSE_NOK
914
915    for (i = 0; i < numVars; i++) {
916        assert(var_rank[i] <= MAX_RANK);
917        assert(var_nels[i] <= MAX_NELS);
918
919        value[0] = 5; /* reset to a value within bounds */
920
921        /* check if can detect a bad file ID */
922        err = PutVars($1)(BAD_ID, i, NULL, NULL, NULL, value);
923        IF (err != NC_EBADID)
924            EXPECT_ERR(NC_EBADID, err)
925        ELSE_NOK
926
927        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
928
929        for (j = 0; j < var_rank[i]; j++) {
930            start[j] = 0;
931            edge[j] = 1;
932            stride[j] = 1;
933        }
934ifdef(`PNETCDF',`dnl
935        /* for non-scalar variables, argument start cannot be NULL */
936        err = PutVars($1)(ncid, i, NULL, NULL, NULL, value);
937        if (!canConvert) {
938            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
939        }
940        else if (var_rank[i] == 0) { /* scalar variable */
941            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
942        }
943        else IF (err != NC_EINVALCOORDS) {
944            EXPECT_ERR(NC_EINVALCOORDS, err)
945        }
946        ELSE_NOK
947
948        /* for non-scalar variables, argument count cannot be NULL */
949        err = PutVars($1)(ncid, i, start, NULL, NULL, value);
950        if (!canConvert) {
951            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
952        }
953        else if (var_rank[i] == 0) { /* scalar variable */
954            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
955        }
956        else IF (err != NC_EEDGE) {
957            EXPECT_ERR(NC_EEDGE, err)
958        }
959        ELSE_NOK
960')dnl
961
962        /* first test when edge[*] > 0 */
963        for (j = 0; j < var_rank[i]; j++) {
964            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
965            start[j] = var_shape[i][j];   /* out of boundary check */
966            err = PutVars($1)(ncid, i, start, edge, stride, value);
967            if (!canConvert) {
968                IF (err != NC_ECHAR)
969                    EXPECT_ERR(NC_ECHAR, err)
970                ELSE_NOK
971                start[j] = 0;
972                continue;
973            }
974            IF (err != NC_EINVALCOORDS)
975                EXPECT_ERR(NC_EINVALCOORDS, err)
976            ELSE_NOK
977            start[j] = 0;
978            edge[j] = var_shape[i][j] + 1;
979            err = PutVars($1)(ncid, i, start, edge, stride, value);
980            IF (err != NC_EEDGE)
981                EXPECT_ERR(NC_EEDGE, err)
982            ELSE_NOK
983            edge[j] = 1;
984            stride[j] = 0;
985            err = PutVars($1)(ncid, i, start, edge, stride, value);
986            IF (err != NC_ESTRIDE)
987                EXPECT_ERR(NC_ESTRIDE, err)
988            ELSE_NOK
989            stride[j] = 1;
990        }
991        /* Check correct error returned even when nothing to put */
992        for (j = 0; j < var_rank[i]; j++) edge[j] = 0;
993
994        for (j = 0; j < var_rank[i]; j++) {
995            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
996            start[j] = var_shape[i][j];
997            err = PutVars($1)(ncid, i, start, edge, stride, value);
998            if (!canConvert) {
999                IF (err != NC_ECHAR)
1000                    EXPECT_ERR(NC_ECHAR, err)
1001                ELSE_NOK
1002                start[j] = 0;
1003                continue;
1004            }
1005            IF (err != NC_NOERR) /* allowed when edge[j]==0 */
1006                EXPECT_ERR(NC_NOERR, err)
1007            ELSE_NOK
1008            start[j] = var_shape[i][j]+1; /* out of boundary check */
1009            err = PutVars($1)(ncid, i, start, edge, stride, value);
1010            IF (err != NC_EINVALCOORDS)
1011                EXPECT_ERR(NC_EINVALCOORDS, err)
1012            ELSE_NOK
1013            start[j] = 0;
1014        }
1015        for (j = 0; j < var_rank[i]; j++) edge[j] = 1;
1016
1017        /* Choose a random point dividing each dim into 2 parts */
1018        /* Put 2^rank (nslabs) slabs so defined */
1019        nslabs = 1;
1020        for (j = 0; j < var_rank[i]; j++) {
1021            mid[j] = roll( var_shape[i][j] );
1022            nslabs *= 2;
1023        }
1024        /* bits of k determine whether to put lower or upper part of dim */
1025        /* choose random stride from 1 to edge */
1026        for (k = 0; k < nslabs; k++) {
1027            nstarts = 1;
1028            for (j = 0; j < var_rank[i]; j++) {
1029                if ((k >> j) & 1) {
1030                    start[j] = 0;
1031                    edge[j] = mid[j];
1032                } else {
1033                    start[j] = mid[j];
1034                    edge[j] = var_shape[i][j] - mid[j];
1035                }
1036                sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
1037                stride[j] = (PTRDType)sstride[j];
1038                nstarts *= stride[j];
1039            }
1040            for (m = 0; m < nstarts; m++) {
1041                err = toMixedBase(m, var_rank[i], sstride, index);
1042                IF (err != 0) error("error in toMixedBase");
1043                nels = 1;
1044                for (j = 0; j < var_rank[i]; j++) {
1045                    count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j];
1046                    nels *= count[j];
1047                    index[j] += start[j];
1048                }
1049                /* Random choice of forward or backward */
1050/* TODO
1051                if ( roll(2) ) {
1052                    for (j = 0; j < var_rank[i]; j++) {
1053                        index[j] += (count[j] - 1) * (IntType)stride[j];
1054                        stride[j] = -stride[j];
1055                    }
1056                }
1057*/
1058                for (allInExtRange = 1, j = 0; j < nels; j++) {
1059                    err = toMixedBase(j, var_rank[i], count, index2);
1060                    IF (err != 0) error("error in toMixedBase");
1061                    for (d = 0; d < var_rank[i]; d++)
1062                        index2[d] = index[d] + index2[d] * (IntType)stride[d];
1063                    value[j] = hash_$1(cdf_format,var_type[i], var_rank[i],
1064                                       index2, NCT_ITYPE($1));
1065                    IfCheckTextChar($1, var_type[i])
1066                        allInExtRange &= inRange3(cdf_format, (double)value[j],
1067                                                  var_type[i], NCT_ITYPE($1));
1068                }
1069                err = PutVars($1)(ncid, i, index, count, stride, value);
1070                if (canConvert) {
1071                    if (allInExtRange) {
1072                        IF (err != NC_NOERR)
1073                            EXPECT_ERR(NC_NOERR, err)
1074                        ELSE_NOK
1075                    }
1076                    PNETCDF_CHECK_ERANGE($1)
1077                } else {
1078                    IF (err != NC_ECHAR)
1079                        EXPECT_ERR(NC_ECHAR, err)
1080                    ELSE_NOK
1081                }
1082            }
1083        }
1084    }
1085
1086    err = APIFunc(close)(ncid);
1087    IF (err != NC_NOERR)
1088        error("close: %s", APIFunc(strerror)(err));
1089
1090    nok += check_vars_$1(scratch, numVars);
1091
1092    err = FileDelete(scratch, info);
1093    IF (err != NC_NOERR)
1094        error("delete file %s failed", scratch);
1095    return nok;
1096}
1097')dnl
1098
1099TEST_NC_PUT_VARS(text)
1100TEST_NC_PUT_VARS(uchar)
1101TEST_NC_PUT_VARS(schar)
1102TEST_NC_PUT_VARS(short)
1103TEST_NC_PUT_VARS(int)
1104TEST_NC_PUT_VARS(long)
1105TEST_NC_PUT_VARS(float)
1106TEST_NC_PUT_VARS(double)
1107TEST_NC_PUT_VARS(ushort)
1108TEST_NC_PUT_VARS(uint)
1109TEST_NC_PUT_VARS(longlong)
1110TEST_NC_PUT_VARS(ulonglong)
1111
1112
1113dnl TEST_NC_PUT_VARM(TYPE)
1114dnl
1115define(`TEST_NC_PUT_VARM',dnl
1116`dnl
1117int
1118TestFunc(varm)_$1(VarArgs)
1119{
1120    int i, k, d, err, nslabs, ncid, cdf_format, nok=0;
1121    int canConvert;     /* Both text or both numeric */
1122    int allInExtRange;  /* all values within external range? */
1123    IntType j, m, nels;
1124    IntType start[MAX_RANK], edge[MAX_RANK], index[MAX_RANK];
1125    IntType index2[MAX_RANK], mid[MAX_RANK], count[MAX_RANK];
1126    IntType sstride[MAX_RANK];
1127    PTRDType nstarts;   /* number of different starts */
1128    PTRDType stride[MAX_RANK], imap[MAX_RANK];
1129    $1 value[MAX_NELS];
1130
1131    err = FileCreate(scratch, NC_CLOBBER);
1132    IF (err != NC_NOERR) {
1133        error("create: %s", APIFunc(strerror)(err));
1134        return nok;
1135    }
1136
1137    err = APIFunc(inq_format)(ncid, &cdf_format);
1138    IF (err != NC_NOERR)
1139        error("inq_format: %s", APIFunc(strerror)(err));
1140
1141    def_dims(ncid);
1142    DefVars(ncid, numVars);
1143
1144    err = APIFunc(enddef)(ncid);
1145    IF (err != NC_NOERR)
1146        error("enddef: %s", APIFunc(strerror)(err));
1147
1148    /* check if can detect a bad file ID */
1149    err = PutVarm($1)(BAD_ID, 0, NULL, NULL, NULL, NULL, NULL);
1150    IF (err != NC_EBADID)
1151        EXPECT_ERR(NC_EBADID, err)
1152    ELSE_NOK
1153
1154    /* check if can detect a bad variable ID */
1155    err = PutVarm($1)(ncid, BAD_VARID, NULL, NULL, NULL, NULL, NULL);
1156    IF (err != NC_ENOTVAR)
1157        EXPECT_ERR(NC_ENOTVAR, err)
1158    ELSE_NOK
1159
1160    for (i = 0; i < numVars; i++) {
1161        assert(var_rank[i] <= MAX_RANK);
1162        assert(var_nels[i] <= MAX_NELS);
1163
1164        value[0] = 5; /* reset to a value within bounds */
1165
1166        /* check if can detect a bad file ID */
1167        err = PutVarm($1)(BAD_ID, i, NULL, NULL, NULL, NULL, value);
1168        IF (err != NC_EBADID)
1169            EXPECT_ERR(NC_EBADID, err)
1170        ELSE_NOK
1171
1172        canConvert = (var_type[i] == NC_CHAR) CheckText($1);
1173
1174        for (j = 0; j < var_rank[i]; j++) {
1175            start[j] = 0;
1176            edge[j] = 1;
1177            stride[j] = 1;
1178            imap[j] = 1;
1179        }
1180
1181ifdef(`PNETCDF',`dnl
1182        /* for non-scalar variables, argument start cannot be NULL */
1183        err = PutVarm($1)(ncid, i, NULL, NULL, NULL, NULL, value);
1184        if (!canConvert) {
1185            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
1186        }
1187        else if (var_rank[i] == 0) { /* scalar variable */
1188            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
1189        }
1190        else IF (err != NC_EINVALCOORDS) {
1191            EXPECT_ERR(NC_EINVALCOORDS, err)
1192        }
1193        ELSE_NOK
1194
1195        /* for non-scalar variables, argument count cannot be NULL */
1196        err = PutVarm($1)(ncid, i, start, NULL, NULL, NULL, value);
1197        if (!canConvert) {
1198            IF (err != NC_ECHAR) EXPECT_ERR(NC_ECHAR, err)
1199        }
1200        else if (var_rank[i] == 0) { /* scalar variable */
1201            IF (err != NC_NOERR) EXPECT_ERR(NC_NOERR, err)
1202        }
1203        else IF (err != NC_EEDGE) {
1204            EXPECT_ERR(NC_EEDGE, err)
1205        }
1206        ELSE_NOK
1207')dnl
1208
1209        /* first test when edge[*] > 0 */
1210        for (j = 0; j < var_rank[i]; j++) {
1211            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
1212            start[j] = var_shape[i][j];   /* out of boundary check */
1213            err = PutVarm($1)(ncid, i, start, edge, stride, imap, value);
1214            if (!canConvert) {
1215                IF (err != NC_ECHAR)
1216                    EXPECT_ERR(NC_ECHAR, err)
1217                ELSE_NOK
1218                start[j] = 0;
1219                continue;
1220            }
1221            IF (err != NC_EINVALCOORDS)
1222                EXPECT_ERR(NC_EINVALCOORDS, err)
1223            ELSE_NOK
1224            start[j] = 0;
1225            edge[j] = var_shape[i][j] + 1;
1226            err = PutVarm($1)(ncid, i, start, edge, stride, imap, value);
1227            IF (err != NC_EEDGE)
1228                EXPECT_ERR(NC_EEDGE, err)
1229            ELSE_NOK
1230            edge[j] = 1;
1231            stride[j] = 0;
1232            err = PutVarm($1)(ncid, i, start, edge, stride, imap, value);
1233            IF (err != NC_ESTRIDE)
1234                EXPECT_ERR(NC_ESTRIDE, err)
1235            ELSE_NOK
1236            stride[j] = 1;
1237        }
1238        /* Check correct error returned when nothing to put, i.e. edge[*]==0 */
1239        for (j = 0; j < var_rank[i]; j++) edge[j] = 0;
1240
1241        for (j = 0; j < var_rank[i]; j++) {
1242            if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */
1243            start[j] = var_shape[i][j];
1244            err = PutVarm($1)(ncid, i, start, edge, stride, imap, value);
1245            if (!canConvert) {
1246                IF (err != NC_ECHAR)
1247                    EXPECT_ERR(NC_ECHAR, err)
1248                ELSE_NOK
1249                start[j] = 0;
1250                continue;
1251            }
1252            IF (err != NC_NOERR) /* allowed when edge[j]==0 */
1253                EXPECT_ERR(NC_NOERR, err)
1254            ELSE_NOK
1255            start[j] = var_shape[i][j]+1; /* out of boundary check */
1256            err = PutVarm($1)(ncid, i, start, edge, stride, imap, value);
1257            IF (err != NC_EINVALCOORDS)
1258                EXPECT_ERR(NC_EINVALCOORDS, err)
1259            ELSE_NOK
1260            start[j] = 0;
1261        }
1262        for (j = 0; j < var_rank[i]; j++) edge[j] = 1;
1263
1264        /* Choose a random point dividing each dim into 2 parts */
1265        /* Put 2^rank (nslabs) slabs so defined */
1266        nslabs = 1;
1267        for (j = 0; j < var_rank[i]; j++) {
1268            mid[j] = roll( var_shape[i][j] );
1269            nslabs *= 2;
1270        }
1271        /* bits of k determine whether to put lower or upper part of dim */
1272        /* choose random stride from 1 to edge */
1273        for (k = 0; k < nslabs; k++) {
1274            nstarts = 1;
1275            for (j = 0; j < var_rank[i]; j++) {
1276                if ((k >> j) & 1) {
1277                    start[j] = 0;
1278                    edge[j] = mid[j];
1279                } else {
1280                    start[j] = mid[j];
1281                    edge[j] = var_shape[i][j] - mid[j];
1282                }
1283                sstride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
1284                stride[j] = (PTRDType)sstride[j];
1285                nstarts *= stride[j];
1286            }
1287            for (m = 0; m < nstarts; m++) {
1288                err = toMixedBase(m, var_rank[i], sstride, index);
1289                IF (err != 0) error("error in toMixedBase");
1290                nels = 1;
1291                for (j = 0; j < var_rank[i]; j++) {
1292                    count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j];
1293                    nels *= count[j];
1294                    index[j] += start[j];
1295                }
1296                /* Random choice of forward or backward */
1297/* TODO
1298                if ( roll(2) ) {
1299                    for (j = 0; j < var_rank[i]; j++) {
1300                        index[j] += (count[j] - 1) * (IntType)stride[j];
1301                        stride[j] = -stride[j];
1302                    }
1303                }
1304*/
1305                if (var_rank[i] > 0) {
1306                    int jj = var_rank[i] - 1;
1307                    imap[jj] = 1;
1308                    for (; jj > 0; jj--)
1309                        imap[jj-1] = imap[jj] * (PTRDType)count[jj];
1310                }
1311                for (allInExtRange = 1, j = 0; j < nels; j++) {
1312                    err = toMixedBase(j, var_rank[i], count, index2);
1313                    IF (err != 0) error("error in toMixedBase");
1314                    for (d = 0; d < var_rank[i]; d++)
1315                        index2[d] = index[d] + index2[d] * (IntType)stride[d];
1316                    value[j] = hash_$1(cdf_format,var_type[i], var_rank[i],
1317                                       index2, NCT_ITYPE($1));
1318                    IfCheckTextChar($1, var_type[i])
1319                        allInExtRange &= inRange3(cdf_format, (double)value[j],
1320                                                  var_type[i], NCT_ITYPE($1));
1321                }
1322                err = PutVarm($1)(ncid,i,index,count,stride,imap,value);
1323                if (canConvert) {
1324                    if (allInExtRange) {
1325                        IF (err != NC_NOERR)
1326                            EXPECT_ERR(NC_NOERR, err)
1327                        ELSE_NOK
1328                    }
1329                    PNETCDF_CHECK_ERANGE($1)
1330                } else {
1331                    IF (err != NC_ECHAR)
1332                        EXPECT_ERR(NC_ECHAR, err)
1333                    ELSE_NOK
1334                }
1335            }
1336        }
1337    }
1338
1339    err = APIFunc(close)(ncid);
1340    IF (err != NC_NOERR)
1341        error("close: %s", APIFunc(strerror)(err));
1342
1343    nok += check_vars_$1(scratch, numVars);
1344
1345    err = FileDelete(scratch, info);
1346    IF (err != NC_NOERR)
1347        error("delete file %s failed", scratch);
1348    return nok;
1349}
1350')dnl
1351
1352TEST_NC_PUT_VARM(text)
1353TEST_NC_PUT_VARM(uchar)
1354TEST_NC_PUT_VARM(schar)
1355TEST_NC_PUT_VARM(short)
1356TEST_NC_PUT_VARM(int)
1357TEST_NC_PUT_VARM(long)
1358TEST_NC_PUT_VARM(float)
1359TEST_NC_PUT_VARM(double)
1360TEST_NC_PUT_VARM(ushort)
1361TEST_NC_PUT_VARM(uint)
1362TEST_NC_PUT_VARM(longlong)
1363TEST_NC_PUT_VARM(ulonglong)
1364
1365
1366int
1367TestFunc(att)_text(AttVarArgs)
1368{
1369    int i, j, err, ncid, nok=0;
1370    double dtmp;
1371    IntType k, ndx[1];
1372    text value[MAX_NELS];
1373
1374    err = FileCreate(scratch, NC_NOCLOBBER);
1375    IF (err != NC_NOERR) {
1376        error("create: %s", APIFunc(strerror)(err));
1377        return nok;
1378    }
1379    def_dims(ncid);
1380    DefVars(ncid, numVars);
1381
1382    /* check if can detect a bad file ID */
1383    err = PutAtt(text)(BAD_ID, 0, NULL, 0, NULL);
1384    IF (err != NC_EBADID)
1385        EXPECT_ERR(NC_EBADID, err)
1386    ELSE_NOK
1387
1388    /* check if can detect a bad variable ID */
1389    err = PutAtt(text)(ncid, BAD_VARID, NULL, 0, NULL);
1390    IF (err != NC_ENOTVAR)
1391        EXPECT_ERR(NC_ENOTVAR, err)
1392    ELSE_NOK
1393
1394    {
1395        const char *const tval = "value for bad name";
1396        const IntType tval_len = (IntType)strlen(tval);
1397
1398        err = PutAtt(text)(ncid, 0, "", tval_len, tval);
1399        IF (err != NC_EBADNAME)
1400           EXPECT_ERR(NC_EBADNAME, err)
1401        ELSE_NOK
1402    }
1403    for (i = -1; i < numVars; i++) {
1404        for (j = 0; j < NATTS(i); j++) {
1405            if (ATT_TYPE(i,j) == NC_CHAR) {
1406                assert(ATT_LEN(i,j) <= MAX_NELS);
1407
1408                err = PutAtt(text)(ncid, BAD_VARID, ATT_NAME(i,j), ATT_LEN(i,j), value);
1409                IF (err != NC_ENOTVAR)
1410                    EXPECT_ERR(NC_ENOTVAR, err)
1411                ELSE_NOK
1412
1413                for (k = 0; k < ATT_LEN(i,j); k++) {
1414                    ndx[0] = k;
1415                    dtmp = hash(ATT_TYPE(i,j), -1, ndx);
1416                    value[k] = (text)dtmp;
1417                }
1418                err = PutAtt(text)(ncid, i, ATT_NAME(i,j), ATT_LEN(i,j), value);
1419                IF (err != NC_NOERR)
1420                    EXPECT_ERR(NC_NOERR, err)
1421                ELSE_NOK
1422            }
1423        }
1424    }
1425
1426    nok += check_atts_text(ncid, numGatts, numVars);
1427    err = APIFunc(close)(ncid);
1428    IF (err != NC_NOERR)
1429        error("close: %s", APIFunc(strerror)(err));
1430
1431    err = FileDelete(scratch, info);
1432    IF (err != NC_NOERR)
1433        error("delete file %s failed", scratch);
1434    return nok;
1435}
1436
1437
1438dnl TEST_NC_PUT_ATT(TYPE)         numeric only
1439dnl
1440define(`TEST_NC_PUT_ATT',dnl
1441`dnl
1442int
1443TestFunc(att)_$1(AttVarArgs)
1444{
1445    int i, j, err, ncid, cdf_format, nok=0;
1446    int allInExtRange;  /* all values within external range? */
1447    IntType k, ndx[1];
1448    $1 value[MAX_NELS];
1449
1450    err = FileCreate(scratch, NC_NOCLOBBER);
1451    IF (err != NC_NOERR) {
1452        error("create: %s", APIFunc(strerror)(err));
1453        return nok;
1454    }
1455
1456    err = APIFunc(inq_format)(ncid, &cdf_format);
1457    IF (err != NC_NOERR)
1458        error("inq_format: %s", APIFunc(strerror)(err));
1459
1460    def_dims(ncid);
1461    DefVars(ncid, numVars);
1462
1463    /* check if can detect a bad file ID */
1464    err = PutAtt($1)(BAD_ID, 0, NULL, 0, 0, NULL);
1465    IF (err != NC_EBADID)
1466        EXPECT_ERR(NC_EBADID, err)
1467    ELSE_NOK
1468
1469    /* check if can detect a bad variable ID */
1470    err = PutAtt($1)(ncid, BAD_VARID, NULL, 0, 0, NULL);
1471    IF (err != NC_ENOTVAR)
1472        EXPECT_ERR(NC_ENOTVAR, err)
1473    ELSE_NOK
1474
1475    for (i = -1; i < numVars; i++) {
1476        for (j = 0; j < NATTS(i); j++) {
1477            if (!(ATT_TYPE(i,j) == NC_CHAR)) {
1478                assert(ATT_LEN(i,j) <= MAX_NELS);
1479
1480                err = PutAtt($1)(ncid, BAD_VARID, ATT_NAME(i,j), ATT_TYPE(i,j), ATT_LEN(i,j), value);
1481                IF (err != NC_ENOTVAR)
1482                    EXPECT_ERR(NC_ENOTVAR, err)
1483                ELSE_NOK
1484
1485                /* check if can detect a bad name */
1486                err = PutAtt($1)(ncid, i, NULL, 0, 0, NULL);
1487                IF (err != NC_EBADNAME)
1488                    EXPECT_ERR(NC_EBADNAME, err)
1489                ELSE_NOK
1490
1491                err = PutAtt($1)(ncid, i, ATT_NAME(i,j), BAD_TYPE, ATT_LEN(i,j), value);
1492                IF (err != NC_EBADTYPE)
1493                    EXPECT_ERR(NC_EBADTYPE, err)
1494                ELSE_NOK
1495
1496                for (allInExtRange = 1, k = 0; k < ATT_LEN(i,j); k++) {
1497                    ndx[0] = k;
1498                    value[k] = hash_$1(cdf_format,ATT_TYPE(i,j), -1, ndx, NCT_ITYPE($1));
1499                    IfCheckTextChar($1, ATT_TYPE(i,j))
1500                        allInExtRange &= inRange3(cdf_format, (double)value[k], ATT_TYPE(i,j), NCT_ITYPE($1));
1501                }
1502                err = PutAtt($1)(ncid, i, ATT_NAME(i,j), ATT_TYPE(i,j), ATT_LEN(i,j), value);
1503                if (allInExtRange) {
1504                    IF (err != NC_NOERR)
1505                        EXPECT_ERR(NC_NOERR, err)
1506                    ELSE_NOK
1507                }
1508                PNETCDF_CHECK_ERANGE($1)
1509            }
1510        }
1511    }
1512
1513    nok += check_atts_$1(ncid, numGatts, numVars);
1514    err = APIFunc(close)(ncid);
1515    IF (err != NC_NOERR)
1516        error("close: %s", APIFunc(strerror)(err));
1517
1518    err = FileDelete(scratch, info);
1519    IF (err != NC_NOERR)
1520        error("delete file %s failed", scratch);
1521    return nok;
1522}
1523')dnl
1524
1525TEST_NC_PUT_ATT(uchar)
1526TEST_NC_PUT_ATT(schar)
1527TEST_NC_PUT_ATT(short)
1528TEST_NC_PUT_ATT(int)
1529TEST_NC_PUT_ATT(long)
1530TEST_NC_PUT_ATT(float)
1531TEST_NC_PUT_ATT(double)
1532TEST_NC_PUT_ATT(ushort)
1533TEST_NC_PUT_ATT(uint)
1534TEST_NC_PUT_ATT(longlong)
1535TEST_NC_PUT_ATT(ulonglong)
1536
1537