1 /*
2 * (C) Copyright 2005- ECMWF.
3 *
4 * This software is licensed under the terms of the Apache Licence Version 2.0
5 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8 * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9 */
10
11 /***************************************************************************
12 * Jean Baptiste Filippi - 01.11.2005 *
13 * Enrico Fucile
14 * *
15 ***************************************************************************/
16 #include "grib_api_internal.h"
17
18 grib_action* grib_parser_all_actions = 0;
19 grib_context* grib_parser_context = 0;
20 grib_concept_value* grib_parser_concept = 0;
21 grib_hash_array_value* grib_parser_hash_array = 0;
22 grib_rule* grib_parser_rules = 0;
23
24 extern FILE* grib_yyin;
25 extern int grib_yydebug;
26
27 static const char* parse_file = 0;
28
29 #if GRIB_PTHREADS
30 static pthread_once_t once = PTHREAD_ONCE_INIT;
31 static pthread_mutex_t mutex_file = PTHREAD_MUTEX_INITIALIZER;
32 static pthread_mutex_t mutex_rules = PTHREAD_MUTEX_INITIALIZER;
33 static pthread_mutex_t mutex_concept = PTHREAD_MUTEX_INITIALIZER;
34 static pthread_mutex_t mutex_hash_array = PTHREAD_MUTEX_INITIALIZER;
35 static pthread_mutex_t mutex_stream = PTHREAD_MUTEX_INITIALIZER;
36 static pthread_mutex_t mutex_parse = PTHREAD_MUTEX_INITIALIZER;
37
init()38 static void init()
39 {
40 pthread_mutexattr_t attr;
41 pthread_mutexattr_init(&attr);
42 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
43 pthread_mutex_init(&mutex_file, &attr);
44 pthread_mutex_init(&mutex_rules, &attr);
45 pthread_mutex_init(&mutex_concept, &attr);
46 pthread_mutex_init(&mutex_hash_array, &attr);
47 pthread_mutex_init(&mutex_stream, &attr);
48 pthread_mutex_init(&mutex_parse, &attr);
49 pthread_mutexattr_destroy(&attr);
50 }
51 #elif GRIB_OMP_THREADS
52 static int once = 0;
53 static omp_nest_lock_t mutex_file;
54 static omp_nest_lock_t mutex_rules;
55 static omp_nest_lock_t mutex_concept;
56 static omp_nest_lock_t mutex_hash_array;
57 static omp_nest_lock_t mutex_stream;
58 static omp_nest_lock_t mutex_parse;
59
init()60 static void init()
61 {
62 GRIB_OMP_CRITICAL(lock_grib_parse_utils_c)
63 {
64 if (once == 0) {
65 omp_init_nest_lock(&mutex_file);
66 omp_init_nest_lock(&mutex_rules);
67 omp_init_nest_lock(&mutex_concept);
68 omp_init_nest_lock(&mutex_hash_array);
69 omp_init_nest_lock(&mutex_stream);
70 omp_init_nest_lock(&mutex_parse);
71 once = 1;
72 }
73 }
74 }
75 #endif
76
grib_recompose_name(grib_handle * h,grib_accessor * observer,const char * uname,char * fname,int fail)77 int grib_recompose_name(grib_handle* h, grib_accessor* observer, const char* uname, char* fname, int fail)
78 {
79 grib_accessor* a;
80 char loc[1024] = {0,};
81 int i = 0;
82 int ret = 0;
83 int mode = -1;
84 char val[1024] = {0,};
85 double dval = 0;
86 long lval = 0;
87 int type = GRIB_TYPE_STRING;
88 size_t replen = 0;
89 char* ptrEnd_fname = NULL; /* Maintain ptr to end of fname string */
90
91 loc[0] = 0;
92 fname[0] = 0;
93 ptrEnd_fname = fname;
94
95 /* uname is a string like "grib[GRIBEditionNumber:l]/boot.def". The result fname will be grib2/boot.def */
96 while (uname[i] != '\0') {
97 if (mode > -1) {
98 if (uname[i] == ':') {
99 type = grib_type_to_int(uname[i + 1]);
100 i++;
101 }
102 else if (uname[i] == ']') {
103 loc[mode] = 0;
104 mode = -1;
105 a = grib_find_accessor(h, loc);
106 if (!a) {
107 if (!fail) {
108 sprintf(val, "undef");
109 }
110 else {
111 grib_context_log(h->context, GRIB_LOG_WARNING, "grib_recompose_name: Problem to recompose filename with : %s ( %s no accessor found)", uname, loc);
112 return GRIB_NOT_FOUND;
113 }
114 }
115 else {
116 switch (type) {
117 case GRIB_TYPE_STRING:
118 replen = 1024;
119 ret = grib_unpack_string(a, val, &replen);
120 break;
121 case GRIB_TYPE_DOUBLE:
122 replen = 1;
123 ret = grib_unpack_double(a, &dval, &replen);
124 sprintf(val, "%.12g", dval);
125 break;
126 case GRIB_TYPE_LONG:
127 replen = 1;
128 ret = grib_unpack_long(a, &lval, &replen);
129 sprintf(val, "%d", (int)lval);
130 break;
131 default:
132 grib_context_log(h->context, GRIB_LOG_WARNING, "grib_recompose_name: Problem to recompose filename with : %s, invalid type %d", loc, type);
133 break;
134 }
135
136 grib_dependency_add(observer, a);
137
138 if ((ret != GRIB_SUCCESS)) {
139 grib_context_log(h->context, GRIB_LOG_ERROR, "grib_recompose_name: Could not recompose filename : %s", uname);
140 return ret;
141 }
142 }
143 {
144 char* pc = fname;
145 while (*pc != '\0')
146 pc++;
147 strcpy(pc, val);
148 ptrEnd_fname = pc + strlen(val); /* Update ptr to end of fname */
149 }
150
151 loc[0] = 0;
152 }
153 else
154 loc[mode++] = uname[i];
155 }
156 else if (uname[i] == '[')
157 mode = 0;
158 else {
159 #if 0
160 int llen=strlen(fname); /* The strlen cost is too high */
161 fname[llen]=uname[i];
162 fname[llen+1]='\0';
163 #else
164 /* Performance: faster to avoid call to strlen. Append to end */
165 *ptrEnd_fname++ = uname[i];
166 *ptrEnd_fname = '\0';
167 #endif
168 type = GRIB_TYPE_STRING;
169 }
170 i++;
171 }
172 /*fprintf(stdout,"parsed > %s\n",fname);*/
173 return GRIB_SUCCESS;
174 }
175
176 #if 0
177 int grib_accessor_print(grib_accessor* a, const char* name, int type, const char* format,
178 const char* separator, int maxcols, int* newline, FILE* out)
179 {
180 size_t size = 0;
181 char* sval = NULL;
182 char* p = NULL;
183 double* dval = 0;
184 long* lval = 0;
185 char sbuf[1024] = {0,};
186 size_t replen = 0;
187 int ret = 0;
188 char* myformat = NULL;
189 char* myseparator = NULL;
190 char double_format[] = "%.12g"; /* default format for printing double keys */
191 char long_format[] = "%ld"; /* default format for printing integer keys */
192 char default_separator[] = " ";
193 grib_handle* h = grib_handle_of_accessor(a);
194
195 if (type == -1)
196 type = grib_accessor_get_native_type(a);
197 switch (type) {
198 case GRIB_TYPE_STRING:
199 replen = sizeof(sbuf) / sizeof(*sbuf);
200 ret = grib_unpack_string(a, sbuf, &replen);
201 fprintf(out, "%s", sbuf);
202 break;
203 case GRIB_TYPE_DOUBLE:
204 myformat = format ? (char*)format : double_format;
205 myseparator = separator ? (char*)separator : default_separator;
206 if (name[0] == '/' || name[0] == '#') {
207 long count;
208 ret = grib_value_count(a, &count);
209 size = count;
210 }
211 else {
212 ret = _grib_get_size(h, a, &size);
213 }
214 if (ret) return ret;
215 dval = (double*)grib_context_malloc_clear(h->context, sizeof(double) * size);
216 if (name[0] == '/' || name[0] == '#') {
217 replen = size;
218 ret = grib_unpack_double(a, dval, &replen);
219 }
220 else {
221 replen = 0;
222 ret = _grib_get_double_array_internal(h, a, dval, size, &replen);
223 }
224 if (replen == 1)
225 fprintf(out, myformat, dval[0]);
226 else {
227 int i = 0;
228 int cols = 0;
229 for (i = 0; i < replen; i++) {
230 *newline = 1;
231 fprintf(out, myformat, dval[i]);
232 if (i < replen - 1)
233 fprintf(out, "%s", myseparator);
234 cols++;
235 if (cols >= maxcols) {
236 fprintf(out, "\n");
237 *newline = 1;
238 cols = 0;
239 }
240 }
241 }
242 grib_context_free(h->context, dval);
243 break;
244 case GRIB_TYPE_LONG:
245 myformat = format ? (char*)format : long_format;
246 myseparator = separator ? (char*)separator : default_separator;
247 if (name[0] == '/' || name[0] == '#') {
248 long count;
249 ret = grib_value_count(a, &count);
250 size = count;
251 }
252 else {
253 ret = _grib_get_size(h, a, &size);
254 }
255 if (ret) return ret;
256 lval = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size);
257 if (name[0] == '/' || name[0] == '#') {
258 replen = size;
259 ret = grib_unpack_long(a, lval, &replen);
260 }
261 else {
262 replen = 0;
263 ret = _grib_get_long_array_internal(h, a, lval, size, &replen);
264 }
265 if (replen == 1)
266 fprintf(out, myformat, lval[0]);
267 else {
268 int i = 0;
269 int cols = 0;
270 for (i = 0; i < replen; i++) {
271 *newline = 1;
272 fprintf(out, myformat, lval[i]);
273 if (i < replen - 1)
274 fprintf(out, "%s", myseparator);
275 cols++;
276 if (cols >= maxcols) {
277 fprintf(out, "\n");
278 *newline = 1;
279 cols = 0;
280 }
281 }
282 }
283 grib_context_free(h->context, lval);
284 break;
285 case GRIB_TYPE_BYTES:
286 replen = a->length;
287 sval = (char*)grib_context_malloc(h->context, replen * sizeof(char));
288 ret = grib_unpack_string(a, sval, &replen);
289 p = sval;
290 while ((replen--) > 0)
291 fprintf(out, "%c", *(p++));
292 grib_context_free(h->context, sval);
293 *newline = 0;
294 break;
295 default:
296 grib_context_log(h->context, GRIB_LOG_WARNING, "grib_accessor_print: Problem to print \"%s\", invalid type %d", a->name, type);
297 }
298 return ret;
299 }
300 #endif
301
grib_accessors_list_print(grib_handle * h,grib_accessors_list * al,const char * name,int type,const char * format,const char * separator,int maxcols,int * newline,FILE * out)302 int grib_accessors_list_print(grib_handle* h, grib_accessors_list* al, const char* name,
303 int type, const char* format, const char* separator, int maxcols, int* newline, FILE* out)
304 {
305 size_t size = 0, len = 0, replen = 0, j = 0;
306 unsigned char* bval = NULL;
307 double* dval = 0;
308 long* lval = 0;
309 char** cvals = NULL;
310 int ret = 0;
311 char* myformat = NULL;
312 char* myseparator = NULL;
313 char double_format[] = "%.12g"; /* default format for printing double keys */
314 char long_format[] = "%ld"; /* default format for printing integer keys */
315 char default_separator[] = " ";
316 grib_accessor* a = al->accessor;
317
318 /* Number of columns specified as 0 means print on ONE line i.e. num cols = infinity */
319 if (maxcols == 0)
320 maxcols = INT_MAX;
321
322 if (type == -1)
323 type = grib_accessor_get_native_type(al->accessor);
324 grib_accessors_list_value_count(al, &size);
325 switch (type) {
326 case GRIB_TYPE_STRING:
327 myseparator = separator ? (char*)separator : default_separator;
328 if (size == 1) {
329 char sbuf[1024] = {0,};
330 len = sizeof(sbuf);
331 ret = grib_unpack_string(al->accessor, sbuf, &len);
332 if (grib_is_missing_string(al->accessor, (unsigned char*)sbuf, len)) {
333 fprintf(out, "%s", "MISSING");
334 }
335 else {
336 fprintf(out, "%s", sbuf);
337 }
338 }
339 else {
340 int cols = 0;
341 j = 0;
342 cvals = (char**)grib_context_malloc_clear(h->context, sizeof(char*) * size);
343 grib_accessors_list_unpack_string(al, cvals, &size);
344 for (j = 0; j < size; j++) {
345 *newline = 1;
346 fprintf(out, "%s", cvals[j]);
347 if (j < size - 1)
348 fprintf(out, "%s", myseparator);
349 cols++;
350 if (cols >= maxcols) {
351 fprintf(out, "\n");
352 *newline = 1;
353 cols = 0;
354 }
355 grib_context_free(h->context, cvals[j]);
356 }
357 }
358 grib_context_free(h->context, cvals);
359 break;
360 case GRIB_TYPE_DOUBLE:
361 myformat = format ? (char*)format : double_format;
362 myseparator = separator ? (char*)separator : default_separator;
363 dval = (double*)grib_context_malloc_clear(h->context, sizeof(double) * size);
364 ret = grib_accessors_list_unpack_double(al, dval, &size);
365 if (size == 1)
366 fprintf(out, myformat, dval[0]);
367 else {
368 int cols = 0;
369 j = 0;
370 for (j = 0; j < size; j++) {
371 *newline = 1;
372 fprintf(out, myformat, dval[j]);
373 if (j < size - 1)
374 fprintf(out, "%s", myseparator);
375 cols++;
376 if (cols >= maxcols) {
377 fprintf(out, "\n");
378 *newline = 1;
379 cols = 0;
380 }
381 }
382 }
383 grib_context_free(h->context, dval);
384 break;
385 case GRIB_TYPE_LONG:
386 myformat = format ? (char*)format : long_format;
387 myseparator = separator ? (char*)separator : default_separator;
388 lval = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size);
389 ret = grib_accessors_list_unpack_long(al, lval, &size);
390 if (size == 1)
391 fprintf(out, myformat, lval[0]);
392 else {
393 int cols = 0;
394 j = 0;
395 for (j = 0; j < size; j++) {
396 *newline = 1;
397 fprintf(out, myformat, lval[j]);
398 if (j < size - 1)
399 fprintf(out, "%s", myseparator);
400 cols++;
401 if (cols >= maxcols) {
402 fprintf(out, "\n");
403 *newline = 1;
404 cols = 0;
405 }
406 }
407 }
408 grib_context_free(h->context, lval);
409 break;
410 case GRIB_TYPE_BYTES:
411 replen = a->length;
412 bval = (unsigned char*)grib_context_malloc(h->context, replen * sizeof(unsigned char));
413 ret = grib_unpack_bytes(al->accessor, bval, &replen);
414 for (j = 0; j < replen; j++) {
415 fprintf(out, "%02x", bval[j]);
416 }
417 grib_context_free(h->context, bval);
418 *newline = 1;
419 break;
420 default:
421 grib_context_log(h->context, GRIB_LOG_WARNING,
422 "grib_accessor_print: Problem printing \"%s\", invalid type %d", a->name, grib_get_type_name(type));
423 }
424 return ret;
425 }
426
grib_recompose_print(grib_handle * h,grib_accessor * observer,const char * uname,int fail,FILE * out)427 int grib_recompose_print(grib_handle* h, grib_accessor* observer, const char* uname, int fail, FILE* out)
428 {
429 grib_accessors_list* al = NULL;
430 char loc[1024];
431 int i = 0;
432 int ret = 0;
433 int mode = -1;
434 char* pp = NULL;
435 char* format = NULL;
436 int type = -1;
437 char* separator = NULL;
438 int l;
439 char buff[10] = {0,};
440 char buff1[1024] = {0,};
441 int maxcolsd = 8;
442 int maxcols;
443 long numcols = 0;
444 int newline = 1;
445 const size_t uname_len = strlen(uname);
446
447 maxcols = maxcolsd;
448 loc[0] = 0;
449 for (i = 0; i < uname_len; i++) {
450 if (mode > -1) {
451 switch (uname[i]) {
452 case ':':
453 type = grib_type_to_int(uname[i + 1]);
454 i++;
455 break;
456 case '\'':
457 pp = (char*)(uname + i + 1);
458 while (*pp != '%' && *pp != '!' && *pp != ']' && *pp != ':' && *pp != '\'')
459 pp++;
460 l = pp - uname - i;
461 if (*pp == '\'')
462 separator = strncpy(buff1, uname + i + 1, l - 1);
463 i += l;
464 break;
465 case '%':
466 pp = (char*)(uname + i + 1);
467 while (*pp != '%' && *pp != '!' && *pp != ']' && *pp != ':' && *pp != '\'')
468 pp++;
469 l = pp - uname - i;
470 format = strncpy(buff, uname + i, l);
471 i += l - 1;
472 break;
473 case '!':
474 pp = (char*)uname;
475 if (string_to_long(uname + i + 1, &numcols) == GRIB_SUCCESS) {
476 maxcols = (int)numcols;
477 }
478 else {
479 /* Columns specification is invalid integer */
480 maxcols = maxcolsd;
481 }
482 strtol(uname + i + 1, &pp, 10);
483 while (pp && *pp != '%' && *pp != '!' && *pp != ']' && *pp != ':' && *pp != '\'')
484 pp++;
485 i += pp - uname - i - 1;
486 break;
487 case ']':
488 loc[mode] = 0;
489 mode = -1;
490 if (al) grib_accessors_list_delete(h->context, al);
491 al = grib_find_accessors_list(h, loc); /* This allocates memory */
492 if (!al) {
493 if (!fail) {
494 fprintf(out, "undef");
495 ret = GRIB_NOT_FOUND;
496 }
497 else {
498 grib_context_log(h->context, GRIB_LOG_WARNING, "grib_recompose_print: Problem to recompose print with : %s, no accessor found", loc);
499 return GRIB_NOT_FOUND;
500 }
501 }
502 else {
503 ret = grib_accessors_list_print(h, al, loc, type, format, separator, maxcols, &newline, out);
504
505 if (ret != GRIB_SUCCESS) {
506 /* grib_context_log(h->context, GRIB_LOG_ERROR,"grib_recompose_print: Could not recompose print : %s", uname); */
507 grib_accessors_list_delete(h->context, al);
508 return ret;
509 }
510 }
511 loc[0] = 0;
512 break;
513 default:
514 loc[mode++] = uname[i];
515 break;
516 }
517 }
518 else if (uname[i] == '[') {
519 mode = 0;
520 }
521 else {
522 fprintf(out, "%c", uname[i]);
523 type = -1;
524 }
525 }
526 if (newline)
527 fprintf(out, "\n");
528
529 grib_accessors_list_delete(h->context, al);
530 return ret;
531 }
532
533 /* Note: A fast cut-down version of strcmp which does NOT return -1 */
534 /* 0 means input strings are equal and 1 means not equal */
grib_inline_strcmp(const char * a,const char * b)535 GRIB_INLINE static int grib_inline_strcmp(const char* a, const char* b)
536 {
537 if (*a != *b)
538 return 1;
539 while ((*a != 0 && *b != 0) && *(a) == *(b)) {
540 a++;
541 b++;
542 }
543 return (*a == 0 && *b == 0) ? 0 : 1;
544 }
545
grib_find_action_file(const char * fname,grib_action_file_list * afl)546 grib_action_file* grib_find_action_file(const char* fname, grib_action_file_list* afl)
547 {
548 grib_action_file* act = afl->first;
549 while (act) {
550 if (grib_inline_strcmp(act->filename, fname) == 0)
551 return act;
552 act = act->next;
553 }
554 return 0;
555 }
556
grib_push_action_file(grib_action_file * af,grib_action_file_list * afl)557 static void grib_push_action_file(grib_action_file* af, grib_action_file_list* afl)
558 {
559 if (!afl->first)
560 afl->first = afl->last = af;
561 else
562 afl->last->next = af;
563 afl->last = af;
564 }
565
566 #define MAXINCLUDE 10
567
568 typedef struct
569 {
570 char* name;
571 FILE* file;
572 char* io_buffer;
573 int line;
574 } context;
575
576 static context stack[MAXINCLUDE];
577 static int top = 0;
578 extern FILE* grib_yyin;
579 extern int grib_yylineno;
580 extern void grib_yyrestart(FILE*);
581 static int error = 0;
582
grib_yywrap()583 int grib_yywrap()
584 {
585 /* int i; */
586 top--;
587
588 /* for(i = 0; i < top ; i++) printf(" "); */
589 /* printf("CLOSE %s\n",parse_file); */
590
591 fclose(stack[top].file);
592 /* if (stack[top].io_buffer) free(stack[top].io_buffer); */
593
594 grib_yylineno = stack[top].line;
595
596 if (top) {
597 parse_file = stack[top - 1].name;
598 grib_yyin = stack[top - 1].file;
599 Assert(parse_file);
600 Assert(grib_yyin);
601 /* grib_yyrestart(grib_yyin); */
602
603 /* for(i = 0; i < top ; i++) printf(" "); */
604 /* printf("BACK TO %s\n",parse_file); */
605
606 grib_context_free(grib_parser_context, stack[top].name);
607 return 0;
608 }
609 else {
610 grib_context_free(grib_parser_context, stack[top].name);
611 parse_file = 0;
612 grib_yyin = NULL;
613 return 1;
614 }
615 }
616
file_being_parsed()617 char* file_being_parsed()
618 {
619 return (char*)parse_file;
620 }
621
grib_yyerror(const char * msg)622 int grib_yyerror(const char* msg)
623 {
624 grib_context_log(grib_parser_context, GRIB_LOG_ERROR,
625 "grib_parser: %s at line %d of %s", msg, grib_yylineno + 1, parse_file);
626 grib_context_log(grib_parser_context, GRIB_LOG_ERROR,
627 "ecCodes Version: %s", ECCODES_VERSION_STR);
628 error = 1;
629 return 1;
630 }
631
grib_parser_include(const char * included_fname)632 void grib_parser_include(const char* included_fname)
633 {
634 FILE* f = NULL;
635 char* io_buffer = 0;
636 /* int i; */
637 Assert(top < MAXINCLUDE);
638 Assert(included_fname);
639 if (!included_fname)
640 return;
641
642 if (parse_file == 0) {
643 parse_file = included_fname;
644 Assert(top == 0);
645 }
646 else {
647 /* When parse_file is not NULL, it's the path of the parent file (includer) */
648 /* and 'included_fname' is the name of the file being included (includee) */
649
650 /* GRIB-796: Search for the included file in ECCODES_DEFINITION_PATH */
651 char* new_path = NULL;
652 Assert(*included_fname != '/');
653 new_path = grib_context_full_defs_path(grib_parser_context, included_fname);
654 if (!new_path) {
655 fprintf(stderr, "ecCodes Version: %s\nDefinition files path: %s\n",
656 ECCODES_VERSION_STR,
657 grib_parser_context->grib_definition_files_path);
658
659 grib_context_log(grib_parser_context, GRIB_LOG_FATAL,
660 "grib_parser_include: Could not resolve '%s' (included in %s)", included_fname, parse_file);
661
662 return;
663 }
664 parse_file = new_path;
665 }
666
667 if (strcmp(parse_file, "-") == 0) {
668 grib_context_log(grib_parser_context, GRIB_LOG_DEBUG, "parsing standard input");
669 f = stdin; /* read from std input */
670 }
671 else {
672 grib_context_log(grib_parser_context, GRIB_LOG_DEBUG, "parsing include file %s", parse_file);
673 f = codes_fopen(parse_file, "r");
674 }
675 /* for(i = 0; i < top ; i++) printf(" "); */
676 /* printf("PARSING %s\n",parse_file); */
677
678 if (f == NULL) {
679 char buffer[1024];
680 grib_context_log(grib_parser_context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "grib_parser_include: cannot open: '%s'", parse_file);
681 sprintf(buffer, "Cannot include file: '%s'", parse_file);
682 grib_yyerror(buffer);
683 }
684 else {
685 /*
686 c=grib_context_get_default();
687 if (c->io_buffer_size) {
688 if (posix_memalign(&(io_buffer),sysconf(_SC_PAGESIZE),c->io_buffer_size) ) {
689 grib_context_log(c,GRIB_LOG_FATAL,"grib_parser_include: posix_memalign unable to allocate io_buffer\n");
690 }
691 setvbuf(f,io_buffer,_IOFBF,c->io_buffer_size);
692 }
693 */
694 grib_yyin = f;
695 stack[top].file = f;
696 stack[top].io_buffer = io_buffer;
697 stack[top].name = grib_context_strdup(grib_parser_context, parse_file);
698 parse_file = stack[top].name;
699 stack[top].line = grib_yylineno;
700 grib_yylineno = 0;
701 top++;
702 /* grib_yyrestart(f); */
703 }
704 }
705
706 extern int grib_yyparse(void);
707
parse(grib_context * gc,const char * filename)708 static int parse(grib_context* gc, const char* filename)
709 {
710 int err = 0;
711 GRIB_MUTEX_INIT_ONCE(&once, &init);
712 GRIB_MUTEX_LOCK(&mutex_parse);
713
714 #ifdef YYDEBUG
715 {
716 extern int grib_yydebug;
717 grib_yydebug = getenv("YYDEBUG") != NULL;
718 }
719 #endif
720
721 gc = gc ? gc : grib_context_get_default();
722
723 grib_yyin = NULL;
724 top = 0;
725 parse_file = 0;
726 grib_parser_include(filename);
727 if (!grib_yyin) {
728 /* Could not read from file */
729 parse_file = 0;
730 GRIB_MUTEX_UNLOCK(&mutex_parse);
731 return GRIB_FILE_NOT_FOUND;
732 }
733 err = grib_yyparse();
734 parse_file = 0;
735
736 if (err)
737 grib_context_log(gc, GRIB_LOG_ERROR, "Parsing error: %s, file: %s\n",
738 grib_get_error_message(err), filename);
739
740 GRIB_MUTEX_UNLOCK(&mutex_parse);
741 return err;
742 }
743
grib_parse_stream(grib_context * gc,const char * filename)744 static grib_action* grib_parse_stream(grib_context* gc, const char* filename)
745 {
746 GRIB_MUTEX_INIT_ONCE(&once, &init);
747 GRIB_MUTEX_LOCK(&mutex_stream);
748
749 grib_parser_all_actions = 0;
750
751 if (parse(gc, filename) == 0) {
752 if (grib_parser_all_actions) {
753 GRIB_MUTEX_UNLOCK(&mutex_stream)
754 return grib_parser_all_actions;
755 }
756 else {
757 grib_action* ret = grib_action_create_noop(gc, filename);
758 GRIB_MUTEX_UNLOCK(&mutex_stream)
759 return ret;
760 }
761 }
762 else {
763 GRIB_MUTEX_UNLOCK(&mutex_stream);
764 return NULL;
765 }
766 }
767
grib_parse_concept_file(grib_context * gc,const char * filename)768 grib_concept_value* grib_parse_concept_file(grib_context* gc, const char* filename)
769 {
770 GRIB_MUTEX_INIT_ONCE(&once, &init);
771 GRIB_MUTEX_LOCK(&mutex_file);
772
773 gc = gc ? gc : grib_context_get_default();
774 grib_parser_context = gc;
775
776 if (parse(gc, filename) == 0) {
777 GRIB_MUTEX_UNLOCK(&mutex_file);
778 return grib_parser_concept;
779 }
780 else {
781 GRIB_MUTEX_UNLOCK(&mutex_file);
782 return NULL;
783 }
784 }
785
grib_parse_hash_array_file(grib_context * gc,const char * filename)786 grib_hash_array_value* grib_parse_hash_array_file(grib_context* gc, const char* filename)
787 {
788 GRIB_MUTEX_INIT_ONCE(&once, &init);
789 GRIB_MUTEX_LOCK(&mutex_file);
790
791 gc = gc ? gc : grib_context_get_default();
792 grib_parser_context = gc;
793
794 if (parse(gc, filename) == 0) {
795 GRIB_MUTEX_UNLOCK(&mutex_file);
796 return grib_parser_hash_array;
797 }
798 else {
799 GRIB_MUTEX_UNLOCK(&mutex_file);
800 return NULL;
801 }
802 }
803
grib_parse_rules_file(grib_context * gc,const char * filename)804 grib_rule* grib_parse_rules_file(grib_context* gc, const char* filename)
805 {
806 if (!gc)
807 gc = grib_context_get_default();
808
809 GRIB_MUTEX_INIT_ONCE(&once, &init);
810 GRIB_MUTEX_LOCK(&mutex_rules);
811
812 gc = gc ? gc : grib_context_get_default();
813 grib_parser_context = gc;
814
815 if (parse(gc, filename) == 0) {
816 GRIB_MUTEX_UNLOCK(&mutex_rules);
817 return grib_parser_rules;
818 }
819 else {
820 GRIB_MUTEX_UNLOCK(&mutex_rules);
821 return NULL;
822 }
823 }
824
grib_parse_file(grib_context * gc,const char * filename)825 grib_action* grib_parse_file(grib_context* gc, const char* filename)
826 {
827 grib_action_file* af;
828
829 GRIB_MUTEX_INIT_ONCE(&once, &init);
830 GRIB_MUTEX_LOCK(&mutex_file);
831
832 af = 0;
833
834 gc = gc ? gc : grib_context_get_default();
835
836 grib_parser_context = gc;
837
838 if (!gc->grib_reader)
839 gc->grib_reader = (grib_action_file_list*)grib_context_malloc_clear_persistent(gc, sizeof(grib_action_file_list));
840 else {
841 af = grib_find_action_file(filename, gc->grib_reader);
842 }
843
844 if (!af) {
845 grib_action* a;
846 grib_context_log(gc, GRIB_LOG_DEBUG, "Loading %s", filename);
847
848 a = grib_parse_stream(gc, filename);
849
850 if (error) {
851 if (a)
852 grib_action_delete(gc, a);
853 GRIB_MUTEX_UNLOCK(&mutex_file);
854 return NULL;
855 }
856
857 af = (grib_action_file*)grib_context_malloc_clear_persistent(gc, sizeof(grib_action_file));
858
859 af->root = a;
860
861 af->filename = grib_context_strdup_persistent(gc, filename);
862 grib_push_action_file(af, gc->grib_reader); /* Add af to grib_reader action file list */
863 }
864 else
865 grib_context_log(gc, GRIB_LOG_DEBUG, "Using cached version of %s", filename);
866
867 GRIB_MUTEX_UNLOCK(&mutex_file);
868 return af->root;
869 }
870
grib_type_to_int(char id)871 int grib_type_to_int(char id)
872 {
873 switch (id) {
874 case 'd':
875 return GRIB_TYPE_DOUBLE;
876 break;
877 case 'f':
878 return GRIB_TYPE_DOUBLE;
879 break;
880 case 'l':
881 return GRIB_TYPE_LONG;
882 break;
883 case 'i':
884 return GRIB_TYPE_LONG;
885 break;
886 case 's':
887 return GRIB_TYPE_STRING;
888 break;
889 }
890 return GRIB_TYPE_UNDEFINED;
891 }
892