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

📄 math.c

📁 nsis是一个流传比较广的程序安装和解安装封装软件
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <windows.h>#include "MyMath.h"#include "Math.h"extern "C" int _fltused;#ifdef __MINGW32__int _fltused = 1;#endifExpressionItem *stack;int UserVarsCount, UserFuncsCount;UserVar UserVars[MAX_USER_VARS];UserFunc UserFuncs[MAX_USER_FUNCS];void PrintTree(ExpressionItem *root, char *str);void ParseString(char *&sp, ExpressionItem* &itemplace);void CleanupItems(ExpressionItem* &itemplace);void PlaceVariable(char *&vb, ParseInfo *pi);void PlaceNewItem(char *&vb, ParseInfo *pi, int precedence){    ExpressionItem *newroot;    PlaceVariable(vb, pi);    if (pi->item == NULL) return;    while ((pi->OpsStack) && ((((int) pi->OpsStack->param2) < precedence)        || ((((int)pi->OpsStack->param2) == precedence)            && (precedence != OPERATOR_SET_PRECEDENCE))))    {        // second operand for our operator        newroot = pi->OpsStack;        *((ExpressionItem **)&(newroot->param2)) = pi->item;        pi->OpsStack = newroot->next;        newroot->next = NULL;        pi->item = newroot;    }    // finally we have got new root    newroot = pi->item;    if (pi->SetupNewRoot)    {        (*pi->root)->next = newroot;        pi->root = &((*pi->root)->next);        pi->SetupNewRoot = 0;    }    if (*pi->place == *pi->root) *pi->place = *pi->root = newroot;    else *pi->root = newroot;    // no item at our pockets    pi->item = NULL;}#define NSIS_VARS_COUNT 27#define NSIS_VARS_STACK 25#define NSIS_VARS_NSTACK 26typedef char smallstr[2];const smallstr NSISVariablesNames[NSIS_VARS_COUNT] = {{'r','0'}, {'r','1'}, {'r','2'}, {'r','3'}, {'r','4'}, {'r','5'}, {'r','6'}, {'r','7'}, {'r','8'}, {'r','9'},{'R','0'}, {'R','1'}, {'R','2'}, {'R','3'}, {'R','4'}, {'R','5'}, {'R','6'}, {'R','7'}, {'R','8'}, {'R','9'},{'C','L'}, {'I','D'}, {'O','D'}, {'E','D'}, {'L','G'}, {'S',0}, {'N','S'}};ExpressionItem *FindVariable(char *varname){    int i;    ExpressionItem *item = AllocItem();    // check NSIS variables    for (i = 0; i < NSIS_VARS_COUNT; i++)    {        if (lstrcmpn(varname, NSISVariablesNames[i],2) == 0)        {            if (i == NSIS_VARS_STACK) item->type = IT_VARIABLE | ITV_STACK;            else if (i == NSIS_VARS_NSTACK) item->type = IT_VARIABLE | ITV_NSTACK;            else                item->type = (IT_VARIABLE | ITV_NSIS) + i;            return item;        }    }    // no.. that's user variable    for (i = 0; i < UserVarsCount; i++)    {        if (lstrcmp(varname, UserVars[i].name) == 0)        {            // ok. we found user var expression needed            break;        }    }    if (i == UserVarsCount)    {        // new variable        UserVarsCount++;        lstrcpy(UserVars[i].name, varname);        UserVars[i].item = NULL;    }    item->type = (IT_VARIABLE | ITV_USER) + i;    return item;}void PlaceVariable(char *&vb, ParseInfo *pi){    if (vb <= pi->valbuf) return;    *vb = 0;    pi->item = FindVariable(pi->valbuf);    vb = pi->valbuf;}typedef double (*math_d2)(double, double);typedef double (*math_ddp)(double, double*);typedef double (*math_di)(double, int*);#define MATHFUNCNUM 29const MathFunction MathFunctions[MATHFUNCNUM] = {    {{'s','i','n'}, ITF_MATH1 >> 8, sin},    {{'s','n','h'}, ITF_MATH1 >> 8, sinh},    {{'a','s','n'}, ITF_MATH1 >> 8, asin},    {{'c','o','s'}, ITF_MATH1 >> 8, cos},    {{'c','s','h'}, ITF_MATH1 >> 8, cosh},    {{'a','c','s'}, ITF_MATH1 >> 8, acos},    {{'t','a','n'}, ITF_MATH1 >> 8, tan},    {{'t','n','h'}, ITF_MATH1 >> 8, tanh},    {{'a','t','n'}, ITF_MATH1 >> 8, atan},    {{'a','b','s'}, ITF_MATH1 >> 8, fabs},    {{'l','n',0}, ITF_MATH1 >> 8, log},    {{'l','o','g'}, ITF_MATH1 >> 8, log10},    {{'e','x','p'}, ITF_MATH1 >> 8, exp},    {{'s','q','t'}, ITF_MATH1 >> 8, sqrt},    {{'c','e','l'}, ITF_MATH1 >> 8, ceil},    {{'f','l','r'}, ITF_MATH1 >> 8, floor},    {{'a','t','2'}, ITF_MATH2 >> 8, (Math1FuncPtr)(math_d2)atan2},    {{'p','o','w'}, ITF_MATH2 >> 8, (Math1FuncPtr)(math_d2)pow},    {{'f','m','d'}, ITF_MATH2 >> 8, (Math1FuncPtr)(math_d2)fmod},    // type conversions    {{'i',0,0}, ITF_TYPE >> 8, (Math1FuncPtr)ITC_INT},    {{'s',0,0}, ITF_TYPE >> 8, (Math1FuncPtr)ITC_STRING},    {{'f',0,0}, ITF_TYPE >> 8, (Math1FuncPtr)ITC_FLOAT},    {{'a',0,0}, ITF_TYPE >> 8, (Math1FuncPtr)ITC_ARRAY},#define ITFT_CARRAY_ID    23    {{'c','a',0}, ITF_TYPE >> 8, (Math1FuncPtr)ITC_ARRAY},    {{'f','f',0}, ITF_TYPE >> 8, (Math1FuncPtr)FTT_FLOATF},    {{'l',0,0}, ITF_TYPE >> 8, (Math1FuncPtr)FTT_LEN},    {{'c',0,0}, ITF_TYPE >> 8, (Math1FuncPtr)FTT_CHAR},    {{'f','e','x'}, ITF_MATH2 >> 8, (Math1FuncPtr)(math_di)frexp},    {{'m','d','f'}, ITF_MATH2 >> 8, (Math1FuncPtr)(math_ddp)modf},};void PlaceFunction(char *&vb, char *&sp, ParseInfo *pi, int redefine){    int i;    ExpressionItem *item = pi->item = AllocItem();    *vb = 0;    // check BUILTIN functions    for (i = 0; i < MATHFUNCNUM; i++)    {        if (lstrcmpn(pi->valbuf, MathFunctions[i].name, 3) == 0)        {            item->type = IT_FUNCTION | (MathFunctions[i].type << 8) | i;            // get first argument            sp++;            ParseString(sp, *((ExpressionItem **)(&item->param1)));            if (*sp == ',')            {                // get second argument                sp++;                ParseString(sp, *((ExpressionItem **)(&item->param2)));            }            sp++; vb = pi->valbuf;            return;        }    }    // heh, may be it user function    for (i = 0; i < UserFuncsCount; i++)    {        if (lstrcmp(pi->valbuf, UserFuncs[i].name) == 0)        {            // Function found? Redefine option specified?            if (redefine) break;            item->type = IT_FUNCTION | ITF_USER | i;            // get arguments list            ExpressionItem **newplace = ((ExpressionItem **)(&pi->item->param1));            while (*sp != ')')            {                *newplace = AllocItem();                (*newplace)->type = IT_EXPRESSION;                sp++;                ParseString(sp, *((ExpressionItem **)(&(*newplace)->param1)));                newplace = &((*newplace)->next);            }            sp++; vb = pi->valbuf;            return;        }    }    // oops, we need no item for function defenition    CleanupItems(item); pi->item = NULL;    // it's user function define    int flags = 0;    char buffer[128], *buf = buffer;    // workaround for redefine flag - if the function already present,    // it will be cleared and redefined    UserFunc *f = &UserFuncs[i];    if (i == UserFuncsCount) UserFuncsCount++;    else CleanupItems(f->root);    lstrcpy(f->name, pi->valbuf);    f->varflags = 0;    f->varsnum = 0;    do    {        sp++;        switch (*sp)        {        case ' ':            break;        case ',':        case ')':            if (buf > buffer)            {                *buf = 0;                // it should be user variable                ExpressionItem *it = FindVariable(buffer);                f->vars[f->varsnum++] = (it->type) & ITEMOPTIONS;                CleanupItems(it);                buf = buffer;                flags <<= 1;            }            break;        case '&':            flags |= 1;            break;        default:            *(buf++) = *sp;            break;        }    }    while (*sp != ')');    // prepare flag for fast analisys    for (i = 0; i < f->varsnum; i++)    {        f->varflags <<= 1;        flags >>= 1;        f->varflags |= flags&1;    }    // find nearest round bracket - function body    while (*sp != '(' && *sp) sp++;    if (!*sp)      return;    sp++;    // now we are ready to parse function body    ParseString(sp, f->root);    sp++; // closing bracket    vb = pi->valbuf;#ifdef _DEBUG  // dump function (in debug mode)  char place[1024];  wsprintf(place, "function %s(", f->name);  flags = f->varflags;  for (i = 0; i < f->varsnum; i++)  {    if (flags&1) lstrcat(place, "&");    lstrcat(place, UserVars[f->vars[i]].name);    if (i < f->varsnum-1) lstrcat(place, ", ");    flags >>= 1;  }  lstrcat(place, ")");  PrintTree(f->root, place);#endif}// operator options#define PO_UNARYPRE    0x1 // this operator can be uniary pre (--a) for ex#define PO_UNARYPOST   0x2 // this op can be uniary post (a++) (couldn't be binary)#define PO_PRENONCONST  0x4 // pre argument (a = b) -> a is non const#define PO_POSTNONCONST 0x8 // post argument (b--) is non const#define PO_LASTOP      0x10 // op should be the last item at expression (=, -=, etc)#define PO_SET         0x20 // op will set new value to one of args#define PO_USESPRE     0x40 // operator will use pre operand#define PO_USESPOST    0x80 // operator will use post operanvoid PlaceOp(char *&vb, int type, int precedence, ParseInfo *pi){    PlaceVariable(vb, pi);    if ((type & PO_UNARYPRE) && (!pi->item))    {        // uniary pre op        ExpressionItem *item = AllocItem();        item->type = type;        item->param2 = (EIPARAM) precedence;        item->next = pi->OpsStack;        pi->OpsStack = item;    }    else    {        // get previous tree as items and operators of lower precedence        PlaceNewItem(vb, pi, precedence);        // post operators        ExpressionItem *item = AllocItem();        item->type = type;        item->param1 = (EIPARAM) (*pi->root);        if (*pi->place == *pi->root) *pi->place = *pi->root = NULL;        else *pi->root = NULL;        if (type & PO_UNARYPOST)        {            // uniary post op            pi->item = item;        } else        {            // binary operator            item->param2 = (EIPARAM) precedence;            item->next = pi->OpsStack;            pi->OpsStack = item;        }    }}#define OPSNUM  35const OpStruct Operators[OPSNUM] ={// three byte ops{{'>','>','='}, 14, ITO_SHR | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{{'<','<','='}, 14, ITO_SHL | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},// two byte ops// !!! don't forget to change Set Operator Precedence !!!{"-=", 14, ITO_MINUS | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"+=", 14, ITO_PLUS | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"/=", 14, ITO_DIV | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"*=", 14, ITO_MUL | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"|=", 14, ITO_OR | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"&=", 14, ITO_AND | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"^=", 14, ITO_XOR | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"%=", 14, ITO_MOD | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPRE | PO_USESPOST},{"--", 2, ITO_DEC | PO_POSTNONCONST | PO_PRENONCONST | PO_UNARYPRE | PO_UNARYPOST | PO_SET | PO_USESPRE | PO_USESPOST},{"++", 2, ITO_INC | PO_POSTNONCONST | PO_PRENONCONST | PO_UNARYPRE | PO_UNARYPOST | PO_SET | PO_USESPRE | PO_USESPOST},{">>", 6, ITO_SHR | PO_USESPRE | PO_USESPOST},{"<<", 6, ITO_SHL | PO_USESPRE | PO_USESPOST},// logical{"&&", 12, ITO_LAND | PO_USESPRE | PO_USESPOST},{"||", 13, ITO_LOR | PO_USESPRE | PO_USESPOST},// comparisons{"<=", 7, ITO_LE | PO_USESPRE | PO_USESPOST},{"=<", 7, ITO_LE | PO_USESPRE | PO_USESPOST},{">=", 7, ITO_GE | PO_USESPRE | PO_USESPOST},{"=>", 7, ITO_GE | PO_USESPRE | PO_USESPOST},{"!=", 8, ITO_NE | PO_USESPRE | PO_USESPOST},{"==", 8, ITO_EQ | PO_USESPRE | PO_USESPOST},// single byte ops// !!! don't forget to change Set Operator Precedence !!!{"=", 14, ITO_SET | PO_PRENONCONST | PO_LASTOP | PO_SET | PO_USESPOST},{"+", 5, ITO_PLUS | PO_USESPRE | PO_USESPOST},{"-", 5, ITO_MINUS | PO_USESPRE | PO_USESPOST | PO_UNARYPRE},{"*", 4, ITO_MUL | PO_USESPRE | PO_USESPOST | PO_UNARYPRE},{"/", 4, ITO_DIV | PO_USESPRE | PO_USESPOST},{"%", 4, ITO_MOD | PO_USESPRE | PO_USESPOST},{"<", 7, ITO_LS | PO_USESPRE | PO_USESPOST},{">", 7, ITO_GR | PO_USESPRE | PO_USESPOST},{"&", 9, ITO_AND | PO_USESPRE | PO_USESPOST | PO_UNARYPRE},{"|", 11, ITO_OR | PO_USESPRE | PO_USESPOST},{"^", 10, ITO_XOR | PO_USESPRE | PO_USESPOST},{"~", 3, ITO_NOT | PO_USESPOST | PO_UNARYPRE},{"!", 3, ITO_LNOT |PO_USESPOST | PO_UNARYPRE}};void CheckForOperator(char *&sp, char *&vb, ParseInfo *pi){    for (int op = 0; op < OPSNUM; op++)    {        int c = lstrlen(Operators[op].name);        if (c > 3) c = 3; // real operator length        if (lstrcmpn(sp, Operators[op].name, c))        {

⌨️ 快捷键说明

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