BOOL ParseMQ2DataPortion(PCHAR szOriginal, MQ2TYPEVAR &Result) { Result.Type = 0; Result.Int64 = 0; // Find [] before a . or null PCHAR pPos = &szOriginal[0]; PCHAR pStart = pPos; CHAR Index[MAX_STRING] = { 0 }; PCHAR pIndex = &Index[0]; BOOL Quote = FALSE; bool function_allowed = false; while (1) { if (*pPos == 0) { // end completely. process if (pStart == pPos) { if (!Result.Type) { MQ2DataError("Nothing to parse"); return FALSE; } return TRUE; } if (!EvaluateDataExpression(Result, pStart, pIndex, function_allowed)) return FALSE; // done processing return TRUE; } if (*pPos == '(') { *pPos = 0; if (pStart == pPos) { if (!Result.Type) { MQ2DataError("Encountered typecast without object to cast"); return FALSE; } return TRUE; } else { if (!EvaluateDataExpression(Result, pStart, pIndex)) return FALSE; } if (!Result.Type) { // error return FALSE; } *pPos = 0; ++pPos; PCHAR pType = pPos; while (*pPos != ')') { if (!*pPos) { // error MQ2DataError("Encountered unmatched parenthesis"); return FALSE; } ++pPos; } *pPos = 0; MQ2Type *pNewType = FindMQ2DataType(pType); if (!pNewType) { // error MQ2DataError("Unknown type '%s'", pType); return FALSE; } if (pNewType == pTypeType) { Result.Ptr = Result.Type; Result.Type = pTypeType; } else Result.Type = pNewType; if (pPos[1] == '.') { ++pPos; pStart = &pPos[1]; } else if (!pPos[1]) { //Result.Type->ToString(Result.VarPtr,szCurrent); return TRUE; } else { MQ2DataError("Invalid character found after typecast ')%s'", &pPos[1]); return FALSE; } } else { if (*pPos == '[') { // index *pPos = 0; ++pPos; function_allowed = true; Quote = false; BOOL BeginParam = true; while (1) { if (*pPos == 0) { MQ2DataError("Unmatched bracket or invalid character following bracket found in index: '%s'", pIndex); return FALSE; } if (BeginParam) { BeginParam = false; if (*pPos == '\"') { Quote = true; ++pPos; continue; } } if (Quote) { if (*pPos == '\"') { if (pPos[1] == ']' || pPos[1] == ',') { Quote = false; ++pPos; continue; } } } else { if (*pPos == ']') { if (pPos[1] == '.' || pPos[1] == '(' || pPos[1] == 0) break;// valid end } else if (*pPos == ',') BeginParam = true; } *pIndex = *pPos; ++pIndex; ++pPos; } *pIndex = 0; pIndex = &Index[0]; *pPos = 0; } else { if (*pPos == '.') { // end of this one, but more to come! *pPos = 0; if (pStart == pPos) { if (!Result.Type) { MQ2DataError("Encountered member access without object"); return FALSE; } return TRUE; } if (!EvaluateDataExpression(Result, pStart, pIndex)) return FALSE; pStart = &pPos[1]; Index[0] = 0; } } } ++pPos; } }
BOOL ParseMQ2DataPortion(PCHAR szOriginal, MQ2TYPEVAR &Result) { Result.Type = 0; Result.DWord = 0; // Find [] before a . or null PCHAR pPos = &szOriginal[0]; PCHAR pStart = pPos; CHAR Index[MAX_STRING] = { 0 }; PCHAR pIndex = &Index[0]; BOOL Quote = FALSE; while (1) { if (*pPos == 0) { // end completely. process if (pStart == pPos) { if (!Result.Type) { MQ2DataError("Nothing to parse"); return FALSE; } //Result.Type->ToString(Result.VarPtr,szCurrent); return TRUE; } else { if (!Result.Type) { if (PMQ2DATAITEM DataItem = FindMQ2Data(pStart)) { if (!DataItem->Function(pIndex, Result)) { return FALSE; } } else if (PDATAVAR DataVar = FindMQ2DataVariable(pStart)) { if (pIndex[0]) { if (DataVar->Var.Type == pArrayType) { if (!((CDataArray*)DataVar->Var.Ptr)->GetElement(pIndex, Result)) { return FALSE; } } } else Result = DataVar->Var; } else { //MQ2DataError("No such Top-Level Object '%s'",pStart); return FALSE; } } else { if (!Result.Type->GetMember(Result.VarPtr, pStart, pIndex, Result)) { if (!Result.Type->FindMember(pStart) && !Result.Type->InheritedMember(pStart)) { MQ2DataError("No such '%s' member '%s'", Result.Type->GetName(), pStart); } return FALSE; } } } //Result.Type->ToString(Result.VarPtr,szCurrent); // done processing return TRUE; } if (*pPos == '(') { *pPos = 0; if (pStart == pPos) { if (!Result.Type) { MQ2DataError("Encountered typecast without object to cast"); return FALSE; } //Result.Type->ToString(Result.VarPtr,szCurrent); return TRUE; } else { if (!Result.Type) { if (PMQ2DATAITEM DataItem = FindMQ2Data(pStart)) { if (!DataItem->Function(pIndex, Result)) { return FALSE; } } else if (PDATAVAR DataVar = FindMQ2DataVariable(pStart)) { if (pIndex[0]) { if (DataVar->Var.Type == pArrayType) { if (!((CDataArray*)DataVar->Var.Ptr)->GetElement(pIndex, Result)) { return FALSE; } } } else Result = DataVar->Var; } else { //MQ2DataError("No such Top-Level Object '%s'",pStart); return FALSE; } } else { if (!Result.Type->GetMember(Result.VarPtr, pStart, pIndex, Result)) { if (!Result.Type->FindMember(pStart) && !Result.Type->InheritedMember(pStart)) { MQ2DataError("No such '%s' member '%s'", Result.Type->GetName(), pStart); } return FALSE; } } } if (!Result.Type) { // error return FALSE; } *pPos = 0; ++pPos; PCHAR pType = pPos; while (*pPos != ')') { if (!*pPos) { // error MQ2DataError("Encountered unmatched parenthesis"); return FALSE; } ++pPos; } *pPos = 0; MQ2Type *pNewType = FindMQ2DataType(pType); if (!pNewType) { // error MQ2DataError("Unknown type '%s'", pType); return FALSE; } if (pNewType == pTypeType) { Result.Ptr = Result.Type; Result.Type = pTypeType; } else Result.Type = pNewType; if (pPos[1] == '.') { ++pPos; pStart = &pPos[1]; } else if (!pPos[1]) { //Result.Type->ToString(Result.VarPtr,szCurrent); return TRUE; } else { MQ2DataError("Invalid character found after typecast ')%s'", &pPos[1]); return FALSE; } } else if (*pPos == '[') { // index *pPos = 0; ++pPos; Quote = false; BOOL BeginParam = true; while (1) { if (*pPos == 0) { MQ2DataError("Unmatched bracket or invalid character following bracket found in index: '%s'", pIndex); return FALSE; } if (BeginParam) { BeginParam = false; if (*pPos == '\"') { Quote = true; ++pPos; continue; } } if (Quote) { if (*pPos == '\"') { if (pPos[1] == ']' || pPos[1] == ',') { Quote = false; ++pPos; continue; } } } else { if (*pPos == ']') { if (pPos[1] == '.' || pPos[1] == '(' || pPos[1] == 0) break;// valid end } else if (*pPos == ',') BeginParam = true; } *pIndex = *pPos; ++pIndex; ++pPos; } *pIndex = 0; pIndex = &Index[0]; *pPos = 0; } else if (*pPos == '.') { // end of this one, but more to come! *pPos = 0; if (pStart == pPos) { if (!Result.Type) { MQ2DataError("Encountered member access without object"); return FALSE; } //Result.Type->ToString(Result.VarPtr,szCurrent); return TRUE; } else { if (!Result.Type) { if (PMQ2DATAITEM DataItem = FindMQ2Data(pStart)) { if (!DataItem->Function(pIndex, Result)) { return FALSE; } } else if (PDATAVAR DataVar = FindMQ2DataVariable(pStart)) { if (pIndex[0]) { if (DataVar->Var.Type == pArrayType) { if (!((CDataArray*)DataVar->Var.Ptr)->GetElement(pIndex, Result)) { return FALSE; } } } else Result = DataVar->Var; } else { //MQ2DataError("No such Top-Level Object '%s'",pStart); return FALSE; } } else { if (!Result.Type->GetMember(Result.VarPtr, pStart, pIndex, Result)) { if (!Result.Type->FindMember(pStart) && !Result.Type->InheritedMember(pStart)) { MQ2DataError("No such '%s' member '%s'", Result.Type->GetName(), pStart); } return FALSE; } } } pStart = &pPos[1]; Index[0] = 0; } ++pPos; } }
bool EvaluateDataExpression(MQ2TYPEVAR& Result, PCHAR pStart, PCHAR pIndex, bool function_allowed = false) { if (!Result.Type) { if (!gWarning) {//if they have warnings turned on in the macro, we will disregard checking the map if (gUndeclaredVars.find(pStart) != gUndeclaredVars.end()) return false;//its a undefined variable no point in moving on further. } if (PMQ2DATAITEM DataItem = FindMQ2Data(pStart)) { if (!DataItem->Function(pIndex, Result)) { return false; } } else if (PDATAVAR DataVar = FindMQ2DataVariable(pStart)) { if (pIndex[0]) { if (DataVar->Var.Type == pArrayType) { if (!((CDataArray*)DataVar->Var.Ptr)->GetElement(pIndex, Result)) { return false; } } } else Result = DataVar->Var; } else if (function_allowed && function_exists(pStart)) { if (!call_function(pStart, pIndex)) return false; strcpy_s(DataTypeTemp, gMacroStack->Return); Result.Ptr = &DataTypeTemp[0]; Result.Type = pStringType; } else { if (gMacroBlock) { if (gWarning) { DumpWarning(pStart,gMacroBlock->CurrIndex); } gUndeclaredVars[pStart] = gMacroBlock->CurrIndex; } return false; } } else { int result = FindMacroDataMember(Result.Type, Result, pStart, pIndex); if (result < 0) { MQ2DataError("No such '%s' member '%s'", Result.Type->GetName(), pStart); } if (result <= 0) return false; } return true; }