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

📄 math.c

📁 nsis是一个流传比较广的程序安装和解安装封装软件
💻 C
📖 第 1 页 / 共 4 页
字号:
                    *thbr = NULL, *elbr = NULL;                // check do branche for existance                if (dobr && ifmode)                {                    // then...                    thbr = *((ExpressionItem**)&(dobr->param1));                    // ... and else branches                    if (dobr->next) elbr = *((ExpressionItem**)&(dobr->next->param1));                }                while (true)                {                    RunAndGetConst((int) ifbr, result, ITC_INT);                    if (ifmode)                    {                        // we need then or else branch?                        if ((*((__int64*)&result->param1))) dobr = thbr;                        else dobr = elbr;                    } else                    {                        // while mode                        if (!(*((__int64*)&result->param1))) break;                    }                    // ok, run the approtiate branch of if statement (if available)                    if (dobr)                    {                        CleanupItems(result);                        RunTree(dobr, result, options);                    }                    if (ifmode) break;                    CleanupItems(result);                }            }            break;        case IT_FUNCTION:            if (subtype == ITF_USER)            {                int i;                UserFunc *f = &(UserFuncs[ioptions]);                int flags = f->varflags;                ExpressionItem *ip = *((ExpressionItem**)&(item->param1));                ExpressionItem *si = AllocItem(), *var = AllocItem();                ExpressionItem *vals[32];                si->type = IT_VARIABLE | ITV_STACK;                for (i = 0; i < f->varsnum; i++)                {                    // push every variable                    ExpressionItem *val;                    var->type = (IT_VARIABLE | ITV_USER) + f->vars[i];                    RunTree(var, val, RTO_NEEDCONST | ITC_STRING | ITC_INT | ITC_FLOAT | ITC_ARRAY);                    SaveResult(si, val);                    CleanupItems(val);                    // calculate argument value and for future                    if (ip)                    {                        if (flags&1)                        {                            // var ptr required                            RunTree(*((ExpressionItem**)&(ip->param1)), vals[i], 0);                        } else                        {                            RunTree(*((ExpressionItem**)&(ip->param1)), vals[i], RTO_NEEDCONST | ITC_STRING | ITC_INT | ITC_FLOAT | ITC_ARRAY);                        }                        ip = ip->next;                    } else vals[i] = AllocItem();                    flags >>= 1;                }                // now when all values got we could save them to variables                for (i = 0; i < f->varsnum; i++)                {                        var->type = (IT_VARIABLE | ITV_USER) + f->vars[i];                        SaveResult(var, vals[i]);                        CleanupItems(vals[i]);                }                // ok, call the func                RunTree(f->root, result, RTO_NEEDCONST | ITC_STRING | ITC_INT | ITC_FLOAT | ITC_ARRAY);                // pop original params                for (i = f->varsnum-1; i >= 0; i--)                {                    // pop every variable                    ExpressionItem *val;                    var->type = (IT_VARIABLE | ITV_USER) + f->vars[i];                    RunTree(si, val, RTO_NEEDCONST | ITC_STRING | ITC_INT | ITC_FLOAT | ITC_ARRAY);                    SaveResult(var, val);                    CleanupItems(val);                }                // free used items                CleanupItems(si); CleanupItems(var);            } else if (subtype == ITF_TYPE)            {                int newtype = (int) MathFunctions[ioptions].fptr;                if (newtype < ITC_UNKNOWN)                {                    // get as possibly close to ready expression                    RunAndGetConst((int)item->param1, result, newtype);                    if (ioptions == ITFT_CARRAY_ID)                        CopyArray(result);                } else if (newtype == FTT_FLOATF)                {                    // float format function                    ExpressionItem *arg1, *arg2;                    RunAndGetConst((int)item->param1, arg1, ITC_FLOAT);                    double value = *((double*)&(arg1->param1));                    RunAndGetConst((int)item->param2, arg2, ITC_INT);                    int format = (int) *((__int64*)&(arg2->param1));                    result = AllocItem();                    result->type = IT_CONST | ITC_STRING;                    result->param1 = (EIPARAM)  AllocString();                    FloatFormat((char*) result->param1, value, format);                    CleanupItems(arg1); CleanupItems(arg2);                } else if (newtype == FTT_LEN)                {                    // length function                    RunTree(*((ExpressionItem **) &(item->param1)), result, RTO_NEEDCONST | ITC_STRING | ITC_ARRAY);                    if ((result->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST|ITC_ARRAY))                    {                        int len = ((ArrayDesc*)(result->param1))->count;                        CleanupItems(result);                        result = AllocItem();                        *((__int64*)&(result->param1)) = (__int64) len;                        break;                    } else                        if ((result->type & (ITEMTYPE|ITEMSUBTYPE)) != (IT_CONST|ITC_STRING))                            ItemToType(result, ITC_STRING);                    if ((result->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST|ITC_STRING))                    {                        // ok, that's string                        int len = lstrlen((char*)result->param1);                        dbgGlobalFree((HGLOBAL) result->param1);                        *((__int64*)&(result->param1)) = (__int64) len;                        result->type = IT_CONST | ITC_INT;                    } else CleanupItems(result);                } else                {                    // only one left - c() - char/int/char conversion                    RunTree(*((ExpressionItem **) &(item->param1)), result, RTO_NEEDCONST | ITC_STRING | ITC_INT);                    if ((result->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST|ITC_STRING))                    {                        // ok, that's string - convert first char to int                        int chr = (*((char*)result->param1)) & 0xFF;                        dbgGlobalFree((HGLOBAL) result->param1);                        *((__int64*)&(result->param1)) = (__int64) chr;                        result->type = IT_CONST | ITC_INT;                        break;                    }                    if ((result->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST|ITC_INT))                    {                        // ok, that's int - convert to new string (char+0)                        int chr = (int) (*((__int64*)&(result->param1))) & 0xFF;                        result->param1 = (EIPARAM)  AllocString();                        *((char*)result->param1) = (char) chr;                        *((char*)(result->param1+1)) = (char) 0;                        result->type = IT_CONST | ITC_STRING;                        break;                    } else CleanupItems(result);                }            } else            {                // oops :-o function call :)                RunAndGetConst((int)item->param1, result, ITC_FLOAT);                double &value = *((double*)&(result->param1));                if (subtype == ITF_MATH1)                {                    // Built-In math function with 1 arg                    value = MathFunctions[ioptions].fptr(value);                } else                if (subtype == ITF_MATH2)                {                    // Built-In math function with 2 args                    if (ioptions >= MATHFUNCNUM-2)                    {                        // specific function - we need second arg as out                        ExpressionItem *arg2, *res2 = AllocItem();                        RunTree(*((ExpressionItem**)&(item->param2)), arg2, 0);                        if (ioptions == MATHFUNCNUM-1)                        {                            // fmodf function - second arg is ptr to double                            res2->type = IT_CONST | ITC_FLOAT;                            double &v = *((double*)&(res2->param1));                            value = ((Math2dFuncPtr)(MathFunctions[ioptions].fptr))(value, &v);                        } else                        {                            // frexp function - second arg is ptr to int                            int v = 0;                            value = ((Math2iFuncPtr)(MathFunctions[ioptions].fptr))(value, &v);                            *((__int64 *)&(res2->param1)) = (__int64) v;                        }                        SaveResult(arg2, res2);                        CleanupItems(arg2); CleanupItems(res2);                    } else                    {                        // normal 2-arg math function                        ExpressionItem *arg2;                        RunAndGetConst((int)item->param2, arg2, ITC_FLOAT);                        double value2 = *((double*)&(arg2->param1));                        value = ((Math2FuncPtr)(MathFunctions[ioptions].fptr))(value, value2);                        CleanupItems(arg2);                    }                }            }            break;        case IT_ARRAY:            {                // currently only array access is used                ExpressionItem *index, *aritem;                RunTree(*((ExpressionItem **) &(item->param1)), aritem, RTO_NEEDCONST | ITC_STRING | ITC_ARRAY);                if ((aritem->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST | ITC_STRING))                {                    // argument is string                    char *str = (char*)(aritem->param1);                    int len = lstrlen(str);                    // have we two indexes or one?                    if ((*((ExpressionItem **) &(item->param2)))->type != IT_EXPRESSION)                    {                        // one index - user need a char                        RunAndGetConst((int)item->param2, index, ITC_INT);                        int pos = (int) *((__int64*)&(index->param1));                        if (pos < 0) pos += len; // -index - means from end                        if ((pos > len) || (pos < 0))                            *str = 0; // index is accross string boundaries                        else                        {                            // new string - just a single char                            *str = *(str+pos);                            *(str+1) = 0;                        }                    } else                    {                        // two indexes                        ExpressionItem *index2;                        // if first index is skipped -> 0 (from first char)                        if ((*((ExpressionItem **) &(item->param2)))->param1 == 0)                            index = AllocItem();                        else                            RunAndGetConst((int)(*((ExpressionItem **) &(item->param2)))->param1, index, ITC_INT);                        if ((*((ExpressionItem **) &(item->param2)))->next->param1 == 0)                        {                            // if second index is skipped -> -1 (till last char)                            index2 = AllocItem();                            *((__int64*)&(index2->param1)) = -1;                        }                        else                            RunAndGetConst((int)(*((ExpressionItem **) &(item->param2)))->next->param1, index2, ITC_INT);                        // ok, we've got two indexes                        int pos1 = (int) *((__int64*)&(index->param1));                        int pos2 = (int) *((__int64*)&(index2->param1));                        if (pos1 < 0) pos1 += len; // -index - means from end                        if (pos2 < 0) pos2 += len; // -index - means from end                        // limit start/stop positions                        if (pos1 < 0) pos1 = 0;                        if (pos2 < 0) pos2 = 0;                        if (pos1 > len) pos1 = len;                        if (pos2 >= len) pos2 = len-1;                        // copy string part                        char* lpos = str + (pos2-pos1);                        while (str <= lpos)                        {                            *str = *(str + pos1);                            str++;                        }                        // null-termiante                        *str = 0;                        CleanupItems(index2);                    }                } else                {                    // argument is array                    RunAndGetConst((int)item->param2, index, ITC_INT);                    // convert array pointer to array item pointer                    aritem->type = IT_VARIABLE | ITV_ARRITEM;                    aritem->param2 = (EIPARAM) *((__int64*)&(index->param1));                    ArrayDesc *ad = (ArrayDesc*)aritem->param1;                    if (((int)aritem->param2) >= ad->count)                    {                        ad->count = ((int)aritem->param2)+1;                        while (ad->count > ad->size)                        {                            // resize array                            ExpressionItem **oldei = ad->array;                            ad->array = (ExpressionItem**) dbgGlobalAlloc(GPTR, 2*ad->size*sizeof(ExpressionItem*));                            for (int i = 0; i < ad->size; i++)                                ad->array[i] = oldei[i];                            ad->size*=2;                            dbgGlobalFree(oldei);                        }                    }                }                CleanupItems(index);                // we need constant result?                if (options & RTO_NEEDCONST)                {                    RunTree(aritem, result, options);                    CleanupItems(aritem);                } else result = aritem;            }            break;        }        item = item->next;    }}extern "C"void __declspec(dllexport) Script(HWND hwndParent, int string_size,                                      char *variables, stack_t **stacktop){  Math_INIT();  char *buffer = AllocString(), *buf = buffer;  ExpressionItem *root = NULL; // root of current tree  // pop script string  popstring(buffer);  // parse it  ParseString(buf, root);#ifdef _DEBUG  // dump  PrintTree(root, buffer);#endif  ExpressionItem *result;  RunTree(root, result, 0);  CleanupItems(result);  CleanupItems(root);  dbgGlobalFree((HGLOBAL) buffer);}double _infinity;extern "C" void _fpreset();void CleanAll(int init){  if (init)  {    unsigned char _infinity_base[8] = {0, 0, 0, 0, 0, 0, 0xf0, 0x7f};    _fltused = 0;    _infinity = *((double*)(_infinity_base));    _fpreset();    stack = NULL;    UserVarsCount = 0;    UserFuncsCount = 0;  } else  {    int i;    // cleanup stack    CleanupItems(stack); stack = NULL;    // cleanup user vars    for (i = 0; i < UserVarsCount; i++)        CleanupItems(UserVars[i].item);    // cleanup user funcs    for (i = 0; i < UserFuncsCount; i++)        CleanupItems(UserFuncs[i].root);    UserVarsCount = 0;    UserFuncsCount = 0;    dbgGlobalCheck();  }}BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved){    CleanAll(ul_reason_for_call == DLL_PROCESS_ATTACH);    return TRUE;}

⌨️ 快捷键说明

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