unsigned int genOperate (Symbol x, Symbol y, int operation)
{
    fputs ("\n    ;operações simples\n",asm_file);
    //se um valor for byte fazer a conversão
    int end = tempEnd;
    char regA [] = "ax";
    char regB [] = "bx";
    if (hasByteAndInteger(x.type,y.type) || hasInteger(x.type,y.type))
    {
        //carrega Y para ax
        loadIntegerAx(y);
        fputs ("    mov bx, ax    ;move ax para bx\n",asm_file);//conveter o tipo para byte
        loadIntegerAx(x);
    }
    else if (areBytes(x.type,y.type))
    {
        fprintf (asm_file,"    mov al, DS:[%d]\n",x.adress);
        fprintf (asm_file,"    mov bl, DS:[%d]\n",y.adress);
        strcpy(regA,"al") ;
        strcpy(regB,"bl") ;
    }
    switch (operation)
    {
    case 1:
        fprintf (asm_file,"    sub %s , %s    ;subtração\n",regA,regB);
        break;
    case 2:
        fprintf (asm_file,"    add %s , %s    ;soma\n",regA,regB);
        break;
    case 3:
        fprintf (asm_file,"    or %s , %s    ;OR\n",regA,regB);
        break;
    }
    fprintf (asm_file,"    mov DS:[%d],%s\n",end,regA);
    tempEnd = (strcmp(regA,"al") == 0) ? tempEnd+1 : tempEnd+2;
    return end;
}
Exemplo n.º 2
0
bool QDBCFile::detectFieldType(quint32 field)
{
    if(field < m_fieldCount && field >= 0) {
        if(field == 0) {
            //the first field seems to be always uint32, so set it asap to save some time
            setFieldType(field,FIELD_TYPE_ID);
            setFieldTypeSQL(field,FIELD_TYPE_SQL_ID);
            return true;
        }
        quint32 strings = 0;
        quint32 floats = 0;
        quint32 uints = 0;
        quint32 ints = 0;
        quint32 nulls = 0;
        quint32 ones = 0;
        quint32 biguints = 0;
        quint32 maxuints = 0;
        quint32 timeuints = 0;
        quint32 bitvaluints = 0;
        quint32 bigints = 0;
        quint32 maxints = 0;
        quint32 timeints = 0;
        quint32 bitvalints = 0;
        quint32 unk = 0;
        //
        DBCFieldType fieldtype = FIELD_TYPE_DEFAULT;
        SQLFieldType fieldtypesql = FIELD_TYPE_SQL_DEFAULT;
        quint8 uintsizelevel = 0;
        quint8 intsizelevel = 0;
        quint8 textsizelevel = 0;
        /*
        sql field size level:
        0 - tiny (tinyint, tinytext)
        1 - small (smallint, text)
        2 - medium (mediumint, mediumtext)
        3 - large (int, longtext)
        */

        for(quint32 record=0; record < m_recordCount; record++) {
            switch(m_fieldSize) {
            case 1:
            case 2:
            case 4:
                {
                    if(hasUsualFloat(field,record)) {
                        float f = getFloat(field,record);
                        if(f != 0.0f)
                            floats++;
                        else
                            nulls++;
                    }
                    else if(hasFullString(field,record)) {
                        strings++;
                        if(getInt(field,record) == 1)
                            ones++;
                        //
                        if(getString(field,record).size() > SQL_TINYTEXT && textsizelevel < 1)
                            textsizelevel = 1;
                        if(getString(field,record).size() > SQL_TEXT && textsizelevel < 2)
                            textsizelevel = 2;
                        if(getString(field,record).size() > SQL_MEDIUMTEXT && textsizelevel < 3)
                            textsizelevel = 3;
                    }
                    else if(hasInteger(field,record,false)) {
                        quint32 u = getUInt(field,record);
                        quint32 uMinusOne = u-1;
                        bool isDegreeOfTwo = !(uMinusOne&u);
                        if(u == 0)
                            nulls++;
                        else
                            uints++;
                        if(u == 1)
                            ones++;
                        /*
                    BITMASK DETECTION TEMPORARY HACKS: wild bitmask guessing. Test in progress.
                    The insteresting thing about it is the fact that blizzards used same shit
                    themselves at least once. Current precision is about 60-70%.
                    */
                        if(u > qPow(2,19)) {
                            biguints++;
                            if(u%10 == 0)
                                timeuints++;
                        }
                        if(u == 0xffffffff)
                            maxuints++;
                        if(isDegreeOfTwo && u > 8)
                            bitvaluints++;
                        //
                        if(u > SQL_TINYINT_UNSIGNED_HI && uintsizelevel < 1)
                            uintsizelevel = 1;
                        if(u > SQL_SMALLINT_UNSIGNED_HI && uintsizelevel < 2)
                            uintsizelevel = 2;
                        if(u > SQL_MEDIUMINT_UNSIGNED_HI && uintsizelevel < 3)
                            uintsizelevel = 3;
                    }
                    else if(hasInteger(field,record,true)) {
                        qint32 i = getInt(field,record);
                        quint32 absI = abs(i);
                        quint32 absIMinusOne = absI-1;
                        bool isDegreeOfTwo = !(absIMinusOne&absI);
                        if(i == 0)
                            nulls++;
                        else
                            ints++;
                        if(i == 1)
                            ones++;
                        /*
                    BITMASK DETECTION TEMPORARY HACKS: wild bitmask guessing. Test in progress.
                    The insteresting thing about it is the fact that blizzards used same shit
                    themselves at least once. Current precision is about 60-70%.
                    */
                        if(i == -1 || i == -2)
                            maxuints++;
                        if(absI > qPow(2,19)) {
                            bigints++;
                            if(absI%10 == 0)
                                timeints++;
                        }
                        if(absI >= 0x7FFFFFFF)
                            maxints++;
                        if(isDegreeOfTwo && absI > 8)
                            bitvalints++;
                        //
                        if((i < SQL_TINYINT_LOW || i > SQL_TINYINT_HI) && intsizelevel < 1)
                            intsizelevel = 1;
                        if((i < SQL_SMALLINT_LOW || i > SQL_SMALLINT_HI) && intsizelevel < 2)
                            intsizelevel = 2;
                        if((i < SQL_MEDIUMINT_LOW || i > SQL_MEDIUMINT_HI) && intsizelevel < 3)
                            intsizelevel = 3;
                    }
                    else {
                        //OMG WTF?!
                        unk++;
                    }
                    break;
                }
            default:
                //Unsupported field size, make error and get out of here
                return makeDetectionError(DBCFILE_ERROR_AUTO_DETECT_FAILED_UNK_FIELD_SIZE,field);
            }
        }
        //Auto-Detecting Generic Field Type...
       if( unk > 0 )
           //OMG WTF?! Normally this thing should NEVER EVER happen.
           fieldtype = FIELD_TYPE_UNKNOWN;
       else if( ones + nulls == m_recordCount && ones > 0 && nulls > 0 )
           fieldtype = FIELD_TYPE_BOOL;
       else if( strings + nulls == m_recordCount && strings > 0 )
           fieldtype = FIELD_TYPE_TEXT;
       else if( nulls == m_recordCount
                && (fieldType(field-1) == FIELD_TYPE_TEXT || fieldType(field-1) == FIELD_TYPE_NULLTEXT))
           //TODO: add some field count correction? Got one more excess column with nulls as nulltext somewhere.
           fieldtype = FIELD_TYPE_NULLTEXT;
       else if( nulls == m_recordCount )
           fieldtype = FIELD_TYPE_NULLS;
       else if( floats + nulls == m_recordCount
                || (floats > m_recordCount - nulls - floats && floats > 0))
           fieldtype = FIELD_TYPE_FLOAT;
       else if( (biguints > uints*0.10f && biguints != timeuints && biguints > 1)
                || (bitvaluints == uints && bitvaluints != ones  && (ones <= uints*0.09f || biguints > 0) && (ints == 0 || (uints > ints && ints == maxuints)) && m_recordCount > 1 && uints > 0)
                || (bitvaluints >= uints*0.30f && strings < uints*0.09f && bitvaluints != ones  && (ones <= uints*0.09f || biguints > 0) && (ints == 0 || (uints > ints && ints == maxuints)) && m_recordCount > 1 && uints > 0)
                || (bigints > ints*0.10f && bigints != timeints && bigints > 1)
                || (bitvalints == ints && bitvalints != ones  && (ones <= ints*0.09f || bigints > 0) && (uints == 0 || (ints > uints && uints == maxuints)) && m_recordCount > 1 && ints > 0)
                || (bitvalints >= ints*0.30f && strings < ints*0.09f && bitvalints != ones  && (ones <= ints*0.09f || bigints > 0) && (uints == 0 || (ints > uints && uints == maxuints)) && m_recordCount > 1 && ints > 0))
           fieldtype = FIELD_TYPE_BITMASK;//Yeah, i know. xD
       else if( ints == 0 || (uints > ints && ints == maxuints && maxuints > uints*0.30f) )
           fieldtype = FIELD_TYPE_UINT;
       else
           fieldtype = FIELD_TYPE_INT;

       switch(fieldtype) {
        case FIELD_TYPE_TEXT:
            switch(textsizelevel) {
            case 0:
                fieldtypesql = FIELD_TYPE_SQL_TINYTEXT;
                break;
            case 1:
                fieldtypesql = FIELD_TYPE_SQL_TEXT;
                break;
            case 2:
                fieldtypesql = FIELD_TYPE_SQL_MEDIUMTEXT;
                break;
            default:
                fieldtypesql = FIELD_TYPE_SQL_LONGTEXT;
            }
            break;
        case FIELD_TYPE_UINT:
            switch(uintsizelevel) {
            case 0:
                fieldtypesql = FIELD_TYPE_SQL_TINYINT_UNSIGNED;
                break;
            case 1:
                fieldtypesql = FIELD_TYPE_SQL_SMALLINT_UNSIGNED;
                break;
            case 2:
                fieldtypesql = FIELD_TYPE_SQL_MEDIUMINT_UNSIGNED;
                break;
            default:
                fieldtypesql = FIELD_TYPE_SQL_INT_UNSIGNED;
            }
            break;
        case FIELD_TYPE_INT:
            switch(intsizelevel) {
            case 0:
                fieldtypesql = FIELD_TYPE_SQL_TINYINT;
                break;
            case 1:
                fieldtypesql = FIELD_TYPE_SQL_SMALLINT;
                break;
            case 2:
                fieldtypesql = FIELD_TYPE_SQL_MEDIUMINT;
                break;
            default:
                fieldtypesql = FIELD_TYPE_SQL_INT;
            }
            break;
        case FIELD_TYPE_FLOAT:
            fieldtypesql = FIELD_TYPE_SQL_FLOAT;
            break;
        case FIELD_TYPE_BOOL:
            fieldtypesql = FIELD_TYPE_SQL_BOOL;
            break;
        case FIELD_TYPE_NULLS:
            fieldtypesql = FIELD_TYPE_SQL_TINYINT_UNSIGNED;
            break;
        case FIELD_TYPE_NULLTEXT:
            fieldtypesql = FIELD_TYPE_SQL_TINYTEXT;
            break;
        case FIELD_TYPE_BITMASK:
            fieldtypesql = FIELD_TYPE_SQL_BITMASK;
            break;
        case FIELD_TYPE_UNKNOWN:
            fieldtypesql = FIELD_TYPE_SQL_UNKNOWN;
            break;
        }
        setFieldType(field,fieldtype);
        setFieldTypeSQL(field,fieldtypesql);
        return true;
    }
    //OK, we are totally screwed if we are right here
    return makeDetectionError(DBCFILE_ERROR_AUTO_DETECT_FAILED_INVALID_FIELD,field);
}