1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** mof.lex
5 **
6 ** This file defines a lexigraphical analyzer for the Managed Object Format
7 ** (MOF). See the BNF in the CIM Infrastructure Specification.
8 **
9 **==============================================================================
10 */
11
12 %{
13
14 /* Do not read from standard input */
15 #define YY_NEVER_INTERACTIVE 1
16 #define MOF_STACK_SIZE 32
17
18 #include "config.h"
19 #include "mof.h"
20 #include "types.h"
21 #include "mofyacc.h"
22 mike 1.1 #include "buffer.h"
23 #include "ptrarray.h"
24 #include "state.h"
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28
29 extern int yyparse();
30 int closeIncludeFile();
31
32 struct _MOF_Parser
33 {
34 MOF_State state;
35 };
36
37 typedef struct _StackItem
38 {
39 char* file;
40 unsigned int line;
41 YY_BUFFER_STATE buffer;
42 }
43 mike 1.1 StackItem;
44
45 /* Stack of parser states for open nested MOF files */
46 static StackItem s_stack[MOF_STACK_SIZE];
47
48 /* Current size of stack s_stack[s_top-1] is the top */
49 static size_t s_top = 0;
50
51 %}
52
53 /*
54 **==============================================================================
55 **
56 ** Case-insensitive keywords (see CIM Infrastructure specification).
57 **
58 **==============================================================================
59 */
60
61 /* True and false */
62 TRUE [Tt][Rr][Uu][Ee]
63 FALSE [Ff][Aa][Ll][Ss][Ee]
64 mike 1.1
65 /* Null value */
66 NULL [Nn][Uu][Ll][Ll]
67
68 /* Data types */
69 DT_BOOLEAN [Bb][Oo][Oo][Ll][Ee][Aa][Nn]
70 DT_SINT8 [Ss][Ii][Nn][Tt]8
71 DT_UINT8 [Uu][Ii][Nn][Tt]8
72 DT_SINT16 [Ss][Ii][Nn][Tt]16
73 DT_UINT16 [Uu][Ii][Nn][Tt]16
74 DT_SINT32 [Ss][Ii][Nn][Tt]32
75 DT_UINT32 [Uu][Ii][Nn][Tt]32
76 DT_SINT64 [Ss][Ii][Nn][Tt]64
77 DT_UINT64 [Uu][Ii][Nn][Tt]64
78 DT_REAL32 [Rr][Ee][Aa][Ll]32
79 DT_REAL64 [Rr][Ee][Aa][Ll]64
80 DT_DATETIME [Dd][Aa][Tt][Ee][Tt][Ii][Mm][Ee]
81 DT_CHAR16 [Cc][Hh][Aa][Rr]16
82 DT_STRING [Ss][Tt][Rr][Ii][Nn][Gg]
83
84 /* Ref */
85 mike 1.1 REF [Rr][Ee][Ff]
86
87 /* Scope */
88 SCOPE [Ss][Cc][Oo][Pp][Ee]
89 CLASS [Cc][Ll][Aa][Ss][Ss]
90 ASSOCIATION [Aa][Ss][Ss][Oo][Cc][Ii][Aa][Tt][Ii][Oo][Nn]
91 INDICATION [Ii][Nn][Dd][Ii][Cc][Aa][Tt][Ii][Oo][Nn]
92 QUALIFIER [Qq][Uu][Aa][Ll][Ii][Ff][Ii][Ee][Rr]
93 PROPERTY [Pp][Rr][Oo][Pp][Ee][Rr][Tt][Yy]
94 REFERENCE [Rr][Ee][Ff][Ee][Rr][Ee][Nn][Cc][Ee]
95 METHOD [Mm][Ee][Tt][Hh][Oo][Dd]
96 PARAMETER [Pp][Aa][Rr][Aa][Mm][Ee][Tt][Ee][Rr]
97 ANY [Aa][Nn][Yy]
98
99 /* Flavor */
100 FLAVOR [Ff][Ll][Aa][Vv][Oo][Rr]
101 ENABLEOVERRIDE [Ee][Nn][Aa][Bb][Ll][Ee][Oo][Vv][Ee][Rr][Rr][Ii][Dd][Ee]
102 DISABLEOVERRIDE [Dd][Ii][Ss][Aa][Bb][Ll][Ee][Oo][Vv][Ee][Rr][Rr][Ii][Dd][Ee]
103 RESTRICTED [Rr][Ee][Ss][Tt][Rr][Ii][Cc][Tt][Ee][Dd]
104 TOSUBCLASS [Tt][Oo][Ss][Uu][Bb][Cc][Ll][Aa][Ss][Ss]
|
105 krisbash 1.3 TOINSTANCE [Tt][Oo][Ii][Nn][Ss][Tt][Aa][Nn][Cc][Ee]
|
106 mike 1.1 TRANSLATABLE [Tt][Rr][Aa][Nn][Ss][Ll][Aa][Tt][Aa][Bb][Ll][Ee]
107
108 /* Instance of */
109 INSTANCE [Ii][Nn][Ss][Tt][Aa][Nn][Cc][Ee]
110 OF [Oo][Ff]
111
|
112 krisbash 1.3 /* Object */
113 OBJECT [Oo][Bb][Jj][Ee][Cc][Tt]
114
|
115 mike 1.1 /* Alias */
116 AS [Aa][Ss]
117
118 /* #pragma */
119 PRAGMA \#[Pp][Rr][Aa][Gg][Mm][Aa][ ]
120
121 /*
122 **==============================================================================
123 **
124 ** Literal productions (see CIM Infrastructure specification).
125 **
126 **==============================================================================
127 */
128
129 simpleChar \'[^\']\'
130 escapedChar \'\\[rntfb\"\'\\]\'
131 hexChar \'\\[xX][A-Fa-f0-9]+\'
132 realValue [+-]?[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?
133 hexValue [+-]?0[xX][A-Fa-f0-9]+
134 decimalValue [+-]?[1-9][0-9]*
135 octalValue [+-]?0[0-7]+
136 mike 1.1 binaryValue [+-]?[01]+[Bb]
137 blank [ \r\n\t]
138 identifier [A-Za-z_][A-Za-z_0-9]*
139 aliasIdentifier \$[A-Za-z_][A-Za-z_0-9]*
140 whiteSpaceChar [ \r\n\t\b\f]
141
142 /*
143 **------------------------------------------------------------------------------
144 **
145 ** Lex productions:
146 **
147 **------------------------------------------------------------------------------
148 */
149
150 %%
151
152 <<EOF>> {
153 if (s_top == 0)
154 yyterminate();
155 else
156 {
157 mike 1.1 if (closeIncludeFile() != 0)
158 return TOK_ERROR;
159 }
160 }
161
162 {TRUE} {
163 yylval.boolean = 1;
164 return TOK_BOOLEAN_VALUE;
165 }
166
167 {FALSE} {
168 yylval.boolean = 0;
169 return TOK_BOOLEAN_VALUE;
170 }
171
172 {NULL} {
173 return TOK_NULL;
174 }
175
176 {DT_BOOLEAN} {
|
177 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
178 mike 1.1 return TOK_BOOLEAN;
179 }
180
181 {DT_SINT8} {
182 return TOK_SINT8;
183 }
184
185 {DT_UINT8} {
186 return TOK_UINT8;
187 }
188
189 {DT_SINT16} {
190 return TOK_SINT16;
191 }
192
193 {DT_UINT16} {
194 return TOK_UINT16;
195 }
196
197 {DT_SINT32} {
198 return TOK_SINT32;
199 mike 1.1 }
200
201 {DT_UINT32} {
202 return TOK_UINT32;
203 }
204
205 {DT_SINT64} {
206 return TOK_SINT64;
207 }
208
209 {DT_UINT64} {
210 return TOK_UINT64;
211 }
212
213 {DT_REAL32} {
214 return TOK_REAL32;
215 }
216
217 {DT_REAL64} {
218 return TOK_REAL64;
219 }
220 mike 1.1
221 {DT_DATETIME} {
|
222 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
223 mike 1.1 return TOK_DATETIME;
224 }
225
226 {DT_CHAR16} {
227 return TOK_CHAR16;
228 }
229
230 {DT_STRING} {
|
231 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
232 mike 1.1 return TOK_STRING;
233 }
234
235 {REF} {
236 return TOK_REF;
237 }
238
239 {SCOPE} {
240 return TOK_SCOPE;
241 }
242
243 {CLASS} {
|
244 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
245 mike 1.1 return TOK_CLASS;
246 }
247
248 {ASSOCIATION} {
|
249 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
250 mike 1.1 return TOK_ASSOCIATION;
251 }
252
253 {INDICATION} {
|
254 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
255 mike 1.1 return TOK_INDICATION;
256 }
257
258 {QUALIFIER} {
|
259 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
260 mike 1.1 return TOK_QUALIFIER;
261 }
262
263 {PROPERTY} {
|
264 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
265 mike 1.1 return TOK_PROPERTY;
266 }
267
268 {REFERENCE} {
|
269 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
270 mike 1.1 return TOK_REFERENCE;
271 }
272
273 {METHOD} {
|
274 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
275 mike 1.1 return TOK_METHOD;
276 }
277
278 {PARAMETER} {
|
279 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
280 mike 1.1 return TOK_PARAMETER;
281 }
282
283 {ANY} {
|
284 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
285 return TOK_ANY;
|
286 mike 1.1 }
287
288 {FLAVOR} {
|
289 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
290 mike 1.1 return TOK_FLAVOR;
291 }
292
293 {ENABLEOVERRIDE} {
|
294 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
295 mike 1.1 return TOK_ENABLEOVERRIDE;
296 }
297
298 {DISABLEOVERRIDE} {
|
299 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
300 mike 1.1 return TOK_DISABLEOVERRIDE;
301 }
302
303 {RESTRICTED} {
|
304 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
305 mike 1.1 return TOK_RESTRICTED;
306 }
307
308 {TOSUBCLASS} {
|
309 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
310 mike 1.1 return TOK_TOSUBCLASS;
311 }
312
|
313 krisbash 1.3 {TOINSTANCE} {
314 yylval.identifier = MOF_Strdup(&state.heap, yytext);
315 return TOK_TOINSTANCE;
316 }
317
|
318 mike 1.1 {TRANSLATABLE} {
|
319 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
320 mike 1.1 return TOK_TRANSLATABLE;
321 }
322
323 {INSTANCE} {
324 return TOK_INSTANCE;
325 }
326
327 {OF} {
|
328 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
329 mike 1.1 return TOK_OF;
330 }
331
332 {AS} {
333 return TOK_AS;
334 }
335
|
336 krisbash 1.3 {OBJECT} {
337 return TOK_OBJECT;
338 }
339
|
340 mike 1.1 {PRAGMA} {
|
341 krisbash 1.3 yylval.identifier = MOF_Strdup(&state.heap, yytext);
|
342 mike 1.1 return TOK_PRAGMA;
343 }
344
345 \/\* {
346 /* C-sytle comments */
347 int c;
348 int prev;
349
350 /* Discard C-style comments. Replace with a single space since
351 * comments may function as token separators.
352 */
353
354 for (c = input(), prev = '\0'; EOF != c; prev = c, c = input())
355 {
356 /* Check for closing comment */
357 if (prev == '*' && c == '/')
358 break;
359
360 /* Increment line counter on newlines */
361 if (c == '\n')
362 state.line++;
363 mike 1.1 }
364
365 /* Inject a blank character into input */
366 unput(' ');
367 }
368
369 \/\/ {
370 /* C++-style comments */
371 int c;
372
373 /* Discard all characters on this comment line including the newline */
374
375 for (c = input(); EOF != c; c = input())
376 {
377 /* Increment line counter on newlines */
378 if (c == '\n')
379 {
380 state.line++;
381 break;
382 }
383 }
384 mike 1.1 }
385
386 \" {
387 /* Read a string literal */
388 int c;
389 Buffer buf = BUFFER_INITIALIZER;
390
391 /* Scan until the closing quote is found */
392 for (;;)
393 {
394 c = input();
395
396 if (EOF == c || c == '"')
397 break;
398
399 if (Buffer_AppendChar(&buf, (char)c) != 0)
400 {
401 yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
402 return TOK_ERROR;
403 }
404
405 mike 1.1 /* If backslash, get next character */
406 if (c == '\\')
407 {
408 c = input();
409
410 if (EOF == c)
411 {
412 yyerrorf(ID_UNTERMINATED_STRING_LITERAL,
413 "unterminated string literal");
414 return TOK_ERROR;
415 }
416
417 if (Buffer_AppendChar(&buf, (char)c) != 0)
418 {
419 yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
420 return TOK_ERROR;
421 }
422 }
423 }
424
425 /* Append zero-terminator */
426 mike 1.1 if (Buffer_AppendChar(&buf, '\0') != 0)
427 {
428 yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
429 return TOK_ERROR;
430 }
431
432 /* Return the string */
433 yylval.string = buf.data;
434 return TOK_STRING_VALUE;
435 }
436
437 {simpleChar} {
438 yylval.character = yytext[1];
439 return TOK_CHAR_VALUE;
440 }
441
442 {escapedChar} {
443
444 switch (yytext[2])
445 {
446 case 'r':
447 mike 1.1 yylval.character = '\r';
448 break;
449 case 'n':
450 yylval.character = '\n';
451 break;
452 case 't':
453 yylval.character = '\t';
454 break;
455 case 'f':
456 yylval.character = '\f';
457 break;
458 case 'b':
459 yylval.character = '\b';
460 break;
461 case '\"':
462 yylval.character = '"';
463 break;
464 case '\'':
465 yylval.character = '\'';
466 break;
467 case '\\':
468 mike 1.1 yylval.character = '\\';
469 break;
470 default:
471 yyerrorf(ID_INTERNAL_ERROR, "internal error");
472 return TOK_ERROR;
473 }
474
475 return TOK_CHAR_VALUE;
476 }
477
478 {hexChar} {
479 char* end;
480
481 if (yyleng - 4 > 4)
482 {
483 yyerrorf(ID_ILLEGAL_HEX_CHARACTER, "illegal hex character");
484 return TOK_ERROR;
485 }
486
487 yylval.character = (MI_Char16)strtoul(&yytext[3], &end, 16);
488
489 mike 1.1 if (*end != '\'')
490 {
491 yyerrorf(ID_ILLEGAL_HEX_CHARACTER, "illegal hex character");
492 return TOK_ERROR;
493 }
494
495 return TOK_CHAR_VALUE;
496 }
497
498 [+-]?0 {
499 yylval.integer = 0;
500 return TOK_INTEGER_VALUE;
501 }
502
503 {decimalValue} {
504 errno = 0;
505 if (yytext[0] == '-')
506 yylval.integer = (MI_Sint64)Strtoll(yytext, NULL, 10);
507 else
508 yylval.integer = (MI_Sint64)Strtoull(yytext, NULL, 10);
509
510 mike 1.1 if (errno == ERANGE)
511 {
512 yyerrorf(ID_INTEGER_OVERFLOW, "integer overflow");
513 return TOK_ERROR;
514 }
515 return TOK_INTEGER_VALUE;
516 }
517
518 {realValue} {
519 yylval.real = (double)strtod(yytext, NULL);
520 return TOK_REAL_VALUE;
521 }
522
523 {hexValue} {
524 errno = 0;
525 if (yytext[0] == '-')
526 yylval.integer = (MI_Sint64)Strtoll(yytext, NULL, 16);
527 else
528 yylval.integer = (MI_Sint64)Strtoull(yytext, NULL, 16);
529
530 if (errno == ERANGE)
531 mike 1.1 {
532 yyerrorf(ID_INTEGER_OVERFLOW, "integer overflow");
533 return TOK_ERROR;
534 }
535 return TOK_INTEGER_VALUE;
536 }
537
538 {octalValue} {
539 errno = 0;
540 if (yytext[0] == '-')
541 yylval.integer = (MI_Sint64)Strtoll(yytext, NULL, 8);
542 else
543 yylval.integer = (MI_Sint64)Strtoull(yytext, NULL, 8);
544
545 if (errno == ERANGE)
546 {
547 yyerrorf(ID_INTEGER_OVERFLOW, "integer overflow");
548 return TOK_ERROR;
549 }
550 return TOK_INTEGER_VALUE;
551 }
552 mike 1.1
553 {binaryValue} {
554 char* end;
555
556 if (yytext[0] == '-')
557 yylval.integer = (MI_Sint64)Strtoll(yytext, &end, 2);
558 else
559 yylval.integer = (MI_Sint64)Strtoull(yytext, &end, 2);
560
561 if (*end != 'B' && *end != 'b')
562 {
563 yyerrorf(ID_ILLEGAL_BINARY_LITERAL, "illegal binary literal");
564 return TOK_ERROR;
565 }
566 if (errno == ERANGE)
567 {
568 yyerrorf(ID_INTEGER_OVERFLOW, "integer overflow");
569 return TOK_ERROR;
570 }
571
572 return TOK_INTEGER_VALUE;
573 mike 1.1 }
574
575 {identifier} {
576 yylval.identifier = MOF_Strdup(&state.heap, yytext);
577 return TOK_IDENT;
578 }
579
580 {aliasIdentifier} {
581 yylval.identifier = MOF_Strdup(&state.heap, yytext);
582 return TOK_ALIAS_IDENTIFIER;
583 }
584
585 \= {
586 return '=';
587 }
588
589 \( {
590 return '(';
591 }
592
593 \) {
594 mike 1.1 return ')';
595 }
596
597 \[ {
598 return '[';
599 }
600
601 \] {
602 return ']';
603 }
604
605 \{ {
606 return '{';
607 }
608
609 \} {
610 return '}';
611 }
612
613 \: {
614 return ':';
615 mike 1.1 }
616
617 \; {
618 return ';';
619 }
620
621 \, {
622 return ',';
623 }
624
625 {whiteSpaceChar}+ {
626 /* swallow whiteSpaceChar */
627 int i;
628
629 for (i = 0; i < yyleng; i++)
630 {
631 if (yytext[i] == '\n')
632 state.line++;
633 }
634 }
635
636 mike 1.1 . {
637 yyterminate();
638 }
639
640 %%
641
642 /*
643 **==============================================================================
644 **
645 ** Function definitions
646 **
647 **==============================================================================
648 */
649
650 int yywrap()
651 {
652 /* Return 1 to indicate the end of input */
653 return 1;
654 }
655
656 static int exists(const char* path)
657 mike 1.1 {
658 if (access(path, R_OK) != 0)
659 return -1;
660
661 return 0;
662 }
663
664 static char* findIncludeFile(const char* path)
665 {
666 /* First attempt to locate the file relative to the one that included it */
667 {
668 Buffer buf = BUFFER_INITIALIZER;
669 char* p;
670
671 p = strrchr(state.path, '/');
672
673 if (p)
674 {
675 if (Buffer_Append(&buf, state.path, p - state.path + 1) != 0)
676 return NULL;
677 }
678 mike 1.1
679 if (Buffer_Append(&buf, path, strlen(path) + 1) != 0)
680 return NULL;
681
682 if (exists((const char*)buf.data) == 0)
683 return (char*)buf.data;
684 }
685
686 /* Attempt to open the file relative to the current directory */
687 {
688 if (exists(path) == 0)
689 return MOF_Strdup(&state.heap, path);
690 }
691
692 /* Search for file using include path array */
693 {
694 size_t i;
695 for (i = 0; i < state.paths.size; i++)
696 {
697 const char* p = (const char*)state.paths.data[i];
698 Buffer buf = BUFFER_INITIALIZER;
699 mike 1.1
700 if (Buffer_Append(&buf, p, strlen(p)) != 0)
701 return NULL;
702
703 if (Buffer_AppendChar(&buf, '/') != 0)
704 return NULL;
705
706 if (Buffer_Append(&buf, path, strlen(path) + 1) != 0)
707 return NULL;
708
709 if (exists((char*)buf.data) == 0)
710 return (char*)buf.data;
711
712 MOF_Free(&state.heap, buf.data);
713 }
714 }
715
716 /* Not found */
717 return NULL;
718 }
719
720 mike 1.1 int openIncludeFile(const char* path_)
721 {
722 FILE* is;
723 char* path;
724
725 if ((path = findIncludeFile(path_)) == NULL)
726 {
727 yyerrorf(ID_FAILED_TO_FIND_INCLUDE_FILE,
728 "failed to find inlude file: \"%s\"", path_);
729 return -1;
730 }
731
732 /* Check for stack overflow. */
733 if (s_top >= MOF_STACK_SIZE)
734 {
735 yyerrorf(ID_MOF_STACK_OVERFLOW, "MOF file stack overflow");
736 return -1;
737 }
738
739 /* Open the file */
|
740 krisbash 1.3 if ((is = File_Open(path, "rb")) == NULL)
|
741 mike 1.1 {
742 yyerrorf(ID_FAILED_TO_OPEN_FILE, "failed to open file: \"%s\"", path);
743 return -1;
744 }
745
746 /* Push current state onto stack. */
747 s_stack[s_top].file = state.path;
748 s_stack[s_top].line = state.line;
749 s_stack[s_top].buffer = YY_CURRENT_BUFFER;
750 s_top++;
751
752 /* Setup state for new file */
753 yy_switch_to_buffer(yy_create_buffer(is, YY_BUF_SIZE));
754 state.path = MOF_Strdup(&state.heap, path);
755 state.line = 1;
756
757 return 0;
758 }
759
760 int closeIncludeFile()
761 {
762 mike 1.1 /* Check for stack underflow. */
763 if (s_top == 0)
764 {
765 yyerrorf(ID_MOF_STACK_UNDERFLOW, "MOF file stack underflow");
766 return -1;
767 }
768
769 /* Release current state */
770 MOF_Free(&state.heap, state.path);
771 fclose(YY_CURRENT_BUFFER->yy_input_file);
772 yy_delete_buffer(YY_CURRENT_BUFFER);
773
774 /* Restore state from top of stack */
775 s_top--;
776 state.path = s_stack[s_top].file;
777 state.line = s_stack[s_top].line;
778 yy_switch_to_buffer(s_stack[s_top].buffer);
779
780 return 0;
781 }
782
783 mike 1.1 /*
784 **==============================================================================
785 **
786 ** MOF_Parser
787 **
788 **==============================================================================
789 */
790
791 MOF_Parser* MOF_Parser_New(
792 const char* const* paths,
793 size_t numPaths)
794 {
|
795 krisbash 1.3 MOF_Parser* self = (MOF_Parser*)PAL_Calloc(1, sizeof(MOF_Parser));
|
796 mike 1.1 size_t i;
797 char* str;
798
799 if (!self)
800 return NULL;
801
802 for (i = 0; i < numPaths; i++)
803 {
804 str = MOF_Strdup(&self->state.heap, paths[i]);
805
806 if (!str)
807 {
808 MOF_Release(&self->state.heap);
|
809 krisbash 1.3 PAL_Free(self);
|
810 mike 1.1 return NULL;
811 }
812
813 /* PtrArray_Append() uses the global state's heap object to
814 * obtain memory, so install self->state as the global state
815 * object temporarily.
816 */
817 {
818 state = self->state;
819 PtrArray_Append(&state.paths, str);
820 self->state = state;
821 memset(&state, 0, sizeof(state));
822 }
823 }
824
825 return self;
826 }
827
828 void MOF_Parser_SetErrorCallback(
829 MOF_Parser* self,
830 void (*callback)(const char* msg, const wchar_t* wmsg, void* data),
831 mike 1.1 void* data)
832 {
833 if (self)
834 {
835 self->state.errorCallback = callback;
836 self->state.errorCallbackData = data;
837 }
838 }
839
840 void MOF_Parser_SetWarningCallback(
841 MOF_Parser* self,
842 void (*callback)(const char* msg, const wchar_t* wmsg, void* data),
843 void* data)
844 {
845 if (self)
846 {
847 self->state.warningCallback = callback;
848 self->state.warningCallbackData = data;
849 }
850 }
851
852 mike 1.1 void MOF_Parser_SetPragmaCallback(
853 MOF_Parser* self,
854 void (*callback)(const char* pragma, const char* value, void* data),
855 void* data)
856 {
857 if (self)
858 {
859 self->state.pragmaCallback = callback;
860 self->state.pragmaCallbackData = data;
861 }
862 }
863
864 void MOF_Parser_SetClassDeclCallback(
865 MOF_Parser* self,
866 void (*callback)(const MI_ClassDecl* decl, void* data),
867 void* data)
868 {
869 if (self)
870 {
871 self->state.classDeclCallback = callback;
872 self->state.classDeclCallbackData = data;
873 mike 1.1 }
874 }
875
876 void MOF_Parser_SetInstanceDeclCallback(
877 MOF_Parser* self,
878 void (*callback)(const MI_InstanceDecl* decl, void* data),
879 void* data)
880 {
881 if (self)
882 {
883 self->state.instanceDeclCallback = callback;
884 self->state.instanceDeclCallbackData = data;
885 }
886 }
887
888 void MOF_Parser_SetQualifierDeclCallback(
889 MOF_Parser* self,
890 void (*callback)(const MI_QualifierDecl* decl, void* data),
891 void* data)
892 {
893 if (self)
894 mike 1.1 {
895 self->state.qualifierDeclCallback = callback;
896 self->state.qualifierDeclCallbackData = data;
897 }
898 }
899
900 void MOF_Parser_Delete(MOF_Parser* self)
901 {
902 if (self)
903 {
904 MOF_Release(&self->state.heap);
|
905 krisbash 1.3 PAL_Free(self);
|
906 mike 1.1 }
907 }
908
909 /* Handle multiple calls to this function */
910 int MOF_Parser_Parse(MOF_Parser* self, const char* path)
911 {
912 /* Reject null parameters */
913 if (!self || !path)
914 return -1;
915
916 /* Clear stack */
917 s_top = 0;
918
919 /* Set global state */
920 state = self->state;
921
922 /* Open input */
|
923 krisbash 1.3 yyin = File_Open(path, "rb");
|
924 mike 1.1
925 if (!yyin)
926 {
927 yyerrorf(ID_FAILED_TO_OPEN_FILE, "failed to open file: %s", path);
928 self->state = state;
929 memset(&state.heap, 0, sizeof(state));
930 return -1;
931 }
932
933 /* Save path */
934 state.path = MOF_Strdup(&state.heap, path);
935
936 /* Set initialize line number */
937 state.line = 1;
938
939 /* Clear the parser state */
940 yy_c_buf_p = 0;
941 yy_last_accepting_cpos = 0;
942 yy_init = 1;
943
944 /* Run the parser */
945 mike 1.1 if (yyparse() != 0)
946 {
947 fclose(yyin);
948 yy_delete_buffer(YY_CURRENT_BUFFER);
949 self->state = state;
950 memset(&state.heap, 0, sizeof(state));
951 return -1;
952 }
953
954 /* Perform post processing (which requires first pass completion) */
955 if (PerformPostProcessing() != 0)
956 {
957 fclose(yyin);
958 yy_delete_buffer(YY_CURRENT_BUFFER);
959 self->state = state;
960 memset(&state.heap, 0, sizeof(state));
961 return -1;
962 }
963
964 /* Close stream and release parse buffer */
965 fclose(yyin);
966 mike 1.1 yy_delete_buffer(YY_CURRENT_BUFFER);
967
968 /* Restore state */
969 self->state = state;
970 memset(&state.heap, 0, sizeof(state));
971
972 return 0;
973 }
974
|
975 krisbash 1.3 /* Parse a MOF string */
976 int MOF_Parser_ParseString(MOF_Parser* self, const char* mof_string)
977 {
978 YY_BUFFER_STATE bp;
979
980 /* Reject null parameters */
981 if (!self || !mof_string)
982 return -1;
983
984 /* Clear stack */
985 s_top = 0;
986
987 /* Set global state */
988 state = self->state;
989
990 /* Save path */
991 state.path = MOF_Strdup(&state.heap, "MOF string");
992
993 /* Set initialize line number */
994 state.line = 1;
995
996 krisbash 1.3 /* Clear the parser state */
997 yy_c_buf_p = 0;
998 yy_last_accepting_cpos = 0;
999 yy_init = 1;
1000
1001 /* Run the parser */
1002 bp = yy_scan_string(mof_string);
1003 yy_switch_to_buffer(bp);
1004 if (yyparse() != 0)
1005 {
1006 yy_delete_buffer(bp);
1007 self->state = state;
1008 memset(&state.heap, 0, sizeof(state));
1009 return -1;
1010 }
1011
1012 /* Perform post processing (which requires first pass completion) */
1013 if (PerformPostProcessing() != 0)
1014 {
1015 yy_delete_buffer(bp);
1016 self->state = state;
1017 krisbash 1.3 memset(&state.heap, 0, sizeof(state));
1018 return -1;
1019 }
1020
1021 /* Close stream and release parse buffer */
1022 yy_delete_buffer(bp);
1023
1024 /* Restore state */
1025 self->state = state;
1026 memset(&state.heap, 0, sizeof(state));
1027
1028 return 0;
1029 }
1030
|
1031 mike 1.1 void MOF_Parser_Dump(MOF_Parser* self, FILE* file)
1032 {
1033 size_t i;
1034
1035 for (i = 0; i < self->state.qualifierDecls.size; i++)
1036 MOF_PrintQualifierDecl(self->state.qualifierDecls.data[i], file);
1037
1038 for (i = 0; i < self->state.classDecls.size; i++)
1039 MOF_PrintClassDecl(self->state.classDecls.data[i], file);
1040
1041 for (i = 0; i < self->state.instanceDecls.size; i++)
1042 MOF_PrintInstanceDecl(self->state.instanceDecls.data[i], file);
1043 }
|
1044 krisbash 1.3
1045 void MOF_Parser_EnableExtensions(MOF_Parser* self, MI_Boolean enabled)
1046 {
1047 self->state.extensionsEnabled = enabled;
1048 return;
1049 }
|