math.c

来自「NullSofts criptable install system2.28源代」· C语言 代码 · 共 1,549 行 · 第 1/4 页

C
1,549
字号
            // wrong - different op
            continue;
        }
        // that is our op
        sp += c;
        PlaceOp(vb, ((int) Operators[op].type) | IT_OPERATOR, Operators[op].precedence, pi);
        break;
    }
}

void ParseString(char *&sp, ExpressionItem* &itemplace)
{
    ParseInfo pi = {0, NULL, NULL, &itemplace, &itemplace};

    int redefine = 0;
    char *vb = pi.valbuf;
    // cycle until current expression end
    while ((*sp != 0) && (*sp != ')') && (*sp != '}') &&
        (*sp != ']') && (*sp != ','))
    {
        int processed = 1;
        switch (*sp)
        {
        case ' ':
        case '\t':
            sp++;
            break;
        case ';':
            // expression delimeter
            PlaceNewItem(vb, &pi, 255);
            if (*pi.root) pi.SetupNewRoot = 1;
            sp++;
            break;
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
            // variable & function names could contain numbers as non first chars
            if (vb > pi.valbuf)
            {
                processed = FALSE;
                break;
            }
        case '\'': case '\"': case '`':
            // constant meet
            pi.item = AllocItem();
            StringToItem(sp, pi.item, STI_STRING | STI_FLOAT | STI_INT);
            break;

        case '(': // start of function or expression
            if (vb > pi.valbuf)
            {
                // thats function
                PlaceFunction(vb, sp, &pi, redefine);
            } else
            {
                // expression
                sp++;
                ParseString(sp, pi.item);
                if (*sp == ')') sp++;
            }
            redefine = 0;
            break;

        case '#':   // start of one of logical expresions
            sp++;
            if ((*sp != '[') && (*sp != '{'))
            {
                // function redefine flag
                redefine = 1;
                break;
            }
            {
                pi.item = AllocItem();
                // IF or WHILE
                pi.item->type = ((*sp == '[')?(IT_LOGIC | ITL_IF):(IT_LOGIC | ITL_WHILE));
                // first expr - logic statement
                sp++;

                ParseString(sp, *((ExpressionItem **)(&pi.item->param1)));
                // ok, second expr - then, third - else statement.. others???
                ExpressionItem **newplace = ((ExpressionItem **)(&pi.item->param2));
                while (*sp == ',')
                {
                    *newplace = AllocItem();
                    (*newplace)->type = IT_EXPRESSION;
                    sp++;
                    ParseString(sp, *((ExpressionItem **)(&(*newplace)->param1)));
                    newplace = &((*newplace)->next);
                }
            }
            sp++;
            break;

        case '[':
            {
            // thats array access
            PlaceOp(vb, IT_ARRAY | ITA_ACCESS | PO_UNARYPOST, 1, &pi);
            sp++;
            // item index
            ParseString(sp, *(ExpressionItem **)&(pi.item->param2));
            if (*sp == ',')
            {
                // two indexes - string access
                ExpressionItem *it = AllocItem();
                it->type = IT_EXPRESSION;
                it->param1 = (EIPARAM)  *(ExpressionItem **)&(pi.item->param2);
                *(ExpressionItem **)&(pi.item->param2) = it;
                it = it->next = AllocItem();
                it->type = IT_EXPRESSION;
                sp++;
                ParseString(sp, *((ExpressionItem **)(&it->param1)));
            }
            sp++;
            }
            break;

        case '{':   // start of array define
            {
                // array define - constists of array copy operator and array define itself

                // type conversion item (to create a copy of array)
                pi.item = AllocItem();
                pi.item->type = IT_FUNCTION | ITF_TYPE | ITFT_CARRAY_ID | ITFA_COPY;

                // during first create our array descriptor and array pointers
                ExpressionItem *ai = AllocArray(DEFAULT_ARRAY_SIZE);
                pi.item->param1 = (EIPARAM)  ai;
                ArrayDesc *ad = *((ArrayDesc**)&(ai->param1));

                // parse array initializers
                while (*sp != '}')
                {
                    sp++;
                    ParseString(sp, ad->array[ad->count]);
                    if (ad->array[ad->count])
                      ad->count++;
                }

                sp++;
            }
            break;
        case '-': case '+': case '<': case '=': case '>':
        case '/': case '*': case '~': case '^': case '!':
        case '&': case '|': case '%':
            CheckForOperator(sp, vb, &pi);
            break;

        // non expression? ok, then it should be common char, like function or var name
        default:
            processed = FALSE;
            break;
        }
        if (!processed) *(vb++) = *(sp++);
    }
    PlaceNewItem(vb, &pi, 255);
}

