📄 math.c
字号:
// 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 _DEBUGHANDLE 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;}#endifvoid 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -