int mof_getnumber()

in LCM/codec/mof/parser/moflex.c [642:809]


int mof_getnumber(MOF_State * state, MI_Boolean sign)
{
    MOF_Buffer * mb = &(state->buf);
    int token = TOK_ERROR;
    int c = mof_getchar(mb->e, mb->cur);
    MI_Boolean isnumber = MI_TRUE;
    void * start = mb->cur;
    while (isnumber && mof_neof(mb))
    {
        switch(c)
        {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '.':
        case '+':
        case '-':
        case 'x':
        case 'X':
            c = mof_nextchar(mb);
            break;
        default:
            if (('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))
            {
                c = mof_nextchar(mb);
            }
            else
            {
                isnumber = MI_FALSE;
            }
            break;
        }
    }
    {
        size_t length = mof_offset(mb->e.u, start, mb->cur);
        if (length == 0)
        {
             yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INVALID_NUMBER_VALUE, "",
                MI_T("empty number string"));
            return token;
        }
        else
        {
            MOF_StringLen data;
            MOF_StringLen * ps = (mb->e.u) ? _cwnumberpattern : _canumberpattern;
            data.str.data = start;
            data.len = length;
            while (ps->str.data)
            {
                MOF_Encoding em;
                em.u = mb->e.u;
                em.t = (em.u) ? UNI :ANSI;
                if (mof_converttoUTF16LE(state, &data) != 0)
                {
                    return TOK_ERROR;
                }
                if (mof_match(em, &data, ps))
                {
                    if (!sign)
                    {
                        data.str.data = mof_getprevcharpos(mb->e.u, data.str.data);
                        data.len += 1;
                    }
                    mof_getidentifiervalue(state, &data);
                    break;
                }
                ps ++;
            }
            if (!ps->str.data)
            {
                yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INVALID_NUMBER_VALUE, "",
                    _mof_gettokenstring(state, &data, 0));
                return token;
            }
            else
            {
                switch(ps->code)
                {
                case REAL:
                    {
                        token = TOK_REAL_VALUE;
                        state->ystate.moflval.real = mof_strtod(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string);//memory is from batch
                    }
                    break;
                case DECIMAL:
                    {
                        token = TOK_INTEGER_VALUE;
                        errno = 0;
                        if (!sign)
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoll(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, NULL, 10);
                        else
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoull(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, NULL, 10);

                        if (errno == ERANGE)
                        {
                            yyerrorf(state->errhandler, ID_INTEGER_OVERFLOW, "integer overflow");
                            return TOK_ERROR;
                        }
                    }
                    break;
                case OCTAL:
                    {
                        token = TOK_INTEGER_VALUE;
                        errno = 0;
                        if (!sign)
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoll(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, NULL, 8);
                        else
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoull(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, NULL, 8);
    
                        if (errno == ERANGE)
                        {
                            yyerrorf(state->errhandler, ID_INTEGER_OVERFLOW, "integer overflow");
                            return TOK_ERROR;
                        }
                    }
                    break;
                case HEX:
                    {
                        token = TOK_INTEGER_VALUE;
                        errno = 0;
                        if (!sign)
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoll(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, NULL, 16);
                        else
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoull(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, NULL, 16);
    
                        if (errno == ERANGE)
                        {
                            yyerrorf(state->errhandler, ID_INTEGER_OVERFLOW, "integer overflow");
                            return TOK_ERROR;
                        }
                    }
                    break;
                case BINARY:
                    {
                        wchar_t* end;
                        token = TOK_INTEGER_VALUE;
                        if (!sign)
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoll(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, (void**)&end, 2);
                        else
                            state->ystate.moflval.integer = (MI_Sint64)mof_strtoull(sizeof(MI_Char) == sizeof(wchar_t), state->ystate.moflval.string, (void**)&end, 2);

                        if (*end != L'B' && *end != L'b')
                        {
                            yyerrorf(state->errhandler, ID_ILLEGAL_BINARY_LITERAL, "");
                            return TOK_ERROR;
                        }
                        if (errno == ERANGE)
                        {
                            yyerrorf(state->errhandler, ID_INTEGER_OVERFLOW, "integer overflow");
                            return TOK_ERROR;
                        }
                    }
                    break;
                default:
                    break;
                }
            }
        }
    }
    return token;
}