1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "netcdf.h"
6 #include "t_srcdir.h"
7
8
9 #undef GENERATE
10
11 #undef DEBUG
12
13 /* Test (some) internal/external type conversions
14 using following DAP dataset (test.02).
15 Dataset {
16 Byte b[DIMSIZE];
17 Int32 i32[DIMSIZE];
18 UInt32 ui32[DIMSIZE];
19 Int16 i16[DIMSIZE];
20 UInt16 ui16[DIMSIZE];
21 Float32 f32[DIMSIZE];
22 Float64 f64[DIMSIZE];
23 String s[DIMSIZE];
24 Url u[DIMSIZE];
25 } OneDimensionalSimpleArrays;
26 */
27
28 #define NDIMS 1
29 #define DIMSIZE 25
30 #define STRLEN 64
31
32 #ifndef USE_NETCDF4
33 #define NC_UBYTE 7 /* unsigned 1 byte int */
34 #define NC_USHORT 8 /* unsigned 2-byte int */
35 #define NC_UINT 9 /* unsigned 4-byte int */
36 #define NC_INT64 10 /* signed 8-byte int */
37 #define NC_UINT64 11 /* unsigned 8-byte int */
38 #define NC_STRING 12 /* string */
39 #endif
40
41
42 #define CHECK(expr) check(expr,__FILE__,__LINE__);
43
44 #define COMMA (i==0?"":",")
45
46 #define COMPARE(t1,t2,v1,v2) compare(t1,t2,(void*)v1,(void*)v2,#v2,__FILE__,__LINE__)
47
48 static int failure = 0;
49
50 static void compare(nc_type,nc_type,void*,void*,char*,char*,int);
51
52 static void
report(const int i,const char * var,const int line)53 report(const int i, const char* var, const int line)
54 {
55 fprintf(stdout,"%s mismatch: [%d] file: %s line: %d\n",var,i,__FILE__,line);
56 failure = 1;
57 }
58
59 static void
check(int ncstat,char * file,int line)60 check(int ncstat, char* file, int line)
61 {
62 if(ncstat == NC_NOERR) return;
63 fprintf(stderr,"*** FAIL: %d (%s) at %s:%d\n",
64 ncstat,nc_strerror(ncstat),file,line);
65 exit(1);
66 }
67
68 /* return 1 if |f1-f2| > 0.05 */
69 static int
fdiff(double f1,double f2)70 fdiff(double f1, double f2)
71 {
72 double delta = (f1 - f2);
73 if(delta < 0) delta = - delta;
74 if(delta > 0.05) {
75 fprintf(stdout,"fdiff: %1.3f %1.3f delta=%1.3f\n",f1,f2,delta);
76 }
77 return (delta > 0.05?1:0);
78 }
79
80 static char ch_data[DIMSIZE];
81 static signed char int8_data[DIMSIZE];
82 static unsigned char uint8_data[DIMSIZE];
83 static int int8toint32_data[DIMSIZE];
84 static float int82float32_data[DIMSIZE];
85 static short int16_data[DIMSIZE];
86 static int int16toint32_data[DIMSIZE];
87 static float int162float32_data[DIMSIZE];
88 static int int32_data[DIMSIZE];
89 static float int32tofloat32_data[DIMSIZE];
90 static long int32toilong_data[DIMSIZE];
91 static float float32_data[DIMSIZE];
92 static double float64_data[DIMSIZE];
93 #ifndef USE_NETCDF4
94 static char string3_data[DIMSIZE][STRLEN];
95 #endif
96
97 static char ch[DIMSIZE];
98 static signed char int8v[DIMSIZE];
99 static unsigned char uint8v[DIMSIZE];
100 static short int16v[DIMSIZE];
101 static int int32v[DIMSIZE];
102 static float float32v[DIMSIZE];
103 static double float64v[DIMSIZE];
104 static long ilong[DIMSIZE];
105 #ifndef USE_NETCDF4
106 static char string3[DIMSIZE][STRLEN];
107 #endif
108
main()109 int main()
110 {
111 int ncid, varid;
112 int ncstat = NC_NOERR;
113 char url[8192];
114 const char* topsrcdir;
115 size_t len;
116 #ifndef USE_NETCDF4
117 int i,j;
118 #endif
119
120 /* location of our target url: use file:// to avoid remote
121 server downtime issues
122 */
123
124 topsrcdir = gettopsrcdir();
125
126 url[0] = '\0';
127
128 #ifdef DEBUG
129 strlcat(url,"[log][show=fetch]",sizeof(url));
130 #endif
131
132 strlcat(url,"file://",sizeof(url));
133 strlcat(url,topsrcdir,sizeof(url));
134 strlcat(url,"/ncdap_test/testdata3/test.02",sizeof(url));
135
136 printf("*** Test: var conversions on URL: %s\n",url);
137
138 /* open file, get varid */
139 CHECK(nc_open(url, NC_NOWRITE, &ncid));
140
141 /* extract the string case for netcdf-3*/
142 #ifndef USE_NETCDF4
143 CHECK(nc_inq_varid(ncid, "s", &varid));
144 CHECK(nc_get_var_text(ncid,varid,(char*)string3));
145 #ifdef GENERATE
146 printf("static %s string3_data[DIMSIZE][STRLEN]={","char");
147 for(i=0;i<DIMSIZE;i++) {
148 int j;
149 /* Do simple escape */
150 for(j=0;j<STRLEN;j++) {
151 if(string3[i][j] > 0
152 && string3[i][j] != '\n'
153 && string3[i][j] != '\r'
154 && string3[i][j] != '\t'
155 &&(string3[i][j] < ' ' || string3[i][j] >= '\177'))
156 string3[i][j] = '?';
157 }
158 printf("%s\"%s\"",COMMA,string3[i]);
159 }
160 printf("};\n");
161 #else
162 fprintf(stdout,"*** testing: %s\n","string3");
163 for(i=0;i<DIMSIZE;i++) {
164 for(j=0;j<STRLEN;j++) {
165 if(string3[i][j] != string3_data[i][j]) {report(i,"string3",__LINE__); break;}
166 }
167 }
168 #endif
169 #endif
170
171 CHECK(nc_inq_varid(ncid, "b", &varid));
172 CHECK(nc_get_var_text(ncid,varid,ch));
173 #ifdef GENERATE
174 printf("static %s ch_data[DIMSIZE]={","char");
175 for(i=0;i<DIMSIZE;i++) printf("%s'\\%03hho'",COMMA,ch[i]);
176 printf("};\n");
177 #else
178 COMPARE(NC_CHAR,NC_CHAR,ch,ch_data);
179 #endif
180
181 CHECK(nc_inq_varid(ncid, "b", &varid));
182 CHECK(nc_get_var_schar(ncid,varid,int8v));
183 #ifdef GENERATE
184 printf("static %s int8_data[DIMSIZE]={","signed char");
185 for(i=0;i<DIMSIZE;i++) printf("%s%hhd",COMMA,int8v[i]);
186 printf("};\n");
187 #else
188 COMPARE(NC_BYTE,NC_BYTE,int8v,int8_data);
189 #endif
190
191 CHECK(nc_inq_varid(ncid, "b", &varid));
192 CHECK(nc_get_var_uchar(ncid,varid,uint8v));
193 #ifdef GENERATE
194 printf("static %s uint8_data[DIMSIZE]={","unsigned char");
195 for(i=0;i<DIMSIZE;i++) printf("%s%hhu",COMMA,uint8v[i]);
196 printf("};\n");
197 #else
198 COMPARE(NC_UBYTE,NC_UBYTE,uint8v,uint8_data);
199 #endif
200
201 CHECK(nc_inq_varid(ncid, "b", &varid));
202 CHECK(nc_get_var_int(ncid,varid,int32v));
203 #ifdef GENERATE
204 printf("static %s int8toint32_data[DIMSIZE]={","int");
205 for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
206 printf("};\n");
207 #else
208 COMPARE(NC_BYTE,NC_INT,int32v,int8toint32_data);
209 #endif
210
211 CHECK(nc_inq_varid(ncid, "b", &varid));
212 CHECK(nc_get_var_float(ncid,varid,float32v));
213 #ifdef GENERATE
214 printf("static %s int82float32_data[DIMSIZE]={","float");
215 for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
216 printf("};\n");
217 #else
218 COMPARE(NC_FLOAT,NC_FLOAT,float32v,int82float32_data);
219 #endif
220
221 CHECK(nc_inq_varid(ncid, "i16", &varid));
222 CHECK(nc_get_var_short(ncid,varid,int16v));
223 #ifdef GENERATE
224 printf("static %s int16_data[DIMSIZE]={","short");
225 for(i=0;i<DIMSIZE;i++) printf("%s%hd",COMMA,int16v[i]);
226 printf("};\n");
227 #else
228 COMPARE(NC_SHORT,NC_SHORT,int16v,int16_data);
229 #endif
230
231 CHECK(nc_inq_varid(ncid, "i16", &varid));
232 CHECK(nc_get_var_int(ncid,varid,int32v));
233 #ifdef GENERATE
234 printf("static %s int16toint32_data[DIMSIZE]={","int");
235 for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
236 printf("};\n");
237 #else
238 COMPARE(NC_SHORT,NC_INT,int32v,int16toint32_data);
239 #endif
240
241 CHECK(nc_inq_varid(ncid, "i16", &varid));
242 CHECK(nc_get_var_float(ncid,varid,float32v));
243 #ifdef GENERATE
244 printf("static %s int162float32_data[DIMSIZE]={","float");
245 for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
246 printf("};\n");
247 #else
248 COMPARE(NC_SHORT,NC_FLOAT,float32v,int162float32_data);
249 #endif
250
251 CHECK(nc_inq_varid(ncid, "i32", &varid));
252 CHECK(nc_get_var_int(ncid,varid,int32v));
253 #ifdef GENERATE
254 printf("static %s int32_data[DIMSIZE]={","int");
255 for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
256 printf("};\n");
257 #else
258 COMPARE(NC_INT,NC_INT,int32v,int32_data);
259 #endif
260
261 CHECK(nc_inq_varid(ncid, "i32", &varid));
262 CHECK(nc_get_var_float(ncid,varid,float32v));
263 #ifdef GENERATE
264 printf("static %s int32tofloat32_data[DIMSIZE]={","float");
265 for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
266 printf("};\n");
267 #else
268 COMPARE(NC_INT,NC_FLOAT,float32v,int32tofloat32_data);
269 #endif
270
271 CHECK(nc_inq_varid(ncid, "i32", &varid));
272 CHECK(nc_get_var_long(ncid,varid,ilong));
273 #ifdef GENERATE
274 printf("static %s int32toilong_data[DIMSIZE]={","long");
275 for(i=0;i<DIMSIZE;i++) printf("%s%ld",COMMA,ilong[i]);
276 printf("};\n");
277 #else
278 COMPARE(NC_INT,NC_NAT,ilong,int32toilong_data);
279 #endif
280
281 CHECK(nc_inq_varid(ncid, "f32", &varid));
282 CHECK(nc_get_var_float(ncid,varid,float32v));
283 #ifdef GENERATE
284 printf("static %s float32_data[DIMSIZE]={","float");
285 for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
286 printf("};\n");
287 #else
288 COMPARE(NC_FLOAT,NC_FLOAT,float32v,float32_data);
289 #endif
290
291 CHECK(nc_inq_varid(ncid, "f64", &varid));
292 CHECK(nc_get_var_double(ncid,varid,float64v));
293 #ifdef GENERATE
294 printf("static %s float64_data[DIMSIZE]={","double");
295 for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float64v[i]);
296 printf("};\n");
297 #else
298 COMPARE(NC_DOUBLE,NC_DOUBLE,float64v,float64_data);
299 #endif
300
301 if(failure) {
302 printf("ncstat=%d %s",ncstat,nc_strerror(ncstat));
303 exit(1);
304 }
305 nc_close(ncid);
306 return 0;
307 }
308
309 static char ch_data[DIMSIZE]={'\000','\001','\002','\003','\004','\005','\006','\007','\010','\011','\012','\013','\014','\015','\016','\017','\020','\021','\022','\023','\024','\025','\026','\027','\030'};
310 static signed char int8_data[DIMSIZE]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
311 static unsigned char uint8_data[DIMSIZE]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
312 static int int8toint32_data[DIMSIZE]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
313 static float int82float32_data[DIMSIZE]={0.000,1.000,2.000,3.000,4.000,5.000,6.000,7.000,8.000,9.000,10.000,11.000,12.000,13.000,14.000,15.000,16.000,17.000,18.000,19.000,20.000,21.000,22.000,23.000,24.000};
314 static short int16_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
315 static int int16toint32_data[DIMSIZE]={0,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3328,3584,3840,4096,4352,4608,4864,5120,5376,5632,5888,6144};
316 static float int162float32_data[DIMSIZE]={0.000,256.000,512.000,768.000,1024.000,1280.000,1536.000,1792.000,2048.000,2304.000,2560.000,2816.000,3072.000,3328.000,3584.000,3840.000,4096.000,4352.000,4608.000,4864.000,5120.000,5376.000,5632.000,5888.000,6144.000};
317 static int int32_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
318 static float int32tofloat32_data[DIMSIZE]={0.000,2048.000,4096.000,6144.000,8192.000,10240.000,12288.000,14336.000,16384.000,18432.000,20480.000,22528.000,24576.000,26624.000,28672.000,30720.000,32768.000,34816.000,36864.000,38912.000,40960.000,43008.000,45056.000,47104.000,49152.000};
319 static long int32toilong_data[DIMSIZE]={0,2048,4096,6144,8192,10240,12288,14336,16384,18432,20480,22528,24576,26624,28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152};
320 static float float32_data[DIMSIZE]={0.000,0.010,0.020,0.030,0.040,0.050,0.060,0.070,0.080,0.090,0.100,0.110,0.120,0.130,0.140,0.149,0.159,0.169,0.179,0.189,0.199,0.208,0.218,0.228,0.238};
321 static double float64_data[DIMSIZE]={1.000,1.000,1.000,1.000,0.999,0.999,0.998,0.998,0.997,0.996,0.995,0.994,0.993,0.992,0.990,0.989,0.987,0.986,0.984,0.982,0.980,0.978,0.976,0.974,0.971};
322
323 #ifndef USE_NETCDF4
324 static char string3_data[DIMSIZE][STRLEN]={"This is a data test string (pass 0).","This is a data test string (pass 1).","This is a data test string (pass 2).","This is a data test string (pass 3).","This is a data test string (pass 4).","This is a data test string (pass 5).","This is a data test string (pass 6).","This is a data test string (pass 7).","This is a data test string (pass 8).","This is a data test string (pass 9).","This is a data test string (pass 10).","This is a data test string (pass 11).","This is a data test string (pass 12).","This is a data test string (pass 13).","This is a data test string (pass 14).","This is a data test string (pass 15).","This is a data test string (pass 16).","This is a data test string (pass 17).","This is a data test string (pass 18).","This is a data test string (pass 19).","This is a data test string (pass 20).","This is a data test string (pass 21).","This is a data test string (pass 22).","This is a data test string (pass 23).","This is a data test string (pass 24)."};
325 #endif
326
327 static void
compare(nc_type t1,nc_type t2,void * v0,void * vdata0,char * tag,char * file,int line)328 compare(nc_type t1, nc_type t2, void* v0, void* vdata0, char* tag,
329 char* file, int line)
330 {
331 int i;
332 fprintf(stdout,"*** testing: %s\n",tag); \
333
334 #ifdef DEBUG
335 #define test \
336 printf("v ="); \
337 for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)v[i]);} \
338 printf("\n"); \
339 printf("vdata ="); \
340 for(i=0;i<DIMSIZE;i++) {printf(" %llu",(unsigned long long)vdata[i]);} \
341 printf("\n"); \
342 for(i=0;i<DIMSIZE;i++) {\
343 if(v[i] != vdata[i]) {report(i,tag,line); break;}\
344 }
345 #define ftest \
346 printf("v ="); \
347 for(i=0;i<DIMSIZE;i++) {printf(" %g",v[i]);} \
348 printf("\n"); \
349 printf("vdata ="); \
350 for(i=0;i<DIMSIZE;i++) {printf(" %g",vdata[i]);} \
351 printf("\n"); \
352 for(i=0;i<DIMSIZE;i++) {\
353 if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
354 }
355 #else
356 #define test for(i=0;i<DIMSIZE;i++) {\
357 if(v[i] != vdata[i]) {report(i,tag,line); break;}\
358 }
359 #define ftest for(i=0;i<DIMSIZE;i++) {\
360 if(fdiff((double)v[i],(double)vdata[i])) {report(i,tag,line); break;}\
361 }
362 #endif
363
364 #define setup(T) T* v = (T*)v0; T* vdata = (T*)vdata0;
365
366 #define CASE(nc1,nc2) (nc1*256+nc2)
367 switch(CASE(t1,t2)) {
368
369 default: {
370 printf("unexpected compare: %d %d\n",(int)t1,(int)t2);
371 abort();
372 }
373
374 case CASE(NC_CHAR,NC_CHAR): {
375 setup(char);
376 test;
377 } break;
378 case CASE(NC_BYTE,NC_BYTE): {
379 setup(signed char);
380 test;
381 } break;
382 case CASE(NC_SHORT,NC_SHORT): {
383 setup(short);
384 test;
385 } break;
386 case CASE(NC_INT,NC_INT): {
387 setup(int);
388 test;
389 } break;
390 case CASE(NC_FLOAT,NC_FLOAT): {
391 setup(float);
392 ftest;
393 } break;
394 case CASE(NC_DOUBLE,NC_DOUBLE): {
395 setup(double);
396 ftest;
397 } break;
398
399
400 /* Mixed comparisons */
401 case CASE(NC_BYTE,NC_INT): {
402 setup(int);
403 test;
404 } break;
405 case CASE(NC_SHORT,NC_INT): {
406 setup(int);
407 test;
408 } break;
409 case CASE(NC_SHORT,NC_FLOAT): {
410 setup(float);
411 ftest;
412 } break;
413 case CASE(NC_INT,NC_FLOAT): {
414 setup(float);
415 ftest;
416 } break;
417
418 /* This is an get_var_long case */
419 case CASE(NC_INT,NC_NAT): {
420 setup(long);
421 test;
422 } break;
423
424 case CASE(NC_UBYTE,NC_UBYTE): {
425 setup(unsigned char);
426 test;
427 } break;
428 case CASE(NC_USHORT,NC_USHORT): {
429 setup(unsigned short);
430 test;
431 } break;
432 case CASE(NC_UINT,NC_UINT): {
433 setup(unsigned int);
434 test;
435 } break;
436
437 /* Mixed cases */
438 case CASE(NC_INT,NC_INT64): {
439 setup(long long);
440 test;
441 } break;
442
443 case CASE(NC_INT,NC_UINT64): {
444 setup(unsigned long long);
445 test;
446 } break;
447
448 case CASE(NC_STRING,NC_STRING):{
449 setup(char*);
450 for(i=0;i<DIMSIZE;i++) {
451 if(strcmp(v[i],vdata[i])!=0) {report(i,tag,line); break;}
452 }
453 } break;
454
455 case CASE(NC_CHAR,NC_STRING):{
456 setup(char*);
457 if(memcmp((void*)v[0],(void*)vdata,DIMSIZE+1)!=0)
458 {report(0,tag,line);}
459 } break;
460
461 } /*switch*/
462 }
463
464