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