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 + -
显示快捷键?