void CleanupArray(ArrayDesc *ad)
{
    if (!(--(ad->references)))
    {
        // last array reference, we could kill it
        // cleanup array items
        for (int i = 0; i < ad->count; i++)
        {
            ExpressionItem *aritem = ad->array[i];
            if (aritem)
                CleanupItems(aritem);
        }
        // cleanup ptrs and descriptor
        dbgGlobalFree(ad->array);
        dbgGlobalFree(ad);
    }
 }

void CleanupItems(ExpressionItem* &itemplace)
{
    if (itemplace == NULL) return;
    ExpressionItem *item = itemplace, *itemnext;
    do
    {
        if (((item->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_VARIABLE|ITV_ARRITEM))
            ||
            ((item->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST|ITC_ARRAY)))
        {
            CleanupArray((ArrayDesc *)item->param1);
        }
        else
        if ((item->type & ITEMTYPE) == IT_CONST)
        {
            if ((item->type & ITEMSUBTYPE) == ITC_STRING)
                dbgGlobalFree((HGLOBAL) item->param1);
        } else
        {
            CleanupItems(*((ExpressionItem**) &item->param1));
            CleanupItems(*((ExpressionItem**) &item->param2));
        }
        // free the item itself
        itemnext = item->next;
        dbgGlobalFree((HGLOBAL) item);
        item = itemnext;
    } while (item != NULL);
    itemplace = NULL;
}

#ifdef _DEBUG
HANDLE myfile;

char *opsnames[] = {"", "-", "+", "<<", ">>", "*", "/", "=", "&&", "||", "++", "--",
"=<", ">=", "!=", "==", "<", ">", "&", "%", "|", "^", "~", "!"};

