int InitializerToValue()

in LCM/codec/mof/parser/types.c [1073:1666]


int InitializerToValue(
    void * mofstate,
    MOF_Initializer* self, 
    MI_Uint32 /*MI_Type*/ type,
    void** value)
{
    /* ATTN: this function could check integer truncation and sign errors */
    /* ATTN: handle case where ZChar is wchar_t */
    size_t i;
    MOF_State * state = (MOF_State *)mofstate;

    /* Check arguments */
    if (!self || !value)
        return -1;

    *value = NULL;

    /* Verify that there is at least one element */
    if (self->size == 0)
    {
        MI_Sint64A* p;
        NEW_ARRAY_T(p, MI_Sint64, self->size);
        p->data = NULL;
        *value = p; 
        return 0;
    }

    /* Verify that array is homogeneous (all elements have same type) */
    for (i = 1; i < self->size; i++)
    {
        if (self->data[0].type != self->data[i].type)
            return -1;
    }

    /* Verify that scalars have exactly 1 initializer */
    if (!self->isArray && self->size != 1)
        return -1;

    /* Convert to a Statik value */
    if (self->isArray)
    {
        switch (self->data[0].type)
        {
            case TOK_INTEGER_VALUE:
            {
                switch (type)
                {
                    case MI_UINT8A:
                    {
                        MI_Uint8A* p;
                        NEW_ARRAY_T(p, MI_Uint8, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_UINT8))
                                return -1;

                            p->data[i] = (MI_Uint8)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_SINT8A:
                    {
                        MI_Sint8A* p;
                        NEW_ARRAY_T(p, MI_Sint8, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_SINT8))
                                return -1;

                            p->data[i] = (MI_Sint8)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_UINT16A:
                    {
                        MI_Uint16A* p;
                        NEW_ARRAY_T(p, MI_Uint16, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_UINT16))
                                return -1;

                            p->data[i] = (MI_Uint16)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_SINT16A:
                    {
                        MI_Sint16A* p;
                        NEW_ARRAY_T(p, MI_Sint16, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_SINT16))
                                return -1;

                            p->data[i] = (MI_Sint16)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_UINT32A:
                    {
                        MI_Uint32A* p;
                        NEW_ARRAY_T(p, MI_Uint32, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_UINT32))
                                return -1;

                            p->data[i] = (MI_Uint32)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_SINT32A:
                    {
                        MI_Sint32A* p;
                        NEW_ARRAY_T(p, MI_Sint32, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_SINT32))
                                return -1;

                            p->data[i] = (MI_Sint32)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_UINT64A:
                    {
                        MI_Uint64A* p;
                        NEW_ARRAY_T(p, MI_Uint64, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_UINT64))
                                return -1;

                            p->data[i] = (MI_Uint64)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_SINT64A:
                    {
                        MI_Sint64A* p;
                        NEW_ARRAY_T(p, MI_Sint64, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            MI_Sint64 x = self->data[i].value.integer;
                            if (0 != _CheckRange(state, x, MI_SINT64))
                                return -1;

                            p->data[i] = (MI_Sint64)x;
                        }

                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
            }
            case TOK_REAL_VALUE:
            {
                switch (type)
                {
                    case MI_REAL32A:
                    {
                        MI_Real32A* p;
                        NEW_ARRAY_T(p, MI_Real32, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            p->data[i] = (MI_Real32)
                                self->data[i].value.real;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_REAL64A:
                    {
                        MI_Real64A* p;
                        NEW_ARRAY_T(p, MI_Real64, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            p->data[i] = (MI_Real64)
                                self->data[i].value.real;
                        }

                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_CHAR_VALUE:
            {
                switch (type)
                {
                    case MI_CHAR16A:
                    {
                        MI_Char16A* p;
                        NEW_ARRAY_T(p, MI_Char16, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            p->data[i] = (MI_Char16)
                                self->data[i].value.character;
                        }

                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_STRING_VALUE:
            {
                switch (type)
                {
                    case MI_STRINGA:
                    {
                        MI_StringA* p;
                        NEW_ARRAY_T(p, MI_String, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            p->data[i] = self->data[i].value.string;
                            self->data[i].value.string = NULL;
                        }

                        *value = p; 
                        return 0;
                    }
                    case MI_DATETIMEA:
                    {
                        MI_DatetimeA* p;
                        NEW_ARRAY_T(p, MI_Datetime, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            if (_StrToDatetime(mofstate,
                                self->data[i].value.string, 
                                &p->data[i]) != 0)
                            {
                                return -1;
                            }
                            self->data[i].value.string = NULL;
                        }

                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_BOOLEAN_VALUE:
            {
                switch (type)
                {
                    case MI_BOOLEANA:
                    {
                        MI_BooleanA* p;
                        NEW_ARRAY_T(p, MI_Boolean, self->size);

                        for (i = 0; i < self->size; i++)
                        {
                            p->data[i] = (MI_Boolean)
                                self->data[i].value.boolean;
                        }

                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
            }
            case TOK_NULL:
            {
                *value = NULL;
                return 0;
            }
            case TOK_ALIAS_IDENTIFIER:
            {
                switch (type)
                {
                    case MI_INSTANCEA:
                    case MI_REFERENCEA:
                    {
                        MI_InstanceA* arr;
                        arr = (MI_InstanceA*)Batch_Get(state->batch, sizeof(MI_InstanceA) + sizeof(MI_Instance*)*self->size);
                        arr->data = (MI_Instance**)(arr + 1);
                        arr->size = self->size;
                        for (i = 0; i < self->size; i++)
                        {
                            const MI_Char* alias = self->data[i].value.string;
                            const MI_InstanceAliasDecl *decl = FindInstanceAliasDecl(state, alias);
                            if (!decl)
                            {
                                yyerrorf(state->errhandler, ID_UNDEFINED_INSTANCE_ALIAS,
                                    "",
                                    tcs(alias));
                                return -1;
                            }
                            arr->data[i] = decl->decl->instance;
                            decl->decl->refs++;
                        }
                        *value = arr; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            default:
                return -1;
        }
    }
    else
    {
        switch (self->data->type)
        {
            case TOK_INTEGER_VALUE:
            {
                switch (type)
                {
                    case MI_UINT8:
                    {
                        MI_Uint8* p = MALLOC_T(MI_Uint8, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_UINT8))
                            return -1;

                        *p = (MI_Uint8)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_SINT8:
                    {
                        MI_Sint8* p = MALLOC_T(MI_Sint8, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_SINT8))
                            return -1;

                        *p = (MI_Sint8)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_UINT16:
                    {
                        MI_Uint16* p = MALLOC_T(MI_Uint16, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_UINT16))
                            return -1;

                        *p = (MI_Uint16)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_SINT16:
                    {
                        MI_Sint16* p = MALLOC_T(MI_Sint16, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_SINT16))
                            return -1;

                        *p = (MI_Sint16)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_UINT32:
                    {
                        MI_Uint32* p = MALLOC_T(MI_Uint32, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_UINT32))
                            return -1;

                        *p = (MI_Uint32)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_SINT32:
                    {
                        MI_Sint32* p = MALLOC_T(MI_Sint32, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_SINT32))
                            return -1;

                        *p = (MI_Sint32)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_UINT64:
                    {
                        MI_Uint64* p = MALLOC_T(MI_Uint64, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_UINT64))
                            return -1;

                        *p = (MI_Uint64)x;
                        *value = p; 
                        return 0;
                    }
                    case MI_SINT64:
                    {
                        MI_Sint64* p = MALLOC_T(MI_Sint64, 1);
                        MI_Sint64 x = self->data->value.integer;
                        if (0 != _CheckRange(state, x, MI_SINT64))
                            return -1;

                        *p = (MI_Sint64)x;
                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_REAL_VALUE:
            {
                switch (type)
                {
                    case MI_REAL32:
                    {
                        MI_Real32* p = MALLOC_T(MI_Real32, 1);
                        *p = (MI_Real32)self->data->value.real;
                        *value = p; 
                        return 0;
                    }
                    case MI_REAL64:
                    {
                        MI_Real64* p = MALLOC_T(MI_Real64, 1);
                        *p = (MI_Real64)self->data->value.real;
                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_CHAR_VALUE:
            {
                switch (type)
                {
                    case MI_CHAR16:
                    {
                        MI_Char16* p = MALLOC_T(MI_Char16, 1);
                        *p = (MI_Char16)self->data->value.character;
                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_STRING_VALUE:
            {
                switch (type)
                {
                    case MI_STRING:
                    {
                        MI_Char *p = self->data->value.string;
                        MI_Char **pp = (MI_Char **)Batch_Get(state->batch, sizeof(MI_Char*));
                        if (!pp)
                        {
                            yyerrorf(state->errhandler, ID_OUT_OF_MEMORY, "out of memory");
                            return -1;
                        }
                        self->data->value.string = NULL;
                        *pp = p;
                        *value = pp; 
                        return 0;
                    }
                    case MI_DATETIME:
                    {
                        MI_Datetime *p = MALLOC_T(MI_Datetime, 1);

                        if (_StrToDatetime(mofstate, self->data->value.string, p) != 0)
                        {
                            return -1;
                        }

                        self->data->value.string = NULL;
                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_BOOLEAN_VALUE:
            {
                switch (type)
                {
                    case MI_BOOLEAN:
                    {
                        MI_Boolean* p = MALLOC_T(MI_Boolean, 1);
                        *p = (MI_Boolean)self->data->value.boolean;
                        *value = p; 
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            case TOK_NULL: {
                *value = NULL;
                return 0;
            }
            case TOK_ALIAS_IDENTIFIER:
            {
                switch (type)
                {
                    case MI_INSTANCE:
                    case MI_REFERENCE:
                    {
                        MI_Instance* inst;
                        const MI_Char* alias = self->data->value.string;
                        const MI_InstanceAliasDecl *decl = FindInstanceAliasDecl(state, alias);
                        if (!decl)
                        {
                            yyerrorf(state->errhandler, ID_UNDEFINED_INSTANCE_ALIAS,
                                "undefined alias : '%s'",
                                tcs(alias));
                            return -1;
                        }
                        self->data->value.string = NULL;
                        inst = decl->decl->instance;
                        decl->decl->refs++;

                        {
                            MI_Instance **pp = (MI_Instance **)Batch_Get(state->batch, sizeof(MI_Instance *));
                            if (!pp)
                            {
                                yyerrorf(state->errhandler, ID_OUT_OF_MEMORY, "out of memory");
                                return -1;
                            }
                            *pp = inst;
                            *value = pp;
                        }
                        return 0;
                    }
                    default:
                        return -1;
                }
                break;
            }
            default:
                return -1;
        }
    }

    UNREACHABLE_RETURN( return 0; )
}