(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 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              }

ViewCVS 0.9.2