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