void PrintNode(int index, int spaces, ExpressionItem* itemplace)
{
    if (itemplace == NULL) return;

    ExpressionItem *item = itemplace;
    do
    {
        DWORD wrote;
        char buffer[1024], *place = buffer;
        for (int k = 0; k < spaces; k++)
            *(place++) = 32;
        *place = 0;

        switch (item->type & ITEMTYPE)
        {
        case  IT_EXPRESSION:
            wsprintf(place, "Expression Place-Holder   ");
            break;
        case  IT_CONST:
            switch (item->type & ITEMSUBTYPE)
            {
            case ITC_STRING:
                wsprintf(place, "String: \"%s\"", (char *) item->param1);
                break;
            case ITC_INT:
                wsprintf(place, "Int: ");
                itoa64(*((__int64*)&(item->param1)), place+5);
                break;
            case ITC_FLOAT:
                wsprintf(place, "Float: ");
                FloatFormat(place+7, *((double*)&(item->param1)), 6);
                break;
            case ITC_ARRAY:
                ArrayDesc *ad = (ArrayDesc*) item->param1;
                wsprintf(place, "Array, ptr %08X, size %d, count %d, references %d",
                    ad->array, ad->size, ad->count, ad->references);
                break;
            }
            strcat(place, "    ");
            break;
        case IT_OPERATOR:
            wsprintf(place, "Op: %s%s    ", opsnames[(item->type & ITEMSUBTYPE) >> 8], (item->type & PO_SET)?("(=)"):(""));
            break;
        case IT_VARIABLE:
            switch (item->type & ITEMSUBTYPE)
            {
            case ITV_NSIS:
                {
                char buffer[128];
                buffer[0] = NSISVariablesNames[item->type & ITEMOPTIONS][0];
                buffer[1] = NSISVariablesNames[item->type & ITEMOPTIONS][1];
                buffer[2] = 0;
                wsprintf(place, "Var: %s (%d)   ",
                    buffer,
                    item->type & ITEMOPTIONS);
                }
                break;
            case ITV_USER:
                wsprintf(place, "Var: %s (%d)   ", UserVars[item->type & ITEMOPTIONS].name, item->type & ITEMOPTIONS);
                break;
            case ITV_STACK:
                wsprintf(place, "Plugin Stack   ");
                break;
            case ITV_NSTACK:
                wsprintf(place, "NSIS Stack   ");
                break;
            }
            break;
        case IT_LOGIC:
            if ((item->type & ITEMSUBTYPE) == ITL_IF)
                wsprintf(place, "IF ");
            else
                wsprintf(place, "WHILE ");
            break;
        case IT_FUNCTION:
            if (((item->type & ITEMSUBTYPE) == ITF_MATH1) ||
                ((item->type & ITEMSUBTYPE) == ITF_MATH2) ||
                ((item->type & ITEMSUBTYPE) == ITF_TYPE))
            {
                char buffer[128];
                buffer[0] = (MathFunctions[item->type &ITEMOPTIONS].name)[0];
                buffer[1] = (MathFunctions[item->type &ITEMOPTIONS].name)[1];
                buffer[2] = (MathFunctions[item->type &ITEMOPTIONS].name)[2];
                buffer[3] = 0;
                wsprintf(place, "Built-In Function %s() [%d] ",
                    buffer,
                    item->type &ITEMOPTIONS);
            }
            else
            {
                UserFunc *f = &(UserFuncs[item->type & ITEMOPTIONS]);
                wsprintf(place, "User Function: %s(", f->name);
                int flags = f->varflags;
                for (int 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, ")   ");
            }
            break;
        case IT_ARRAY:
            wsprintf(place, "Array access []   ");
            break;
        }
        place += lstrlen(place);
        wsprintf(place, "Addr: %08X Type: %08X   Next: %08X  Param1: %08X  Param2: %08X", item, item->type, item->next, item->param1, item->param2);
        lstrcat(place, "\n");
        WriteFile(myfile, buffer, lstrlen(buffer), &wrote, NULL);
        if (((item->type & ITEMTYPE) != IT_CONST) && ((item->type & (ITEMTYPE|ITEMSUBTYPE)) != (IT_VARIABLE|ITV_ARRITEM)))
        {
            place = buffer;
            for (int k = 0; k < spaces+2; k++)
                *(place++) = 32;
            int show = 0;
            if (((item->param1 != NULL) && ((*((ExpressionItem**) &item->param1))->next != NULL)) ||
                ((item->param2 != NULL) && ((*((ExpressionItem**) &item->param2))->next != NULL)))
                show = 1;
            if (show)
            {
                wsprintf(place, "Sub1:\n");
                WriteFile(myfile, buffer, lstrlen(buffer), &wrote, NULL);
            }
            PrintNode(1, spaces + 4, *((ExpressionItem**) &item->param1));
            if (show)
            {
                wsprintf(place, "Sub2:\n");
                WriteFile(myfile, buffer, lstrlen(buffer), &wrote, NULL);
            }
            PrintNode(2, spaces + 4, *((ExpressionItem**) &item->param2));
        } else if ((item->type & (ITEMSUBTYPE|ITEMTYPE)) == (ITC_ARRAY|IT_CONST))
        {
            ArrayDesc *ad = (ArrayDesc *) item->param1;
            for (int i = 0; i < ad->count; i++)
            {
                ExpressionItem *aritem = ad->array[i];
                if (aritem)
                    PrintNode(2, spaces + 4, aritem);
            }
        }
        item = item->next;
    } while (item != NULL);
}

void PrintTree(ExpressionItem *root, char *str)
{
    myfile = CreateFile("d:\\math.debug", GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0);
    SetFilePointer(myfile, 0, NULL, FILE_END);
    char buffer[1024]; DWORD wrote;
    wsprintf(buffer, "New tree for \'%s\'\n", str);
    WriteFile(myfile, buffer, lstrlen(buffer), &wrote, NULL);

    PrintNode(0, 4, root);
    CloseHandle(myfile);
    myfile = NULL;
}
#endif

void CopyArray(ExpressionItem *&item)
{
    if (item == NULL) return;
    // especial case - array to array conversion is requested array copy
    ExpressionItem *olditem = item;
    ArrayDesc *oad = (ArrayDesc *) (olditem->param1);
    // Initialize the array of the same size
    item = AllocArray(oad->size);
    ArrayDesc *nad = (ArrayDesc *) (item->param1);
    nad->count = oad->count;
    // copy items
    for (int i = 0; i < oad->count; i++)
       nad->array[i] = CopyItem(oad->array[i], TRUE);
    // cleanup old array pointer (may be array itself)
    CleanupItems(olditem);
}

void ItemToType(ExpressionItem* &item, int type)

⌨️ 快捷键说明

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