int mof_getChar16()

in LCM/codec/mof/parser/moflex.c [454:590]


int mof_getChar16(MOF_State * state)
{
    MOF_Buffer * mb = &(state->buf);
    int c;
    int firstc = mof_nextchar(mb);
    _mof_buffer_marktokenstart(mb);
    switch(firstc)
    {
        case '\'': /* Double quote '' is invalid */
            {
                yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INVALID_CHAR16_VALUE, "", MI_T("''"));
                return TOK_ERROR;
            }
            break;
        case '\\': /* Escaped char16 value */
        {
            int secondc;
            MOF_StringLen r = {{0}};
            c = mof_nextchar(mb);
            r.str.data = mb->cur;
            while(c != '\'' && mof_neof(mb))
            {
                c = mof_nextchar(mb);
            }
            r.len = mof_offset(mb->e.u, r.str.data, mb->cur);
            if (mof_eof(mb))
            {
                yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INCOMPLETE_ESCAPED_CHAR16_VALUE,
                    "",
                    mb->llineNo,
                    mb->lcharPosOfLine);
                return TOK_ERROR;
            }
            if (mof_converttoUTF16LE(state, &r) != 0)
            {
                return TOK_ERROR;
            }

            /* skip closing quote */
            mof_nextchar(mb);

            secondc = mof_getchar(mb->e, r.str.data);
            if (secondc == 'x' ||secondc == 'X') // hex char
            {
                if (r.len > 5)
                {
                    yyerrorf(state->errhandler, ID_ILLEGAL_HEX_CHARACTER, "",
                        _mof_gettokenstring(state, &r, 0));
                    return TOK_ERROR;
                }
                /* convert HEX string to integer */
                {
                    wchar_t ew = L'\'';
                    char ea = '\'';
                    unsigned long chr = 0;
                    void * hexdata = mof_nextcharofbuf(mb->e.u, r.str.data);
                    MI_Boolean res = mof_isvalidhexstring(state->buf.e.u, hexdata, r.len - 1);
                    if (res == MI_TRUE)
                    {
                        res = mof_strtoul(state->buf.e.u,
                            hexdata,
                            16,
                            mb->e.u ? (void*)&ew : (void*)&ea,
                            &chr);
                    }
                    if (!res)
                    {
                        yyerrorf(state->errhandler, ID_ILLEGAL_HEX_CHARACTER, "",
                            _mof_gettokenstring(state, &r, 0));
                        return TOK_ERROR;
                    }
                    state->ystate.moflval.character = (MI_Char16) chr;
                }
                return TOK_CHAR_VALUE;
            }
            else
            {
                if (r.len != 1)
                {
                    yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INVALID_ESCAPED_CHAR16_VALUE,
                        "",
                       _mof_gettokenstring(state, &r, 0),
                       r.len);
                    return TOK_ERROR;
                }
                c = mof_getchar(mb->e, r.str.data);
                {
                    char ec;
                    int r = _mof_getescapedchar(c, &ec);
                    if (r == 0)
                    {
                        state->ystate.moflval.character = (MI_Char16)ec;
                    }
                    else
                    {
                        yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INVALID_ESCAPED_CHAR, "", c);
                        return TOK_ERROR;
                    }
                }
            }
            return TOK_CHAR_VALUE;
        }
        break;
        default:
        {
            MI_Char buf[3] = {0};
            MI_Boolean invalid = MI_FALSE;
            buf[0] = (MI_Char)mof_getchar(mb->e, mb->cur);
            c = mof_nextchar(mb);
            if(mof_eof(mb))
            {
                invalid = MI_TRUE;
                buf[1] = 0;
            }
            else if (c != '\'')
            {
                invalid = MI_TRUE;
                c = mof_nextchar(mb);
                buf[1] = (MI_Char)c;
                buf[2] = 0;
            }

            if (invalid)
            {
                yyerrorf(state->errhandler, ID_SYNTAX_ERROR_INVALID_CHAR16_VALUE, "",
                    buf);
                return TOK_ERROR;
            }

            /* valid Char16 value, skip closing quote */
            mof_nextchar(mb);
            state->ystate.moflval.character = (MI_Char16)firstc;
            return TOK_CHAR_VALUE;
        }
        break;
    }
}