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