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

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include "config.h"
  26           #include <string.h>
  27           #include <stdlib.h>
  28           #include <stdio.h>
  29           #include <assert.h>
  30           #include <time.h>
  31           #include "types.h"
  32           #include "ptrarray.h"
  33           #include "config.h"
  34           #include "mofyacc.h"
  35           #include "buffer.h"
  36           #include "state.h"
  37           #include <base/helpers.h>
  38           
  39           /*
  40           **==============================================================================
  41           **
  42           ** Local definitions
  43 mike  1.1 **
  44           **==============================================================================
  45           */
  46           
  47           #define NEW_ARRAY_T(PTR, TYPE, SIZE)  \
  48               for (;;) \
  49               { \
  50                   PTR = ((TYPE##A*)MOF_Malloc(&state.heap, \
  51                       sizeof(TYPE##A) + sizeof(TYPE) * (SIZE))); \
  52                   PTR->data = (TYPE*)(PTR + 1); \
  53                   PTR->size = SIZE; \
  54                   break; \
  55               }
  56           
  57           const char* _getTypeName(MI_Type type)
  58           {
  59               switch (type)
  60               {
  61                   case MI_BOOLEAN:
  62                       return "BOOLEAN";
  63                   case MI_UINT8:
  64 mike  1.1             return "UINT8";
  65                   case MI_SINT8:
  66                       return "SINT8";
  67                   case MI_UINT16:
  68                       return "UINT16";
  69                   case MI_SINT16:
  70                       return "SINT16";
  71                   case MI_UINT32:
  72                       return "UINT32";
  73                   case MI_SINT32:
  74                       return "SINT32";
  75                   case MI_UINT64:
  76                       return "UINT64";
  77                   case MI_SINT64:
  78                       return "SINT64";
  79                   case MI_REAL32:
  80                       return "REAL32";
  81                   case MI_REAL64:
  82                       return "REAL64";
  83                   case MI_CHAR16:
  84                       return "CHAR16";
  85 mike  1.1         case MI_DATETIME:
  86                       return "DATETIME";
  87                   case MI_STRING:
  88                       return "STRING";
  89                   case MI_REFERENCE:
  90                       return "REFERENCE";
  91                   case MI_INSTANCE:
  92                       return "INSTANCE";
  93                   case MI_BOOLEANA:
  94                       return "BOOLEAN[]";
  95                   case MI_UINT8A:
  96                       return "UINT8[]";
  97                   case MI_SINT8A:
  98                       return "SINT8[]";
  99                   case MI_UINT16A:
 100                       return "UINT16[]";
 101                   case MI_SINT16A:
 102                       return "SINT16[]";
 103                   case MI_UINT32A:
 104                       return "UINT32[]";
 105                   case MI_SINT32A:
 106 mike  1.1             return "SINT32[]";
 107                   case MI_UINT64A:
 108                       return "UINT64[]";
 109                   case MI_SINT64A:
 110                       return "SINT64[]";
 111                   case MI_REAL32A:
 112                       return "REAL32[]";
 113                   case MI_REAL64A:
 114                       return "REAL64[]";
 115                   case MI_CHAR16A:
 116                       return "CHAR16[]";
 117                   case MI_DATETIMEA:
 118                       return "DATETIME[]";
 119                   case MI_STRINGA:
 120                       return "STRING[]";
 121                   case MI_REFERENCEA:
 122                       return "REFERENCE[]";
 123                   case MI_INSTANCEA:
 124                       return "INSTANCE[]";
 125                   default:
 126                       return "UNKNOWN";
 127 mike  1.1     }
 128           }
 129           
 130           static size_t _typeSizes[] =
 131           {
 132               sizeof(MI_Boolean),
 133               sizeof(MI_Uint8),
 134               sizeof(MI_Sint8),
 135               sizeof(MI_Uint16),
 136               sizeof(MI_Sint16),
 137               sizeof(MI_Uint32),
 138               sizeof(MI_Sint32),
 139               sizeof(MI_Uint64),
 140               sizeof(MI_Sint64),
 141               sizeof(MI_Real32),
 142               sizeof(MI_Real64),
 143               sizeof(MI_Char16),
 144               sizeof(MI_Datetime),
 145               sizeof(MI_String),
 146               sizeof(void*), /* reference */
 147               sizeof(void*), /* instance */
 148 mike  1.1 };
 149           
 150           static int _ParseUint32(
 151               const char* p, 
 152               size_t n, 
 153               MI_Uint32* result)
 154           {
 155               char buf[9];
 156               char* end;
 157           
 158               if (n > 8)
 159                   return -1;
 160           
 161               memcpy(buf, p, n);
 162               buf[n] = '\0';
 163           
 164               *result = (MI_Uint32)strtoul(buf, &end, 10);
 165           
 166               if (*end != '\0')
 167                   return -1;
 168           
 169 mike  1.1     return 0;
 170           }
 171           
 172           typedef struct _Flag
 173           {
 174               const char* name;
 175               MI_Uint32 flag;
 176           }
 177           Flag;
 178           
 179           static Flag _flags[] =
 180           {
 181               { "CLASS", MI_FLAG_CLASS },
 182               { "METHOD", MI_FLAG_METHOD },
 183               { "PROPERTY", MI_FLAG_PROPERTY },
 184               { "PARAMETER", MI_FLAG_PARAMETER },
 185               { "ASSOCIATION", MI_FLAG_ASSOCIATION },
 186               { "INDICATION", MI_FLAG_INDICATION },
 187               { "REFERENCE", MI_FLAG_REFERENCE },
 188           
 189               { "KEY", MI_FLAG_KEY },
 190 mike  1.1     { "IN", MI_FLAG_IN },
 191               { "OUT", MI_FLAG_OUT },
 192               { "REQUIRED", MI_FLAG_REQUIRED },
 193               { "STATIC", MI_FLAG_STATIC },
 194               { "ABSTRACT", MI_FLAG_ABSTRACT },
 195               { "TERMINAL", MI_FLAG_TERMINAL },
 196               { "EXPENSIVE", MI_FLAG_EXPENSIVE },
 197               { "STREAM", MI_FLAG_STREAM },
 198           
 199               { "ENABLEOVERRIDE", MI_FLAG_ENABLEOVERRIDE },
 200               { "DISABLEOVERRIDE", MI_FLAG_DISABLEOVERRIDE },
 201               { "RESTRICTED", MI_FLAG_RESTRICTED},
 202               { "TOSUBCLASS", MI_FLAG_TOSUBCLASS},
 203               { "TRANSLATABLE", MI_FLAG_TRANSLATABLE},
 204           };
 205           
 206           static size_t _flagsSize = MI_COUNT(_flags);
 207           
 208           static int _StrToDatetime(const char* str, MI_Datetime* result)
 209           {
 210               const char* p = str;
 211 mike  1.1 
 212               /* Check arguments */
 213               if (!str || !result)
 214                   return -1;
 215           
 216               /* Datetime strings must be exactly 25 bytes long */
 217               if (strlen(p) != 25)
 218                   return -1;
 219           
 220               if (p[21] == ':')
 221               {
 222                   /* DDDDDDDDHHMMSS.MMMMMM:000 */
 223                   MI_Uint32 dddddddd;
 224                   MI_Uint32 hh;
 225                   MI_Uint32 mm;
 226                   MI_Uint32 ss;
 227                   MI_Uint32 mmmmmm;
 228           
 229                   if (_ParseUint32(p, 8, &dddddddd) != 0)
 230                       return -1;
 231                   if (_ParseUint32(p + 8, 2, &hh) != 0)
 232 mike  1.1             return -1;
 233                   if (_ParseUint32(p + 10, 2, &mm) != 0)
 234                       return -1;
 235                   if (_ParseUint32(p + 12, 2, &ss) != 0)
 236                       return -1;
 237                   if (p[14] != '.')
 238                       return -1;
 239                   if (_ParseUint32(p + 15, 6, &mmmmmm) != 0)
 240                       return -1;
 241                   if (p[22] != '0' || p[23] != '0' || p[24] != '0')
 242                       return -1;
 243           
 244                   /* Set the fields */
 245                   result->u.interval.days = dddddddd;
 246                   result->u.interval.hours = hh;
 247                   result->u.interval.minutes = mm;
 248                   result->u.interval.seconds = ss;
 249                   result->u.interval.microseconds = mmmmmm;
 250                   result->isTimestamp = 0;
 251               }
 252               else
 253 mike  1.1     {
 254                   /* YYYYMMDDHHMMSS.MMMMMMSUTC */
 255                   MI_Uint32 yyyy;
 256                   MI_Uint32 MM;
 257                   MI_Uint32 dd;
 258                   MI_Uint32 hh;
 259                   MI_Uint32 mm;
 260                   MI_Uint32 ss;
 261                   MI_Uint32 mmmmmm;
 262                   MI_Uint32 s;
 263                   MI_Uint32 utc;
 264           
 265                   if (_ParseUint32(p, 4, &yyyy) != 0)
 266                       return -1;
 267                   if (_ParseUint32(p + 4, 2, &MM) != 0)
 268                       return -1;
 269                   if (_ParseUint32(p + 6, 2, &dd) != 0)
 270                       return -1;
 271                   if (_ParseUint32(p + 8, 2, &hh) != 0)
 272                       return -1;
 273                   if (_ParseUint32(p + 10, 2, &mm) != 0)
 274 mike  1.1             return -1;
 275                   if (_ParseUint32(p + 12, 2, &ss) != 0)
 276                       return -1;
 277                   if (p[14] != '.')
 278                       return -1;
 279                   if (_ParseUint32(p + 15, 6, &mmmmmm) != 0)
 280                       return -1;
 281                   s = p[21];
 282                   if (s != '-' && s != '+')
 283                       return -1;
 284                   if (_ParseUint32(p + 22, 3, &utc) != 0)
 285                       return -1;
 286           
 287                   /* Set the result */
 288                   result->u.timestamp.year = yyyy;
 289                   result->u.timestamp.month = MM;
 290                   result->u.timestamp.day = dd;
 291                   result->u.timestamp.hour = hh;
 292                   result->u.timestamp.minute = mm;
 293                   result->u.timestamp.second = ss;
 294                   result->u.timestamp.microseconds = mmmmmm;
 295 mike  1.1 
 296                   if (s == '-')
 297                       result->u.timestamp.utc = -((MI_Sint16)utc);
 298                   else
 299                       result->u.timestamp.utc = (MI_Uint16)utc;
 300           
 301                   result->isTimestamp = 1;
 302               }
 303           
 304               return 0;
 305           }
 306           
 307           static void _indent(size_t n, FILE* file)
 308           {
 309               size_t i;
 310           
 311               for (i = 0; i < n; i++)
 312                   fprintf(file,"    ");
 313           }
 314           
 315           static int _CheckRange(MI_Sint64 x, MI_Type type)
 316 mike  1.1 {
 317               static const MI_Sint64 _UINT8_MIN = 0;
 318               static const MI_Sint64 _UINT8_MAX = 255;
 319               static const MI_Sint64 _SINT8_MIN = -128;
 320               static const MI_Sint64 _SINT8_MAX = 127;
 321               static const MI_Sint64 _SINT16_MIN = -32768;
 322               static const MI_Sint64 _SINT16_MAX = 32767;
 323               static const MI_Sint64 _UINT16_MIN = 0;
 324               static const MI_Sint64 _UINT16_MAX = 65535;
 325               static const MI_Sint64 _SINT32_MIN = -2147483647-1;
 326               static const MI_Sint64 _SINT32_MAX = 2147483647;
 327               static const MI_Sint64 _UINT32_MIN = 0;
 328               static const MI_Sint64 _UINT32_MAX = 4294967295U;
 329               /* ATTN: commented out until 
 330               static const MI_Sint64 _SINT64_MIN = -MI_LL(9223372036854775807)- MI_LL(1);
 331               static const MI_Sint64 _SINT64_MAX = MI_LL(9223372036854775807);
 332               static const MI_Sint64 _UINT64_MIN = 0;
 333               static const MI_Sint64 _UINT64_MAX = MI_ULL(9223372036854775807);
 334               */
 335           
 336               switch (type)
 337 mike  1.1     {
 338                   case MI_UINT8:
 339                   {
 340                       if (x < _UINT8_MIN || x > _UINT8_MAX)
 341                           goto error;
 342                       break;
 343                   }
 344                   case MI_SINT8:
 345                   {
 346                       if (x < _SINT8_MIN || x > _SINT8_MAX)
 347                           goto error;
 348                       break;
 349                   }
 350                   case MI_UINT16:
 351                   {
 352                       if (x < _UINT16_MIN || x > _UINT16_MAX)
 353                           goto error;
 354                       break;
 355                   }
 356                   case MI_SINT16:
 357                   {
 358 mike  1.1             if (x < _SINT16_MIN || x > _SINT16_MAX)
 359                           goto error;
 360                       break;
 361                   }
 362                   case MI_UINT32:
 363                   {
 364                       if (x < _UINT32_MIN || x > _UINT32_MAX)
 365                           goto error;
 366                       break;
 367                   }
 368                   case MI_SINT32:
 369                   {
 370                       if (x < _SINT32_MIN || x > _SINT32_MAX)
 371                           goto error;
 372                       break;
 373                   }
 374                   case MI_UINT64:
 375                   case MI_SINT64:
 376                       /* since 'x' is sint64 type, it's impossible to validate 64 bit types for ranges */
 377                       break;
 378           
 379 mike  1.1         default:
 380                       goto unexpected;
 381               }
 382           
 383               return 0;
 384           
 385           error:
 386               yyerrorf(ID_INITIALIZER_OUT_OF_RANGE, 
 387                   "initializer out of range: " SINT64_FMT, x);
 388               return -1;
 389           
 390           unexpected:
 391               yyerrorf(ID_INTERNAL_ERROR, "internal error: %s(%u)", __FILE__, __LINE__);
 392               return -1;
 393           }
 394           
 395           /*
 396           **==============================================================================
 397           **
 398           ** Public definitions
 399           **
 400 mike  1.1 **==============================================================================
 401           */
 402           
 403           void yyerrorf(int id, const char *format, ...)
 404           {
 405           #if defined(_MSC_VER)
 406               wchar_t* wformat = LookupString(id);
 407               if (wformat)
 408               {
 409                   wchar_t buf[1024];
 410                   int n;
 411                   va_list ap;
 412           	memset(&ap, 0, sizeof(ap));
 413           
 414                   if (state.path)
 415                   {
 416                       n = _snwprintf_s(buf, MI_COUNT(buf), _TRUNCATE, 
 417                           L"%S(%u): ", state.path, state.line);
 418                   }
 419                   else
 420                       n = 0;
 421 mike  1.1 
 422                   va_start(ap, format);
 423                   _vsnwprintf_s(buf + n, MI_COUNT(buf) - n, _TRUNCATE, wformat, ap);
 424                   va_end(ap);
 425           
 426                   if (state.errorCallback)
 427                       (*state.errorCallback)(NULL, buf, state.errorCallbackData);
 428               }
 429               else
 430           #endif
 431               {
 432                   char buf[1024];
 433                   int n;
 434                   va_list ap;
 435           	memset(&ap, 0, sizeof(ap));
 436           
 437                   MI_UNUSED(id);
 438           
 439                   if (state.path)
 440                       n = Snprintf(buf, sizeof(buf), "%s(%u): ", state.path, 
 441                           state.line);
 442 mike  1.1         else
 443                       n = 0;
 444           
 445                   va_start(ap, format);
 446                   Vsnprintf(buf + n, sizeof(buf) - n, format, ap);
 447                   va_end(ap);
 448           
 449                   PtrArray_Append(&state.errors, MOF_Strdup(&state.heap, buf));
 450           
 451                   if (state.errorCallback)
 452                       (*state.errorCallback)(buf, NULL, state.errorCallbackData);
 453               }
 454           }
 455           
 456           void yyerror(const char* msg)
 457           {
 458               /* There is no way to inject a localization string identifier before
 459                * calling this function (it is called from generated code). So instead,
 460                * we map the set of known strings to identifiers below.
 461                */
 462               if (strcmp(msg, "syntax error") == 0)
 463 mike  1.1     {
 464                   yyerrorf(ID_SYNTAX_ERROR, "%s", msg);
 465               }
 466               else if (strcmp(msg, "yacc stack overflow") == 0)
 467               {
 468                   yyerrorf(ID_PARSER_STACK_OVERFLOW, "%s", msg);
 469               }
 470               else
 471               {
 472                   yyerrorf(ID_INTERNAL_ERROR, "%s", msg);
 473               }
 474           }
 475           
 476           void yywarnf(int id, const char *format, ...)
 477           {
 478           #if defined(_MSC_VER)
 479               wchar_t* wformat = LookupString(id);
 480               if (wformat)
 481               {
 482                   wchar_t buf[1024];
 483                   int n;
 484 mike  1.1         va_list ap;
 485           
 486                   n = _snwprintf_s(buf, MI_COUNT(buf), _TRUNCATE, L"%S(%u): ", 
 487                       state.path, state.line);
 488                   va_start(ap, format);
 489                   _vsnwprintf_s(buf + n, MI_COUNT(buf) - n, _TRUNCATE, wformat, ap);
 490                   va_end(ap);
 491           
 492                   if (state.warningCallback)
 493                       (*state.warningCallback)(NULL, buf, state.warningCallbackData);
 494               }
 495               else
 496           #endif
 497               {
 498                   char buf[1024];
 499                   int n;
 500                   va_list ap;
 501           	memset(&ap, 0, sizeof(ap));
 502           
 503                   MI_UNUSED(id);
 504           
 505 mike  1.1         n = Snprintf(buf, sizeof(buf), "%s(%u): ", state.path, 
 506                       state.line);
 507                   va_start(ap, format);
 508                   Vsnprintf(buf + n, sizeof(buf) - n, format, ap);
 509                   va_end(ap);
 510           
 511                   if (state.warningCallback)
 512                       (*state.warningCallback)(buf, NULL, state.warningCallbackData);
 513           
 514                   PtrArray_Append(&state.warnings, MOF_Strdup(&state.heap, buf));
 515               }
 516           }
 517           
 518           static int _PromoteValue(
 519               MI_Uint32 sourceType,
 520               MI_Uint32 destType,
 521               void** value)
 522           {
 523               MI_Uint32 i;
 524           
 525               /* Nothing to do if value is null */
 526 mike  1.1     if (*value == NULL)
 527                   return 0;
 528           
 529               /* Convert from sourceType to destType */
 530               switch (sourceType)
 531               {
 532                   case MI_BOOLEAN:
 533                   {
 534                       if (destType != sourceType)
 535                       {
 536                           return -1;
 537                       }
 538           
 539                       return 0;
 540                   }
 541                   case MI_SINT64:
 542                   {
 543                       const MI_Sint64* p = *((const MI_Sint64**)value);
 544           
 545                       switch (destType)
 546                       {
 547 mike  1.1                 case MI_UINT8:
 548                           {
 549                               MI_Uint8* q = MALLOC_T(MI_Uint8, 1);
 550                               MI_Sint64 x = *p;
 551           
 552                               if (_CheckRange(x, MI_UINT8) != 0)
 553                                   return -1;
 554           
 555                               *q = (MI_Uint8)x;
 556                               *value = q; 
 557                               return 0;
 558                           }
 559                           case MI_SINT8:
 560                           {
 561                               MI_Sint8* q = MALLOC_T(MI_Sint8, 1);
 562                               MI_Sint64 x = *p;
 563           
 564                               if (_CheckRange(x, MI_SINT8) != 0)
 565                                   return -1;
 566           
 567                               *q = (MI_Sint8)x;
 568 mike  1.1                     *value = q; 
 569                               return 0;
 570                           }
 571                           case MI_UINT16:
 572                           {
 573                               MI_Uint16* q = MALLOC_T(MI_Uint16, 1);
 574                               MI_Sint64 x = *p;
 575           
 576                               if (_CheckRange(x, MI_UINT16) != 0)
 577                                   return -1;
 578           
 579                               *q = (MI_Uint16)x;
 580                               *value = q; 
 581                               return 0;
 582                           }
 583                           case MI_SINT16:
 584                           {
 585                               MI_Sint16* q = MALLOC_T(MI_Sint16, 1);
 586                               MI_Sint64 x = *p;
 587           
 588                               if (_CheckRange(x, MI_SINT16) != 0)
 589 mike  1.1                         return -1;
 590           
 591                               *q = (MI_Sint16)x;
 592                               *value = q; 
 593                               return 0;
 594                           }
 595                           case MI_UINT32:
 596                           {
 597                               MI_Uint32* q = MALLOC_T(MI_Uint32, 1);
 598                               MI_Sint64 x = *p;
 599           
 600                               if (_CheckRange(x, MI_UINT32) != 0)
 601                                   return -1;
 602           
 603                               *q = (MI_Uint32)x;
 604                               *value = q; 
 605                               return 0;
 606                           }
 607                           case MI_SINT32:
 608                           {
 609                               MI_Sint32* q = MALLOC_T(MI_Sint32, 1);
 610 mike  1.1                     MI_Sint64 x = *p;
 611           
 612                               if (_CheckRange(x, MI_SINT32) != 0)
 613                                   return -1;
 614           
 615                               *q = (MI_Sint32)x;
 616                               *value = q; 
 617                               return 0;
 618                           }
 619                           case MI_UINT64:
 620                           {
 621                               MI_Uint64* q = MALLOC_T(MI_Uint64, 1);
 622                               MI_Sint64 x = *p;
 623           
 624                               if (_CheckRange(x, MI_UINT64) != 0)
 625                                   return -1;
 626           
 627                               *q = (MI_Uint64)x;
 628                               *value = q; 
 629                               return 0;
 630                           }
 631 mike  1.1                 case MI_SINT64:
 632                           {
 633                               return 0;
 634                           }
 635                           default:
 636                           {
 637                               return -1;
 638                           }
 639                       }
 640                   }
 641                   case MI_REAL64:
 642                   {
 643                       const MI_Real64* p = *((const MI_Real64**)value);
 644           
 645                       switch (destType)
 646                       {
 647                           case MI_REAL32:
 648                           {
 649                               MI_Real32* q = MALLOC_T(MI_Real32, 1);
 650                               *q = (MI_Real32)*p;
 651                               *value = q; 
 652 mike  1.1                     return 0;
 653                           }
 654                           case MI_REAL64:
 655                           {
 656                               return 0;
 657                           }
 658                           default:
 659                           {
 660                               return -1;
 661                           }
 662                       }
 663                   }
 664                   case MI_CHAR16:
 665                   {
 666                       if (destType != sourceType)
 667                           return -1;
 668           
 669                       return 0;
 670                   }
 671                   case MI_STRING:
 672                   {
 673 mike  1.1             const char* p = *((const char**)value);
 674           
 675                       switch (destType)
 676                       {
 677                           case MI_STRING:
 678                           {
 679                               return 0;
 680                           }
 681                           case MI_DATETIME:
 682                           {
 683                               MI_Datetime* q = MALLOC_T(MI_Datetime, 1);
 684           
 685                               if (_StrToDatetime(p, q) != 0)
 686                                   return -1;
 687           
 688                               *value = q; 
 689                               return 0;
 690                           }
 691                           default:
 692                           {
 693                               return -1;
 694 mike  1.1                 }
 695                       }
 696                   }
 697                   case MI_BOOLEANA:
 698                   {
 699                       if (destType != sourceType)
 700                           return -1;
 701           
 702                       return 0;
 703                   }
 704                   case MI_SINT64A:
 705                   {
 706                       const MI_Sint64A* p = *((const MI_Sint64A**)value);
 707           
 708                       switch (destType)
 709                       {
 710                           case MI_UINT8A:
 711                           {
 712                               MI_Uint8A* q;
 713                               NEW_ARRAY_T(q, MI_Uint8, p->size);
 714           
 715 mike  1.1                     for (i = 0; i < p->size; i++)
 716                               {
 717                                   MI_Sint64 x = p->data[i];
 718           
 719                                   if (_CheckRange(x, MI_UINT8) != 0)
 720                                       return -1;
 721           
 722                                   q->data[i] = (MI_Uint8)x;
 723                               }
 724           
 725                               *value = q;
 726                               return 0;
 727                           }
 728                           case MI_SINT8A:
 729                           {
 730                               MI_Sint8A* q;
 731                               NEW_ARRAY_T(q, MI_Sint8, p->size);
 732           
 733                               for (i = 0; i < p->size; i++)
 734                               {
 735                                   MI_Sint64 x = p->data[i];
 736 mike  1.1 
 737                                   if (_CheckRange(x, MI_SINT8) != 0)
 738                                       return -1;
 739           
 740                                   q->data[i] = (MI_Sint8)x;
 741                               }
 742           
 743                               *value = q;
 744                               return 0;
 745                           }
 746                           case MI_UINT16A:
 747                           {
 748                               MI_Uint16A* q;
 749                               NEW_ARRAY_T(q, MI_Uint16, p->size);
 750           
 751                               for (i = 0; i < p->size; i++)
 752                               {
 753                                   MI_Sint64 x = p->data[i];
 754           
 755                                   if (_CheckRange(x, MI_UINT16) != 0)
 756                                       return -1;
 757 mike  1.1 
 758                                   q->data[i] = (MI_Uint16)x;
 759                               }
 760           
 761                               *value = q;
 762                               return 0;
 763                           }
 764                           case MI_SINT16A:
 765                           {
 766                               MI_Sint16A* q;
 767                               NEW_ARRAY_T(q, MI_Sint16, p->size);
 768           
 769                               for (i = 0; i < p->size; i++)
 770                               {
 771                                   MI_Sint64 x = p->data[i];
 772           
 773                                   if (_CheckRange(x, MI_SINT16) != 0)
 774                                       return -1;
 775           
 776                                   q->data[i] = (MI_Sint16)x;
 777                               }
 778 mike  1.1 
 779                               *value = q;
 780                               return 0;
 781                           }
 782                           case MI_UINT32A:
 783                           {
 784                               MI_Uint32A* q;
 785                               NEW_ARRAY_T(q, MI_Uint32, p->size);
 786           
 787                               for (i = 0; i < p->size; i++)
 788                               {
 789                                   MI_Sint64 x = p->data[i];
 790           
 791                                   if (_CheckRange(x, MI_UINT32) != 0)
 792                                       return -1;
 793           
 794                                   q->data[i] = (MI_Uint32)x;
 795                               }
 796           
 797                               *value = q;
 798                               return 0;
 799 mike  1.1                 }
 800                           case MI_SINT32A:
 801                           {
 802                               MI_Sint32A* q;
 803                               NEW_ARRAY_T(q, MI_Sint32, p->size);
 804           
 805                               for (i = 0; i < p->size; i++)
 806                               {
 807                                   MI_Sint64 x = p->data[i];
 808           
 809                                   if (_CheckRange(x, MI_SINT32) != 0)
 810                                       return -1;
 811           
 812                                   q->data[i] = (MI_Sint32)x;
 813                               }
 814           
 815                               *value = q;
 816                               return 0;
 817                           }
 818                           case MI_UINT64A:
 819                           {
 820 mike  1.1                     MI_Uint64A* q;
 821                               NEW_ARRAY_T(q, MI_Uint64, p->size);
 822           
 823                               for (i = 0; i < p->size; i++)
 824                               {
 825                                   MI_Sint64 x = p->data[i];
 826           
 827                                   if (_CheckRange(x, MI_UINT64) != 0)
 828                                       return -1;
 829           
 830                                   q->data[i] = (MI_Uint64)x;
 831                               }
 832           
 833                               *value = q;
 834                               return 0;
 835                           }
 836                           case MI_SINT64A:
 837                           {
 838                               return 0;
 839                           }
 840                           default:
 841 mike  1.1                     return -1;
 842                       }
 843                   }
 844                   case MI_REAL64A:
 845                   {
 846                       const MI_Real64A* p = *((const MI_Real64A**)value);
 847           
 848                       switch (destType)
 849                       {
 850                           case MI_REAL64A:
 851                           {
 852                               return 0;
 853                           }
 854                           case MI_REAL32A:
 855                           {
 856                               MI_Real32A* q;
 857                               NEW_ARRAY_T(q, MI_Real32, p->size);
 858           
 859                               for (i = 0; i < p->size; i++)
 860                               {
 861                                   q->data[i] = (MI_Real32)p->data[i];
 862 mike  1.1                     }
 863           
 864                               *value = q; 
 865                               return 0;
 866                           }
 867                           default:
 868                               return -1;
 869                       }
 870                   }
 871                   case MI_CHAR16A:
 872                   {
 873                       if (destType != sourceType)
 874                           return -1;
 875           
 876                       return 0;
 877                   }
 878                   case MI_STRINGA:
 879                   {
 880                       const MI_StringA* p = *((const MI_StringA**)value);
 881           
 882                       switch (destType)
 883 mike  1.1             {
 884                           case MI_STRINGA:
 885                           {
 886                               return 0;
 887                           }
 888                           case MI_DATETIMEA:
 889                           {
 890                               MI_DatetimeA* q;
 891                               NEW_ARRAY_T(q, MI_Datetime, p->size);
 892           
 893                               for (i = 0; i < p->size; i++)
 894                               {
 895                                   if (_StrToDatetime(p->data[i], &q->data[i]) != 0)
 896                                       return -1;
 897                               }
 898           
 899                               *value = q; 
 900                               return 0;
 901                           }
 902                           default:
 903                               return -1;
 904 mike  1.1             }
 905                   }
 906                   default:
 907                       break;
 908               }
 909           
 910               return -1;
 911           }
 912           
 913           int InitializerToValue(
 914               MOF_Initializer* self, 
 915               MI_Uint32 /*MI_Type*/ type,
 916               void** value)
 917           {
 918               /* ATTN: this function could check integer truncation and sign errors */
 919               /* ATTN: handle case where MI_Char is wchar_t */
 920               size_t i;
 921           
 922               /* Check arguments */
 923               if (!self || !value)
 924                   return -1;
 925 mike  1.1 
 926               *value = NULL;
 927           
 928               /* Verify that there is at least one element */
 929               if (self->size == 0)
 930                   return -1;
 931           
 932               /* Verify that array is homogeneous (all elements have same type) */
 933               for (i = 1; i < self->size; i++)
 934               {
 935                   if (self->data[0].type != self->data[i].type)
 936                       return -1;
 937               }
 938           
 939               /* Verify that scalars have exactly 1 initializer */
 940               if (!self->isArray && self->size != 1)
 941                   return -1;
 942           
 943               /* Convert to a Statik value */
 944               if (self->isArray)
 945               {
 946 mike  1.1         switch (self->data[0].type)
 947                   {
 948                       case TOK_INTEGER_VALUE:
 949                       {
 950                           switch (type)
 951                           {
 952                               case MI_UINT8A:
 953                               {
 954                                   MI_Uint8A* p;
 955                                   NEW_ARRAY_T(p, MI_Uint8, self->size);
 956           
 957                                   for (i = 0; i < self->size; i++)
 958                                   {
 959                                       MI_Sint64 x = self->data[i].value.integer;
 960                                       if (0 != _CheckRange(x, MI_UINT8))
 961                                           return -1;
 962           
 963                                       p->data[i] = (MI_Uint8)x;
 964                                   }
 965           
 966                                   *value = p; 
 967 mike  1.1                         return 0;
 968                               }
 969                               case MI_SINT8A:
 970                               {
 971                                   MI_Sint8A* p;
 972                                   NEW_ARRAY_T(p, MI_Sint8, self->size);
 973           
 974                                   for (i = 0; i < self->size; i++)
 975                                   {
 976                                       MI_Sint64 x = self->data[i].value.integer;
 977                                       if (0 != _CheckRange(x, MI_SINT8))
 978                                           return -1;
 979           
 980                                       p->data[i] = (MI_Sint8)x;
 981                                   }
 982           
 983                                   *value = p; 
 984                                   return 0;
 985                               }
 986                               case MI_UINT16A:
 987                               {
 988 mike  1.1                         MI_Uint16A* p;
 989                                   NEW_ARRAY_T(p, MI_Uint16, self->size);
 990           
 991                                   for (i = 0; i < self->size; i++)
 992                                   {
 993                                       MI_Sint64 x = self->data[i].value.integer;
 994                                       if (0 != _CheckRange(x, MI_UINT16))
 995                                           return -1;
 996           
 997                                       p->data[i] = (MI_Uint16)x;
 998                                   }
 999           
1000                                   *value = p; 
1001                                   return 0;
1002                               }
1003                               case MI_SINT16A:
1004                               {
1005                                   MI_Sint16A* p;
1006                                   NEW_ARRAY_T(p, MI_Sint16, self->size);
1007           
1008                                   for (i = 0; i < self->size; i++)
1009 mike  1.1                         {
1010                                       MI_Sint64 x = self->data[i].value.integer;
1011                                       if (0 != _CheckRange(x, MI_SINT16))
1012                                           return -1;
1013           
1014                                       p->data[i] = (MI_Sint16)x;
1015                                   }
1016           
1017                                   *value = p; 
1018                                   return 0;
1019                               }
1020                               case MI_UINT32A:
1021                               {
1022                                   MI_Uint32A* p;
1023                                   NEW_ARRAY_T(p, MI_Uint32, self->size);
1024           
1025                                   for (i = 0; i < self->size; i++)
1026                                   {
1027                                       MI_Sint64 x = self->data[i].value.integer;
1028                                       if (0 != _CheckRange(x, MI_UINT32))
1029                                           return -1;
1030 mike  1.1 
1031                                       p->data[i] = (MI_Uint32)x;
1032                                   }
1033           
1034                                   *value = p; 
1035                                   return 0;
1036                               }
1037                               case MI_SINT32A:
1038                               {
1039                                   MI_Sint32A* p;
1040                                   NEW_ARRAY_T(p, MI_Sint32, self->size);
1041           
1042                                   for (i = 0; i < self->size; i++)
1043                                   {
1044                                       MI_Sint64 x = self->data[i].value.integer;
1045                                       if (0 != _CheckRange(x, MI_SINT32))
1046                                           return -1;
1047           
1048                                       p->data[i] = (MI_Sint32)x;
1049                                   }
1050           
1051 mike  1.1                         *value = p; 
1052                                   return 0;
1053                               }
1054                               case MI_UINT64A:
1055                               {
1056                                   MI_Uint64A* p;
1057                                   NEW_ARRAY_T(p, MI_Uint64, self->size);
1058           
1059                                   for (i = 0; i < self->size; i++)
1060                                   {
1061                                       MI_Sint64 x = self->data[i].value.integer;
1062                                       if (0 != _CheckRange(x, MI_UINT64))
1063                                           return -1;
1064           
1065                                       p->data[i] = (MI_Uint64)x;
1066                                   }
1067           
1068                                   *value = p; 
1069                                   return 0;
1070                               }
1071                               case MI_SINT64A:
1072 mike  1.1                     {
1073                                   MI_Sint64A* p;
1074                                   NEW_ARRAY_T(p, MI_Sint64, self->size);
1075           
1076                                   for (i = 0; i < self->size; i++)
1077                                   {
1078                                       MI_Sint64 x = self->data[i].value.integer;
1079                                       if (0 != _CheckRange(x, MI_SINT64))
1080                                           return -1;
1081           
1082                                       p->data[i] = (MI_Sint64)x;
1083                                   }
1084           
1085                                   *value = p; 
1086                                   return 0;
1087                               }
1088                               default:
1089                                   return -1;
1090                           }
1091                       }
1092                       case TOK_REAL_VALUE:
1093 mike  1.1             {
1094                           switch (type)
1095                           {
1096                               case MI_REAL32A:
1097                               {
1098                                   MI_Real32A* p;
1099                                   NEW_ARRAY_T(p, MI_Real32, self->size);
1100           
1101                                   for (i = 0; i < self->size; i++)
1102                                   {
1103                                       p->data[i] = (MI_Real32)
1104                                           self->data[i].value.real;
1105                                   }
1106           
1107                                   *value = p; 
1108                                   return 0;
1109                               }
1110                               case MI_REAL64A:
1111                               {
1112                                   MI_Real64A* p;
1113                                   NEW_ARRAY_T(p, MI_Real64, self->size);
1114 mike  1.1 
1115                                   for (i = 0; i < self->size; i++)
1116                                   {
1117                                       p->data[i] = (MI_Real64)
1118                                           self->data[i].value.real;
1119                                   }
1120           
1121                                   *value = p; 
1122                                   return 0;
1123                               }
1124                               default:
1125                                   return -1;
1126                           }
1127                           break;
1128                       }
1129                       case TOK_CHAR_VALUE:
1130                       {
1131                           switch (type)
1132                           {
1133                               case MI_CHAR16A:
1134                               {
1135 mike  1.1                         MI_Char16A* p;
1136                                   NEW_ARRAY_T(p, MI_Char16, self->size);
1137           
1138                                   for (i = 0; i < self->size; i++)
1139                                   {
1140                                       p->data[i] = (MI_Char16)
1141                                           self->data[i].value.character;
1142                                   }
1143           
1144                                   *value = p; 
1145                                   return 0;
1146                               }
1147                               default:
1148                                   return -1;
1149                           }
1150                           break;
1151                       }
1152                       case TOK_STRING_VALUE:
1153                       {
1154                           switch (type)
1155                           {
1156 mike  1.1                     case MI_STRINGA:
1157                               {
1158                                   MI_StringA* p;
1159                                   NEW_ARRAY_T(p, MI_String, self->size);
1160           
1161                                   for (i = 0; i < self->size; i++)
1162                                   {
1163                                       p->data[i] = self->data[i].value.string;
1164                                       self->data[i].value.string = NULL;
1165                                   }
1166           
1167                                   *value = p; 
1168                                   return 0;
1169                               }
1170                               case MI_DATETIMEA:
1171                               {
1172                                   MI_DatetimeA* p;
1173                                   NEW_ARRAY_T(p, MI_Datetime, self->size);
1174           
1175                                   for (i = 0; i < self->size; i++)
1176                                   {
1177 mike  1.1                             if (_StrToDatetime(self->data[i].value.string, 
1178                                           &p->data[i]) != 0)
1179                                       {
1180                                           MOF_Free(&state.heap, p);
1181                                           return -1;
1182                                       }
1183           
1184                                       MOF_Free(&state.heap, self->data[i].value.string);
1185                                       self->data[i].value.string = NULL;
1186                                   }
1187           
1188                                   *value = p; 
1189                                   return 0;
1190                               }
1191                               default:
1192                                   return -1;
1193                           }
1194                           break;
1195                       }
1196                       case TOK_BOOLEAN_VALUE:
1197                       {
1198 mike  1.1                 switch (type)
1199                           {
1200                               case MI_BOOLEANA:
1201                               {
1202                                   MI_BooleanA* p;
1203                                   NEW_ARRAY_T(p, MI_Boolean, self->size);
1204           
1205                                   for (i = 0; i < self->size; i++)
1206                                   {
1207                                       p->data[i] = (MI_Boolean)
1208                                           self->data[i].value.boolean;
1209                                   }
1210           
1211                                   *value = p; 
1212                                   return 0;
1213                               }
1214                               default:
1215                                   return -1;
1216                           }
1217                       }
1218                       case TOK_NULL:
1219 mike  1.1             {
1220                           *value = NULL;
1221                           return 0;
1222                       }
1223                       default:
1224                           return -1;
1225                   }
1226               }
1227               else
1228               {
1229                   switch (self->data->type)
1230                   {
1231                       case TOK_INTEGER_VALUE:
1232                       {
1233                           switch (type)
1234                           {
1235                               case MI_UINT8:
1236                               {
1237                                   MI_Uint8* p = MALLOC_T(MI_Uint8, 1);
1238                                   MI_Sint64 x = self->data->value.integer;
1239                                   if (0 != _CheckRange(x, MI_UINT8))
1240 mike  1.1                             return -1;
1241           
1242                                   *p = (MI_Uint8)x;
1243                                   *value = p; 
1244                                   return 0;
1245                               }
1246                               case MI_SINT8:
1247                               {
1248                                   MI_Sint8* p = MALLOC_T(MI_Sint8, 1);
1249                                   MI_Sint64 x = self->data->value.integer;
1250                                   if (0 != _CheckRange(x, MI_SINT8))
1251                                       return -1;
1252           
1253                                   *p = (MI_Sint8)x;
1254                                   *value = p; 
1255                                   return 0;
1256                               }
1257                               case MI_UINT16:
1258                               {
1259                                   MI_Uint16* p = MALLOC_T(MI_Uint16, 1);
1260                                   MI_Sint64 x = self->data->value.integer;
1261 mike  1.1                         if (0 != _CheckRange(x, MI_UINT16))
1262                                       return -1;
1263           
1264                                   *p = (MI_Uint16)x;
1265                                   *value = p; 
1266                                   return 0;
1267                               }
1268                               case MI_SINT16:
1269                               {
1270                                   MI_Sint16* p = MALLOC_T(MI_Sint16, 1);
1271                                   MI_Sint64 x = self->data->value.integer;
1272                                   if (0 != _CheckRange(x, MI_SINT16))
1273                                       return -1;
1274           
1275                                   *p = (MI_Sint16)x;
1276                                   *value = p; 
1277                                   return 0;
1278                               }
1279                               case MI_UINT32:
1280                               {
1281                                   MI_Uint32* p = MALLOC_T(MI_Uint32, 1);
1282 mike  1.1                         MI_Sint64 x = self->data->value.integer;
1283                                   if (0 != _CheckRange(x, MI_UINT32))
1284                                       return -1;
1285           
1286                                   *p = (MI_Uint32)x;
1287                                   *value = p; 
1288                                   return 0;
1289                               }
1290                               case MI_SINT32:
1291                               {
1292                                   MI_Sint32* p = MALLOC_T(MI_Sint32, 1);
1293                                   MI_Sint64 x = self->data->value.integer;
1294                                   if (0 != _CheckRange(x, MI_SINT32))
1295                                       return -1;
1296           
1297                                   *p = (MI_Sint32)x;
1298                                   *value = p; 
1299                                   return 0;
1300                               }
1301                               case MI_UINT64:
1302                               {
1303 mike  1.1                         MI_Uint64* p = MALLOC_T(MI_Uint64, 1);
1304                                   MI_Sint64 x = self->data->value.integer;
1305                                   if (0 != _CheckRange(x, MI_UINT64))
1306                                       return -1;
1307           
1308                                   *p = (MI_Uint64)x;
1309                                   *value = p; 
1310                                   return 0;
1311                               }
1312                               case MI_SINT64:
1313                               {
1314                                   MI_Sint64* p = MALLOC_T(MI_Sint64, 1);
1315                                   MI_Sint64 x = self->data->value.integer;
1316                                   if (0 != _CheckRange(x, MI_SINT64))
1317                                       return -1;
1318           
1319                                   *p = (MI_Sint64)x;
1320                                   *value = p; 
1321                                   return 0;
1322                               }
1323                               default:
1324 mike  1.1                         return -1;
1325                           }
1326                           break;
1327                       }
1328                       case TOK_REAL_VALUE:
1329                       {
1330                           switch (type)
1331                           {
1332                               case MI_REAL32:
1333                               {
1334                                   MI_Real32* p = MALLOC_T(MI_Real32, 1);
1335                                   *p = (MI_Real32)self->data->value.real;
1336                                   *value = p; 
1337                                   return 0;
1338                               }
1339                               case MI_REAL64:
1340                               {
1341                                   MI_Real64* p = MALLOC_T(MI_Real64, 1);
1342                                   *p = (MI_Real64)self->data->value.real;
1343                                   *value = p; 
1344                                   return 0;
1345 mike  1.1                     }
1346                               default:
1347                                   return -1;
1348                           }
1349                           break;
1350                       }
1351                       case TOK_CHAR_VALUE:
1352                       {
1353                           switch (type)
1354                           {
1355                               case MI_CHAR16:
1356                               {
1357                                   MI_Char16* p = MALLOC_T(MI_Char16, 1);
1358                                   *p = (MI_Char16)self->data->value.character;
1359                                   *value = p; 
1360                                   return 0;
1361                               }
1362                               default:
1363                                   return -1;
1364                           }
1365                           break;
1366 mike  1.1             }
1367                       case TOK_STRING_VALUE:
1368                       {
1369                           switch (type)
1370                           {
1371                               case MI_STRING:
1372                               {
1373                                   char *p;
1374                                   p = self->data->value.string;
1375                                   self->data->value.string = NULL;
1376                                   *value = p; 
1377                                   return 0;
1378                               }
1379                               case MI_DATETIME:
1380                               {
1381                                   MI_Datetime *p = MALLOC_T(MI_Datetime, 1);
1382           
1383                                   if (_StrToDatetime(self->data->value.string, p) != 0)
1384                                   {
1385                                       MOF_Free(&state.heap, p);
1386                                       return -1;
1387 mike  1.1                         }
1388           
1389                                   MOF_Free(&state.heap, self->data->value.string);
1390                                   self->data->value.string = NULL;
1391                                   *value = p; 
1392                                   return 0;
1393                               }
1394                               default:
1395                                   return -1;
1396                           }
1397                           break;
1398                       }
1399                       case TOK_BOOLEAN_VALUE:
1400                       {
1401                           switch (type)
1402                           {
1403                               case MI_BOOLEAN:
1404                               {
1405                                   MI_Boolean* p = MALLOC_T(MI_Boolean, 1);
1406                                   *p = (MI_Boolean)self->data->value.boolean;
1407                                   *value = p; 
1408 mike  1.1                         return 0;
1409                               }
1410                               default:
1411                                   return -1;
1412                           }
1413                           break;
1414                       }
1415                       case TOK_NULL: {
1416                           *value = NULL;
1417                           return 0;
1418                       }
1419                       default:
1420                           return -1;
1421                   }
1422               }
1423           
1424               UNREACHABLE_RETURN( return 0; )
1425           }
1426           
1427           void ReleaseInitializer(
1428               MOF_Initializer* init)
1429 mike  1.1 {
1430               if (init)
1431               {
1432                   if (init->data)
1433                   {
1434                       size_t i;
1435           
1436                       for (i = 0; i < init->size; i++)
1437                       {
1438                           if (init->data[i].type == TOK_STRING_VALUE)
1439                               MOF_Free(&state.heap, init->data[i].value.string);
1440                       }
1441           
1442                       MOF_Free(&state.heap, init->data);
1443                   }
1444               }
1445           }
1446           
1447           static void _PrintFlags(MI_Uint32 flags, size_t level, FILE* file)
1448           {
1449               size_t i;
1450 mike  1.1 
1451               _indent(level, file);
1452               fprintf(file,"flags:");
1453           
1454               for (i = 0; i < _flagsSize; i++)
1455               {
1456                   if (_flags[i].flag & flags)
1457                       fprintf(file," %s", MI_GET_SAFE_PRINTF_STRING(_flags[i].name));
1458               }
1459           
1460               fprintf(file,"\n");
1461           }
1462           
1463           void MOF_PrintQualifierDecl(
1464               const MI_QualifierDecl* self, 
1465               FILE* file)
1466           {
1467               size_t level = 0;
1468           
1469               /* Header */
1470               _indent(level, file);
1471 mike  1.1     fprintf(file,"MI_QualifierDecl\n");
1472               _indent(level, file);
1473               fprintf(file,"{\n");
1474               level++;
1475           
1476               /* name  */
1477               _indent(level, file);
1478               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
1479           
1480               /* type */
1481               _indent(level, file);
1482               fprintf(file,"type: %s\n", _getTypeName(self->type));
1483           
1484               /* scope */
1485               {
1486                   _indent(level, file);
1487                   fprintf(file,"scope:");
1488           
1489                   if (self->flavor == MI_FLAG_ANY)
1490                       fprintf(file,"ANY\n");
1491                   else
1492 mike  1.1         {
1493                       if (self->scope & MI_FLAG_ASSOCIATION)
1494                           fprintf(file," ASSOCIATION");
1495                       if (self->scope & MI_FLAG_CLASS)
1496                           fprintf(file," CLASS");
1497                       if (self->scope & MI_FLAG_INDICATION)
1498                           fprintf(file," INDICATION");
1499                       if (self->scope & MI_FLAG_METHOD)
1500                           fprintf(file," METHOD");
1501                       if (self->scope & MI_FLAG_PARAMETER)
1502                           fprintf(file," PARAMETER");
1503                       if (self->scope & MI_FLAG_PROPERTY)
1504                           fprintf(file," PROPERTY");
1505                       if (self->scope & MI_FLAG_REFERENCE)
1506                           fprintf(file," REFERENCE");
1507           
1508                       fprintf(file,"\n");
1509                   }
1510               }
1511           
1512               /* subscript */
1513 mike  1.1 
1514               _indent(level, file);
1515               fprintf(file,"subscript: %u\n", self->subscript);
1516           
1517               /* flavor */
1518               {
1519                   _indent(level, file);
1520                   fprintf(file,"flavor:");
1521           
1522                   if (self->flavor & MI_FLAG_ENABLEOVERRIDE)
1523                       fprintf(file," ENABLEOVERRIDE");
1524                   if (self->flavor & MI_FLAG_DISABLEOVERRIDE)
1525                       fprintf(file," DISABLEOVERRIDE");
1526                   if (self->flavor & MI_FLAG_RESTRICTED)
1527                       fprintf(file," RESTRICTED");
1528                   if (self->flavor & MI_FLAG_TOSUBCLASS)
1529                       fprintf(file," TOSUBCLASS");
1530                   if (self->flavor & MI_FLAG_TRANSLATABLE)
1531                       fprintf(file," TRANSLATABLE");
1532           
1533                   fprintf(file,"\n");
1534 mike  1.1     }
1535           
1536               /* value */
1537               _indent(level, file);
1538               fprintf(file,"value: ");
1539               PrintValue(self->value, self->type, file);
1540               fprintf(file,"\n");
1541           
1542               level--;
1543               _indent(level, file);
1544               fprintf(file,"}\n");
1545           }
1546           
1547           static void _DatetimeToStr(const MI_Datetime* x, char buf[26])
1548           {
1549               if (x->isTimestamp)
1550               {
1551                   const MI_Char FMT[] =  "%04d%02d%02d%02d%02d%02d.%06d%c%03d";
1552                   MI_Sint32 utc = x->u.timestamp.utc;
1553                   Snprintf(buf, 26, FMT,
1554                       x->u.timestamp.year,
1555 mike  1.1             x->u.timestamp.month,
1556                       x->u.timestamp.day,
1557                       x->u.timestamp.hour,
1558                       x->u.timestamp.minute,
1559                       x->u.timestamp.second,
1560                       x->u.timestamp.microseconds,
1561                       utc < 0 ? '-' : '+',
1562                       utc < 0 ? -utc : utc);
1563               }
1564               else
1565               {
1566                   const MI_Char FMT[] = "%08u%02u%02u%02u.%06u:000";
1567                   Snprintf(buf, 26, FMT,
1568                       x->u.interval.days,
1569                       x->u.interval.hours,
1570                       x->u.interval.minutes,
1571                       x->u.interval.seconds,
1572                       x->u.interval.microseconds);
1573               }
1574           }
1575           
1576 mike  1.1 void PrintValue(const void* value, MI_Type type, FILE* file)
1577           {
1578               if (!value) 
1579               {
1580                   fprintf(file,"NULL");
1581                   return;
1582               }
1583               else 
1584               {
1585                   switch (type)
1586                   {
1587                       case MI_BOOLEAN:
1588                       {
1589                           const MI_Boolean* p = (const MI_Boolean*)value;
1590                           fprintf(file,"%s", *p ? "true" : "false");
1591                           break;
1592                       }
1593                       case MI_SINT8:
1594                       {
1595                           fprintf(file,"%d", *((const MI_Sint8*)value));
1596                           break;
1597 mike  1.1             }
1598                       case MI_UINT8:
1599                       {
1600                           fprintf(file,"%u", *((const MI_Uint8*)value));
1601                           break;
1602                       }
1603                       case MI_SINT16:
1604                       {
1605                           fprintf(file,"%d", *((const MI_Sint16*)value));
1606                           break;
1607                       }
1608                       case MI_UINT16:
1609                       {
1610                           fprintf(file,"%u", *((const MI_Uint16*)value));
1611                           break;
1612                       }
1613                       case MI_SINT32:
1614                       {
1615                           fprintf(file,"%d", *((const MI_Sint32*)value));
1616                           break;
1617                       }
1618 mike  1.1             case MI_UINT32:
1619                       {
1620                           fprintf(file,"%u", *((const MI_Uint32*)value));
1621                           break;
1622                       }
1623                       case MI_SINT64:
1624                       {
1625                           fprintf(file, SINT64_FMT, *((const MI_Sint64*)value));
1626                           break;
1627                       }
1628                       case MI_UINT64:
1629                       {
1630                           fprintf(file, UINT64_FMT, *((const MI_Uint64*)value));
1631                           break;
1632                       }
1633                       case MI_REAL32:
1634                       {
1635                           fprintf(file,"%g", *((const MI_Real32*)value));
1636                           break;
1637                       }
1638                       case MI_REAL64:
1639 mike  1.1             {
1640                           fprintf(file,"%g", *((const MI_Real64*)value));
1641                           break;
1642                       }
1643                       case MI_CHAR16:
1644                       {
1645                           fprintf(file,"%u", *((const MI_Char16*)value));
1646                           break;
1647                       }
1648                       case MI_DATETIME:
1649                       {
1650                           char buf[26];
1651                           _DatetimeToStr((const MI_Datetime*)value, buf);
1652                           fprintf(file, "%s", buf);
1653                           break;
1654                       }
1655                       case MI_STRING:
1656                       {
1657                           fprintf(file,"%s", MI_GET_SAFE_PRINTF_STRING(((const char*)value)));
1658                           break;
1659                       }
1660 mike  1.1             case MI_BOOLEANA:
1661                       case MI_SINT8A:
1662                       case MI_UINT8A:
1663                       case MI_SINT16A:
1664                       case MI_UINT16A:
1665                       case MI_SINT32A:
1666                       case MI_UINT32A:
1667                       case MI_SINT64A:
1668                       case MI_UINT64A:
1669                       case MI_REAL32A:
1670                       case MI_REAL64A:
1671                       case MI_CHAR16A:
1672                       case MI_DATETIMEA:
1673                       {
1674                           MI_BooleanA* arr = (MI_BooleanA*)value;
1675                           char* ptr = (char*)arr->data;
1676                           MI_Uint32 i;
1677           
1678                           fprintf(file,"{");
1679           
1680                           for (i = 0; i < arr->size; i++)
1681 mike  1.1                 {
1682                               MI_Type stype = type & ~MI_ARRAY_BIT;
1683                               PrintValue(ptr, stype, file);
1684           #ifdef _PREFAST_
1685               #pragma prefast (push)
1686               #pragma prefast (disable: 26014)
1687           #endif          
1688                               ptr += _typeSizes[stype];
1689           #ifdef _PREFAST_
1690                   #pragma prefast (pop)
1691           #endif          
1692           
1693                               if (i + 1 != arr->size)
1694                                   fprintf(file,", ");
1695                           }
1696                           fprintf(file,"}");
1697                           break;
1698                       }
1699                       case MI_STRINGA:
1700                       {
1701                           MI_StringA* arr = (MI_StringA*)value;
1702 mike  1.1                 MI_Uint32 i;
1703           
1704                           fprintf(file,"{");
1705           
1706                           for (i = 0; i < arr->size; i++)
1707                           {
1708                               fprintf(file,"%s", MI_GET_SAFE_PRINTF_STRING(arr->data[i]));
1709           
1710                               if (i + 1 != arr->size)
1711                                   fprintf(file,", ");
1712                           }
1713           
1714                           fprintf(file,"}");
1715                           break;
1716                       }
1717                       default:
1718                           break;
1719                   }
1720               }
1721           }
1722           
1723 mike  1.1 const MI_QualifierDecl* FindQualifierDeclaration(const char* name)
1724           {
1725               size_t i;
1726           
1727               for (i = 0; i < state.qualifierDecls.size; i++)
1728               {
1729                   if (Strcasecmp(state.qualifierDecls.data[i]->name, name) == 0)
1730                       return state.qualifierDecls.data[i];
1731               }
1732           
1733               /* Not found */
1734               return NULL;
1735           }
1736           
1737           int AddQualifierDeclaration(MI_QualifierDecl* qd)
1738           {
1739               if (FindQualifierDeclaration(qd->name))
1740               {
1741                   yyerrorf(ID_QUALIFIER_ALREADY_DECLARED, 
1742                       "qualifier already declared: \"%s\"", 
1743                       MI_GET_SAFE_PRINTF_STRING(qd->name));
1744 mike  1.1         return -1;
1745               }
1746           
1747               /* Validate some qualifiers */
1748               if (Strcasecmp(qd->name, "MaxValue") == 0 && qd->type != MI_SINT64)
1749               {
1750                   yyerrorf(ID_WRONG_TYPE_FOR_QUALIFIER, 
1751                       "wrong type for standard %s qualifier", "MaxValue");
1752                   return -1;
1753               }
1754               else if (Strcasecmp(qd->name, "MinValue") == 0 && qd->type != MI_SINT64)
1755               {
1756                   yyerrorf(ID_WRONG_TYPE_FOR_QUALIFIER, 
1757                       "wrong type for standard %s qualifier", "MinValue");
1758                   return -1;
1759               }
1760               else if (Strcasecmp(qd->name, "MinLen") == 0 && qd->type != MI_UINT32)
1761               {
1762                   yyerrorf(ID_WRONG_TYPE_FOR_QUALIFIER, 
1763                       "wrong type for standard %s qualifier", "MinLen");
1764                   return -1;
1765 mike  1.1     }
1766               else if (Strcasecmp(qd->name, "MaxLen") == 0 && qd->type != MI_UINT32)
1767               {
1768                   yyerrorf(ID_WRONG_TYPE_FOR_QUALIFIER, 
1769                       "wrong type for standard %s qualifier", "MaxLen");
1770                   return -1;
1771               }
1772           
1773               /* Add the declaration */
1774               PtrArray_Append((PtrArray*)&state.qualifierDecls, qd);
1775               return 0;
1776           }
1777           
1778           const MI_ClassDecl* FindClassDecl(const char* name)
1779           {
1780               size_t i;
1781           
1782               for (i = 0; i < state.classDecls.size; i++)
1783               {
1784                   if (Strcasecmp(state.classDecls.data[i]->name, name) == 0)
1785                       return state.classDecls.data[i];
1786 mike  1.1     }
1787           
1788               /* Not found */
1789               return NULL;
1790           }
1791           
1792           int AddClassDecl(MI_ClassDecl* qd)
1793           {
1794               if (FindClassDecl(qd->name))
1795               {
1796                   yyerrorf(ID_CLASS_ALREADY_DEFINED, "class already declared: \"%s\"", 
1797                       MI_GET_SAFE_PRINTF_STRING(qd->name));
1798                   return -1;
1799               }
1800           
1801               /* Add the declaration */
1802               PtrArray_Append((PtrArray*)&state.classDecls, qd);
1803               return 0;
1804           }
1805           
1806           void PrintQualifier(const MI_Qualifier* self, size_t level, FILE* file)
1807 mike  1.1 {
1808               if (!self)
1809                   return;
1810           
1811               /* Header */
1812               _indent(level, file);
1813               fprintf(file,"MI_Qualifier\n");
1814               _indent(level, file);
1815               fprintf(file,"{\n");
1816               level++;
1817           
1818               /* name  */
1819               _indent(level, file);
1820               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
1821           
1822               /* type */
1823               _indent(level, file);
1824               fprintf(file,"type: %s\n", _getTypeName(self->type));
1825           
1826               /* flavor */
1827           
1828 mike  1.1     _indent(level, file);
1829               fprintf(file,"flavor:");
1830           
1831               if (self->flavor & MI_FLAG_ENABLEOVERRIDE)
1832                   fprintf(file," ENABLEOVERRIDE");
1833               if (self->flavor & MI_FLAG_DISABLEOVERRIDE)
1834                   fprintf(file," DISABLEOVERRIDE");
1835               if (self->flavor & MI_FLAG_RESTRICTED)
1836                   fprintf(file," RESTRICTED");
1837               if (self->flavor & MI_FLAG_TOSUBCLASS)
1838                   fprintf(file," TOSUBCLASS");
1839               if (self->flavor & MI_FLAG_TRANSLATABLE)
1840                   fprintf(file," TRANSLATABLE");
1841           
1842               fprintf(file,"\n");
1843           
1844               /* value */
1845               _indent(level, file);
1846               fprintf(file,"value: ");
1847               PrintValue(self->value, self->type, file);
1848               fprintf(file,"\n");
1849 mike  1.1 
1850               /* Footer */
1851               level--;
1852               _indent(level, file);
1853               fprintf(file,"}\n");
1854           }
1855           
1856           static void _PrintQualifiers(
1857               MI_Qualifier** qualifiers, 
1858               size_t numQualifiers,
1859               size_t level, 
1860               FILE* file)
1861           {
1862               size_t i;
1863           
1864               _indent(level, file);
1865               fprintf(file,"qualifiers\n");
1866               _indent(level, file);
1867               fprintf(file,"{\n");
1868               level++;
1869           
1870 mike  1.1     for (i = 0; i < numQualifiers; i++)
1871                   PrintQualifier(qualifiers[i], level, file);
1872           
1873               level--;
1874               _indent(level, file);
1875               fprintf(file,"}\n");
1876           }
1877           
1878           void PrintParameter(const MI_ParameterDecl* self, size_t level, FILE* file)
1879           {
1880               if (!self)
1881                   return;
1882           
1883               _indent(level, file);
1884               fprintf(file,"MI_ParameterDecl\n");
1885               _indent(level, file);
1886               fprintf(file,"{\n");
1887               level++;
1888           
1889               /* flags */
1890               _PrintFlags(self->flags, level, file);
1891 mike  1.1 
1892               /* name  */
1893               _indent(level, file);
1894               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
1895           
1896               /* type */
1897               _indent(level, file);
1898               fprintf(file,"type: %s\n", _getTypeName(self->type));
1899           
1900               /* className */
1901               if (self->className)
1902               {
1903                   _indent(level, file);
1904                   fprintf(file,"className: %s\n", MI_GET_SAFE_PRINTF_STRING(self->className));
1905               }
1906           
1907               /* subscript */
1908               _indent(level, file);
1909               fprintf(file,"subscript: %u\n", self->subscript);
1910           
1911               /* offset */
1912 mike  1.1     _indent(level, file);
1913               fprintf(file,"offset: %u\n", self->offset);
1914           
1915               /* qualifiers */
1916               if (self->qualifiers)
1917                   _PrintQualifiers(self->qualifiers, self->numQualifiers, level, file);
1918           
1919               level--;
1920               _indent(level, file);
1921               fprintf(file,"}\n");
1922           }
1923           
1924           static void _PrintParameters(
1925               MI_ParameterDecl** parameters, 
1926               size_t numParameters,
1927               size_t level, 
1928               FILE* file)
1929           {
1930               size_t i;
1931           
1932               _indent(level, file);
1933 mike  1.1     fprintf(file,"parameters\n");
1934               _indent(level, file);
1935               fprintf(file,"{\n");
1936               level++;
1937           
1938               for (i = 0; i < numParameters; i++)
1939                   PrintParameter(parameters[i], level, file);
1940           
1941               level--;
1942               _indent(level, file);
1943               fprintf(file,"}\n");
1944           }
1945           
1946           void PrintProperty(const MI_PropertyDecl* self, size_t level, FILE* file)
1947           {
1948               if (!self)
1949                   return;
1950           
1951               _indent(level, file);
1952               fprintf(file,"MI_PropertyDecl\n");
1953               _indent(level, file);
1954 mike  1.1     fprintf(file,"{\n");
1955               level++;
1956           
1957               /* flags */
1958               _PrintFlags(self->flags, level, file);
1959           
1960               /* name  */
1961               _indent(level, file);
1962               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
1963           
1964               /* type */
1965               _indent(level, file);
1966               fprintf(file,"type: %s\n", _getTypeName(self->type));
1967           
1968               /* subscript */
1969               _indent(level, file);
1970               fprintf(file,"subscript: %u\n", self->subscript);
1971           
1972               /* className */
1973               if (self->className)
1974               {
1975 mike  1.1         _indent(level, file);
1976                   fprintf(file,"className: %s\n", MI_GET_SAFE_PRINTF_STRING(self->className));
1977               }
1978           
1979               /* offset */
1980               _indent(level, file);
1981               fprintf(file,"offset: %u\n", self->offset);
1982           
1983               /* qualifiers */
1984               if (self->qualifiers)
1985                   _PrintQualifiers(self->qualifiers, self->numQualifiers, level, file);
1986           
1987               /* origin */
1988               if (self->origin)
1989               {
1990                   _indent(level, file);
1991                   fprintf(file,"origin: %s\n", MI_GET_SAFE_PRINTF_STRING(self->origin));
1992               }
1993           
1994               /* propagator */
1995               if (self->propagator)
1996 mike  1.1     {
1997                   _indent(level, file);
1998                   fprintf(file,"propagator: %s\n", MI_GET_SAFE_PRINTF_STRING(self->propagator));
1999               }
2000           
2001               /* value */
2002               _indent(level, file);
2003               fprintf(file,"value: ");
2004               PrintValue(self->value, self->type, file);
2005               fprintf(file,"\n");
2006           
2007               level--;
2008               _indent(level, file);
2009               fprintf(file,"}\n");
2010           }
2011           
2012           static void _PrintProperties(
2013               MI_PropertyDecl** properties, 
2014               size_t numProperties,
2015               size_t level, 
2016               FILE* file)
2017 mike  1.1 {
2018               size_t i;
2019           
2020               _indent(level, file);
2021               fprintf(file,"properties\n");
2022               _indent(level, file);
2023               fprintf(file,"{\n");
2024               level++;
2025           
2026               for (i = 0; i < numProperties; i++)
2027                   PrintProperty(properties[i], level, file);
2028           
2029               level--;
2030               _indent(level, file);
2031               fprintf(file,"}\n");
2032           }
2033           
2034           void PrintMethod(const MI_MethodDecl* self, size_t level, FILE* file)
2035           {
2036               /*flags:name:type:size:parameters:qualifiers:origin:propagator*/
2037           
2038 mike  1.1     if (!self)
2039                   return;
2040           
2041               _indent(level, file);
2042               fprintf(file,"MI_MethodDecl\n");
2043               _indent(level, file);
2044               fprintf(file,"{\n");
2045               level++;
2046           
2047               /* flags */
2048               _PrintFlags(self->flags, level, file);
2049           
2050               /* name  */
2051               _indent(level, file);
2052               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
2053           
2054               /* size */
2055               _indent(level, file);
2056               fprintf(file,"size: %u\n", self->size);
2057           
2058               /* parameters */
2059 mike  1.1     if (self->parameters)
2060                   _PrintParameters(self->parameters, self->numParameters, level, file);
2061           
2062               /* origin */
2063               if (self->origin)
2064               {
2065                   _indent(level, file);
2066                   fprintf(file,"origin: %s\n", MI_GET_SAFE_PRINTF_STRING(self->origin));
2067               }
2068           
2069               /* propagator */
2070               if (self->propagator)
2071               {
2072                   _indent(level, file);
2073                   fprintf(file,"propagator: %s\n", MI_GET_SAFE_PRINTF_STRING(self->propagator));
2074               }
2075           
2076               level--;
2077               _indent(level, file);
2078               fprintf(file,"}\n");
2079           }
2080 mike  1.1 
2081           static void _PrintMethods(
2082               MI_MethodDecl** methods, 
2083               size_t numMethods,
2084               size_t level, 
2085               FILE* file)
2086           {
2087               size_t i;
2088           
2089               _indent(level, file);
2090               fprintf(file,"methods\n");
2091               _indent(level, file);
2092               fprintf(file,"{\n");
2093               level++;
2094           
2095               for (i = 0; i < numMethods; i++)
2096                   PrintMethod(methods[i], level, file);
2097           
2098               level--;
2099               _indent(level, file);
2100               fprintf(file,"}\n");
2101 mike  1.1 }
2102           
2103           MI_PropertyDecl* FindProperty(
2104               MOF_PropertyList* self,
2105               const char* name)
2106           {
2107               MI_Uint32 i;
2108           
2109               if (!self)
2110                   return NULL;
2111           
2112               for (i = 0; i < self->size; i++)
2113               {
2114                   if (Strcasecmp(self->data[i]->name, name) == 0)
2115                       return self->data[i];
2116               }
2117           
2118               /* Not found */
2119               return NULL;
2120           }
2121           
2122 mike  1.1 MI_ParameterDecl* FindParameter(
2123               MOF_ParameterList* self,
2124               const char* name)
2125           {
2126               size_t i;
2127           
2128               if (!self)
2129                   return NULL;
2130           
2131               for (i = 0; i < self->size; i++)
2132               {
2133                   if (Strcasecmp(self->data[i]->name, name) == 0)
2134                       return self->data[i];
2135               }
2136           
2137               /* Not found */
2138               return NULL;
2139           }
2140           
2141           MI_MethodDecl* FindMethod(
2142               MOF_MethodList* self,
2143 mike  1.1     const char* name)
2144           {
2145               size_t i;
2146           
2147               if (!self)
2148                   return NULL;
2149           
2150               for (i = 0; i < self->size; i++)
2151               {
2152                   if (Strcasecmp(self->data[i]->name, name) == 0)
2153                       return self->data[i];
2154               }
2155           
2156               /* Not found */
2157               return NULL;
2158           }
2159           
2160           void MOF_PrintClassDecl(
2161               const MI_ClassDecl* self,
2162               FILE* file)
2163           {
2164 mike  1.1     size_t level = 0;
2165           
2166               if (!self)
2167                   return;
2168           
2169               /* Header */
2170               _indent(level, file);
2171               fprintf(file,"MI_ClassDecl\n");
2172               _indent(level, file);
2173               fprintf(file,"{\n");
2174               level++;
2175           
2176               /* flags */
2177               _PrintFlags(self->flags, level, file);
2178           
2179               /* name  */
2180               _indent(level, file);
2181               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
2182           
2183               /* superClass  */
2184               _indent(level, file);
2185 mike  1.1     fprintf(file,"superClass: %s\n", MI_GET_SAFE_PRINTF_STRING(self->superClass));
2186           
2187               /* size */
2188               _indent(level, file);
2189               fprintf(file,"size: %u\n", self->size);
2190           
2191               /* properties */
2192               if (self->properties)
2193                   _PrintProperties(self->properties, self->numProperties, level, file);
2194           
2195               /* methods */
2196               if (self->methods)
2197                   _PrintMethods(self->methods, self->numMethods, level, file);
2198           
2199               /* qualifiers */
2200               if (self->qualifiers)
2201                   _PrintQualifiers(self->qualifiers, self->numQualifiers, level, file);
2202           
2203               /* Footer */
2204               level--;
2205               _indent(level, file);
2206 mike  1.1     fprintf(file,"}\n");
2207           }
2208           
2209           void MOF_PrintInstanceDecl(
2210               const MI_InstanceDecl* self,
2211               FILE* file)
2212           {
2213               size_t level = 0;
2214           
2215               if (!self)
2216                   return;
2217           
2218               /* Header */
2219               _indent(level, file);
2220               fprintf(file,"MI_InstanceDecl\n");
2221               _indent(level, file);
2222               fprintf(file,"{\n");
2223               level++;
2224           
2225               /* flags */
2226               _PrintFlags(self->flags, level, file);
2227 mike  1.1 
2228               /* name  */
2229               _indent(level, file);
2230               fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name));
2231           
2232               /* size */
2233               _indent(level, file);
2234               fprintf(file,"size: %u\n", self->size);
2235           
2236               /* properties */
2237               if (self->properties)
2238                   _PrintProperties(self->properties, self->numProperties, level, file);
2239           
2240               /* qualifiers */
2241               if (self->qualifiers)
2242                   _PrintQualifiers(self->qualifiers, self->numQualifiers, level, file);
2243           
2244               /* Footer */
2245               level--;
2246               _indent(level, file);
2247               fprintf(file,"}\n");
2248 mike  1.1 }
2249           
2250           MI_Uint32 GetQualFlags(
2251               MI_Qualifier** qualifiers,
2252               size_t numQualifiers)
2253           {
2254               MI_Uint32 flags = 0;
2255               size_t i;
2256           
2257               if (!qualifiers)
2258                   return 0;
2259           
2260               for (i = 0; i < numQualifiers; i++)
2261               {
2262                   const MI_Qualifier* q = qualifiers[i];
2263           
2264                   if (q->type == MI_BOOLEAN)
2265                   {
2266                       size_t j;
2267           
2268                       for (j = 0; j < _flagsSize; j++)
2269 mike  1.1             {
2270                           if (Strcasecmp(q->name, _flags[j].name) == 0)
2271                           {
2272                               MI_Boolean* p = (MI_Boolean*)q->value;
2273           
2274                               if (p && *p)
2275                                   flags |= _flags[j].flag;
2276                           }
2277                       }
2278                   }
2279           
2280                   if (q->type == MI_STRING &&
2281                       Strcasecmp(q->name, "EmbeddedInstance") == 0)
2282                   {
2283                       MOF_EmbeddedInstance* p;
2284           
2285                       /* Create line-address pair */
2286                       {
2287                           p = CALLOC_T(MOF_EmbeddedInstance, 1);
2288           
2289                           if (!p)
2290 mike  1.1                 {
2291                               yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
2292                               return 0;
2293                           }
2294           
2295                           p->qualifier = (void*)q;
2296                           p->line = state.line;
2297                       }
2298           
2299                       /* Append to 'lines' list */
2300                       if (PtrArray_Append(
2301                           (PtrArray*)(void*)&state.embeddedInstanceList, p) != 0)
2302                       {
2303                           yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
2304                           return 0;
2305                       }
2306                   }
2307               }
2308           
2309               return flags;
2310           }
2311 mike  1.1 
2312           void* NewTrueValue()
2313           {
2314               MI_Boolean* p = (MI_Boolean*)MOF_Malloc(&state.heap, sizeof(MI_Boolean));
2315           
2316               if (!p)
2317                   return NULL;
2318           
2319               *p = 1;
2320               return p;
2321           }
2322           
2323           static MI_Uint32 _FindPropertyDecl(
2324               MOF_PropertyList* self,
2325               const char* name)
2326           {
2327               MI_Uint32 i;
2328           
2329               for (i = 0; i < self->size; i++)
2330               {
2331                   if (Strcasecmp(self->data[i]->name, name) == 0)
2332 mike  1.1             return i;
2333               }
2334           
2335               /* Not found! */
2336               return MOF_NOT_FOUND;
2337           }
2338           
2339           static MI_Uint32 _FindMethodDecl(
2340               MOF_MethodList* self,
2341               const char* name)
2342           {
2343               MI_Uint32 i;
2344           
2345               for (i = 0; i < self->size; i++)
2346               {
2347                   if (Strcasecmp(self->data[i]->name, name) == 0)
2348                       return i;
2349               }
2350           
2351               /* Not found! */
2352               return MOF_NOT_FOUND;
2353 mike  1.1 }
2354           
2355           MI_Uint32 _FindQualifierPos(
2356               MOF_QualifierList* self,
2357               const char* name)
2358           {
2359               MI_Uint32 i;
2360           
2361               for (i = 0; i < self->size; i++)
2362               {
2363                   if (Strcasecmp(self->data[i]->name, name) == 0)
2364                       return i;
2365               }
2366           
2367               /* Not found! */
2368               return MOF_NOT_FOUND;
2369           }
2370           
2371           MI_Qualifier* FindQualifier(
2372               MOF_QualifierList* self, 
2373               const char* name)
2374 mike  1.1 {
2375               size_t i;
2376           
2377               if (!self)
2378                   return NULL;
2379           
2380               for (i = 0; i < self->size; i++)
2381               {
2382                   if (Strcasecmp(self->data[i]->name, name) == 0)
2383                       return self->data[i];
2384               }
2385           
2386               /* Not found! */
2387               return NULL;
2388           }
2389           
2390           /*
2391           **==============================================================================
2392           **
2393           ** Identical
2394           **
2395 mike  1.1 **     Compares two values to determine whether they are identical. Returns
2396           **     a non-zero value if they are identical.
2397           **
2398           **==============================================================================
2399           */
2400           MI_Boolean Identical(const void* v1, const void* v2, MI_Type type)
2401           {
2402               if (v1 == NULL && v2 == NULL)
2403                   return 1;
2404           
2405               if (v1  == NULL && v2 != NULL)
2406                   return 0;
2407           
2408               if (v1 != NULL && v2 == NULL)
2409                   return 0;
2410           
2411               switch (type)
2412               {
2413                   case MI_BOOLEAN:
2414                       return *((MI_Boolean*)v1) == *((MI_Boolean*)v2);
2415                   case MI_UINT8:
2416 mike  1.1             return *((MI_Uint8*)v1) == *((MI_Uint8*)v2);
2417                   case MI_SINT8:
2418                       return *((MI_Sint8*)v1) == *((MI_Sint8*)v2);
2419                   case MI_UINT16:
2420                       return *((MI_Uint16*)v1) == *((MI_Uint16*)v2);
2421                   case MI_SINT16:
2422                       return *((MI_Sint16*)v1) == *((MI_Sint16*)v2);
2423                   case MI_UINT32:
2424                       return *((MI_Uint32*)v1) == *((MI_Uint32*)v2);
2425                   case MI_SINT32:
2426                       return *((MI_Sint32*)v1) == *((MI_Sint32*)v2);
2427                   case MI_UINT64:
2428                       return *((MI_Uint64*)v1) == *((MI_Uint64*)v2);
2429                   case MI_SINT64:
2430                       return *((MI_Sint64*)v1) == *((MI_Sint64*)v2);
2431                   case MI_REAL32:
2432                       return *((MI_Real32*)v1) == *((MI_Real32*)v2);
2433                   case MI_REAL64:
2434                       return *((MI_Real64*)v1) == *((MI_Real64*)v2);
2435                   case MI_CHAR16:
2436                       return *((MI_Char16*)v1) == *((MI_Char16*)v2);
2437 mike  1.1         case MI_DATETIME:
2438                       return memcmp((MI_Datetime*)v1, (MI_Datetime*)v2, 
2439                           sizeof(MI_Datetime)) == 0;
2440                   case MI_STRING:
2441                       return strcmp((char*)v1, (char*)v2) == 0;
2442                   case MI_BOOLEANA:
2443                   case MI_UINT8A:
2444                   case MI_SINT8A:
2445                   case MI_UINT16A:
2446                   case MI_SINT16A:
2447                   case MI_UINT32A:
2448                   case MI_SINT32A:
2449                   case MI_UINT64A:
2450                   case MI_SINT64A:
2451                   case MI_CHAR16A:
2452                   case MI_DATETIMEA:
2453                   {
2454                       MI_BooleanA* a1 = (MI_BooleanA*)v1;
2455                       MI_BooleanA* a2 = (MI_BooleanA*)v2;
2456           #ifdef _PREFAST_
2457               #pragma prefast (push)
2458 mike  1.1     #pragma prefast (disable: 26014)
2459           #endif          
2460                       MI_Uint32 elementSize = (MI_Uint32)_typeSizes[type & ~MI_ARRAY_BIT];
2461           #ifdef _PREFAST_
2462               #pragma prefast (pop)
2463           #endif          
2464           
2465                       if (a1->size != a2->size)
2466                           return 0;
2467           
2468                       if (memcmp(a1->data, a2->data, a1->size * elementSize) != 0)
2469                           return 0;
2470           
2471                       return 1;
2472                   }
2473                   case MI_REAL32A:
2474                   {
2475                       MI_Real32A* a1 = (MI_Real32A*)v1;
2476                       MI_Real32A* a2 = (MI_Real32A*)v2;
2477                       MI_Uint32 i;
2478           
2479 mike  1.1             if (a1->size != a2->size)
2480                           return 0;
2481           
2482                       for (i = 0; i < a1->size; i++)
2483                       {
2484                           if (a1->data[i] != a2->data[i])
2485                               return 0;
2486                       }
2487           
2488                       return 1;
2489                   }
2490                   case MI_REAL64A:
2491                   {
2492                       MI_Real64A* a1 = (MI_Real64A*)v1;
2493                       MI_Real64A* a2 = (MI_Real64A*)v2;
2494                       MI_Uint32 i;
2495           
2496                       if (a1->size != a2->size)
2497                           return 0;
2498           
2499                       for (i = 0; i < a1->size; i++)
2500 mike  1.1             {
2501                           if (a1->data[i] != a2->data[i])
2502                               return 0;
2503                       }
2504           
2505                       return 1;
2506                   }
2507                   case MI_STRINGA:
2508                   {
2509                       MI_StringA* a1 = (MI_StringA*)v1;
2510                       MI_StringA* a2 = (MI_StringA*)v2;
2511                       MI_Uint32 i;
2512           
2513                       if (a1->size != a2->size)
2514                           return 0;
2515           
2516                       for (i = 0; i < a1->size; i++)
2517                       {
2518                           if (strcmp(a1->data[i], a2->data[i]) != 0)
2519                               return 0;
2520                       }
2521 mike  1.1 
2522                       return 1;
2523                   }
2524                   default:
2525                   {
2526                       yyerrorf(ID_INTERNAL_ERROR, "internal error: %s(%u)",
2527                           __FILE__, __LINE__);
2528                       return 0;
2529                   }
2530               }
2531           }
2532           
2533           /*
2534           **==============================================================================
2535           **
2536           ** _FinalizeQualifiers()
2537           **
2538           **     This function performs qualifier propagation (from an inherited feature
2539           **     to a derived feature). It operates according to the flavor given by each
2540           **     qualifier. See the CIM infrastructure specification for a complete
2541           **     discussion of qualifier propagation.
2542 mike  1.1 **
2543           **     The algorithm works as follows. A new empty qualifier list is created.
2544           **     Next non-restricted inherited qualifiers are appended to this list.
2545           **     Finally derived qualifiers are applied to the list. Qualifiers not
2546           **     already in the list are appended. Qualifiers already in the list are
2547           **     overriden.
2548           **
2549           **     Propation is performed using the MI_Qualifier.flavor whose bits may be
2550           **     masked by these macros.
2551           **
2552           **         MI_FLAG_ENABLEOVERRIDE
2553           **         MI_FLAG_DISABLEOVERRIDE
2554           **         MI_FLAG_RESTRICTED
2555           **         MI_FLAG_TOSUBCLASS
2556           **
2557           **==============================================================================
2558           */
2559           static int _FinalizeQualifiers(
2560               const char* className,
2561               const char* featureName,
2562               MI_Qualifier** derived,
2563 mike  1.1     MI_Uint32 numDerived,
2564               MI_Qualifier** inherited,
2565               MI_Uint32 numInherited,
2566               MI_Qualifier*** qualifiers_,
2567               MI_Uint32* numQualifiers_)
2568           {
2569               MOF_QualifierList qualifierList = PTRARRAY_INITIALIZER;
2570               MI_Uint32 i;
2571           
2572               /* Propagate non-restricted inherited qualifiers */
2573               for (i = 0; i < numInherited; i++)
2574               {
2575                   MI_Qualifier* q = inherited[i];
2576           
2577                   if (!(q->flavor & MI_FLAG_RESTRICTED))
2578                   {
2579                       if (PtrArray_Append((PtrArray*)(void*)&qualifierList, q) != 0)
2580                       {
2581                           yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
2582                           return -1;
2583                       }
2584 mike  1.1         }
2585               }
2586           
2587               /* Apply derived qualifiers */
2588               for (i = 0; i < numDerived; i++)
2589               {
2590                   MI_Qualifier* q = derived[i];
2591                   MI_Uint32 pos = _FindQualifierPos(&qualifierList, q->name);
2592           
2593                   if (pos == MOF_NOT_FOUND)
2594                   {
2595                       if (PtrArray_Append((PtrArray*)(void*)&qualifierList, q) != 0)
2596                       {
2597                           yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
2598                           return -1;
2599                       }
2600                   }
2601                   else
2602                   {
2603                       /* If DisableOverride flavor, then disallow value change */
2604                       if (qualifierList.data[pos]->flavor & MI_FLAG_DISABLEOVERRIDE &&
2605 mike  1.1                 !Identical(qualifierList.data[pos]->value, q->value, q->type))
2606                       {
2607                           if (featureName)
2608                           {
2609                               yyerrorf(ID_ILLEGAL_QUALIFIER_OVERRIDE,
2610                                   "illegal qualifier override: %s.%s.%s",
2611                                   MI_GET_SAFE_PRINTF_STRING(className), 
2612                                   MI_GET_SAFE_PRINTF_STRING(featureName), 
2613                                   MI_GET_SAFE_PRINTF_STRING(q->name));
2614                           }
2615                           else
2616                           {
2617                               yyerrorf(ID_ILLEGAL_QUALIFIER_OVERRIDE, 
2618                                   "illegal qualifier override: %s.%s.%s",
2619                                   "",
2620                                   MI_GET_SAFE_PRINTF_STRING(className), 
2621                                   MI_GET_SAFE_PRINTF_STRING(q->name));
2622                           }
2623                           return -1;
2624                       }
2625           
2626 mike  1.1             q->flavor = PropagateFlavors(q->flavor, 
2627                           qualifierList.data[pos]->flavor);
2628                       qualifierList.data[pos] = q;
2629                   }
2630               }
2631           
2632               *qualifiers_ = qualifierList.data;
2633               *numQualifiers_ = qualifierList.size;
2634           
2635               return 0;
2636           }
2637           
2638           static int _FinalizeClassProperties(
2639               MI_ClassDecl* cd)
2640           {
2641               size_t i;
2642               MOF_PropertyList propertySet = PTRARRAY_INITIALIZER;
2643           
2644               /* First inherit properties from finalized super class */
2645               if (cd->superClass)
2646               {
2647 mike  1.1         const MI_ClassDecl* super;
2648                   
2649                   /* Retrieve the super class */
2650                   super = FindClassDecl(cd->superClass);
2651           
2652                   if (!super)
2653                   {
2654                       yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", 
2655                           MI_GET_SAFE_PRINTF_STRING(cd->superClass));
2656                       return -1;
2657                   }
2658           
2659                   /* Use the superclass casing for this class name */
2660                   cd->superClass = super->name;
2661           
2662                   /* Propagate class qualifiers */
2663                   {
2664                       MI_Qualifier** qualifiers = NULL;
2665                       MI_Uint32 numQualifiers = 0;
2666           
2667                       /* This property overrides an inherited property */
2668 mike  1.1             if (_FinalizeQualifiers(
2669                           cd->name,
2670                           NULL,
2671                           cd->qualifiers,
2672                           cd->numQualifiers,
2673                           super->qualifiers,
2674                           super->numQualifiers,
2675                           &qualifiers,
2676                           &numQualifiers) != 0)
2677                       {
2678                           return -1;
2679                       }
2680           
2681                       MOF_Free(&state.heap, cd->qualifiers);
2682                       cd->qualifiers = qualifiers;
2683                       cd->numQualifiers = numQualifiers;
2684                       cd->flags |= GetQualFlags(cd->qualifiers, cd->numQualifiers);
2685                   }
2686           
2687                   /* Clone the superclass property array */
2688                   for (i = 0; i < super->numProperties; i++)
2689 mike  1.1         {
2690                       if (PtrArray_Append((PtrArray*)(void*)&propertySet, 
2691                           super->properties[i]) != 0)
2692                       {
2693                           yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
2694                           return -1;
2695                       }
2696                   }
2697               }
2698           
2699               /* Now append local properties (overriding as necessary) */
2700               for (i = 0; i < cd->numProperties; i++)
2701               {
2702                   MI_PropertyDecl* pd = cd->properties[i];
2703                   MI_Uint32 pos;
2704           
2705                   /* Set MI_PropertyDecl.propagator */
2706                   pd->propagator = MOF_Strdup(&state.heap, cd->name);
2707           
2708                   /* See if the property is already in the list */
2709           
2710 mike  1.1         pos = _FindPropertyDecl(&propertySet, pd->name);
2711           
2712                   if (pos == MOF_NOT_FOUND)
2713                   {
2714                       /* First time this property has been seen in hierarchy */
2715                       pd->origin = MOF_Strdup(&state.heap, cd->name);
2716           
2717                       PtrArray_Append((PtrArray*)(void*)&propertySet, pd);
2718                   }
2719                   else
2720                   {
2721                       MI_Qualifier** qualifiers;
2722                       MI_Uint32 numQualifiers;
2723           
2724                       /* This property overrides an inherited property */
2725           
2726                       if (_FinalizeQualifiers(
2727                           cd->name,
2728                           pd->name,
2729                           pd->qualifiers,
2730                           pd->numQualifiers,
2731 mike  1.1                 propertySet.data[pos]->qualifiers,
2732                           propertySet.data[pos]->numQualifiers,
2733                           &qualifiers,
2734                           &numQualifiers) != 0)
2735                       {
2736                           return -1;
2737                       }
2738           
2739                       MOF_Free(&state.heap, pd->qualifiers);
2740                       pd->qualifiers = qualifiers;
2741                       pd->numQualifiers = numQualifiers;
2742                       pd->flags |= GetQualFlags(qualifiers, numQualifiers);
2743           
2744                       pd->origin = MOF_Strdup(&state.heap, 
2745                           propertySet.data[pos]->origin);
2746           
2747                       /* Use the superclass casing for the property name */
2748                       pd->name = propertySet.data[pos]->name;
2749           
2750                       propertySet.data[pos] = pd;
2751                   }
2752 mike  1.1     }
2753           
2754               /* Replace local property list with aggregate property list */
2755               MOF_Free(&state.heap, cd->properties);
2756               cd->properties = propertySet.data;
2757               cd->numProperties = propertySet.size;
2758           
2759               return 0;
2760           }
2761           
2762           static int _VerifyClassKeys(
2763               const MI_ClassDecl* cd)
2764           {
2765               MI_Uint32 i;
2766               const MI_ClassDecl* super;
2767               MI_Boolean superDefinedKeys = MI_FALSE;
2768           
2769               /* If no super class, no validation needed */
2770               if (!cd->superClass)
2771                   return 0;
2772           
2773 mike  1.1         
2774               /* Retrieve the super class */
2775               super = FindClassDecl(cd->superClass);
2776           
2777               if (!super)
2778               {
2779                   yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", 
2780                       MI_GET_SAFE_PRINTF_STRING(cd->superClass));
2781                   return -1;
2782               }
2783           
2784               /* Check if super class defined keys */
2785               for (i = 0; i < super->numProperties; i++)
2786               {
2787                   if (super->properties[i]->flags & MI_FLAG_KEY)
2788                   {
2789                       superDefinedKeys = MI_TRUE;
2790                       break;
2791                   }
2792               }
2793           
2794 mike  1.1     /* If super class does not have keys no extra check needed */
2795               if (!superDefinedKeys)
2796                   return 0;
2797           
2798               /* Now append local properties (overriding as necessary) */
2799               for (i = 0; i < cd->numProperties; i++)
2800               {
2801                   MI_PropertyDecl* pd = cd->properties[i];
2802                   MI_Uint32 pos;
2803                   MI_Boolean foundInBase = MI_FALSE;
2804           
2805                   for (pos = 0; pos < super->numProperties; pos++)
2806                   {
2807                       if (Strcasecmp(pd->name, super->properties[pos]->name) != 0)
2808                           continue;
2809           
2810                       foundInBase = MI_TRUE;
2811           
2812                       /* new property is a key */
2813                       if (pd->flags & MI_FLAG_KEY)
2814                       {
2815 mike  1.1                 if ((super->properties[pos]->flags & MI_FLAG_KEY) == 0)
2816                           {
2817                               yyerrorf(ID_KEY_MUTATION_ERROR, 
2818                                   "property \"%s\" defined as [key] in class \"%s\", "
2819                                   "but was not key in base class", 
2820                                   MI_GET_SAFE_PRINTF_STRING(pd->name),
2821                                   MI_GET_SAFE_PRINTF_STRING(cd->name));
2822                               return -1;
2823                           }
2824                       }
2825           
2826                       /* compare prop type */
2827                       if ((pd->flags & MI_FLAG_KEY) != 0 ||
2828                           (super->properties[pos]->flags & MI_FLAG_KEY) != 0)
2829                       {
2830                           if (pd->type != super->properties[pos]->type)
2831                           {
2832                               yyerrorf(ID_KEY_TYPE_MUTATION_ERROR, 
2833                                   "key property \"%s\" re-defined with different type "
2834                                   "in class \"%s\"", 
2835                                   MI_GET_SAFE_PRINTF_STRING(pd->name),
2836 mike  1.1                         MI_GET_SAFE_PRINTF_STRING(cd->name));
2837                               return -1;
2838                           }
2839           
2840                       }
2841           
2842                   }
2843           
2844                   if (!foundInBase && (pd->flags & MI_FLAG_KEY) != 0)
2845                   {
2846                       yyerrorf(ID_KEY_STRUCTURE_MUTATION_ERROR,
2847                           "new key property \"%s\" is introduced by class \"%s\"", 
2848                           MI_GET_SAFE_PRINTF_STRING(pd->name),
2849                           MI_GET_SAFE_PRINTF_STRING(cd->name));
2850                       return -1;
2851                   }
2852               }
2853           
2854               return 0;
2855           }
2856           
2857 mike  1.1 static int _FinalizeClassMethods(
2858               MI_ClassDecl* cd)
2859           {
2860               size_t i;
2861               MOF_MethodList methodList = PTRARRAY_INITIALIZER;
2862           
2863               /* First inherit methods from finalized super class */
2864               if (cd->superClass)
2865               {
2866                   const MI_ClassDecl* super;
2867                   
2868                   /* Retrieve the super class */
2869                   super = FindClassDecl(cd->superClass);
2870           
2871                   if (!super)
2872                   {
2873                       yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", 
2874                           MI_GET_SAFE_PRINTF_STRING(cd->superClass));
2875                       return -1;
2876                   }
2877           
2878 mike  1.1         /* Propagate class qualifiers */
2879                   {
2880                       MI_Qualifier** qualifiers = NULL;
2881                       MI_Uint32 numQualifiers = 0;
2882           
2883                       /* This method overrides an inherited method */
2884                       if (_FinalizeQualifiers(
2885                           cd->name,
2886                           NULL,
2887                           cd->qualifiers,
2888                           cd->numQualifiers,
2889                           super->qualifiers,
2890                           super->numQualifiers,
2891                           &qualifiers,
2892                           &numQualifiers) != 0)
2893                       {
2894                           return -1;
2895                       }
2896           
2897                       MOF_Free(&state.heap, cd->qualifiers);
2898                       cd->qualifiers = qualifiers;
2899 mike  1.1             cd->numQualifiers = numQualifiers;
2900                       cd->flags |= GetQualFlags(cd->qualifiers, cd->numQualifiers);
2901                   }
2902           
2903                   /* Clone the superclass method array */
2904                   for (i = 0; i < super->numMethods; i++)
2905                   {
2906                       if (PtrArray_Append((PtrArray*)(void*)&methodList, 
2907                           super->methods[i]) != 0)
2908                       {
2909                           yyerrorf(ID_OUT_OF_MEMORY, "out of memory");
2910                           return -1;
2911                       }
2912                   }
2913               }
2914           
2915               /* Now append local methods (overriding as necessary) */
2916               for (i = 0; i < cd->numMethods; i++)
2917               {
2918                   MI_MethodDecl* md = cd->methods[i];
2919                   MI_Uint32 pos;
2920 mike  1.1 
2921                   /* Set MI_MethodDecl.propagator */
2922                   md->propagator = MOF_Strdup(&state.heap, cd->name);
2923           
2924                   /* See if the method is already in the list */
2925           
2926                   pos = _FindMethodDecl(&methodList, md->name);
2927           
2928                   if (pos == MOF_NOT_FOUND)
2929                   {
2930                       /* First time this method has been seen in hierarchy */
2931                       md->origin = MOF_Strdup(&state.heap, cd->name);
2932           
2933                       PtrArray_Append((PtrArray*)(void*)&methodList, md);
2934                   }
2935                   else
2936                   {
2937                       MI_Qualifier** qualifiers;
2938                       MI_Uint32 numQualifiers;
2939           
2940                       /* This method overrides an inherited method */
2941 mike  1.1             if (_FinalizeQualifiers(
2942                           cd->name,
2943                           md->name,
2944                           md->qualifiers,
2945                           md->numQualifiers,
2946                           methodList.data[pos]->qualifiers,
2947                           methodList.data[pos]->numQualifiers,
2948                           &qualifiers,
2949                           &numQualifiers) != 0)
2950                       {
2951                           return -1;
2952                       }
2953           
2954                       MOF_Free(&state.heap, md->qualifiers);
2955                       md->qualifiers = qualifiers;
2956                       md->numQualifiers = numQualifiers;
2957                       md->flags |= GetQualFlags(qualifiers, numQualifiers);
2958           
2959                       md->origin = MOF_Strdup(&state.heap, 
2960                           methodList.data[pos]->origin);
2961           
2962 mike  1.1             /* Use the superclass casing for the method name */
2963                       md->name = methodList.data[pos]->name;
2964           
2965                       methodList.data[pos] = md;
2966                   }
2967               }
2968           
2969               /* Replace local method list with aggregate method list */
2970               MOF_Free(&state.heap, cd->methods);
2971               cd->methods = methodList.data;
2972               cd->numMethods = methodList.size;
2973           
2974               return 0;
2975           }
2976           
2977           int FinalizeClass(MI_ClassDecl* cd)
2978           {
2979               /* 
2980                   Verify keys structure: 
2981                   - derived class maynot introduce new keys or
2982                       change key type if base class defined keys
2983 mike  1.1     */
2984               if (_VerifyClassKeys(cd) != 0)
2985                   return -1;
2986           
2987               /* Perform property propagation */
2988               if (_FinalizeClassProperties(cd) != 0)
2989                   return -1;
2990           
2991               /* Perform method propagation */
2992               if (_FinalizeClassMethods(cd) != 0)
2993                   return -1;
2994           
2995               return 0;
2996           }
2997           
2998           int FinalizeInstance(MI_InstanceDecl* id)
2999           {
3000               const MI_ClassDecl* cd;
3001               MI_Uint32 i;
3002               MI_Uint32 j;
3003           
3004 mike  1.1     /* Find the class declaration for this instance */
3005               {
3006                   cd = FindClassDecl(id->name);
3007           
3008                   if (!cd)
3009                   {
3010                       yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", id->name);
3011                       return -1;
3012                   }
3013               }
3014           
3015               /* For each instance property */
3016               for (i = 0; i < id->numProperties; i++)
3017               {
3018                   MI_PropertyDecl* p = id->properties[i];
3019                   MI_PropertyDecl* q = NULL;
3020           
3021                   /* Find the class property with the same name */
3022                   {
3023                       for (j = 0; j < cd->numProperties; j++)
3024                       {
3025 mike  1.1                 if (Strcasecmp(cd->properties[j]->name, p->name) == 0)
3026                           {
3027                               q = cd->properties[j];
3028                               break;
3029                           }
3030                       }
3031           
3032                       if (!q)
3033                       {
3034                           yyerrorf(ID_UNDEFINED_PROPERTY, "undefined property: \"%s\"", 
3035                               p->name);
3036                           return -1;
3037                       }
3038                   }
3039           
3040                   /* Promote instance property (to the type given by class property) */
3041                   if (_PromoteValue(p->type, q->type, &p->value) != 0)
3042                   {
3043                       yyerrorf(ID_INVALID_INITIALIZER, "invalid initializer: \"%s\"",
3044                           p->name);
3045                       return -1;
3046 mike  1.1         }
3047           
3048                   /* Assume type of class property */
3049                   p->type = q->type;
3050               }
3051           
3052               return 0;
3053           }
3054           
3055           MI_Uint32 PropagateFlavors(MI_Uint32 flavor, MI_Uint32 baseFlavor)
3056           {
3057               MI_Uint32 r = flavor;
3058           
3059               /* Only propagate these non-default flavors: 
3060                *     MI_FLAG_RESTRICTED
3061                *     MI_FLAG_DISABLEOVERRIDE
3062                *     MI_FLAG_TRANSLATABLE
3063                */
3064           
3065               /* MI_FLAG_TOSUBCLASS | MI_FLAG_RESTRICTED */
3066               if (!(r & MI_FLAG_TOSUBCLASS) && !(r & MI_FLAG_RESTRICTED))
3067 mike  1.1     {
3068                   if (baseFlavor & MI_FLAG_RESTRICTED)
3069                       r |= MI_FLAG_RESTRICTED;
3070               }
3071           
3072               /* MI_FLAG_ENABLEOVERRIDE | MI_FLAG_DISABLEOVERRIDE */
3073               if (!(r & MI_FLAG_ENABLEOVERRIDE) && !(r & MI_FLAG_DISABLEOVERRIDE))
3074               {
3075                   if (baseFlavor & MI_FLAG_DISABLEOVERRIDE)
3076                       r |= MI_FLAG_DISABLEOVERRIDE;
3077               }
3078           
3079               /* MI_FLAG_TRANSLATABLE */
3080               if (!(r & MI_FLAG_TRANSLATABLE))
3081               {
3082                   if (baseFlavor & MI_FLAG_TRANSLATABLE)
3083                       r |= MI_FLAG_TRANSLATABLE;
3084               }
3085           
3086               return r;
3087           }
3088 mike  1.1 
3089           #if 0
3090           static void _PrintBits(MI_Uint32 mask)
3091           {
3092               MI_Uint32 i = 31;
3093           
3094               while (i)
3095               {
3096                   if ((1 << i) & mask)
3097                       printf("1");
3098                   else
3099                       printf("0");
3100           
3101                   i--;
3102               }
3103           
3104               printf("\n");
3105           }
3106           #endif
3107           
3108           int CheckScope(MI_Uint32 scope, MOF_QualifierList* qualifiers)
3109 mike  1.1 {
3110               size_t i;
3111           
3112               if (!qualifiers)
3113                   return 0;
3114           
3115               for (i = 0; i < qualifiers->size; i++)
3116               {
3117                   const MI_Qualifier* q = qualifiers->data[i];
3118                   const MI_QualifierDecl* qd;
3119           
3120                   /* Find qualifier declaration */
3121                   qd = FindQualifierDeclaration(q->name);
3122           
3123                   if (!qd)
3124                   {
3125                       yyerrorf(ID_UNKNOWN_QUALIFIER, "unknown qualifier: \"%s\"", 
3126                           MI_GET_SAFE_PRINTF_STRING(q->name));
3127                       return -1;
3128                   }
3129           
3130 mike  1.1         if (Strcasecmp(q->name, "Association") == 0)
3131                   {
3132                       if (!(scope & MI_FLAG_CLASS))
3133                       {
3134                           yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, 
3135                               "illegal scope for qualifier: \"%s\"", 
3136                               MI_GET_SAFE_PRINTF_STRING(q->name));
3137                           return -1;
3138                       }
3139           
3140                       scope |= MI_FLAG_ASSOCIATION;
3141                   }
3142                   else if (Strcasecmp(q->name, "Indication") == 0)
3143                   {
3144                       if (!(scope & MI_FLAG_CLASS))
3145                       {
3146                           yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, 
3147                               "illegal scope for qualifier: \"%s\"", 
3148                               MI_GET_SAFE_PRINTF_STRING(q->name));
3149                           return -1;
3150                       }
3151 mike  1.1 
3152                       scope |= MI_FLAG_INDICATION;
3153                   }
3154                   else if ((qd->scope & scope) == 0)
3155                   {
3156                       yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, 
3157                           "illegal scope for qualifier: \"%s\"", 
3158                           MI_GET_SAFE_PRINTF_STRING(q->name));
3159                       return -1;
3160                   }
3161               }
3162           
3163               return 0;
3164           }
3165           
3166           static int _CheckMinValue(const MI_PropertyDecl* pd, const MI_Qualifier* q)
3167           {
3168               MI_Sint64 r;
3169               MI_Uint32 i;
3170           
3171               switch (pd->type)
3172 mike  1.1     {
3173                   case MI_UINT8:
3174                   case MI_SINT8:
3175                   case MI_UINT16:
3176                   case MI_SINT16:
3177                   case MI_UINT32:
3178                   case MI_SINT32:
3179                   case MI_UINT64:
3180                   case MI_REAL32:
3181                   case MI_REAL64:
3182                   case MI_SINT64:
3183                   case MI_UINT8A:
3184                   case MI_SINT8A:
3185                   case MI_UINT16A:
3186                   case MI_SINT16A:
3187                   case MI_UINT32A:
3188                   case MI_SINT32A:
3189                   case MI_UINT64A:
3190                   case MI_SINT64A:
3191                   case MI_REAL32A:
3192                   case MI_REAL64A:
3193 mike  1.1             break;
3194                   default:
3195                       goto incompatibleError;
3196               }
3197           
3198               if (!q->value || !pd->value)
3199                   return 0;
3200           
3201               r = *((MI_Sint64*)q->value);
3202           
3203               switch (pd->type)
3204               {
3205                   case MI_UINT8:
3206                   {
3207                       MI_Uint8 x = *((MI_Uint8*)pd->value);
3208                       if ((MI_Sint64)x < r)
3209                           goto constraintError;
3210                       break;
3211                   }
3212                   case MI_SINT8:
3213                   {
3214 mike  1.1             MI_Sint8 x = *((MI_Sint8*)pd->value);
3215                       if ((MI_Sint64)x < r)
3216                           goto constraintError;
3217                       break;
3218                   }
3219                   case MI_UINT16:
3220                   {
3221                       MI_Uint16 x = *((MI_Uint16*)pd->value);
3222                       if ((MI_Sint64)x < r)
3223                           goto constraintError;
3224                       break;
3225                   }
3226                   case MI_SINT16:
3227                   {
3228                       MI_Sint16 x = *((MI_Sint16*)pd->value);
3229                       if ((MI_Sint64)x < r)
3230                           goto constraintError;
3231                       break;
3232                   }
3233                   case MI_UINT32:
3234                   {
3235 mike  1.1             MI_Uint32 x = *((MI_Uint32*)pd->value);
3236                       if ((MI_Sint64)x < r)
3237                           goto constraintError;
3238                       break;
3239                   }
3240                   case MI_SINT32:
3241                   {
3242                       MI_Sint32 x = *((MI_Sint32*)pd->value);
3243                       if ((MI_Sint64)x < r)
3244                           goto constraintError;
3245                       break;
3246                   }
3247                   case MI_UINT64:
3248                   {
3249                       MI_Uint64 x = *((MI_Uint64*)pd->value);
3250                       if ((MI_Sint64)x < r)
3251                           goto constraintError;
3252                       break;
3253                   }
3254                   case MI_SINT64:
3255                   {
3256 mike  1.1             MI_Sint64 x = *((MI_Sint64*)pd->value);
3257                       if ((MI_Sint64)x < r)
3258                           goto constraintError;
3259                       break;
3260                   }
3261                   case MI_REAL32:
3262                   {
3263                       MI_Real32 x = *((MI_Real32*)pd->value);
3264                       if (x < (MI_Real32)r)
3265                           goto constraintError;
3266                       break;
3267                   }
3268                   case MI_REAL64:
3269                   {
3270                       MI_Real64 x = *((MI_Real64*)pd->value);
3271                       if (x < (MI_Real64)r)
3272                           goto constraintError;
3273                       break;
3274                   }
3275                   case MI_UINT8A:
3276                   {
3277 mike  1.1             MI_Uint8A x = *((MI_Uint8A*)pd->value);
3278           
3279                       for (i = 0; i < x.size; i++)
3280                       {
3281                           if ((MI_Uint8)x.data[i] < r)
3282                               goto constraintError;
3283                       }
3284                       break;
3285                   }
3286                   case MI_SINT8A:
3287                   {
3288                       MI_Sint8A x = *((MI_Sint8A*)pd->value);
3289           
3290                       for (i = 0; i < x.size; i++)
3291                       {
3292                           if ((MI_Sint8)x.data[i] < r)
3293                               goto constraintError;
3294                       }
3295                       break;
3296                   }
3297                   case MI_UINT16A:
3298 mike  1.1         {
3299                       MI_Uint16A x = *((MI_Uint16A*)pd->value);
3300           
3301                       for (i = 0; i < x.size; i++)
3302                       {
3303                           if ((MI_Uint16)x.data[i] < r)
3304                               goto constraintError;
3305                       }
3306                       break;
3307                   }
3308                   case MI_SINT16A:
3309                   {
3310                       MI_Sint16A x = *((MI_Sint16A*)pd->value);
3311           
3312                       for (i = 0; i < x.size; i++)
3313                       {
3314                           if ((MI_Sint16)x.data[i] < r)
3315                               goto constraintError;
3316                       }
3317                       break;
3318                   }
3319 mike  1.1         case MI_UINT32A:
3320                   {
3321                       MI_Uint32A x = *((MI_Uint32A*)pd->value);
3322           
3323                       for (i = 0; i < x.size; i++)
3324                       {
3325                           if ((MI_Uint32)x.data[i] < r)
3326                               goto constraintError;
3327                       }
3328                       break;
3329                   }
3330                   case MI_SINT32A:
3331                   {
3332                       MI_Sint32A x = *((MI_Sint32A*)pd->value);
3333           
3334                       for (i = 0; i < x.size; i++)
3335                       {
3336                           if ((MI_Sint32)x.data[i] < r)
3337                               goto constraintError;
3338                       }
3339                       break;
3340 mike  1.1         }
3341                   case MI_UINT64A:
3342                   {
3343                       MI_Uint64A x = *((MI_Uint64A*)pd->value);
3344           
3345                       for (i = 0; i < x.size; i++)
3346                       {
3347                           if ((MI_Sint64)x.data[i] < r)
3348                               goto constraintError;
3349                       }
3350                       break;
3351                   }
3352                   case MI_SINT64A:
3353                   {
3354                       MI_Sint64A x = *((MI_Sint64A*)pd->value);
3355           
3356                       for (i = 0; i < x.size; i++)
3357                       {
3358                           if ((MI_Sint64)x.data[i] < r)
3359                               goto constraintError;
3360                       }
3361 mike  1.1             break;
3362                   }
3363                   case MI_REAL32A:
3364                   {
3365                       MI_Real32A x = *((MI_Real32A*)pd->value);
3366           
3367                       for (i = 0; i < x.size; i++)
3368                       {
3369                           if (x.data[i] < (MI_Real32)r)
3370                               goto constraintError;
3371                       }
3372                       break;
3373                   }
3374                   case MI_REAL64A:
3375                   {
3376                       MI_Real64A x = *((MI_Real64A*)pd->value);
3377           
3378                       for (i = 0; i < x.size; i++)
3379                       {
3380                           if (x.data[i] < (MI_Real64)r)
3381                               goto constraintError;
3382 mike  1.1             }
3383                       break;
3384                   }
3385                   default:
3386                       goto incompatibleError;
3387               }
3388           
3389               return 0;
3390           
3391           constraintError:
3392               yyerrorf(
3393                   ID_PROPERTY_CONSTRAINT_FAILURE,
3394                   "value for property \"%s\" fails constraint given by \"%s\" qualifier", 
3395                   MI_GET_SAFE_PRINTF_STRING(pd->name), 
3396                   MI_GET_SAFE_PRINTF_STRING(q->name));
3397               return -1;
3398           
3399           incompatibleError:
3400               yyerrorf(
3401                   ID_PROPERTY_QUALIFIER_INCOMPATIBLE,
3402                   "%s qualifier applied to incompatible property: %s", 
3403 mike  1.1         MI_GET_SAFE_PRINTF_STRING(q->name), 
3404                   MI_GET_SAFE_PRINTF_STRING(pd->name));
3405               return -1;
3406           }
3407           
3408           static int _CheckMaxValue(const MI_PropertyDecl* pd, const MI_Qualifier* q)
3409           {
3410               MI_Sint64 r;
3411               MI_Uint32 i;
3412           
3413               switch (pd->type)
3414               {
3415                   case MI_UINT8:
3416                   case MI_SINT8:
3417                   case MI_UINT16:
3418                   case MI_SINT16:
3419                   case MI_UINT32:
3420                   case MI_SINT32:
3421                   case MI_UINT64:
3422                   case MI_REAL32:
3423                   case MI_REAL64:
3424 mike  1.1         case MI_SINT64:
3425                   case MI_UINT8A:
3426                   case MI_SINT8A:
3427                   case MI_UINT16A:
3428                   case MI_SINT16A:
3429                   case MI_UINT32A:
3430                   case MI_SINT32A:
3431                   case MI_UINT64A:
3432                   case MI_SINT64A:
3433                   case MI_REAL32A:
3434                   case MI_REAL64A:
3435                       break;
3436                   default:
3437                       goto incompatibleError;
3438               }
3439           
3440               if (!q->value || !pd->value)
3441                   return 0;
3442           
3443               r = *((MI_Sint64*)q->value);
3444           
3445 mike  1.1     switch (pd->type)
3446               {
3447                   case MI_UINT8:
3448                   {
3449                       MI_Uint8 x = *((MI_Uint8*)pd->value);
3450                       if ((MI_Sint64)x > r)
3451                           goto constraintError;
3452                       break;
3453                   }
3454                   case MI_SINT8:
3455                   {
3456                       MI_Sint8 x = *((MI_Sint8*)pd->value);
3457                       if ((MI_Sint64)x > r)
3458                           goto constraintError;
3459                       break;
3460                   }
3461                   case MI_UINT16:
3462                   {
3463                       MI_Uint16 x = *((MI_Uint16*)pd->value);
3464                       if ((MI_Sint64)x > r)
3465                           goto constraintError;
3466 mike  1.1             break;
3467                   }
3468                   case MI_SINT16:
3469                   {
3470                       MI_Sint16 x = *((MI_Sint16*)pd->value);
3471                       if ((MI_Sint64)x > r)
3472                           goto constraintError;
3473                       break;
3474                   }
3475                   case MI_UINT32:
3476                   {
3477                       MI_Uint32 x = *((MI_Uint32*)pd->value);
3478                       if ((MI_Sint64)x > r)
3479                           goto constraintError;
3480                       break;
3481                   }
3482                   case MI_SINT32:
3483                   {
3484                       MI_Sint32 x = *((MI_Sint32*)pd->value);
3485                       if ((MI_Sint64)x > r)
3486                           goto constraintError;
3487 mike  1.1             break;
3488                   }
3489                   case MI_UINT64:
3490                   {
3491                       MI_Uint64 x = *((MI_Uint64*)pd->value);
3492                       if (x > (MI_Uint64)r)
3493                           goto constraintError;
3494                       break;
3495                   }
3496                   case MI_SINT64:
3497                   {
3498                       MI_Sint64 x = *((MI_Sint64*)pd->value);
3499                       if ((MI_Sint64)x > r)
3500                           goto constraintError;
3501                       break;
3502                   }
3503                   case MI_REAL32:
3504                   {
3505                       MI_Real32 x = *((MI_Real32*)pd->value);
3506                       if (x > (MI_Real32)r)
3507                           goto constraintError;
3508 mike  1.1             break;
3509                   }
3510                   case MI_REAL64:
3511                   {
3512                       MI_Real64 x = *((MI_Real64*)pd->value);
3513                       if (x > (MI_Real64)r)
3514                           goto constraintError;
3515                       break;
3516                   }
3517                   case MI_UINT8A:
3518                   {
3519                       MI_Uint8A x = *((MI_Uint8A*)pd->value);
3520           
3521                       for (i = 0; i < x.size; i++)
3522                       {
3523                           if ((MI_Uint8)x.data[i] > r)
3524                               goto constraintError;
3525                       }
3526                       break;
3527                   }
3528                   case MI_SINT8A:
3529 mike  1.1         {
3530                       MI_Sint8A x = *((MI_Sint8A*)pd->value);
3531           
3532                       for (i = 0; i < x.size; i++)
3533                       {
3534                           if ((MI_Sint8)x.data[i] > r)
3535                               goto constraintError;
3536                       }
3537                       break;
3538                   }
3539                   case MI_UINT16A:
3540                   {
3541                       MI_Uint16A x = *((MI_Uint16A*)pd->value);
3542           
3543                       for (i = 0; i < x.size; i++)
3544                       {
3545                           if ((MI_Uint16)x.data[i] > r)
3546                               goto constraintError;
3547                       }
3548                       break;
3549                   }
3550 mike  1.1         case MI_SINT16A:
3551                   {
3552                       MI_Sint16A x = *((MI_Sint16A*)pd->value);
3553           
3554                       for (i = 0; i < x.size; i++)
3555                       {
3556                           if ((MI_Sint16)x.data[i] > r)
3557                               goto constraintError;
3558                       }
3559                       break;
3560                   }
3561                   case MI_UINT32A:
3562                   {
3563                       MI_Uint32A x = *((MI_Uint32A*)pd->value);
3564           
3565                       for (i = 0; i < x.size; i++)
3566                       {
3567                           if ((MI_Uint32)x.data[i] > r)
3568                               goto constraintError;
3569                       }
3570                       break;
3571 mike  1.1         }
3572                   case MI_SINT32A:
3573                   {
3574                       MI_Sint32A x = *((MI_Sint32A*)pd->value);
3575           
3576                       for (i = 0; i < x.size; i++)
3577                       {
3578                           if ((MI_Sint32)x.data[i] > r)
3579                               goto constraintError;
3580                       }
3581                       break;
3582                   }
3583                   case MI_UINT64A:
3584                   {
3585                       MI_Uint64A x = *((MI_Uint64A*)pd->value);
3586           
3587                       for (i = 0; i < x.size; i++)
3588                       {
3589                           if ((MI_Sint64)x.data[i] > r)
3590                               goto constraintError;
3591                       }
3592 mike  1.1             break;
3593                   }
3594                   case MI_SINT64A:
3595                   {
3596                       MI_Sint64A x = *((MI_Sint64A*)pd->value);
3597           
3598                       for (i = 0; i < x.size; i++)
3599                       {
3600                           if ((MI_Sint64)x.data[i] > r)
3601                               goto constraintError;
3602                       }
3603                       break;
3604                   }
3605                   case MI_REAL32A:
3606                   {
3607                       MI_Real32A x = *((MI_Real32A*)pd->value);
3608           
3609                       for (i = 0; i < x.size; i++)
3610                       {
3611                           if (x.data[i] > (MI_Real32)r)
3612                               goto constraintError;
3613 mike  1.1             }
3614                       break;
3615                   }
3616                   case MI_REAL64A:
3617                   {
3618                       MI_Real64A x = *((MI_Real64A*)pd->value);
3619           
3620                       for (i = 0; i < x.size; i++)
3621                       {
3622                           if (x.data[i] > (MI_Real64)r)
3623                               goto constraintError;
3624                       }
3625                       break;
3626                   }
3627                   default:
3628                       goto incompatibleError;
3629               }
3630           
3631               return 0;
3632           
3633           constraintError:
3634 mike  1.1     yyerrorf(
3635                   ID_PROPERTY_CONSTRAINT_FAILURE,
3636                   "value for property \"%s\" fails constraint given by \"%s\" qualifier",
3637                   MI_GET_SAFE_PRINTF_STRING(pd->name), 
3638                   MI_GET_SAFE_PRINTF_STRING(q->name));
3639               return -1;
3640           
3641           incompatibleError:
3642               yyerrorf(
3643                   ID_PROPERTY_QUALIFIER_INCOMPATIBLE,
3644                   "%s qualifier applied to incompatible property: %s", 
3645                   MI_GET_SAFE_PRINTF_STRING(q->name), 
3646                   MI_GET_SAFE_PRINTF_STRING(pd->name));
3647               return -1;
3648           }
3649           
3650           static int _CheckMaxLen(const MI_PropertyDecl* pd, const MI_Qualifier* q)
3651           {
3652               MI_Uint32 r;
3653               MI_Uint32 i;
3654           
3655 mike  1.1     if (pd->type != MI_STRING && pd->type != MI_STRINGA)
3656                   goto incompatibleError;
3657           
3658               if (!q->value || !pd->value)
3659                   return 0;
3660           
3661               r = *((MI_Uint32*)q->value);
3662           
3663               switch (pd->type)
3664               {
3665                   case MI_STRING:
3666                   {
3667                       const MI_Char* s = (const MI_Char*)pd->value;
3668                       if (strlen(s) > r)
3669                           goto constraintError;
3670                       break;
3671                   }
3672                   case MI_STRINGA:
3673                   {
3674                       MI_StringA x = *((MI_StringA*)pd->value);
3675           
3676 mike  1.1             for (i = 0; i < x.size; i++)
3677                       {
3678                           if (strlen(x.data[i]) > r)
3679                               goto constraintError;
3680                       }
3681                       break;
3682                   }
3683                   default:
3684                       goto incompatibleError;
3685               }
3686           
3687               return 0;
3688           
3689           constraintError:
3690               yyerrorf(
3691                   ID_PROPERTY_CONSTRAINT_FAILURE,
3692                   "value for property \"%s\" fails constraint given by \"%s\" qualifier",
3693                   MI_GET_SAFE_PRINTF_STRING(pd->name), 
3694                   MI_GET_SAFE_PRINTF_STRING(q->name));
3695               return -1;
3696           
3697 mike  1.1 incompatibleError:
3698               yyerrorf(
3699                   ID_PROPERTY_QUALIFIER_INCOMPATIBLE,
3700                   "%s qualifier applied to incompatible property: %s", 
3701                   MI_GET_SAFE_PRINTF_STRING(q->name), 
3702                   MI_GET_SAFE_PRINTF_STRING(pd->name));
3703               return -1;
3704           }
3705           
3706           static int _CheckMinLen(const MI_PropertyDecl* pd, const MI_Qualifier* q)
3707           {
3708               MI_Uint32 r;
3709               MI_Uint32 i;
3710           
3711               if (pd->type != MI_STRING && pd->type != MI_STRINGA)
3712                   goto incompatibleError;
3713           
3714               if (!q->value || !pd->value)
3715                   return 0;
3716           
3717               r = *((MI_Uint32*)q->value);
3718 mike  1.1 
3719               switch (pd->type)
3720               {
3721                   case MI_STRING:
3722                   {
3723                       const MI_Char* s = (const MI_Char*)pd->value;
3724                       if (strlen(s) < r)
3725                           goto constraintError;
3726                       break;
3727                   }
3728                   case MI_STRINGA:
3729                   {
3730                       MI_StringA x = *((MI_StringA*)pd->value);
3731           
3732                       for (i = 0; i < x.size; i++)
3733                       {
3734                           if (strlen(x.data[i]) < r)
3735                               goto constraintError;
3736                       }
3737                       break;
3738                   }
3739 mike  1.1         default:
3740                       goto incompatibleError;
3741               }
3742           
3743               return 0;
3744           
3745           constraintError:
3746               yyerrorf(
3747                   ID_PROPERTY_CONSTRAINT_FAILURE,
3748                   "value for property \"%s\" fails constraint given by \"%s\" qualifier", 
3749                   MI_GET_SAFE_PRINTF_STRING(pd->name), 
3750                   MI_GET_SAFE_PRINTF_STRING(q->name));
3751               return -1;
3752           
3753           incompatibleError:
3754               yyerrorf(
3755                   ID_PROPERTY_QUALIFIER_INCOMPATIBLE, 
3756                   "%s qualifier applied to incompatible property: %s", 
3757                   MI_GET_SAFE_PRINTF_STRING(q->name), 
3758                   MI_GET_SAFE_PRINTF_STRING(pd->name));
3759               return -1;
3760 mike  1.1 }
3761           
3762           int CheckPropertyValueConstraints(const MI_PropertyDecl* pd)
3763           {
3764               MI_Uint32 i;
3765           
3766               /* Check constraint qualifiers against the property value */
3767               for (i = 0; i < pd->numQualifiers; i++)
3768               {
3769                   const MI_Qualifier* q = pd->qualifiers[i];
3770           
3771                   if (Strcasecmp(q->name, "MaxValue") == 0 && q->value)
3772                   {
3773                       if (_CheckMaxValue(pd, q) != 0)
3774                           return -1;
3775                   }
3776                   else if (Strcasecmp(q->name, "MinValue") == 0 && q->value)
3777                   {
3778                       if (_CheckMinValue(pd, q) != 0)
3779                           return -1;
3780                   }
3781 mike  1.1         else if (Strcasecmp(q->name, "MaxLen") == 0 && q->value)
3782                   {
3783                       if (_CheckMaxLen(pd, q) != 0)
3784                           return -1;
3785                   }
3786                   else if (Strcasecmp(q->name, "MinLen") == 0 && q->value)
3787                   {
3788                       if (_CheckMinLen(pd, q) != 0)
3789                           return -1;
3790                   }
3791                   else if (Strcasecmp(q->name, "Override") == 0 && q->value &&
3792                       q->type == MI_STRING)
3793                   {
3794                       if (!(Strcasecmp(pd->name, (char*)q->value) == 0))
3795                       {
3796                           yyerrorf(
3797                               ID_OVERRIDE_QUALIFIER_NAME_MISMATCH, 
3798                               "name given by Override qualifier (\"%s\") does "
3799                               "not match property name (\"%s\")", (char*)q->value,
3800                               pd->name);
3801                       }
3802 mike  1.1         }
3803               }
3804           
3805               /* Success! */
3806               return 0;
3807           }
3808           
3809           int ResolveEmbeddedInstanceQualifier(const MOF_EmbeddedInstance* ei)
3810           {
3811               const char* cn;
3812               MI_Qualifier* q = ei->qualifier;
3813           
3814               if (q->type != MI_STRING || Strcasecmp(q->name, "EmbeddedInstance") != 0)
3815               {
3816                   yyerrorf(ID_INTERNAL_ERROR, "internal error: %s(%u)", __FILE__, 
3817                       __LINE__);
3818                   return -1;
3819               }
3820           
3821               cn = (const char*)q->value;
3822           
3823 mike  1.1     if (cn)
3824               {
3825                   const MI_ClassDecl* cd = FindClassDecl(cn);
3826           
3827                   if (!cd)
3828                   {
3829                       state.line = ei->line;
3830                       yyerrorf(
3831                           ID_UNDEFINED_CLASS_IN_EMBEDDEDINSTANCE_QUALIFIER,
3832                           "Undefined class in EmbeddedInstance qualifier: %s", cn);
3833                       return -1;
3834                   }
3835           
3836                   /* Use the original casing for the classname */
3837                   q->value = cd->name;
3838               }
3839           
3840               return 0;
3841           }
3842           
3843           int PerformPostProcessing()
3844 mike  1.1 {
3845               MI_Uint32 i;
3846           
3847               for (i = 0; i < state.embeddedInstanceList.size; i++)
3848               {
3849                   if (0 != ResolveEmbeddedInstanceQualifier(state.embeddedInstanceList.data[i]))
3850                       return -1;
3851               }
3852           
3853               return 0;
3854           }
3855           
3856           MI_Type InitializerToType(const MOF_Initializer* initializer)
3857           {
3858               if (initializer->isArray)
3859               {
3860                   switch (initializer->data[0].type)
3861                   {
3862                       case TOK_INTEGER_VALUE:
3863                           return MI_SINT64A;
3864                       case TOK_REAL_VALUE:
3865 mike  1.1                 return MI_REAL64A;
3866                       case TOK_CHAR_VALUE:
3867                           return MI_CHAR16A;
3868                       case TOK_STRING_VALUE:
3869                           return MI_STRINGA;
3870                       case TOK_BOOLEAN_VALUE:
3871                           return MI_BOOLEANA;
3872                       case TOK_NULL:
3873                           return MI_STRINGA;
3874                   }
3875               }
3876               else
3877               {
3878                   switch (initializer->data[0].type)
3879                   {
3880                       case TOK_INTEGER_VALUE:
3881                           return MI_SINT64;
3882                       case TOK_REAL_VALUE:
3883                           return MI_REAL64;
3884                       case TOK_CHAR_VALUE:
3885                           return MI_CHAR16;
3886 mike  1.1             case TOK_STRING_VALUE:
3887                           return MI_STRING;
3888                       case TOK_BOOLEAN_VALUE:
3889                           return MI_BOOLEAN;
3890                       case TOK_NULL:
3891                           return MI_STRING;
3892                   }
3893               }
3894           
3895               /* Unreachable */
3896               return MI_BOOLEAN;
3897           }
3898           
3899           int AddInstanceDecl(MI_InstanceDecl* id)
3900           {
3901               /* Add the declaration */
3902               PtrArray_Append((PtrArray*)&state.instanceDecls, id);
3903               return 0;
3904           }

ViewCVS 0.9.2