JD2022-TU1/main/extern/Camcam/Tools/StringTools.cpp

613 lines
No EOL
16 KiB
C++

#include "DEFINES.H"
#include "TRACK.H"
#define PI 3.14159265358979323846
void SimplifyPlusMinus(char *src, char *dst)
{
int sign;
while (*src) {
if (*src == '+' || *src == '-')
{
if (*src == '+') sign = 1;
else sign = -1;
src++;
for (; *src == '+' || *src == '-' || *src == ' '; src++)
{
if (*src == '-') sign *= -1;
}
if (sign == 1) *(dst++) = '+';
else *(dst++) = '-';
} else
*(dst++) = *(src++);
}
*dst = 0;
}
// Version plus lourde avec calcul en plusieur passe
enum
{
OP_CONCAT = 0,
OP_NOT,
OP_MULTIPLY,
OP_DIVIDE,
OP_PLUS,
OP_MINUS,
OP_EQUAL,
OP_DIFF,
OP_LE,
OP_HE,
OP_L,
OP_H,
OP_AND,
OP_OR,
NB_OPERATORS
};
#define MAX_LVL 4
char *operators[NB_OPERATORS] = {":", "!", "*", "/", "+", "-", "==", "!=", "<=", ">=", "<", ">", "&&", "||"};
int operatorLen[NB_OPERATORS] = {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2};
int operatorLvl[NB_OPERATORS] = {1,1,2,2,3,3,4,4,4,4,4,4,5,5};
int IsOperator(char *src)
{
int resOP = -1;
int resLen = 0;
for (int opIdx=0; opIdx<NB_OPERATORS; opIdx++)
{
if (!strncmp(src, operators[opIdx], operatorLen[opIdx]))
{
if (operatorLen[opIdx] > resLen)
{
resOP = opIdx;
resLen = operatorLen[opIdx];
}
}
}
return resOP;
}
#define NB_FUNCTIONS 7
char *functions[NB_FUNCTIONS] = {"sqrt", "cos", "sin", "tan", "acos", "asin", "atan"};
int IsFunction(char *src)
{
for (int fcIdx=0; fcIdx<NB_FUNCTIONS; fcIdx++)
{
if (!strncmp(src, functions[fcIdx], strlen(functions[fcIdx])))
return fcIdx;
}
return -1;
}
enum
{
TYPE_DUMMY = 0,
TYPE_INT,
TYPE_FLOAT,
TYPE_FUNCTION,
TYPE_OPERATOR,
};
typedef struct Expr_Node_ {
char type; // 0 dummy; 1 int; 2 float; 3 function; 4 op
int nbIntFloatTab;
float intFloatTab[256];
int idx;
struct Expr_Node_ *LeftChild;
struct Expr_Node_ *RightChild;
} Expr_Node;
static Expr_Node NodeBuffer[512];
static int NodeBufferIdx;
Expr_Node *CreateExprTreeFromNodes(Expr_Node **NodeListPtr, int nbNodes)
{
int maxOpLvl;
int maxOpPos;
Expr_Node *rootNode;
if (nbNodes == 0) return NULL;
if (nbNodes == 1) return *NodeListPtr;
maxOpLvl = -2;
maxOpPos = -1;
for (int pos=0; pos<nbNodes; pos++)
{
if (NodeListPtr[pos]->type != TYPE_OPERATOR) continue;
if (operatorLvl[NodeListPtr[pos]->idx] < maxOpLvl) continue;
if ((NodeListPtr[pos]->idx == OP_PLUS || NodeListPtr[pos]->idx == OP_MINUS) &&
(pos == 0 || NodeListPtr[pos-1]->type == TYPE_OPERATOR))
{
if (maxOpLvl == -2)
{
maxOpLvl = -1;
maxOpPos = pos;
}
continue;
}
maxOpPos = pos;
maxOpLvl = operatorLvl[NodeListPtr[pos]->idx];
}
if (maxOpPos < 0 || maxOpPos == (nbNodes - 1)) return NULL;
rootNode = NodeListPtr[maxOpPos];
rootNode->LeftChild = CreateExprTreeFromNodes(NodeListPtr, maxOpPos);
rootNode->RightChild = CreateExprTreeFromNodes(NodeListPtr + maxOpPos + 1, nbNodes - maxOpPos - 1);
return rootNode;
}
Expr_Node * CreateExprTree(char * expr)
{
char bloc[2048];
int blocPos;
int nbNodes = 0;
Expr_Node *NodeListPtr[512];
Expr_Node *currentNode;
int res;
int inFunction;
// Step 1 Get All Nodes at the same level
while (*expr)
{
for (; *expr == ' '; expr++);
if (!*expr) break;
res = IsOperator(expr);
if (res >= 0) {
currentNode = NodeBuffer + NodeBufferIdx++;
currentNode->type = TYPE_OPERATOR;
currentNode->idx = res;
NodeListPtr[nbNodes++] = currentNode;
expr += strlen(operators[res]);
continue;
}
res = IsFunction(expr);
if (res >= 0) {
currentNode = NodeBuffer + NodeBufferIdx++;
currentNode->type = TYPE_FUNCTION;
currentNode->idx = res;
NodeListPtr[nbNodes++] = currentNode;
expr += strlen(functions[res]);
if (*expr != '(') return NULL;
inFunction = 1;
} else
inFunction = 0;
if (*expr == '(') {
int parLevel = 1;
expr++;
blocPos = 0;
while (parLevel > 0 && *expr != 0)
{
if (*expr == '(') parLevel++;
if (*expr == ')') parLevel--;
bloc[blocPos++] = *(expr++);
}
if (parLevel > 0) return NULL;
bloc[blocPos-1] = 0;
currentNode = CreateExprTree(bloc);
if (currentNode == NULL) return NULL;
if (!inFunction)
{
NodeListPtr[nbNodes] = NodeBuffer + NodeBufferIdx++;
NodeListPtr[nbNodes]->type = TYPE_DUMMY;
nbNodes++;
}
NodeListPtr[nbNodes-1]->RightChild = currentNode;
continue;
}
if (*expr == '{')
{
currentNode = NodeBuffer + NodeBufferIdx++;
currentNode->nbIntFloatTab = 0;
expr++;
blocPos = 0;
res = 0;
for (; *expr != 0 && *expr != '}'; expr++)
{
if (*expr == '{') return NULL;
if (*expr == ' ')
{
if (blocPos > 0)
{
bloc[blocPos] = 0;
currentNode->intFloatTab[currentNode->nbIntFloatTab++] = atof(bloc);
blocPos = 0;
}
continue;
}
if (*expr == '.') res = 1;
if (('0' <= *expr && *expr <= '9') || *expr == '.' || *expr == '-' || *expr == '+')
bloc[blocPos++] = *expr;
else
return NULL;
}
if (*expr == 0) return NULL;
expr++;
if (blocPos > 0)
{
bloc[blocPos] = 0;
currentNode->intFloatTab[currentNode->nbIntFloatTab++] = atof(bloc);
}
currentNode->type = TYPE_INT + res;
NodeListPtr[nbNodes++] = currentNode;
for (int idx = 0; idx<2; idx++)
{
for (; *expr == ' '; expr++);
if (*expr == '[')
{
int parLevel = 1;
expr++;
blocPos = 0;
while (parLevel > 0 && *expr != 0)
{
if (*expr == '[') parLevel++;
if (*expr == ']') parLevel--;
bloc[blocPos++] = *(expr++);
}
if (parLevel > 0) return NULL;
bloc[blocPos-1] = 0;
if (idx == 0)
currentNode->LeftChild = CreateExprTree(bloc);
else
currentNode->RightChild = CreateExprTree(bloc);
}
}
continue;
}
currentNode = NodeBuffer + NodeBufferIdx++;
blocPos = 0;
res = 0;
for (; ('0' <= *expr && *expr <= '9') || *expr == '.'; expr++)
{
if (*expr == '.')
{
if (res) return NULL;
else res = 1;
}
bloc[blocPos++] = *expr;
}
if ((res && blocPos >= 2) || (!res && blocPos >= 1))
{
bloc[blocPos] = 0;
currentNode->intFloatTab[0] = atof(bloc);
currentNode->nbIntFloatTab = 1;
currentNode->type = TYPE_INT + res;
NodeListPtr[nbNodes++] = currentNode;
} else
return NULL;
}
// Step 2 : create tree whith node List ...
return CreateExprTreeFromNodes(NodeListPtr, nbNodes);
}
#define NODE_OPERATION(op, mycast) { if (lChild->nbIntFloatTab == rChild->nbIntFloatTab) \
{ \
for (idx=0; idx<rChild->nbIntFloatTab; idx++) \
lChild->intFloatTab[idx] = (mycast)lChild->intFloatTab[idx] op (mycast)rChild->intFloatTab[idx];\
return lChild; \
} else if (rChild->nbIntFloatTab == 1) \
{ \
for (idx=0; idx<lChild->nbIntFloatTab; idx++) \
lChild->intFloatTab[idx] = (mycast)lChild->intFloatTab[idx] op (mycast)rChild->intFloatTab[0]; \
return lChild; \
} else if (lChild->nbIntFloatTab == 1) \
{ \
for (idx=0; idx<rChild->nbIntFloatTab; idx++) \
rChild->intFloatTab[idx] = (mycast)lChild->intFloatTab[0] op (mycast)rChild->intFloatTab[idx]; \
return rChild; \
} \
return NULL; }
#define NODE_COMPARE(op, ini, cp) { if (!isDuo) return NULL; \
res = -1; \
if (lChild->nbIntFloatTab == rChild->nbIntFloatTab) \
{ \
res = ini; \
for (idx=0; idx<rChild->nbIntFloatTab; idx++) \
res = res cp (lChild->intFloatTab[idx] op rChild->intFloatTab[idx]); \
} else if (rChild->nbIntFloatTab == 1) \
{ \
res = ini; \
for (idx=0; idx<lChild->nbIntFloatTab; idx++) \
res = res cp (lChild->intFloatTab[idx] op rChild->intFloatTab[0]); \
} else if (lChild->nbIntFloatTab == 1) \
{ \
res = ini; \
for (idx=0; idx<rChild->nbIntFloatTab; idx++) \
res = res cp (lChild->intFloatTab[0] op rChild->intFloatTab[idx]); \
} \
if (res == -1) return NULL; \
rChild->type = TYPE_INT; \
rChild->nbIntFloatTab = 1; \
rChild->intFloatTab[0] = res; \
return rChild; } \
Expr_Node * Eval_Node(Expr_Node *node)
{
Expr_Node *rChild;
Expr_Node *lChild;
int isFloat = 0;
int isDuo;
int idx;
int res;
if (node == NULL) return NULL;
switch (node->type)
{
case TYPE_DUMMY:
if (node->LeftChild) return NULL;
return Eval_Node(node->RightChild);
break;
case TYPE_INT:
case TYPE_FLOAT:
if (node->LeftChild != NULL)
{
lChild = Eval_Node(node->LeftChild);
if ((lChild->type != TYPE_INT && lChild->type != TYPE_FLOAT) ||
lChild->nbIntFloatTab != 1) return NULL;
idx = (int)lChild->intFloatTab[0];
res = 1;
if (node->RightChild != NULL)
{
rChild = Eval_Node(node->RightChild);
if ((rChild->type == TYPE_INT || rChild->type != TYPE_FLOAT) &&
rChild->nbIntFloatTab == 1)
{
res = (int)rChild->intFloatTab[0];
}
}
if (idx >= node->nbIntFloatTab) return NULL;
for (int i=0; i < res && (idx + i) < node->nbIntFloatTab; i++)
{
node->intFloatTab[i] = node->intFloatTab[idx+i];
}
node->nbIntFloatTab = res;
}
return node;
case TYPE_FUNCTION:
if (node->LeftChild != NULL) return NULL;
rChild = Eval_Node(node->RightChild);
if (rChild == NULL) return NULL;
if (rChild->type != TYPE_INT && rChild->type != TYPE_FLOAT) return NULL;
rChild->type = TYPE_FLOAT;
switch (node->idx)
{
case 0:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
{
if (rChild->intFloatTab[idx] < 0.0f) return NULL;
rChild->intFloatTab[idx] = sqrt(rChild->intFloatTab[idx]);
}
return rChild;
case 1:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = cos(rChild->intFloatTab[idx] * PI / 180.0);
return rChild;
case 2:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = sin(rChild->intFloatTab[idx] * PI / 180.0);
return rChild;
case 3:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = tan(rChild->intFloatTab[idx] * PI / 180.0);
return rChild;
case 4:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = acos(rChild->intFloatTab[idx]) * 180 / PI;
return rChild;
case 5:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = asin(rChild->intFloatTab[idx]) * 180 / PI;
return rChild;
case 6:
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = atan(rChild->intFloatTab[idx]) * 180 / PI;
return rChild;
}
case TYPE_OPERATOR:
rChild = Eval_Node(node->RightChild);
lChild = Eval_Node(node->LeftChild);
if (rChild == NULL || (rChild->type != TYPE_INT && rChild->type != TYPE_FLOAT)) return NULL;
isFloat = rChild->type - TYPE_INT;
if (lChild == NULL || (lChild->type != TYPE_INT && lChild->type != TYPE_FLOAT))
isDuo = 0;
else
{
isDuo = 1;
isFloat = isFloat || (lChild->type - TYPE_INT);
}
if (isDuo)
rChild->type = lChild->type = TYPE_INT + isFloat;
switch (node->idx)
{
case OP_CONCAT:
if (!isDuo) return NULL;
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
lChild->intFloatTab[lChild->nbIntFloatTab++] = rChild->intFloatTab[idx];
return lChild;
case OP_NOT:
if (isDuo) return NULL;
rChild->type = TYPE_INT;
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = !rChild->intFloatTab[idx];
return rChild;
case OP_MULTIPLY:
if (!isDuo) return NULL;
if (isFloat)
NODE_OPERATION(*, float)
else
NODE_OPERATION(*, int)
case OP_DIVIDE:
if (!isDuo) return NULL;
if (isFloat)
NODE_OPERATION(/, float)
else
NODE_OPERATION(/, int)
case OP_PLUS:
if (!isDuo) return rChild;
if (isFloat)
NODE_OPERATION(+, float)
else
NODE_OPERATION(+, int)
case OP_MINUS:
if (!isDuo) {
for (idx=0; idx<rChild->nbIntFloatTab; idx++)
rChild->intFloatTab[idx] = -rChild->intFloatTab[idx];
return rChild;
}
if (isFloat)
NODE_OPERATION(-, float)
else
NODE_OPERATION(-, int)
case OP_EQUAL:
NODE_COMPARE(==,1,&&)
case OP_DIFF:
NODE_COMPARE(!=,0,||)
case OP_LE:
NODE_COMPARE(<=,1,&&)
case OP_HE:
NODE_COMPARE(>=,1,&&)
case OP_L:
NODE_COMPARE(<,1,&&)
case OP_H:
NODE_COMPARE(>,1,&&)
case OP_AND:
NODE_COMPARE(&&,1,&&)
case OP_OR:
NODE_COMPARE(||,0,||)
}
return NULL;
}
return NULL;
}
int
Expr_CalcFormat(char *expr, char *dest)
{
strlwr(expr);
//SimplifyPlusMinus(expr, expr);
NodeBufferIdx = 0;
memset(NodeBuffer, 0, sizeof(NodeBuffer));
Expr_Node *rootNode = CreateExprTree(expr);
if (rootNode == NULL)
return 0;
rootNode = Eval_Node(rootNode);
if (rootNode == NULL) return 0;
if ((rootNode->type != TYPE_INT && rootNode->type != TYPE_FLOAT) || rootNode->nbIntFloatTab == 0)
return 0;
if (rootNode->nbIntFloatTab == 1)
{
if (rootNode->type == TYPE_INT)
sprintf(dest, "%i", (int)rootNode->intFloatTab[0]);
else
sprintf(dest, "%f", rootNode->intFloatTab[0]);
} else
{
int pos = 0;
int idx;
strcpy(dest, "{ ");
pos += strlen(dest + pos);
for (idx=0; idx < rootNode->nbIntFloatTab; idx++)
{
if (rootNode->type == TYPE_INT)
sprintf(dest + pos, "%i ", (int)rootNode->intFloatTab[idx]);
else
sprintf(dest + pos, "%f ", rootNode->intFloatTab[idx]);
pos += strlen(dest + pos);
}
strcpy(dest + pos, "}");
}
return 1;
}
#ifndef SKIMMED_NET
int GetIpFromString(char *IPPtr,u32 *ulIP)
{
char MyIP[256];
unsigned char IP[4];
u32 PointCounter;
PointCounter = 0;
for (u32 Counter = 0 ; Counter < 4 ; Counter++)
{
IP[Counter] = 0;
while ((*IPPtr >= '0') && (*IPPtr <= '9')) {IP[Counter]*=10;IP[Counter]+=*IPPtr - '0';IPPtr++;};
while (*IPPtr && (*IPPtr <= 32)) {IPPtr++;};
if (*IPPtr == '.') {IPPtr++;PointCounter++;};
while (*IPPtr && (*IPPtr <= 32)) {IPPtr++;};
}
if (PointCounter >= 3)
{
sprintf(MyIP,"%d.%d.%d.%d",IP[0],IP[1],IP[2],IP[3]);
*ulIP = ntohl ( inet_addr(MyIP) ) ;
return 1;
} else
return 0;
}
#endif
int GetAffectFromString(char *AffectStr,int *Number)
{
*Number = 0;
while (*AffectStr && (*AffectStr == '.')) AffectStr++;
while (*AffectStr && (*AffectStr > 32))
{
if (Upper(*AffectStr) == 'T') {*Number |= 1;};
if (Upper(*AffectStr) == 'R') {*Number |= 2;};
if (Upper(*AffectStr) == 'I') {*Number |= 4;};
if (Upper(*AffectStr) == 'J') {*Number |= 8;};
if (Upper(*AffectStr) == 'K') {*Number |= 16;};
if (Upper(*AffectStr) == 'X') {*Number |= 32;};
if (Upper(*AffectStr) == 'Y') {*Number |= 64;};
if (Upper(*AffectStr) == 'Z') {*Number |= 128;};
if (Upper(*AffectStr) == 'S') {*Number |= 256;};
AffectStr++;
}
return 1;
}
char * FormatFloat22(float num, char *dstStr)
{
float numInt = floor(num);
float numDec = 100*(num - floor(num)) + 0.5f;
sprintf(dstStr, "%02i.%02i", (int)numInt, (int)numDec);
return dstStr;
}
extern char *xorBase;
char * CryptBuffer(char *buff, u32 size)
{
int processLen, xorLen = size;
char *xorStr, *buffPtr= buff;
while (xorLen)
{
processLen = (xorLen > 32) ? 32 : xorLen;
xorStr = xorBase;
for (int i=0; i<processLen; i++, buffPtr++, xorStr++)
*buffPtr = *buffPtr ^ *xorStr;
xorLen -= processLen;
}
return buff;
}