BOOL AddMQ2Type(MQ2Type &Type) { if (FindMQ2DataType(Type.GetName())) return false; unsigned long N = MQ2DataTypes.GetUnused(); MQ2DataTypes[N] = &Type; MQ2DataTypeMap[Type.GetName()] = N + 1; return true; }
BOOL dataType(PCHAR szIndex, MQ2TYPEVAR &Ret) { if (MQ2Type* pType = FindMQ2DataType(szIndex)) { Ret.Ptr = pType; Ret.Type = pTypeType; return true; } return false; }
// *************************************************************************** // Function: Call // Description: Our '/call' command // Usage: /call <Subroutine> // *************************************************************************** VOID Call(PSPAWNINFO pChar, PCHAR szLine) { PMACROSTACK pStack; PMACROBLOCK pCallingPoint = gMacroBlock; CHAR SubName[MAX_STRING] = {0}; PCHAR SubParam = NULL; CHAR SubLine[MAX_STRING] = {0}; CHAR SubLineP[MAX_STRING] = {0}; DWORD StackNum = 0; bRunNextCommand = TRUE; if (szLine[0]==0) { SyntaxError("Usage: /call <subroutine> [param [param...]]"); return; } if (!gMacroBlock) { MacroError("Cannot call when a macro isn't running."); return; } GetArg(SubName,szLine,1); SubParam = GetNextArg(szLine); sprintf(SubLine,"sub %s",SubName); sprintf(SubLineP,"sub %s(",SubName); // Sub in Map? PMACROBLOCK pSubBlock = gMacroSubLookupMap[SubName]; // If not, find it and add. if (!pSubBlock) { while (gMacroBlock->pPrev) gMacroBlock = gMacroBlock->pPrev; while (gMacroBlock->pNext) { if (!stricmp(gMacroBlock->Line,SubLine) || !strnicmp(gMacroBlock->Line,SubLineP,strlen(SubLineP))) { pSubBlock = gMacroBlock; break; } gMacroBlock = gMacroBlock->pNext; } if (!pSubBlock) { gMacroBlock=pCallingPoint; FatalError("Subroutine %s wasn't found",SubName); return; } else { gMacroSubLookupMap[SubName] = pSubBlock; } } // Prep to call the Sub gMacroBlock = pSubBlock; DebugSpewNoFile("Call - Calling subroutine %s with params %s",SubName,SubParam); pStack = (PMACROSTACK)malloc(sizeof(MACROSTACK)); pStack->Location = gMacroBlock; pStack->Return[0] = 0; pStack->Parameters = NULL; pStack->LocalVariables = NULL; pStack->pNext = gMacroStack; gMacroStack = pStack; if (SubParam) { StackNum = 0; while (SubParam[0]!=0) { CHAR szParamName[MAX_STRING] = {0}; CHAR szParamType[MAX_STRING] = {0}; CHAR szNewValue[MAX_STRING]={0}; GetArg(szNewValue,SubParam,1); GetFuncParam(gMacroBlock->Line,StackNum,szParamName,szParamType); MQ2Type *pType = FindMQ2DataType(szParamType); if (!pType) pType=pStringType; AddMQ2DataVariable(szParamName,"",pType,&gMacroStack->Parameters,szNewValue); SubParam = GetNextArg(SubParam); StackNum++; } } return; }
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 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; } }