⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 math.c

📁 nsis是一个流传比较广的程序安装和解安装封装软件
💻 C
📖 第 1 页 / 共 4 页
字号:
{    char *buffer, *bp;    if (item == NULL) return;    int itemt = item->type & ITEMTYPE, oldtype = item->type & ITEMSUBTYPE;    if (((itemt == IT_CONST) && (oldtype == type))        || (itemt != IT_CONST)) return;    switch (type)    {    case ITC_STRING:        buffer = AllocString();        ItemToString(buffer, item);        item->param1 = (EIPARAM)  buffer;        item->param2 = 0;        break;    case ITC_FLOAT:        if (oldtype == ITC_INT)            *((double *)&(item->param1)) = (double) *((__int64 *)&(item->param1));        else        {            bp = buffer = (char*) item->param1;            StringToItem(buffer, item, STI_FLOAT);            dbgGlobalFree(bp);        }        break;    case ITC_INT:        if (oldtype == ITC_FLOAT)            *((__int64 *)&(item->param1)) = (__int64) *((double *)&(item->param1));        else        {            bp = buffer = (char*) item->param1;            StringToItem(buffer, item, STI_INT);            dbgGlobalFree(bp);        }        break;    case ITC_ARRAY:        if (oldtype == ITC_STRING)        {            char *buf = (char*) item->param1;            int len = lstrlen(buf)+1;            ExpressionItem *ni = AllocArray(lstrlen(buf)+1);            ArrayDesc *ad = (ArrayDesc*) ni->param1;            for (int i = 0; i < len; i++)            {                ad->array[i] = AllocItem();                *((__int64 *) &(ad->array[i]->param1)) = (__int64) buf[i];            }            ad->count = len;            CleanupItems(item);            item = ni;        }        break;    }    item->type = IT_CONST | type;}void SaveResult(ExpressionItem *var, ExpressionItem *result){    if ((var->type & ITEMTYPE) != IT_VARIABLE) return;    // result should be stored at variable to    int varindex = var->type & ITEMOPTIONS;    switch (var->type & ITEMSUBTYPE)    {    case ITV_NSIS:        {            // store string result direct to NSIS variable            char *ptr = g_variables + varindex*g_stringsize;            ItemToString(ptr, result);        }        break;    case ITV_USER:        {            CleanupItems(UserVars[varindex].item);            UserVars[varindex].item = CopyItem(result);        }        break;    case ITV_ARRITEM:        {            ExpressionItem *&ei = ((ArrayDesc*)(var->param1))->array[(int)var->param2];            CleanupItems(ei);            ei = CopyItem(result);        }        break;    case ITV_STACK:        {            ExpressionItem *newitem = CopyItem(result);            newitem->next = stack;            stack = newitem;        }        break;    case ITV_NSTACK:        {            char *buf = AllocString();            ItemToString(buf, result);            pushstring(buf);            dbgGlobalFree(buf);        }        break;    }}void RunAndGetConst(int from, ExpressionItem* &result, int type){    RunTree(*((ExpressionItem**)&(from)), result, type | RTO_NEEDCONST);    ItemToType(result, type);}void RunTree(ExpressionItem *from, ExpressionItem* &result, int options){    ExpressionItem *item = from;    result = NULL;    while (item != NULL)    {        CleanupItems(result);        int type = item->type & ITEMTYPE,            subtype = item->type & ITEMSUBTYPE,            ioptions = item->type & ITEMOPTIONS;        switch (type)        {        case IT_EXPRESSION:            RunTree(*((ExpressionItem**)&(item->param1)), result, options);            break;        case IT_CONST:            result = CopyItem(item);            break;        case IT_VARIABLE:            if (options & RTO_NEEDCONST)            {                // we need const result - :) is it nsis or common variable                switch (subtype)                {                case ITV_NSIS:                    {                        // nsis                        result = AllocItem();                        char *variable = getuservariable(ioptions);                        StringToItem(variable, result, options);                    }                    break;                case ITV_USER:                    {                        // usual variable                        if (UserVars[ioptions].item)                            result = CopyItem(UserVars[ioptions].item);                        else                            result = AllocItem();                    }                    break;                case ITV_ARRITEM:                    {                        // array item                        ExpressionItem *ei = ((ArrayDesc*)(item->param1))->array[(int)item->param2];                        if (ei)                            result = CopyItem(ei);                        else                            result = AllocItem();                    }                    break;                case ITV_STACK:                    {                        // pop from plugin stack                        result = stack;                        if (result == NULL) result = AllocItem();                        stack = result->next;                        result->next = NULL;                    }                    break;                case ITV_NSTACK:                    {                        // NSIS stack                        char buffer[1024], *buf = buffer;                        result = AllocItem();                        popstring(buffer);                        StringToItem(buf, result, options);                    }                    break;                }            }            else                // if we don't need const - we will just pass variable record                result = CopyItem(item);            break;        case IT_OPERATOR:            {                ExpressionItem *var = NULL, *item1 = NULL, *item2 = NULL;                // prepare arguments in case of SET operator                if (ioptions & PO_SET)                {                    if ((item->param1) && (ioptions & PO_PRENONCONST))                    {                        RunTree(*((ExpressionItem**)&(item->param1)), var, 0);                        if (ioptions & PO_USESPRE)                            RunTree(var, item1, RTO_NEEDCONST | STI_INT | STI_FLOAT | STI_STRING);                    } else                    if ((item->param2) && (ioptions & PO_POSTNONCONST))                    {                        RunTree(*((ExpressionItem**)&(item->param2)), var, 0);                        if (ioptions & PO_USESPOST)                            RunTree(var, item2, RTO_NEEDCONST | STI_INT | STI_FLOAT | STI_STRING);                    }                }                // prepare arguments in case of any operator                int needmore = 1;                if ((!item1) && (item->param1) && (ioptions & PO_USESPRE))                {                    RunTree(*((ExpressionItem**)&(item->param1)), item1, RTO_NEEDCONST | STI_INT | STI_FLOAT | STI_STRING);                    // logical expressions && and || can make decision on first arg basis                    if ((subtype == ITO_LAND) || (subtype == ITO_LOR) )                    {                        ItemToType(item1, ITC_INT);                        int res = (int) *((__int64*) &(item1->param1));                        if (((res)&&(subtype==ITO_LOR)) || ((!res)&&(subtype==ITO_LAND)))                            needmore = 0;                    }                }                // get-reference operator                if ((!item1) && (subtype == ITO_AND) && (!item2) && (item->param2))                {                    RunTree(*((ExpressionItem**)&(item->param2)), result, 0);                    break;                }                if ((needmore) && (!item2) && (item->param2) && (ioptions & PO_USESPOST))                    RunTree(*((ExpressionItem**)&(item->param2)), item2, RTO_NEEDCONST | STI_INT | STI_FLOAT | STI_STRING);                // reference operator                if ((!item1) && (subtype == ITO_MUL) && ((item2->type & ITEMTYPE) == (IT_VARIABLE)))                {                    // ok, that's the result we need                    if (options & RTO_NEEDCONST)                    {                        RunTree(item2, result, options);                        CleanupItems(item2);                    } else                        result = item2;                    break;                }                __int64 i1=0, i2=0, i3=0, i4=0;                if (((!item1)||((item1->type & ITEMTYPE)==IT_CONST)) &&                    ((!item2)||((item2->type & ITEMTYPE)==IT_CONST)))                {                // find the best type match for operation                int it1 = (item1 && (ioptions & PO_USESPRE))?(item1->type & ITEMSUBTYPE):(ITC_UNKNOWN),                    it2 = (item2 && (ioptions & PO_USESPOST))?(item2->type & ITEMSUBTYPE):(ITC_UNKNOWN),                    type = (it1 < it2)?(it1):(it2);                // convert operands to desired type                ItemToType(item1, type);                ItemToType(item2, type);                switch (type)                {                case ITC_INT:                    {                        i1 = (item1)?(*((__int64*)&item1->param1)):(0);                        i2 = (item2)?(*((__int64*)&item2->param1)):(0);                    switch (subtype)                    {                    case ITO_MINUS: i1 -= i2; break;    // unary minus auto handled with NULL                    case ITO_PLUS:  i1 += i2; break;                    case ITO_SHL:   i1 <<= i2; break;                    case ITO_SHR:   i1 >>= i2; break;                    case ITO_MUL:   i1 *= i2; break;                    case ITO_MOD:                    case ITO_DIV:                                    if (i2 == 0) { i3 = 0; i4 = i1;  }                                    else { i3 = i1 / i2; i4 = i1 % i2; }                                    if (subtype == ITO_DIV) i1 = i3; else i1 = i4;                                    break;                    case ITO_SET:   i1 = i2; break;                    case ITO_LE:    i1 = (i1 <= i2); break;                    case ITO_GE:    i1 = (i1 >= i2); break;                    case ITO_NE:    i1 = (i1 != i2); break;                    case ITO_EQ:    i1 = (i1 == i2); break;                    case ITO_LS:    i1 = (i1 < i2); break;                    case ITO_GR:    i1 = (i1 > i2); break;                    case ITO_AND:   i1 = (i1 & i2); break;                    case ITO_OR:    i1 = (i1 | i2); break;                    case ITO_XOR:   i1 = (i1 ^ i2); break;                    case ITO_NOT:   i1 = ~i2; break;                    case ITO_LNOT:  i1 = !i2; break;                    case ITO_LAND:  i1 = i1 && i2; break;                    case ITO_LOR:   i1 = i1 || i2; break;                    case ITO_INC:                            if (item1) i2 = i1++;                            else i1 = ++i2;                            break;                    case ITO_DEC:                            if (item1) i2 = i1--;                            else i1 = --i2;                            break;                    }                    result = AllocItem();                    *((__int64*)&result->param1) = i1;                    }                    break;                case ITC_FLOAT:                    {                        int ir = -666;                        double i1 = (item1)?(*((double*)&item1->param1)):(0.0);                        double i2 = (item2)?(*((double*)&item2->param1)):(0.0);                    switch (subtype)                    {                    case ITO_MINUS: i1 -= i2; break;    // unary minus auto handled with NULL                    case ITO_PLUS:  i1 += i2; break;                    case ITO_MUL:   i1 *= i2; break;                    case ITO_DIV:   i1 /= i2; break;                    case ITO_SET:   i1 = i2; break;                    case ITO_LE:    ir = (i1 <= i2); break;                    case ITO_GE:    ir = (i1 >= i2); break;                    case ITO_NE:    ir = (i1 != i2); break;                    case ITO_EQ:    ir = (i1 == i2); break;                    case ITO_LS:    ir = (i1 < i2); break;                    case ITO_GR:    ir = (i1 > i2); break;                    }                    result = AllocItem();                    if (ir == -666)                    {                        // if ir value left intact - result is double                        result->type = IT_CONST | ITC_FLOAT;                        *((double*)&result->param1) = i1;                    } else                        *((__int64*)&result->param1) = (__int64) ir;                    }                    break;                case ITC_STRING:                    {                        int ir = -666;                        char *i1 = (item1)?((char*)item1->param1):(NULL);                        char *i2 = (item2)?((char*)item2->param1):(NULL);                       	int sc = (i1 && i2)?(lstrcmp(i1, i2)):((i1)?(1):((i2)?(-1):(0)));                    switch (subtype)                    {                    case ITO_PLUS:  lstrcat(i1, i2); break;                    case ITO_SET:   i1 = i2; break;                    case ITO_LE:    ir = (sc <= 0); break;                    case ITO_GE:    ir = (sc >= 0); break;                    case ITO_NE:    ir = (sc != 0); break;                    case ITO_EQ:    ir = (sc == 0); break;                    case ITO_LS:    ir = (sc < 0); break;                    case ITO_GR:    ir = (sc > 0); break;                    }                    if (ir == -666)                    {                        result = CopyItem((item1)?(item1):(item2));                    } else                    {                        result = AllocItem();                        *((__int64*)&result->param1) = (__int64) ir;                    }                    }                    break;                case ITC_ARRAY:                    result = CopyItem(item2);                    break;                }                } // check for both items constant                // the other case - usually UniaryPre operators working with non constants                else result = CopyItem(item2);                if (ioptions & PO_SET)                {                    // Save our result in output variable                    SaveResult(var, result);                }                // Actual value to be returned as result is at i2 for ++ and -- ops                if ((subtype == ITO_DEC) || (subtype == ITO_INC))                    *((__int64*)&result->param1) = i2;                CleanupItems(item1); CleanupItems(item2); CleanupItems(var);            }            break;        case IT_LOGIC:            {                int ifmode = (subtype == ITL_IF);                ExpressionItem *ifbr = *((ExpressionItem**)&(item->param1)),                    *dobr = *((ExpressionItem**)&(item->param2)),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -