version 1.2, 2015/04/20 18:10:13
|
version 1.3, 2015/04/20 18:19:53
|
|
|
#include "state.h" | #include "state.h" |
#include <base/helpers.h> | #include <base/helpers.h> |
| |
|
#ifdef _PREFAST_ |
|
#pragma prefast (push) |
|
#pragma prefast (disable: 28719) |
|
#endif |
|
|
/* | /* |
**============================================================================== | **============================================================================== |
** | ** |
|
|
static int _ParseUint32( | static int _ParseUint32( |
const char* p, | const char* p, |
size_t n, | size_t n, |
|
MI_Boolean asterisks, |
MI_Uint32* result) | MI_Uint32* result) |
{ | { |
char buf[9]; | char buf[9]; |
char* end; | char* end; |
|
size_t i; |
| |
if (n > 8) | if (n > 8) |
return -1; | return -1; |
|
|
memcpy(buf, p, n); | memcpy(buf, p, n); |
buf[n] = '\0'; | buf[n] = '\0'; |
| |
|
if (asterisks && buf[0] == '*') |
|
{ |
|
for (i = 1; i < n; i++) |
|
{ |
|
if (buf[i] != '*') |
|
return -1; |
|
} |
|
*result = 0; |
|
return 0; |
|
} |
*result = (MI_Uint32)strtoul(buf, &end, 10); | *result = (MI_Uint32)strtoul(buf, &end, 10); |
| |
if (*end != '\0') | if (*end != '\0') |
|
|
{ "DISABLEOVERRIDE", MI_FLAG_DISABLEOVERRIDE }, | { "DISABLEOVERRIDE", MI_FLAG_DISABLEOVERRIDE }, |
{ "RESTRICTED", MI_FLAG_RESTRICTED}, | { "RESTRICTED", MI_FLAG_RESTRICTED}, |
{ "TOSUBCLASS", MI_FLAG_TOSUBCLASS}, | { "TOSUBCLASS", MI_FLAG_TOSUBCLASS}, |
|
{ "TOINSTANCE", MI_FLAG_TOINSTANCE}, |
{ "TRANSLATABLE", MI_FLAG_TRANSLATABLE}, | { "TRANSLATABLE", MI_FLAG_TRANSLATABLE}, |
}; | }; |
| |
|
|
MI_Uint32 ss; | MI_Uint32 ss; |
MI_Uint32 mmmmmm; | MI_Uint32 mmmmmm; |
| |
if (_ParseUint32(p, 8, &dddddddd) != 0) |
if (_ParseUint32(p, 8, MI_FALSE, &dddddddd) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 8, 2, &hh) != 0) |
if (_ParseUint32(p + 8, 2, MI_FALSE, &hh) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 10, 2, &mm) != 0) |
if (_ParseUint32(p + 10, 2, MI_FALSE, &mm) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 12, 2, &ss) != 0) |
if (_ParseUint32(p + 12, 2, MI_FALSE, &ss) != 0) |
return -1; | return -1; |
if (p[14] != '.') | if (p[14] != '.') |
return -1; | return -1; |
if (_ParseUint32(p + 15, 6, &mmmmmm) != 0) |
if (_ParseUint32(p + 15, 6, MI_TRUE, &mmmmmm) != 0) |
return -1; | return -1; |
if (p[22] != '0' || p[23] != '0' || p[24] != '0') | if (p[22] != '0' || p[23] != '0' || p[24] != '0') |
return -1; | return -1; |
|
|
} | } |
else | else |
{ | { |
|
/* Any field may be replaced with asterisks, which indicates |
|
a repetitive time, that is, every year on a certain day or |
|
every certain day of any month. For time zones, "+***" |
|
means use the local time zone. In this implementation, this |
|
is only useful for the year, month, and day fields, because |
|
the asterisk fields are returned as 0, which is a valid hour, |
|
minute, second, micorosecond and time zone ("+***" becomes |
|
"+000", which is UTC). If support for repetitive times |
|
in these fields is needed, perhaps the non time zone |
|
fields in MI_DateTime::u.timestamp can be made signed |
|
and set to -1 when asterisks are seen. |
|
*/ |
|
|
/* YYYYMMDDHHMMSS.MMMMMMSUTC */ | /* YYYYMMDDHHMMSS.MMMMMMSUTC */ |
MI_Uint32 yyyy; | MI_Uint32 yyyy; |
MI_Uint32 MM; | MI_Uint32 MM; |
|
|
MI_Uint32 s; | MI_Uint32 s; |
MI_Uint32 utc; | MI_Uint32 utc; |
| |
if (_ParseUint32(p, 4, &yyyy) != 0) |
if (_ParseUint32(p, 4, MI_TRUE, &yyyy) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 4, 2, &MM) != 0) |
if (_ParseUint32(p + 4, 2, MI_TRUE, &MM) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 6, 2, &dd) != 0) |
if (_ParseUint32(p + 6, 2, MI_TRUE, &dd) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 8, 2, &hh) != 0) |
if (_ParseUint32(p + 8, 2, MI_TRUE, &hh) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 10, 2, &mm) != 0) |
if (_ParseUint32(p + 10, 2, MI_TRUE, &mm) != 0) |
return -1; | return -1; |
if (_ParseUint32(p + 12, 2, &ss) != 0) |
if (_ParseUint32(p + 12, 2, MI_TRUE, &ss) != 0) |
return -1; | return -1; |
if (p[14] != '.') | if (p[14] != '.') |
return -1; | return -1; |
if (_ParseUint32(p + 15, 6, &mmmmmm) != 0) |
if (_ParseUint32(p + 15, 6, MI_TRUE, &mmmmmm) != 0) |
return -1; | return -1; |
s = p[21]; | s = p[21]; |
if (s != '-' && s != '+') | if (s != '-' && s != '+') |
return -1; | return -1; |
if (_ParseUint32(p + 22, 3, &utc) != 0) |
if (_ParseUint32(p + 22, 3, MI_TRUE, &utc) != 0) |
return -1; | return -1; |
| |
/* Set the result */ | /* Set the result */ |
|
|
{ | { |
return 0; | return 0; |
} | } |
|
case MI_STRING: |
|
{ |
|
char Buf[24]; |
|
MI_Char* q; |
|
MI_Sint64 x = *p; |
|
|
|
if (x < 0) |
|
{ |
|
sprintf(Buf, "%ld", (long)x); |
|
} |
|
else |
|
{ |
|
sprintf(Buf, "%lu", (unsigned long)x); |
|
} |
|
q = MALLOC_T(MI_Char, strlen(Buf) + 1); |
|
strcpy(q, Buf); |
|
*value = q; |
|
return 0; |
|
} |
default: | default: |
{ | { |
return -1; | return -1; |
|
|
{ | { |
return 0; | return 0; |
} | } |
|
case MI_STRING: |
|
{ |
|
char Buf[24]; |
|
MI_Char* q; |
|
MI_Real64 x = *p; |
|
sprintf(Buf, "%f", x); |
|
q = MALLOC_T(MI_Char, strlen(Buf) + 1); |
|
strcpy(q, Buf); |
|
*value = q; |
|
return 0; |
|
} |
default: | default: |
{ | { |
return -1; | return -1; |
|
|
switch (destType) | switch (destType) |
{ | { |
case MI_STRING: | case MI_STRING: |
|
case MI_INSTANCE: |
|
case MI_REFERENCE: |
{ | { |
return 0; | return 0; |
} | } |
|
|
{ | { |
return 0; | return 0; |
} | } |
|
case MI_STRINGA: |
|
{ |
|
char Buf[24]; |
|
MI_StringA* q; |
|
NEW_ARRAY_T(q, MI_String, p->size); |
|
for (i = 0; i < p->size; i++) |
|
{ |
|
MI_Sint64 x = p->data[i]; |
|
if (x < 0) |
|
{ |
|
sprintf(Buf, "%ld", (long)x); |
|
} |
|
else |
|
{ |
|
sprintf(Buf, "%lu", (unsigned long)x); |
|
} |
|
strcpy(q->data[i], Buf); |
|
} |
|
|
|
*value = q; |
|
return 0; |
|
} |
default: | default: |
return -1; | return -1; |
} | } |
|
|
*value = q; | *value = q; |
return 0; | return 0; |
} | } |
|
case MI_STRINGA: |
|
{ |
|
char Buf[24]; |
|
MI_StringA* q; |
|
NEW_ARRAY_T(q, MI_String, p->size); |
|
for (i = 0; i < p->size; i++) |
|
{ |
|
MI_Real64 x = p->data[i]; |
|
sprintf(Buf, "%f", x); |
|
strcpy(q->data[i], Buf); |
|
} |
|
|
|
*value = q; |
|
return 0; |
|
} |
default: | default: |
return -1; | return -1; |
} | } |
|
|
switch (destType) | switch (destType) |
{ | { |
case MI_STRINGA: | case MI_STRINGA: |
|
case MI_INSTANCEA: |
|
case MI_REFERENCEA: |
{ | { |
return 0; | return 0; |
} | } |
|
|
void** value) | void** value) |
{ | { |
/* ATTN: this function could check integer truncation and sign errors */ | /* ATTN: this function could check integer truncation and sign errors */ |
/* ATTN: handle case where MI_Char is wchar_t */ |
/* ATTN: handle case where ZChar is wchar_t */ |
size_t i; | size_t i; |
| |
/* Check arguments */ | /* Check arguments */ |
|
|
| |
*value = NULL; | *value = NULL; |
| |
/* Verify that there is at least one element */ |
/* Early out for a zero-length array */ |
if (self->size == 0) | if (self->size == 0) |
return -1; |
return 0; |
| |
/* Verify that array is homogeneous (all elements have same type) */ | /* Verify that array is homogeneous (all elements have same type) */ |
for (i = 1; i < self->size; i++) | for (i = 1; i < self->size; i++) |
|
|
if (!self->isArray && self->size != 1) | if (!self->isArray && self->size != 1) |
return -1; | return -1; |
| |
/* Convert to a Statik value */ |
/* Convert to a static value */ |
if (self->isArray) | if (self->isArray) |
{ | { |
switch (self->data[0].type) | switch (self->data[0].type) |
|
|
*value = p; | *value = p; |
return 0; | return 0; |
} | } |
|
case MI_STRINGA: |
|
{ |
|
char Buf[24]; |
|
MI_StringA* p; |
|
NEW_ARRAY_T(p, MI_String, self->size); |
|
for (i = 0; i < self->size; i++) |
|
{ |
|
if (self->data->value.integer < 0) |
|
{ |
|
sprintf(Buf, "%ld", (long)self->data->value.integer); |
|
} |
|
else |
|
{ |
|
sprintf(Buf, "%lu", (unsigned long)self->data->value.integer); |
|
} |
|
p->data[i] = MALLOC_T(MI_Char, strlen(Buf) + 1); |
|
strcpy(p->data[i], Buf); |
|
} |
|
*value = p; |
|
return 0; |
|
} |
default: | default: |
return -1; | return -1; |
} | } |
|
|
| |
for (i = 0; i < self->size; i++) | for (i = 0; i < self->size; i++) |
{ | { |
p->data[i] = (MI_Real32) |
p->data[i] = (MI_Real32)self->data[i].value.real; |
self->data[i].value.real; |
|
} | } |
| |
*value = p; | *value = p; |
|
|
*value = p; | *value = p; |
return 0; | return 0; |
} | } |
|
case MI_STRINGA: |
|
{ |
|
char Buf[24]; |
|
MI_StringA* p; |
|
NEW_ARRAY_T(p, MI_String, self->size); |
|
for (i = 0; i < self->size; i++) |
|
{ |
|
sprintf(Buf, "%f", self->data->value.real); |
|
p->data[i] = MALLOC_T(MI_Char, strlen(Buf) + 1); |
|
strcpy(p->data[i], Buf); |
|
} |
|
*value = p; |
|
return 0; |
|
} |
default: | default: |
return -1; | return -1; |
} | } |
|
|
| |
for (i = 0; i < self->size; i++) | for (i = 0; i < self->size; i++) |
{ | { |
p->data[i] = (MI_Char16) |
p->data[i] = (MI_Char16)self->data[i].value.character; |
self->data[i].value.character; |
|
} | } |
| |
*value = p; | *value = p; |
|
|
return -1; | return -1; |
} | } |
} | } |
|
case TOK_INSTANCE: |
case TOK_NULL: | case TOK_NULL: |
{ | { |
*value = NULL; | *value = NULL; |
|
|
*value = p; | *value = p; |
return 0; | return 0; |
} | } |
|
case MI_STRING: |
|
{ |
|
char Buf[24]; |
|
MI_Char* p; |
|
if (self->data->value.integer < 0) |
|
{ |
|
sprintf(Buf, "%ld", (long)self->data->value.integer); |
|
} |
|
else |
|
{ |
|
sprintf(Buf, "%lu", (unsigned long)self->data->value.integer); |
|
} |
|
p = MALLOC_T(MI_Char, strlen(Buf) + 1); |
|
strcpy(p, Buf); |
|
*value = p; |
|
return 0; |
|
} |
default: | default: |
return -1; | return -1; |
} | } |
|
|
*value = p; | *value = p; |
return 0; | return 0; |
} | } |
|
case MI_STRING: |
|
{ |
|
char Buf[24]; |
|
MI_Char* p; |
|
sprintf(Buf, "%f", self->data->value.real); |
|
p = MALLOC_T(MI_Char, strlen(Buf) + 1); |
|
strcpy(p, Buf); |
|
*value = p; |
|
return 0; |
|
} |
default: | default: |
return -1; | return -1; |
} | } |
|
|
} | } |
break; | break; |
} | } |
case TOK_NULL: { |
case TOK_INSTANCE: |
|
case TOK_NULL: |
|
{ |
*value = NULL; | *value = NULL; |
return 0; | return 0; |
} | } |
|
|
| |
UNREACHABLE_RETURN( return 0; ) | UNREACHABLE_RETURN( return 0; ) |
} | } |
|
|
void ReleaseInitializer( | void ReleaseInitializer( |
MOF_Initializer* init) | MOF_Initializer* init) |
{ | { |
|
|
for (i = 0; i < _flagsSize; i++) | for (i = 0; i < _flagsSize; i++) |
{ | { |
if (_flags[i].flag & flags) | if (_flags[i].flag & flags) |
fprintf(file," %s", MI_GET_SAFE_PRINTF_STRING(_flags[i].name)); |
fprintf(file," %s", scs(_flags[i].name)); |
} | } |
| |
fprintf(file,"\n"); | fprintf(file,"\n"); |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* type */ | /* type */ |
_indent(level, file); | _indent(level, file); |
|
|
fprintf(file," RESTRICTED"); | fprintf(file," RESTRICTED"); |
if (self->flavor & MI_FLAG_TOSUBCLASS) | if (self->flavor & MI_FLAG_TOSUBCLASS) |
fprintf(file," TOSUBCLASS"); | fprintf(file," TOSUBCLASS"); |
|
if (self->flavor & MI_FLAG_TOINSTANCE) |
|
fprintf(file," TOINSTANCE"); |
if (self->flavor & MI_FLAG_TRANSLATABLE) | if (self->flavor & MI_FLAG_TRANSLATABLE) |
fprintf(file," TRANSLATABLE"); | fprintf(file," TRANSLATABLE"); |
| |
|
|
fprintf(file,"}\n"); | fprintf(file,"}\n"); |
} | } |
| |
static void _DatetimeToStr(const MI_Datetime* x, char buf[26]) |
static void _DatetimeToStr(const MI_Datetime* x, _Pre_writable_size_(26) char buf[26]) |
{ | { |
if (x->isTimestamp) | if (x->isTimestamp) |
{ | { |
const MI_Char FMT[] = "%04d%02d%02d%02d%02d%02d.%06d%c%03d"; |
const ZChar FMT[] = "%04d%02d%02d%02d%02d%02d.%06d%c%03d"; |
MI_Sint32 utc = x->u.timestamp.utc; | MI_Sint32 utc = x->u.timestamp.utc; |
Snprintf(buf, 26, FMT, | Snprintf(buf, 26, FMT, |
x->u.timestamp.year, | x->u.timestamp.year, |
|
|
} | } |
else | else |
{ | { |
const MI_Char FMT[] = "%08u%02u%02u%02u.%06u:000"; |
const ZChar FMT[] = "%08u%02u%02u%02u.%06u:000"; |
Snprintf(buf, 26, FMT, | Snprintf(buf, 26, FMT, |
x->u.interval.days, | x->u.interval.days, |
x->u.interval.hours, | x->u.interval.hours, |
|
|
} | } |
case MI_STRING: | case MI_STRING: |
{ | { |
fprintf(file,"%s", MI_GET_SAFE_PRINTF_STRING(((const char*)value))); |
fprintf(file,"%s", scs(((const char*)value))); |
break; | break; |
} | } |
case MI_BOOLEANA: | case MI_BOOLEANA: |
|
|
| |
for (i = 0; i < arr->size; i++) | for (i = 0; i < arr->size; i++) |
{ | { |
fprintf(file,"%s", MI_GET_SAFE_PRINTF_STRING(arr->data[i])); |
fprintf(file,"%s", scs(arr->data[i])); |
| |
if (i + 1 != arr->size) | if (i + 1 != arr->size) |
fprintf(file,", "); | fprintf(file,", "); |
|
|
{ | { |
yyerrorf(ID_QUALIFIER_ALREADY_DECLARED, | yyerrorf(ID_QUALIFIER_ALREADY_DECLARED, |
"qualifier already declared: \"%s\"", | "qualifier already declared: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(qd->name)); |
scs(qd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
if (FindClassDecl(qd->name)) | if (FindClassDecl(qd->name)) |
{ | { |
yyerrorf(ID_CLASS_ALREADY_DEFINED, "class already declared: \"%s\"", | yyerrorf(ID_CLASS_ALREADY_DEFINED, "class already declared: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(qd->name)); |
scs(qd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* type */ | /* type */ |
_indent(level, file); | _indent(level, file); |
|
|
fprintf(file," RESTRICTED"); | fprintf(file," RESTRICTED"); |
if (self->flavor & MI_FLAG_TOSUBCLASS) | if (self->flavor & MI_FLAG_TOSUBCLASS) |
fprintf(file," TOSUBCLASS"); | fprintf(file," TOSUBCLASS"); |
|
if (self->flavor & MI_FLAG_TOINSTANCE) |
|
fprintf(file," TOINSTANCE"); |
if (self->flavor & MI_FLAG_TRANSLATABLE) | if (self->flavor & MI_FLAG_TRANSLATABLE) |
fprintf(file," TRANSLATABLE"); | fprintf(file," TRANSLATABLE"); |
| |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* type */ | /* type */ |
_indent(level, file); | _indent(level, file); |
|
|
if (self->className) | if (self->className) |
{ | { |
_indent(level, file); | _indent(level, file); |
fprintf(file,"className: %s\n", MI_GET_SAFE_PRINTF_STRING(self->className)); |
fprintf(file,"className: %s\n", scs(self->className)); |
} | } |
| |
/* subscript */ | /* subscript */ |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* type */ | /* type */ |
_indent(level, file); | _indent(level, file); |
|
|
if (self->className) | if (self->className) |
{ | { |
_indent(level, file); | _indent(level, file); |
fprintf(file,"className: %s\n", MI_GET_SAFE_PRINTF_STRING(self->className)); |
fprintf(file,"className: %s\n", scs(self->className)); |
} | } |
| |
/* offset */ | /* offset */ |
|
|
if (self->origin) | if (self->origin) |
{ | { |
_indent(level, file); | _indent(level, file); |
fprintf(file,"origin: %s\n", MI_GET_SAFE_PRINTF_STRING(self->origin)); |
fprintf(file,"origin: %s\n", scs(self->origin)); |
} | } |
| |
/* propagator */ | /* propagator */ |
if (self->propagator) | if (self->propagator) |
{ | { |
_indent(level, file); | _indent(level, file); |
fprintf(file,"propagator: %s\n", MI_GET_SAFE_PRINTF_STRING(self->propagator)); |
fprintf(file,"propagator: %s\n", scs(self->propagator)); |
} | } |
| |
/* value */ | /* value */ |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* size */ | /* size */ |
_indent(level, file); | _indent(level, file); |
|
|
if (self->origin) | if (self->origin) |
{ | { |
_indent(level, file); | _indent(level, file); |
fprintf(file,"origin: %s\n", MI_GET_SAFE_PRINTF_STRING(self->origin)); |
fprintf(file,"origin: %s\n", scs(self->origin)); |
} | } |
| |
/* propagator */ | /* propagator */ |
if (self->propagator) | if (self->propagator) |
{ | { |
_indent(level, file); | _indent(level, file); |
fprintf(file,"propagator: %s\n", MI_GET_SAFE_PRINTF_STRING(self->propagator)); |
fprintf(file,"propagator: %s\n", scs(self->propagator)); |
} | } |
| |
level--; | level--; |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* superClass */ | /* superClass */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"superClass: %s\n", MI_GET_SAFE_PRINTF_STRING(self->superClass)); |
fprintf(file,"superClass: %s\n", scs(self->superClass)); |
| |
/* size */ | /* size */ |
_indent(level, file); | _indent(level, file); |
|
|
| |
/* name */ | /* name */ |
_indent(level, file); | _indent(level, file); |
fprintf(file,"name: %s\n", MI_GET_SAFE_PRINTF_STRING(self->name)); |
fprintf(file,"name: %s\n", scs(self->name)); |
| |
/* size */ | /* size */ |
_indent(level, file); | _indent(level, file); |
|
|
** already in the list are appended. Qualifiers already in the list are | ** already in the list are appended. Qualifiers already in the list are |
** overriden. | ** overriden. |
** | ** |
** Propation is performed using the MI_Qualifier.flavor whose bits may be |
** Propagation is performed using the MI_Qualifier.flavor whose bits may be |
** masked by these macros. | ** masked by these macros. |
** | ** |
** MI_FLAG_ENABLEOVERRIDE | ** MI_FLAG_ENABLEOVERRIDE |
|
|
} | } |
else | else |
{ | { |
|
_Analysis_assume_(qualifierList.data); |
|
|
/* If DisableOverride flavor, then disallow value change */ | /* If DisableOverride flavor, then disallow value change */ |
if (qualifierList.data[pos]->flavor & MI_FLAG_DISABLEOVERRIDE && | if (qualifierList.data[pos]->flavor & MI_FLAG_DISABLEOVERRIDE && |
!Identical(qualifierList.data[pos]->value, q->value, q->type)) | !Identical(qualifierList.data[pos]->value, q->value, q->type)) |
|
|
{ | { |
yyerrorf(ID_ILLEGAL_QUALIFIER_OVERRIDE, | yyerrorf(ID_ILLEGAL_QUALIFIER_OVERRIDE, |
"illegal qualifier override: %s.%s.%s", | "illegal qualifier override: %s.%s.%s", |
MI_GET_SAFE_PRINTF_STRING(className), |
scs(className), |
MI_GET_SAFE_PRINTF_STRING(featureName), |
scs(featureName), |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
} | } |
else | else |
{ | { |
yyerrorf(ID_ILLEGAL_QUALIFIER_OVERRIDE, | yyerrorf(ID_ILLEGAL_QUALIFIER_OVERRIDE, |
"illegal qualifier override: %s.%s.%s", | "illegal qualifier override: %s.%s.%s", |
"", | "", |
MI_GET_SAFE_PRINTF_STRING(className), |
scs(className), |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
} | } |
return -1; | return -1; |
} | } |
|
|
if (!super) | if (!super) |
{ | { |
yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", | yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(cd->superClass)); |
scs(cd->superClass)); |
return -1; | return -1; |
} | } |
| |
|
|
MI_Uint32 numQualifiers; | MI_Uint32 numQualifiers; |
| |
/* This property overrides an inherited property */ | /* This property overrides an inherited property */ |
|
_Analysis_assume_(propertySet.data); |
| |
if (_FinalizeQualifiers( | if (_FinalizeQualifiers( |
cd->name, | cd->name, |
|
|
if (!super) | if (!super) |
{ | { |
yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", | yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(cd->superClass)); |
scs(cd->superClass)); |
return -1; | return -1; |
} | } |
| |
|
|
yyerrorf(ID_KEY_MUTATION_ERROR, | yyerrorf(ID_KEY_MUTATION_ERROR, |
"property \"%s\" defined as [key] in class \"%s\", " | "property \"%s\" defined as [key] in class \"%s\", " |
"but was not key in base class", | "but was not key in base class", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(cd->name)); |
scs(cd->name)); |
return -1; | return -1; |
} | } |
} | } |
|
|
yyerrorf(ID_KEY_TYPE_MUTATION_ERROR, | yyerrorf(ID_KEY_TYPE_MUTATION_ERROR, |
"key property \"%s\" re-defined with different type " | "key property \"%s\" re-defined with different type " |
"in class \"%s\"", | "in class \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(cd->name)); |
scs(cd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
yyerrorf(ID_KEY_STRUCTURE_MUTATION_ERROR, | yyerrorf(ID_KEY_STRUCTURE_MUTATION_ERROR, |
"new key property \"%s\" is introduced by class \"%s\"", | "new key property \"%s\" is introduced by class \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(cd->name)); |
scs(cd->name)); |
return -1; | return -1; |
} | } |
} | } |
|
|
if (!super) | if (!super) |
{ | { |
yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", | yyerrorf(ID_UNDEFINED_CLASS, "undefined class: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(cd->superClass)); |
scs(cd->superClass)); |
return -1; | return -1; |
} | } |
| |
|
|
MI_Qualifier** qualifiers; | MI_Qualifier** qualifiers; |
MI_Uint32 numQualifiers; | MI_Uint32 numQualifiers; |
| |
|
_Analysis_assume_(methodList.data); |
|
|
/* This method overrides an inherited method */ | /* This method overrides an inherited method */ |
if (_FinalizeQualifiers( | if (_FinalizeQualifiers( |
cd->name, | cd->name, |
|
|
return 0; | return 0; |
} | } |
| |
|
static MI_Boolean _HasRefs( |
|
const MI_ClassDecl* cd) |
|
{ |
|
size_t i; |
|
|
|
for (i = 0; i < cd->numProperties; i++) |
|
{ |
|
MI_PropertyDecl* pd = cd->properties[i]; |
|
|
|
if (pd->type == MI_REFERENCE) |
|
{ |
|
return MI_TRUE; |
|
} |
|
} |
|
|
|
return MI_FALSE; |
|
} |
|
|
int FinalizeClass(MI_ClassDecl* cd) | int FinalizeClass(MI_ClassDecl* cd) |
{ | { |
/* | /* |
|
|
if (_FinalizeClassMethods(cd) != 0) | if (_FinalizeClassMethods(cd) != 0) |
return -1; | return -1; |
| |
|
/* Perform association and reference check */ |
|
if (!(cd->flags & MI_FLAG_ASSOCIATION) && _HasRefs(cd)) |
|
{ |
|
yywarnf(ID_INVALID_REFERENCE, |
|
"class \"%s\" has at least one reference property but no 'Association' qualifier", |
|
scs(cd->name)); |
|
} |
|
|
|
/* Check schema prefix in classname */ |
|
if (strchr(cd->name, '_') == NULL) |
|
{ |
|
yywarnf(ID_NON_STANDARD_COMPLIANT_CLASSNAME, |
|
"classname \"%s\" has no schema prefix e.g. prefix \"CIM_\" in classname \"CIM_Device\"", |
|
scs(cd->name)); |
|
} |
|
|
return 0; | return 0; |
} | } |
| |
|
|
return -1; | return -1; |
} | } |
| |
/* Assume type of class property */ |
/* Assume type of class property if not instance or reference */ |
|
if (q->type != MI_INSTANCE && |
|
q->type != MI_REFERENCE && |
|
q->type != MI_INSTANCEA && |
|
q->type != MI_REFERENCEA) |
p->type = q->type; | p->type = q->type; |
} | } |
| |
|
|
if (!qd) | if (!qd) |
{ | { |
yyerrorf(ID_UNKNOWN_QUALIFIER, "unknown qualifier: \"%s\"", | yyerrorf(ID_UNKNOWN_QUALIFIER, "unknown qualifier: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, | yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, |
"illegal scope for qualifier: \"%s\"", | "illegal scope for qualifier: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, | yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, |
"illegal scope for qualifier: \"%s\"", | "illegal scope for qualifier: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, | yyerrorf(ID_ILLEGAL_SCOPE_FOR_QUALIFIER, |
"illegal scope for qualifier: \"%s\"", | "illegal scope for qualifier: \"%s\"", |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
} | } |
} | } |
|
|
yyerrorf( | yyerrorf( |
ID_PROPERTY_CONSTRAINT_FAILURE, | ID_PROPERTY_CONSTRAINT_FAILURE, |
"value for property \"%s\" fails constraint given by \"%s\" qualifier", | "value for property \"%s\" fails constraint given by \"%s\" qualifier", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
| |
incompatibleError: | incompatibleError: |
yyerrorf( | yyerrorf( |
ID_PROPERTY_QUALIFIER_INCOMPATIBLE, | ID_PROPERTY_QUALIFIER_INCOMPATIBLE, |
"%s qualifier applied to incompatible property: %s", | "%s qualifier applied to incompatible property: %s", |
MI_GET_SAFE_PRINTF_STRING(q->name), |
scs(q->name), |
MI_GET_SAFE_PRINTF_STRING(pd->name)); |
scs(pd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
yyerrorf( | yyerrorf( |
ID_PROPERTY_CONSTRAINT_FAILURE, | ID_PROPERTY_CONSTRAINT_FAILURE, |
"value for property \"%s\" fails constraint given by \"%s\" qualifier", | "value for property \"%s\" fails constraint given by \"%s\" qualifier", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
| |
incompatibleError: | incompatibleError: |
yyerrorf( | yyerrorf( |
ID_PROPERTY_QUALIFIER_INCOMPATIBLE, | ID_PROPERTY_QUALIFIER_INCOMPATIBLE, |
"%s qualifier applied to incompatible property: %s", | "%s qualifier applied to incompatible property: %s", |
MI_GET_SAFE_PRINTF_STRING(q->name), |
scs(q->name), |
MI_GET_SAFE_PRINTF_STRING(pd->name)); |
scs(pd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
case MI_STRING: | case MI_STRING: |
{ | { |
const MI_Char* s = (const MI_Char*)pd->value; |
const ZChar* s = (const ZChar*)pd->value; |
if (strlen(s) > r) | if (strlen(s) > r) |
goto constraintError; | goto constraintError; |
break; | break; |
|
|
yyerrorf( | yyerrorf( |
ID_PROPERTY_CONSTRAINT_FAILURE, | ID_PROPERTY_CONSTRAINT_FAILURE, |
"value for property \"%s\" fails constraint given by \"%s\" qualifier", | "value for property \"%s\" fails constraint given by \"%s\" qualifier", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
| |
incompatibleError: | incompatibleError: |
yyerrorf( | yyerrorf( |
ID_PROPERTY_QUALIFIER_INCOMPATIBLE, | ID_PROPERTY_QUALIFIER_INCOMPATIBLE, |
"%s qualifier applied to incompatible property: %s", | "%s qualifier applied to incompatible property: %s", |
MI_GET_SAFE_PRINTF_STRING(q->name), |
scs(q->name), |
MI_GET_SAFE_PRINTF_STRING(pd->name)); |
scs(pd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
case MI_STRING: | case MI_STRING: |
{ | { |
const MI_Char* s = (const MI_Char*)pd->value; |
const ZChar* s = (const ZChar*)pd->value; |
if (strlen(s) < r) | if (strlen(s) < r) |
goto constraintError; | goto constraintError; |
break; | break; |
|
|
yyerrorf( | yyerrorf( |
ID_PROPERTY_CONSTRAINT_FAILURE, | ID_PROPERTY_CONSTRAINT_FAILURE, |
"value for property \"%s\" fails constraint given by \"%s\" qualifier", | "value for property \"%s\" fails constraint given by \"%s\" qualifier", |
MI_GET_SAFE_PRINTF_STRING(pd->name), |
scs(pd->name), |
MI_GET_SAFE_PRINTF_STRING(q->name)); |
scs(q->name)); |
return -1; | return -1; |
| |
incompatibleError: | incompatibleError: |
yyerrorf( | yyerrorf( |
ID_PROPERTY_QUALIFIER_INCOMPATIBLE, | ID_PROPERTY_QUALIFIER_INCOMPATIBLE, |
"%s qualifier applied to incompatible property: %s", | "%s qualifier applied to incompatible property: %s", |
MI_GET_SAFE_PRINTF_STRING(q->name), |
scs(q->name), |
MI_GET_SAFE_PRINTF_STRING(pd->name)); |
scs(pd->name)); |
return -1; | return -1; |
} | } |
| |
|
|
{ | { |
if (initializer->isArray) | if (initializer->isArray) |
{ | { |
|
if (initializer->size == 0) |
|
return MI_STRINGA; |
switch (initializer->data[0].type) | switch (initializer->data[0].type) |
{ | { |
case TOK_INTEGER_VALUE: | case TOK_INTEGER_VALUE: |
|
|
PtrArray_Append((PtrArray*)&state.instanceDecls, id); | PtrArray_Append((PtrArray*)&state.instanceDecls, id); |
return 0; | return 0; |
} | } |
|
|
|
#ifdef _PREFAST_ |
|
#pragma prefast (pop) |
|
#endif |