(file) Return to mof.l CVS log (file) (dir) Up to [OMI] / omi / mof

  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           }

ViewCVS 0.9.2