1 /*********************************************************************
2 * Copyright 1993, UCAR/Unidata
3 * See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 * $Id: ncmpigen.y 2238 2015-12-18 18:20:25Z wkliao $
5 *********************************************************************/
6
7 /* yacc source for "ncmpigen", a netCDL parser and netCDF generator */
8
9 %{
10 #ifdef sccs
11 static char SccsId[] = "$Id: ncmpigen.y 2238 2015-12-18 18:20:25Z wkliao $";
12 #endif
13
14 #include <string.h>
15 #include <stdlib.h>
16 #include <stddef.h> /* ptrdiff_t */
17 #include <pnetcdf.h>
18 #include "generic.h"
19 #include "ncmpigen.h"
20 #include "genlib.h" /* for grow_darray() et al */
21
22 typedef struct Symbol { /* symbol table entry */
23 char *name;
24 struct Symbol *next;
25 unsigned is_dim : 1; /* appears as netCDF dimension */
26 unsigned is_var : 1; /* appears as netCDF variable */
27 unsigned is_att : 1; /* appears as netCDF attribute */
28 int dnum; /* handle as a dimension */
29 int vnum; /* handle as a variable */
30 } *YYSTYPE1;
31
32 /* True if string a equals string b*/
33 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
34 #define NC_UNSPECIFIED ((nc_type)0) /* unspecified (as yet) type */
35
36 #define YYSTYPE YYSTYPE1
37 YYSTYPE symlist; /* symbol table: linked list */
38
39 extern int derror_count; /* counts errors in netcdf definition */
40 extern int lineno; /* line number for error messages */
41
42 static int not_a_string; /* whether last constant read was a string */
43 static char termstring[MAXTRST]; /* last terminal string read */
44 static double double_val; /* last double value read */
45 static float float_val; /* last float value read */
46 static int int_val; /* last int value read */
47 static short short_val; /* last short value read */
48 static char char_val; /* last char value read */
49 static signed char byte_val; /* last byte value read */
50 static unsigned char ubyte_val; /* last byte value read */
51 static unsigned short ushort_val; /* last byte value read */
52 static unsigned int uint_val; /* last byte value read */
53 static long long int64_val; /* last byte value read */
54 static unsigned long long uint64_val; /* last byte value read */
55
56 static nc_type type_code; /* holds declared type for variables */
57 static nc_type atype_code; /* holds derived type for attributes */
58 static char *netcdfname; /* to construct netcdf file name */
59 static void *att_space; /* pointer to block for attribute values */
60 static nc_type valtype; /* type code for list of attribute values */
61
62 static char *char_valp; /* pointers used to accumulate data values */
63 static signed char *byte_valp;
64 static short *short_valp;
65 static int *int_valp;
66 static float *float_valp;
67 static double *double_valp;
68 static unsigned char *ubyte_valp;
69 static unsigned short *ushort_valp;
70 static unsigned int *uint_valp;
71 static long long *int64_valp;
72 static unsigned long long *uint64_valp;
73
74 static void *rec_cur; /* pointer to where next data value goes */
75 static void *rec_start; /* start of space for data */
76
77 /* Forward declarations */
78 void defatt(void);
79 void equalatt(void);
80
81 #ifdef YYLEX_PARAM
82 int yylex(YYLEX_PARAM);
83 #else
84 int yylex(void);
85 #endif
86
87 #ifdef vms
88 void yyerror(char*);
89 #else
90 int yyerror(char*);
91 #endif
92 %}
93
94 /* DECLARATIONS */
95
96 %token
97 NC_UNLIMITED_K /* keyword for unbounded record dimension */
98 BYTE_K /* keyword for byte datatype */
99 CHAR_K /* keyword for char datatype */
100 SHORT_K /* keyword for short datatype */
101 INT_K /* keyword for int datatype */
102 FLOAT_K /* keyword for float datatype */
103 DOUBLE_K /* keyword for double datatype */
104 UBYTE_K /* keyword for unsigned char datatype */
105 USHORT_K /* keyword for unsigned short datatype */
106 UINT_K /* keyword for unsigned int datatype */
107 INT64_K /* keyword for long long datatype */
108 UINT64_K /* keyword for unsigned long long datatype */
109 IDENT /* name for a dimension, variable, or attribute */
110 TERMSTRING /* terminal string */
111 BYTE_CONST /* byte constant */
112 CHAR_CONST /* char constant */
113 SHORT_CONST /* short constant */
114 INT_CONST /* int constant */
115 FLOAT_CONST /* float constant */
116 DOUBLE_CONST /* double constant */
117 UBYTE_CONST /* unsigned char constant */
118 USHORT_CONST /* unsigned short constant */
119 UINT_CONST /* unsigned int constant */
120 INT64_CONST /* long long constant */
121 UINT64_CONST /* unsigned long long constant */
122 DIMENSIONS /* keyword starting dimensions section, if any */
123 VARIABLES /* keyword starting variables section, if any */
124 NETCDF /* keyword declaring netcdf name */
125 DATA /* keyword starting data section, if any */
126 FILLVALUE /* fill value, from _FillValue attribute or default */
127
128 %start ncdesc /* start symbol for grammar */
129
130 %%
131
132 /* RULES */
133
134 ncdesc: NETCDF
135 '{'
136 { init_netcdf(); }
137 dimsection /* dimension declarations */
138 vasection /* variable and attribute declarations */
139 {
140 if (derror_count == 0)
141 define_netcdf(netcdfname);
142 if (derror_count > 0)
143 exit(6);
144 }
145 datasection /* data, variables loaded as encountered */
146 '}'
147 {
148 if (derror_count == 0)
149 close_netcdf();
150 }
151 ;
152 dimsection: /* empty */
153 | DIMENSIONS dimdecls
154 ;
155 dimdecls: dimdecline ';'
156 | dimdecls dimdecline ';'
157 ;
158 dimdecline: dimdecl
159 | dimdecline ',' dimdecl
160 ;
161 dimdecl: dimd '=' INT_CONST
162 { if (int_val <= 0)
163 derror("dimension length must be positive");
164 dims[ndims].size = int_val;
165 ndims++;
166 }
167 | dimd '=' DOUBLE_CONST
168 { /* for rare case where 2^31 < dimsize < 2^32 */
169 if (double_val <= 0)
170 derror("dimension length must be positive");
171 if (double_val > 4294967295.0)
172 derror("dimension too large");
173 if (double_val - (MPI_Offset) double_val > 0)
174 derror("dimension length must be an integer");
175 dims[ndims].size = (MPI_Offset) double_val;
176 ndims++;
177 }
178 | dimd '=' NC_UNLIMITED_K
179 { if (rec_dim != -1)
180 derror("only one NC_UNLIMITED dimension allowed");
181 rec_dim = ndims; /* the unlimited (record) dimension */
182 dims[ndims].size = NC_UNLIMITED;
183 ndims++;
184 }
185 ;
186 dimd: dim
187 {
188 if ($1->is_dim == 1) {
189 derror( "duplicate dimension declaration for %s",
190 $1->name);
191 }
192 $1->is_dim = 1;
193 $1->dnum = ndims;
194 /* make sure dims array will hold dimensions */
195 grow_darray(ndims, /* must hold ndims+1 dims */
196 &dims); /* grow as needed */
197 dims[ndims].name = (char *) emalloc(strlen($1->name)+1);
198 (void) strcpy(dims[ndims].name, $1->name);
199 /* name for use in generated Fortran and C variables */
200 dims[ndims].lname = decodify($1->name);
201 }
202 ;
203 dim: IDENT
204 ;
205 vasection: /* empty */
206 | VARIABLES vadecls
207 | gattdecls
208 ;
209 vadecls: vadecl ';'
210 | vadecls vadecl ';'
211 ;
212 vadecl: vardecl | attdecl | gattdecl
213 ;
214 gattdecls: gattdecl ';'
215 | gattdecls gattdecl ';'
216 ;
217 vardecl: type varlist
218 ;
219 type: BYTE_K { type_code = NC_BYTE; }
220 | CHAR_K { type_code = NC_CHAR; }
221 | SHORT_K { type_code = NC_SHORT; }
222 | INT_K { type_code = NC_INT; }
223 | FLOAT_K { type_code = NC_FLOAT; }
224 | DOUBLE_K{ type_code = NC_DOUBLE; }
225 | UBYTE_K { type_code = NC_UBYTE; }
226 | USHORT_K{ type_code = NC_USHORT; }
227 | UINT_K { type_code = NC_UINT; }
228 | INT64_K { type_code = NC_INT64; }
229 | UINT64_K{ type_code = NC_UINT64; }
230 ;
231 varlist: varspec
232 | varlist ',' varspec
233 ;
234 varspec: var
235 {
236 static struct vars dummyvar;
237
238 dummyvar.name = "dummy";
239 dummyvar.type = NC_DOUBLE;
240 dummyvar.ndims = 0;
241 dummyvar.dims = 0;
242 dummyvar.fill_value.doublev = NC_FILL_DOUBLE;
243 dummyvar.has_data = 0;
244
245 nvdims = 0;
246 /* make sure variable not re-declared */
247 if ($1->is_var == 1) {
248 derror( "duplicate variable declaration for %s",
249 $1->name);
250 }
251 $1->is_var = 1;
252 $1->vnum = nvars;
253 /* make sure vars array will hold variables */
254 grow_varray(nvars, /* must hold nvars+1 vars */
255 &vars); /* grow as needed */
256 vars[nvars] = dummyvar; /* to make Purify happy */
257 vars[nvars].name = (char *) emalloc(strlen($1->name)+1);
258 (void) strcpy(vars[nvars].name, $1->name);
259 /* name for use in generated Fortran and C variables */
260 vars[nvars].lname = decodify($1->name);
261 vars[nvars].type = type_code;
262 /* set default fill value. You can override this with
263 * the variable attribute "_FillValue". */
264 nc_getfill(type_code, &vars[nvars].fill_value);
265 vars[nvars].has_data = 0; /* has no data (yet) */
266 }
267 dimspec
268 {
269 vars[nvars].ndims = nvdims;
270 nvars++;
271 }
272 ;
273 var: IDENT
274 ;
275 dimspec: /* empty */
276 | '(' dimlist ')'
277 ;
278 dimlist: vdim
279 | dimlist ',' vdim
280 ;
281 vdim: dim
282 {
283 if (nvdims >= NC_MAX_VAR_DIMS) {
284 derror("%s has too many dimensions",vars[nvars].name);
285 }
286 if ($1->is_dim == 1)
287 dimnum = $1->dnum;
288 else {
289 derror( "%s is not declared as a dimension",
290 $1->name);
291 dimnum = ndims;
292 }
293 if (rec_dim != -1 && dimnum == rec_dim && nvdims != 0) {
294 derror("unlimited dimension must be first");
295 }
296 grow_iarray(nvdims, /* must hold nvdims+1 ints */
297 &vars[nvars].dims); /* grow as needed */
298 vars[nvars].dims[nvdims] = dimnum;
299 nvdims++;
300 }
301 ;
302 attdecl: att
303 {
304 defatt();
305 }
306 '=' attvallist
307 {
308 equalatt();
309 }
310 ;
311 gattdecl: gatt
312 {
313 defatt();
314 }
315 '=' attvallist
316 {
317 equalatt();
318 }
319 ;
320
321 att: avar ':' attr
322
323 gatt: ':' attr
324 {
325 varnum = NC_GLOBAL; /* handle of "global" attribute */
326 }
327 ;
328
329 avar: var
330 { if ($1->is_var == 1)
331 varnum = $1->vnum;
332 else {
333 derror("%s not declared as a variable, fatal error",
334 $1->name);
335 YYABORT;
336 }
337 }
338 ;
339 attr: IDENT
340 {
341 /* make sure atts array will hold attributes */
342 grow_aarray(natts, /* must hold natts+1 atts */
343 &atts); /* grow as needed */
344 atts[natts].name = (char *) emalloc(strlen($1->name)+1);
345 (void) strcpy(atts[natts].name,$1->name);
346 /* name for use in generated Fortran and C variables */
347 atts[natts].lname = decodify($1->name);
348 }
349 ;
350 attvallist: aconst
351 | attvallist ',' aconst
352 ;
353 aconst: attconst
354 {
355 if (valtype == NC_UNSPECIFIED)
356 valtype = atype_code;
357 if (valtype != atype_code)
358 derror("values for attribute must be all of same type");
359 }
360 ;
361
362 attconst: CHAR_CONST
363 {
364 atype_code = NC_CHAR;
365 *char_valp++ = char_val;
366 valnum++;
367 }
368 | TERMSTRING
369 {
370 atype_code = NC_CHAR;
371 {
372 /* don't null-terminate attribute strings */
373 MPI_Offset len = strlen(termstring);
374 if (len == 0) /* need null if that's only value */
375 len = 1;
376 (void)strncpy(char_valp,termstring,len);
377 valnum += len;
378 char_valp += len;
379 }
380 }
381 | BYTE_CONST
382 {
383 atype_code = NC_BYTE;
384 *byte_valp++ = byte_val;
385 valnum++;
386 }
387 | SHORT_CONST
388 {
389 atype_code = NC_SHORT;
390 *short_valp++ = short_val;
391 valnum++;
392 }
393 | INT_CONST
394 {
395 atype_code = NC_INT;
396 *int_valp++ = int_val;
397 valnum++;
398 }
399 | FLOAT_CONST
400 {
401 atype_code = NC_FLOAT;
402 *float_valp++ = float_val;
403 valnum++;
404 }
405 | DOUBLE_CONST
406 {
407 atype_code = NC_DOUBLE;
408 *double_valp++ = double_val;
409 valnum++;
410 }
411 | UBYTE_CONST
412 {
413 atype_code = NC_UBYTE;
414 *ubyte_valp++ = ubyte_val;
415 valnum++;
416 }
417 | USHORT_CONST
418 {
419 atype_code = NC_USHORT;
420 *ushort_valp++ = ushort_val;
421 valnum++;
422 }
423 | UINT_CONST
424 {
425 atype_code = NC_UINT;
426 *uint_valp++ = uint_val;
427 valnum++;
428 }
429 | INT64_CONST
430 {
431 atype_code = NC_INT64;
432 *int64_valp++ = int64_val;
433 valnum++;
434 }
435 | UINT64_CONST
436 {
437 atype_code = NC_UINT64;
438 *uint64_valp++ = uint64_val;
439 valnum++;
440 }
441 ;
442
443 datasection: /* empty */
444 | DATA datadecls
445 | DATA
446 ;
447
448 datadecls: datadecl ';'
449 | datadecls datadecl ';'
450 ;
451 datadecl: avar
452 {
453 valtype = vars[varnum].type; /* variable type */
454 valnum = 0; /* values accumulated for variable */
455 vars[varnum].has_data = 1;
456 /* compute dimensions product */
457 var_size = nctypesize(valtype);
458 if (vars[varnum].ndims == 0) { /* scalar */
459 var_len = 1;
460 } else if (vars[varnum].dims[0] == rec_dim) {
461 var_len = 1; /* one record for unlimited vars */
462 } else {
463 var_len = dims[vars[varnum].dims[0]].size;
464 }
465 for(dimnum = 1; dimnum < vars[varnum].ndims; dimnum++)
466 var_len = var_len*dims[vars[varnum].dims[dimnum]].size;
467 /* allocate memory for variable data */
468 if (var_len*var_size != (MPI_Offset)(var_len*var_size)) {
469 derror("variable %s too large for memory",
470 vars[varnum].name);
471 exit(9);
472 }
473 rec_len = var_len;
474 rec_start = malloc ((MPI_Offset)(rec_len*var_size));
475 if (rec_start == 0) {
476 derror ("out of memory\n");
477 exit(3);
478 }
479 rec_cur = rec_start;
480 switch (valtype) {
481 case NC_CHAR:
482 char_valp = (char *) rec_start;
483 break;
484 case NC_BYTE:
485 byte_valp = (signed char *) rec_start;
486 break;
487 case NC_SHORT:
488 short_valp = (short *) rec_start;
489 break;
490 case NC_INT:
491 int_valp = (int *) rec_start;
492 break;
493 case NC_FLOAT:
494 float_valp = (float *) rec_start;
495 break;
496 case NC_DOUBLE:
497 double_valp = (double *) rec_start;
498 break;
499 case NC_UBYTE:
500 ubyte_valp = (unsigned char *) rec_start;
501 break;
502 case NC_USHORT:
503 ushort_valp = (unsigned short *) rec_start;
504 break;
505 case NC_UINT:
506 uint_valp = (unsigned int *) rec_start;
507 break;
508 case NC_INT64:
509 int64_valp = (long long *) rec_start;
510 break;
511 case NC_UINT64:
512 uint64_valp = (unsigned long long *) rec_start;
513 break;
514 default: break;
515 }
516 }
517 '=' constlist
518 {
519 if (valnum < var_len) { /* leftovers */
520 nc_fill(valtype,
521 var_len - valnum,
522 rec_cur,
523 vars[varnum].fill_value);
524 }
525 /* put out var_len values */
526 /* vars[varnum].nrecs = valnum / rec_len; */
527 vars[varnum].nrecs = var_len / rec_len;
528 if (derror_count == 0)
529 put_variable(rec_start);
530 free ((char *) rec_start);
531 }
532 ;
533 constlist: dconst
534 | constlist ',' dconst
535 ;
536 dconst:
537 {
538 if(valnum >= var_len) {
539 if (vars[varnum].dims[0] != rec_dim) { /* not recvar */
540 derror("too many values for this variable, %d >= %d",
541 valnum, var_len);
542 exit (4);
543 } else { /* a record variable, so grow data
544 container and increment var_len by
545 multiple of record size */
546 ptrdiff_t rec_inc = (char *)rec_cur
547 - (char *)rec_start;
548 var_len = rec_len * (1 + valnum / rec_len);
549 rec_start = erealloc(rec_start, var_len*var_size);
550 rec_cur = (char *)rec_start + rec_inc;
551 char_valp = (char *) rec_cur;
552 byte_valp = (signed char *) rec_cur;
553 short_valp = (short *) rec_cur;
554 int_valp = (int *) rec_cur;
555 float_valp = (float *) rec_cur;
556 double_valp = (double *) rec_cur;
557 ubyte_valp = (unsigned char *) rec_cur;
558 ushort_valp = (unsigned short *) rec_cur;
559 uint_valp = (unsigned int *) rec_cur;
560 int64_valp = (long long *) rec_cur;
561 uint64_valp = (unsigned long long *) rec_cur;
562 }
563 }
564 not_a_string = 1;
565 }
566 const
567 {
568 if (not_a_string) {
569 switch (valtype) {
570 case NC_CHAR:
571 rec_cur = (void *) char_valp;
572 break;
573 case NC_BYTE:
574 rec_cur = (void *) byte_valp;
575 break;
576 case NC_SHORT:
577 rec_cur = (void *) short_valp;
578 break;
579 case NC_INT:
580 rec_cur = (void *) int_valp;
581 break;
582 case NC_FLOAT:
583 rec_cur = (void *) float_valp;
584 break;
585 case NC_DOUBLE:
586 rec_cur = (void *) double_valp;
587 break;
588 case NC_UBYTE:
589 rec_cur = (void *) ubyte_valp;
590 break;
591 case NC_USHORT:
592 rec_cur = (void *) ushort_valp;
593 break;
594 case NC_UINT:
595 rec_cur = (void *) uint_valp;
596 break;
597 case NC_INT64:
598 rec_cur = (void *) int64_valp;
599 break;
600 case NC_UINT64:
601 rec_cur = (void *) uint64_valp;
602 break;
603 default: break;
604 }
605 }
606 }
607 ;
608
609 const: CHAR_CONST
610 {
611 atype_code = NC_CHAR;
612 switch (valtype) {
613 case NC_CHAR:
614 *char_valp++ = char_val;
615 break;
616 case NC_BYTE:
617 *byte_valp++ = char_val;
618 break;
619 case NC_SHORT:
620 *short_valp++ = char_val;
621 break;
622 case NC_INT:
623 *int_valp++ = char_val;
624 break;
625 case NC_FLOAT:
626 *float_valp++ = char_val;
627 break;
628 case NC_DOUBLE:
629 *double_valp++ = char_val;
630 break;
631 case NC_UBYTE:
632 *ubyte_valp++ = char_val;
633 break;
634 case NC_USHORT:
635 *ushort_valp++ = char_val;
636 break;
637 case NC_UINT:
638 *uint_valp++ = char_val;
639 break;
640 case NC_INT64:
641 *int64_valp++ = char_val;
642 break;
643 case NC_UINT64:
644 *uint64_valp++ = char_val;
645 break;
646 default: break;
647 }
648 valnum++;
649 }
650 | TERMSTRING
651 {
652 not_a_string = 0;
653 atype_code = NC_CHAR;
654 {
655 MPI_Offset len = strlen(termstring);
656
657 if(valnum + len > var_len) {
658 if (vars[varnum].dims[0] != rec_dim) {
659 derror("too many values for this variable, %d>%d",
660 valnum+len, var_len);
661 exit (5);
662 } else {/* a record variable so grow it */
663 ptrdiff_t rec_inc = (char *)rec_cur
664 - (char *)rec_start;
665 var_len += rec_len * (len + valnum - var_len)/rec_len;
666 rec_start = erealloc(rec_start, var_len*var_size);
667 rec_cur = (char *)rec_start + rec_inc;
668 char_valp = (char *) rec_cur;
669 }
670 }
671 switch (valtype) {
672 case NC_CHAR:
673 {
674 int ld;
675 MPI_Offset i, sl;
676 (void)strncpy(char_valp,termstring,len);
677 ld = vars[varnum].ndims-1;
678 if (ld > 0) {/* null-fill to size of last dim */
679 sl = dims[vars[varnum].dims[ld]].size;
680 for (i =len;i<sl;i++)
681 char_valp[i] = '\0';
682 if (sl < len)
683 sl = len;
684 valnum += sl;
685 char_valp += sl;
686 } else { /* scalar or 1D strings */
687 valnum += len;
688 char_valp += len;
689 }
690 rec_cur = (void *) char_valp;
691 }
692 break;
693 case NC_BYTE:
694 case NC_SHORT:
695 case NC_INT:
696 case NC_FLOAT:
697 case NC_DOUBLE:
698 derror("string value invalid for %s variable",
699 nctype(valtype));
700 break;
701 default: break;
702 }
703 }
704 }
705 | BYTE_CONST
706 {
707 atype_code = NC_BYTE;
708 switch (valtype) {
709 case NC_CHAR:
710 *char_valp++ = byte_val;
711 break;
712 case NC_BYTE:
713 *byte_valp++ = byte_val;
714 break;
715 case NC_SHORT:
716 *short_valp++ = byte_val;
717 break;
718 case NC_INT:
719 *int_valp++ = byte_val;
720 break;
721 case NC_FLOAT:
722 *float_valp++ = byte_val;
723 break;
724 case NC_DOUBLE:
725 *double_valp++ = byte_val;
726 break;
727 case NC_UBYTE:
728 *ubyte_valp++ = byte_val;
729 break;
730 case NC_USHORT:
731 *ushort_valp++ = byte_val;
732 break;
733 case NC_UINT:
734 *uint_valp++ = byte_val;
735 break;
736 case NC_INT64:
737 *int64_valp++ = byte_val;
738 break;
739 case NC_UINT64:
740 *uint64_valp++ = byte_val;
741 break;
742 default: break;
743 }
744 valnum++;
745 }
746 | SHORT_CONST
747 {
748 atype_code = NC_SHORT;
749 switch (valtype) {
750 case NC_CHAR:
751 *char_valp++ = short_val;
752 break;
753 case NC_BYTE:
754 *byte_valp++ = short_val;
755 break;
756 case NC_SHORT:
757 *short_valp++ = short_val;
758 break;
759 case NC_INT:
760 *int_valp++ = short_val;
761 break;
762 case NC_FLOAT:
763 *float_valp++ = short_val;
764 break;
765 case NC_DOUBLE:
766 *double_valp++ = short_val;
767 break;
768 case NC_UBYTE:
769 *ubyte_valp++ = short_val;
770 break;
771 case NC_USHORT:
772 *ushort_valp++ = short_val;
773 break;
774 case NC_UINT:
775 *uint_valp++ = short_val;
776 break;
777 case NC_INT64:
778 *int64_valp++ = short_val;
779 break;
780 case NC_UINT64:
781 *uint64_valp++ = short_val;
782 break;
783 default: break;
784 }
785 valnum++;
786 }
787 | INT_CONST
788 {
789 atype_code = NC_INT;
790 switch (valtype) {
791 case NC_CHAR:
792 *char_valp++ = int_val;
793 break;
794 case NC_BYTE:
795 *byte_valp++ = int_val;
796 break;
797 case NC_SHORT:
798 *short_valp++ = int_val;
799 break;
800 case NC_INT:
801 *int_valp++ = int_val;
802 break;
803 case NC_FLOAT:
804 *float_valp++ = int_val;
805 break;
806 case NC_DOUBLE:
807 *double_valp++ = int_val;
808 break;
809 case NC_UBYTE:
810 *ubyte_valp++ = int_val;
811 break;
812 case NC_USHORT:
813 *ushort_valp++ = int_val;
814 break;
815 case NC_UINT:
816 *uint_valp++ = int_val;
817 break;
818 case NC_INT64:
819 *int64_valp++ = int_val;
820 break;
821 case NC_UINT64:
822 *uint64_valp++ = int_val;
823 break;
824 default: break;
825 }
826 valnum++;
827 }
828 | FLOAT_CONST
829 {
830 atype_code = NC_FLOAT;
831 switch (valtype) {
832 case NC_CHAR:
833 *char_valp++ = float_val;
834 break;
835 case NC_BYTE:
836 *byte_valp++ = float_val;
837 break;
838 case NC_SHORT:
839 *short_valp++ = float_val;
840 break;
841 case NC_INT:
842 *int_valp++ = float_val;
843 break;
844 case NC_FLOAT:
845 *float_valp++ = float_val;
846 break;
847 case NC_DOUBLE:
848 *double_valp++ = float_val;
849 break;
850 case NC_UBYTE:
851 *ubyte_valp++ = float_val;
852 break;
853 case NC_USHORT:
854 *ushort_valp++ = float_val;
855 break;
856 case NC_UINT:
857 *uint_valp++ = float_val;
858 break;
859 case NC_INT64:
860 *int64_valp++ = float_val;
861 break;
862 case NC_UINT64:
863 *uint64_valp++ = float_val;
864 break;
865 default: break;
866 }
867 valnum++;
868 }
869 | DOUBLE_CONST
870 {
871 atype_code = NC_DOUBLE;
872 switch (valtype) {
873 case NC_CHAR:
874 *char_valp++ = double_val;
875 break;
876 case NC_BYTE:
877 *byte_valp++ = double_val;
878 break;
879 case NC_SHORT:
880 *short_valp++ = double_val;
881 break;
882 case NC_INT:
883 *int_valp++ = double_val;
884 break;
885 case NC_FLOAT:
886 if (double_val == NC_FILL_DOUBLE)
887 *float_valp++ = NC_FILL_FLOAT;
888 else
889 *float_valp++ = double_val;
890 break;
891 case NC_DOUBLE:
892 *double_valp++ = double_val;
893 break;
894 case NC_UBYTE:
895 *ubyte_valp++ = double_val;
896 break;
897 case NC_USHORT:
898 *ushort_valp++ = double_val;
899 break;
900 case NC_UINT:
901 *uint_valp++ = double_val;
902 break;
903 case NC_INT64:
904 *int64_valp++ = double_val;
905 break;
906 case NC_UINT64:
907 *uint64_valp++ = double_val;
908 break;
909 default: break;
910 }
911 valnum++;
912 }
913 | UBYTE_CONST
914 {
915 atype_code = NC_UBYTE;
916 switch (valtype) {
917 case NC_CHAR:
918 *char_valp++ = ubyte_val;
919 break;
920 case NC_BYTE:
921 *byte_valp++ = ubyte_val;
922 break;
923 case NC_SHORT:
924 *short_valp++ = ubyte_val;
925 break;
926 case NC_INT:
927 *int_valp++ = ubyte_val;
928 break;
929 case NC_FLOAT:
930 *float_valp++ = ubyte_val;
931 break;
932 case NC_DOUBLE:
933 *double_valp++ = ubyte_val;
934 break;
935 case NC_UBYTE:
936 *ubyte_valp++ = ubyte_val;
937 break;
938 case NC_USHORT:
939 *ushort_valp++ = ubyte_val;
940 break;
941 case NC_UINT:
942 *uint_valp++ = ubyte_val;
943 break;
944 case NC_INT64:
945 *int64_valp++ = ubyte_val;
946 break;
947 case NC_UINT64:
948 *uint64_valp++ = ubyte_val;
949 break;
950 default:
951 derror("Unhandled type %d\n", valtype);
952 break;
953 }
954 valnum++;
955 }
956 | USHORT_CONST
957 {
958 atype_code = NC_USHORT;
959 switch (valtype) {
960 case NC_CHAR:
961 *char_valp++ = ushort_val;
962 break;
963 case NC_BYTE:
964 *byte_valp++ = ushort_val;
965 break;
966 case NC_SHORT:
967 *short_valp++ = ushort_val;
968 break;
969 case NC_INT:
970 *int_valp++ = ushort_val;
971 break;
972 case NC_FLOAT:
973 *float_valp++ = ushort_val;
974 break;
975 case NC_DOUBLE:
976 *double_valp++ = ushort_val;
977 break;
978 case NC_UBYTE:
979 *ubyte_valp++ = ushort_val;
980 break;
981 case NC_USHORT:
982 *ushort_valp++ = ushort_val;
983 break;
984 case NC_UINT:
985 *uint_valp++ = ushort_val;
986 break;
987 case NC_INT64:
988 *int64_valp++ = ushort_val;
989 break;
990 case NC_UINT64:
991 *uint64_valp++ = ushort_val;
992 break;
993 default:
994 derror("Unhandled type %d\n", valtype);
995 break;
996 }
997 valnum++;
998 }
999 | UINT_CONST
1000 {
1001 atype_code = NC_UINT;
1002 switch (valtype) {
1003 case NC_CHAR:
1004 *char_valp++ = uint_val;
1005 break;
1006 case NC_BYTE:
1007 *byte_valp++ = uint_val;
1008 break;
1009 case NC_SHORT:
1010 *short_valp++ = uint_val;
1011 break;
1012 case NC_INT:
1013 *int_valp++ = uint_val;
1014 break;
1015 case NC_FLOAT:
1016 *float_valp++ = uint_val;
1017 break;
1018 case NC_DOUBLE:
1019 *double_valp++ = uint_val;
1020 break;
1021 case NC_UBYTE:
1022 *ubyte_valp++ = uint_val;
1023 break;
1024 case NC_USHORT:
1025 *ushort_valp++ = uint_val;
1026 break;
1027 case NC_UINT:
1028 *uint_valp++ = uint_val;
1029 break;
1030 case NC_INT64:
1031 *int64_valp++ = uint_val;
1032 break;
1033 case NC_UINT64:
1034 *uint64_valp++ = uint_val;
1035 break;
1036 default:
1037 derror("Unhandled type %d\n", valtype);
1038 break;
1039 }
1040 valnum++;
1041 }
1042 | INT64_CONST
1043 {
1044 atype_code = NC_INT64;
1045 switch (valtype) {
1046 case NC_CHAR:
1047 *char_valp++ = int64_val;
1048 break;
1049 case NC_BYTE:
1050 *byte_valp++ = int64_val;
1051 break;
1052 case NC_SHORT:
1053 *short_valp++ = int64_val;
1054 break;
1055 case NC_INT:
1056 *int_valp++ = int64_val;
1057 break;
1058 case NC_FLOAT:
1059 *float_valp++ = int64_val;
1060 break;
1061 case NC_DOUBLE:
1062 *double_valp++ = int64_val;
1063 break;
1064 case NC_UBYTE:
1065 *ubyte_valp++ = int64_val;
1066 break;
1067 case NC_USHORT:
1068 *ushort_valp++ = int64_val;
1069 break;
1070 case NC_UINT:
1071 *uint_valp++ = int64_val;
1072 break;
1073 case NC_INT64:
1074 *int64_valp++ = int64_val;
1075 break;
1076 case NC_UINT64:
1077 *uint64_valp++ = int64_val;
1078 break;
1079 default:
1080 derror("Unhandled type %d\n", valtype);
1081 break;
1082 }
1083 valnum++;
1084 }
1085 | UINT64_CONST
1086 {
1087 atype_code = NC_UINT64;
1088 switch (valtype) {
1089 case NC_CHAR:
1090 *char_valp++ = uint64_val;
1091 break;
1092 case NC_BYTE:
1093 *byte_valp++ = uint64_val;
1094 break;
1095 case NC_SHORT:
1096 *short_valp++ = uint64_val;
1097 break;
1098 case NC_INT:
1099 *int_valp++ = uint64_val;
1100 break;
1101 case NC_FLOAT:
1102 *float_valp++ = uint64_val;
1103 break;
1104 case NC_DOUBLE:
1105 *double_valp++ = uint64_val;
1106 break;
1107 case NC_UBYTE:
1108 *ubyte_valp++ = uint64_val;
1109 break;
1110 case NC_USHORT:
1111 *ushort_valp++ = uint64_val;
1112 break;
1113 case NC_UINT:
1114 *uint_valp++ = uint64_val;
1115 break;
1116 case NC_INT64:
1117 *int64_valp++ = uint64_val;
1118 break;
1119 case NC_UINT64:
1120 *uint64_valp++ = uint64_val;
1121 break;
1122 default:
1123 derror("Unhandled type %d\n", valtype);
1124 break;
1125 }
1126 valnum++;
1127 }
1128 | FILLVALUE
1129 {
1130 /* store fill_value */
1131 switch (valtype) {
1132 case NC_CHAR:
1133 nc_fill(valtype, 1, (void *)char_valp++,
1134 vars[varnum].fill_value);
1135 break;
1136 case NC_BYTE:
1137 nc_fill(valtype, 1, (void *)byte_valp++,
1138 vars[varnum].fill_value);
1139 break;
1140 case NC_SHORT:
1141 nc_fill(valtype, 1, (void *)short_valp++,
1142 vars[varnum].fill_value);
1143 break;
1144 case NC_INT:
1145 nc_fill(valtype, 1, (void *)int_valp++,
1146 vars[varnum].fill_value);
1147 break;
1148 case NC_FLOAT:
1149 nc_fill(valtype, 1, (void *)float_valp++,
1150 vars[varnum].fill_value);
1151 break;
1152 case NC_DOUBLE:
1153 nc_fill(valtype, 1, (void *)double_valp++,
1154 vars[varnum].fill_value);
1155 break;
1156 case NC_UBYTE:
1157 nc_fill(valtype, 1, (void *)ubyte_valp++,
1158 vars[varnum].fill_value);
1159 break;
1160 case NC_USHORT:
1161 nc_fill(valtype, 1, (void *)ushort_valp++,
1162 vars[varnum].fill_value);
1163 break;
1164 case NC_UINT:
1165 nc_fill(valtype, 1, (void *)uint_valp++,
1166 vars[varnum].fill_value);
1167 break;
1168 case NC_INT64:
1169 nc_fill(valtype, 1, (void *)int64_valp++,
1170 vars[varnum].fill_value);
1171 break;
1172 case NC_UINT64:
1173 nc_fill(valtype, 1, (void *)uint64_valp++,
1174 vars[varnum].fill_value);
1175 break;
1176 default: break;
1177 }
1178 valnum++;
1179 }
1180 ;
1181
1182 /* END OF RULES */
1183
1184 %%
1185
1186 /* HELPER PROGRAMS */
1187 void defatt(void)
1188 {
1189 valnum = 0;
1190 valtype = NC_UNSPECIFIED;
1191 /* get a large block for attributes, realloc later */
1192 att_space = emalloc(MAX_NC_ATTSIZE);
1193 /* make all kinds of pointers point to it */
1194 char_valp = (char *) att_space;
1195 byte_valp = (signed char *) att_space;
1196 short_valp = (short *) att_space;
1197 int_valp = (int *) att_space;
1198 float_valp = (float *) att_space;
1199 double_valp = (double *) att_space;
1200 ubyte_valp = (unsigned char *) att_space;
1201 ushort_valp = (unsigned short *) att_space;
1202 uint_valp = (unsigned int *) att_space;
1203 int64_valp = (long long *) att_space;
1204 uint64_valp = (unsigned long long *) att_space;
1205 }
1206
equalatt(void)1207 void equalatt(void)
1208 {
1209 /* check if duplicate attribute for this var */
1210 int i;
1211 for(i=0; i<natts; i++) { /* expensive */
1212 if(atts[i].var == varnum &&
1213 STREQ(atts[i].name,atts[natts].name)) {
1214 derror("duplicate attribute %s:%s",
1215 vars[varnum].name,atts[natts].name);
1216 }
1217 }
1218 atts[natts].var = varnum ;
1219 atts[natts].type = valtype;
1220 atts[natts].len = valnum;
1221 /* shrink space down to what was really needed */
1222 att_space = erealloc(att_space, valnum*nctypesize(valtype));
1223 atts[natts].val = att_space;
1224 if (STREQ(atts[natts].name, _FillValue) &&
1225 atts[natts].var != NC_GLOBAL) {
1226 nc_putfill(atts[natts].type,atts[natts].val,
1227 &vars[atts[natts].var].fill_value);
1228 if(atts[natts].type != vars[atts[natts].var].type) {
1229 derror("variable %s: %s type mismatch",
1230 vars[atts[natts].var].name, _FillValue);
1231 }
1232 }
1233 natts++;
1234 }
1235 /* PROGRAMS */
1236
1237 #ifdef vms
1238 void
1239 #else
1240 int
1241 #endif
yyerror(char * s)1242 yyerror( /* called for yacc syntax error */
1243 char *s)
1244 {
1245 derror(s);
1246 #ifndef vms
1247 return -1;
1248 #endif
1249 }
1250
1251 /* undefine yywrap macro, in case we are using bison instead of yacc */
1252 #ifdef ncmpiwrap
1253 #undef ncmpiwrap
1254 #endif
1255
1256 int
ncmpiwrap(void)1257 ncmpiwrap(void) /* returns 1 on EOF if no more input */
1258 {
1259 return 1;
1260 }
1261
1262
1263 /* Symbol table operations for ncmpigen tool */
1264
1265 /* Find CDL name in symbol table (linear search). Note, this has a
1266 * side-effect: it handles escape characters in the name, deleting
1267 * single escape characters from the CDL name, before looking it up.
1268 */
lookup(char * sname)1269 YYSTYPE lookup(char *sname)
1270 {
1271 YYSTYPE sp;
1272 deescapify(sname); /* delete escape chars from names,
1273 * e.g. 'ab\:cd\ ef' becomes
1274 * 'ab:cd ef' */
1275 for (sp = symlist; sp != (YYSTYPE) 0; sp = sp -> next)
1276 if (STREQ(sp -> name, sname)) {
1277 return sp;
1278 }
1279 return 0; /* 0 ==> not found */
1280 }
1281
install(const char * sname)1282 YYSTYPE install( /* install sname in symbol table */
1283 const char *sname)
1284 {
1285 YYSTYPE sp;
1286
1287 sp = (YYSTYPE) emalloc (sizeof (struct Symbol));
1288 sp -> name = (char *) emalloc (strlen (sname) + 1);/* +1 for '\0' */
1289 (void) strcpy (sp -> name, sname);
1290 sp -> next = symlist; /* put at front of list */
1291 sp -> is_dim = 0;
1292 sp -> is_var = 0;
1293 sp -> is_att = 0;
1294 symlist = sp;
1295 return sp;
1296 }
1297
1298 void
clearout(void)1299 clearout(void) /* reset symbol table to empty */
1300 {
1301 YYSTYPE sp, tp;
1302 for (sp = symlist; sp != (YYSTYPE) 0;) {
1303 tp = sp -> next;
1304 free (sp -> name);
1305 free ((char *) sp);
1306 sp = tp;
1307 }
1308 symlist = 0;
1309 }
1310
1311 /* get lexical input routine generated by lex */
1312
1313 /* Keep compile quiet */
1314 #define YY_NO_UNPUT
1315 #define YY_NO_INPUT
1316
1317 #include "ncmpigenyy.c"
1318