/*======================================================== =================== * * Command.CPP - Dave Humphrey (uesp@m0use.net), 11 November 2000 * *=========================================================================*/ /* Include Files */ #include "command.h" /*=========================================================================== * * Begin Global Variables * *=========================================================================*/ /*=========================================================================== * End of Global Variables *=========================================================================*/ /*=========================================================================== * * Internal Function Prototypes * *=========================================================================*/ /* Helper function to excecute a root command */ boolean CmdExecuteRoot (cmdfunc_record_t* pFunction, cmd_parameter_t& Parameters); boolean CmdExecute (cmdfunc_record_t* pFunction, CCommandObject* pObject, cmd_parameter_t& Parameters); /* Return the number of parameters required for a particular function type */ int GetRequiredParameters (const cmdfunc_type_t Type); /* Conversion functions */ inline signed char CMDStringTo_c (const char* pString) { return (signed char) (*pString); } inline unsigned char CMDStringTo_C (const char* pString) { return (unsigned char) (*pString); } inline void* CMDStringTo_pv(char* pString) { return (void*) pString; } inline char* CMDStringTo_pc(char* pString) { return (char*) pString; } boolean CMDStringTo_b (const char* pString); signed int CMDStringTo_i (const char* pString); unsigned int CMDStringTo_I (const char* pString); signed long CMDStringTo_l (const char* pString); unsigned long CMDStringTo_L (const char* pString); float CMDStringTo_f (const char* pString); /* Return value conversion functions */ void CMDReturn_b (const boolean Result, cmd_parameter_t& Parameters); void CMDReturn_c (const signed char Result, cmd_parameter_t& Parameters); void CMDReturn_C (const unsigned char Result, cmd_parameter_t& Parameters); void CMDReturn_i (const signed int Result, cmd_parameter_t& Parameters); void CMDReturn_I (const unsigned int Result, cmd_parameter_t& Parameters); void CMDReturn_l (const signed long Result, cmd_parameter_t& Parameters); void CMDReturn_L (const unsigned long Result, cmd_parameter_t& Parameters); void CMDReturn_pc (const char* pResult, cmd_parameter_t& Parameters); /*=========================================================================== * End of Internal Function Prototypes *=========================================================================*/ /*=========================================================================== * * Exported Commands/Functions for the command classes. * *=========================================================================*/ BEGIN_COMMAND_FUNCTION(CCommandObject) DECLARE_COMMAND_FUNCTION("GetCommandName", GetCommandName, CMDFUNC_pcv) END_COMMAND_FUNCTION() BEGIN_COMMAND_OBJECT(CCommandObject) END_COMMAND_OBJECT() /*=========================================================================== * End of Exported Commands/Functions *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::CCommandHandler()" /*=========================================================================== * * Class CCommandHandler Constructor * *=========================================================================*/ CCommandHandler::CCommandHandler() { NumObjects = 0; NumFunctions = 0; NumFunctionArrays = 0; } /*=========================================================================== * End of Class CCommandHandler Constructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::Destroy()" /*=========================================================================== * * Class CCommandHandler Destructor * *=========================================================================*/ void CCommandHandler::Destroy (void) { int LoopCounter; /* Unallocate all root function records */ for (LoopCounter = 0; LoopCounter < NumFunctions; LoopCounter++) { DestroyPointer(pFunctions[LoopCounter]); } NumObjects = 0; NumFunctions = 0; NumFunctionArrays = 0; } /*=========================================================================== * End of Class CCommandHandler Destructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::FindFunction()" /*=========================================================================== * * Class CCommandObject Method - cmdfunc_record_t* FindFunction (Parameters); * * Attempt to find the function somewhere in the command object * Returns the pointer to the object on success or NULL on any error. * *=========================================================================*/ cmdfunc_record_t* CCommandObject::FindFunction (cmd_parameter_t& Parameters) { cmdfunc_record_t* pFuncPtr = GetCmdFuncArray(); int LoopCounter = 0; /* Look through entire function array for class */ while (pFuncPtr[LoopCounter].Type != CMDFUNC_ENDARRAY) { /* Look for a function name match */ if (strnicmp(Parameters.pFunction, pFuncPtr[LoopCounter].Name, CMD_FUNCNAME_LENGTH) == 0) { return (&pFuncPtr[LoopCounter]); } LoopCounter++; } /* Look through all sub-objects in class */ /* No match found */ SET_EXT_ERROR3(ERR_CUSTOM, "\tFailed to find function \"%s\"!", Parameters.pFunction); return (NULL); } /*=========================================================================== * End of Class Method CCommandObject::FindObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::FindObject()" /*=========================================================================== * * Class CCommandObject Method - CCommandObject* FindObject (InitialObject, Parameters); * * Attempt to find an object somewhere in the overall command heirarchy. * Returns the pointer to the object on success or NULL on any error. * Protected class method. * *=========================================================================*/ CCommandObject* CCommandObject::FindObject (const int InitialObject, cmd_parameter_t& Parameters) { CCommandObject** pObjPtr = GetCmdObjArray(); int LoopCounter = 0; /* Have we reached the end of the object list */ if (InitialObject >= Parameters.NumObjects) return (this); /* Search the root object list */ while (pObjPtr[LoopCounter] != NULL) { /* Ensure a valid command object */ if (!pObjPtr[LoopCounter]->IsValidObject()) continue; /* Found a match? */ if (stricmp(Parameters.pObjects[InitialObject], pObjPtr[LoopCounter]->GetCommandName()) == 0) { if (InitialObject+1 >= Parameters.NumObjects) return (pObjPtr[LoopCounter]); return (pObjPtr[LoopCounter]->FindObject(InitialObject+1, Parameters)); } LoopCounter++; } /* No match found */ SET_EXT_ERROR3(ERR_CUSTOM, "\tFailed to find object \"%s\"!", Parameters.pObjects[InitialObject]); return (NULL); } /*=========================================================================== * End of Class Method CCommandObject::FindObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::AddFunctionArray()" /*=========================================================================== * * Class CCommandHandler Method - boolean AddFunctionArray (pArray) * * Attempt to add a new function array to the handler. Returns FALSE * on any error. * *=========================================================================*/ boolean CCommandHandler::AddFunctionArray (cmdfunc_record_t* pArray) { /* Ensure valid input */ if (pArray == NULL) { SET_EXT_ERROR2(ERR_NULL, "Received invalid NULL input!"); return (FALSE); } /* Will the new function fit in the array? */ if (NumFunctionArrays >= CMD_MAX_FUNCTIONS) { SET_EXT_ERROR3(ERR_NULL, "Maximum of %d function arrays exceeded!", CMD_MAX_FUNCTIONS); return (FALSE); } /* Save the new function array */ pFunctionArrays[NumFunctionArrays] = pArray; NumFunctionArrays++; return (TRUE); } /*=========================================================================== * End of Class Method CCommandHandler::AddFunctionArray() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::AddRootFunction()" /*=========================================================================== * * Class CCommandHandler Method - boolean AddRootFunction (pName, pFunc, Type) * * Attempt to add a new root function to the handler. Returns FALSE * on any error. * *=========================================================================*/ boolean CCommandHandler::AddRootFunction (const char* pName, pVOIDFUNC_T pFunc, const cmdfunc_type_t Type) { /* Ensure valid input */ if (pName == NULL || pFunc == NULL) { SET_EXT_ERROR2(ERR_NULL, "Received invalid NULL input!"); return (FALSE); } /* Will the new function fit in the array? */ if (NumFunctions >= CMD_MAX_FUNCTIONS) { SET_EXT_ERROR3(ERR_NULL, "Maximum of %d root functions exceeded!", CMD_MAX_FUNCTIONS); return (FALSE); } /* Allocate the new function */ CreatePointer(pFunctions[NumFunctions], cmdfunc_record_t); /* Initialize the function values */ strnncpy (pFunctions[NumFunctions]->Name, pName, CMD_FUNCNAME_LENGTH); pFunctions[NumFunctions]->pRootFunction = pFunc; pFunctions[NumFunctions]->pCmdFunction = NULL; pFunctions[NumFunctions]->Type = Type; NumFunctions++; return (TRUE); } /*=========================================================================== * End of Class Method CCommandHandler::AddFunctionArray() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::AddObject()" /*=========================================================================== * * Class CCommandHandler Method - boolean AddObject (pname, pObject); * * Attempt to add a new object reference to the object array. Returns FALSE * on any error. * *=========================================================================*/ boolean CCommandHandler::AddObject (const char* pName, CCommandObject* pObject) { /* Ensure valid input */ if (pObject == NULL || pName == NULL) { SET_EXT_ERROR2(ERR_NULL, "Invalid NULL name or object received!"); return (FALSE); } /* Ensure valid command object */ if (!pObject->IsValidObject()) { SET_EXT_ERROR2(ERR_NULL, "Bad command object supplied!"); return (FALSE); } /* Ensure object will fit into object array */ if (NumObjects >= CMD_MAX_OBJECTS) { SET_EXT_ERROR3(ERR_NULL, "Maximum of %d command objects exceeded!", CMD_MAX_OBJECTS); return (FALSE); } /* Initialize the object pointer */ pObjects[NumObjects] = pObject; pObjects[NumObjects]->SetCommandName(pName); NumObjects++; return (TRUE); } /*=========================================================================== * End of Class Method CCommandHandler::AddObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::CallCommand()" /*=========================================================================== * * Class CCommandHandler Method - boolean CallCommand (pCommandName, Parameters); * * Main access point to activate a command function. Attempts to find and * call the given command with the supplied parameters. Returns FALSE on * any error. * *=========================================================================*/ boolean CCommandHandler::CallCommand (const char* pCommandName, cmd_parameter_t& Parameters) { cmdfunc_record_t* pFunction; CCommandObject* pObject; boolean Result; /* Ensure valid input */ if (pCommandName == NULL) { SET_EXT_ERROR2(ERR_NULL, "\tReceived invalid NULL command name!"); return (FALSE); } /* Attempt to find a root function */ if (Parameters.NumObjects == 0) { pFunction = FindRootFunction(pCommandName); if (pFunction == NULL) return (FALSE); /* Execute the given root command */ Result = CmdExecuteRoot(pFunction, Parameters); } /* Attempt to find object and object function */ else { pObject = FindObject(Parameters); if (pObject == NULL) return (FALSE); /* Find the function in the object */ pFunction = pObject->FindFunction(Parameters); if (pFunction == NULL) return (FALSE); /* Execute the given function command */ Result = CmdExecute(pFunction, pObject, Parameters); } return (Result); } /*=========================================================================== * End of Class Method CCommandHandler::CallCommand() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::FindObject()" /*=========================================================================== * * Class CCommandHandler Method - CCommandObject* FindObject (Parameters); * * Attempt to find an object somewhere in the overall command heirarchy. * Returns the pointer to the object on success or NULL on any error. * Protected class method. * *=========================================================================*/ CCommandObject* CCommandHandler::FindObject (cmd_parameter_t& Parameters) { int LoopCounter; /* Search the root object list */ for (LoopCounter = 0; LoopCounter < NumObjects; LoopCounter++) { /* Ensure a valid command object */ if (pObjects[LoopCounter] == NULL || !pObjects[LoopCounter]->IsValidObject()) continue; /* Found a first level match? */ if (stricmp(Parameters.pObjects[0], pObjects[LoopCounter]->GetCommandName()) == 0) { if (Parameters.NumObjects == 1) return (pObjects[LoopCounter]); return (pObjects[LoopCounter]->FindObject(1, Parameters)); } } /* No match found */ SET_EXT_ERROR3(ERR_CUSTOM, "\tFailed to find object \"%s\"!", Parameters.pObjects[0]); return (NULL); } /*=========================================================================== * End of Class Method CCommandHandler::FindObjectFunction() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::FindRootFunction()" /*=========================================================================== * * Class CCommandHandler Method - cmdfunc_record_t FindRootFunction (pName); * * Attempt to find a root function name in the function list or function * arrays. Returns the found function record or NULL on any error. Protected * class method. * *=========================================================================*/ cmdfunc_record_t* CCommandHandler::FindRootFunction (const char* pName) { cmdfunc_record_t* pFuncPtr; int LoopCounter; /* Search the function list first */ for (LoopCounter = 0; LoopCounter < NumFunctions; LoopCounter++) { if (strnicmp(pName, pFunctions[LoopCounter]->Name, CMD_FUNCNAME_LENGTH) == 0) return (pFunctions[LoopCounter]); } /* No match yet found, look in all the defined function arrays */ for (LoopCounter = 0; LoopCounter < NumFunctionArrays; LoopCounter++) { pFuncPtr = pFunctionArrays[LoopCounter]; /* Search all defined functions in the array */ while (pFuncPtr != NULL && pFuncPtr->Type != CMDFUNC_ENDARRAY) { /* Compare function names for a match */ if (strnicmp(pName, pFuncPtr->Name, CMD_FUNCNAME_LENGTH) == 0) return (pFuncPtr); /* Move to next function in array */ pFuncPtr++; } } /* No match found */ SET_EXT_ERROR3(ERR_CUSTOM, "\tFailed to find command \"%s\"!", pName); return (NULL); } /*=========================================================================== * End of Class Method CCommandHandler::FindRootFunction() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::ParseCommand()" /*=========================================================================== * * Class CCommandHandler Method - char* ParseCommand (pCommand); * * Similar to CallCommand() but also parses out the command name and * parameters from the input string. Returns NULL on any error or the * newly allocated return string on success. * *=========================================================================*/ char* CCommandHandler::ParseCommand (char* pCommand) { cmd_parameter_t Parameters; boolean Result; Result = ParseCommand(pCommand, Parameters); if (!Result) { if (Parameters.AllocateReturn) { DestroyPointer(Parameters.pReturnValue); } return (NULL); } return(Parameters.pReturnValue); } /*=========================================================================== * End of Class Method CCommandHandler::ParseCommand() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CCommandHandler::ParseCommand()" /*=========================================================================== * * Class CCommandHandler Method - boolean ParseCommand (pCommand, Parameters); * * Similar to CallCommand() but also parses out the command name and * parameters from the input string. Returns FALSE on any error. or the * newly allocated return string on success. * *=========================================================================*/ boolean CCommandHandler::ParseCommand (char* pCommand, cmd_parameter_t& Parameters) { char* pCommandName; boolean Result; /* Parse the input string */ pCommandName = ParseCommandString(pCommand, Parameters); if (pCommandName == NULL) return (FALSE); /* Call the command with the parameters information */ Result = CallCommand(pCommand, Parameters); return (Result); } /*=========================================================================== * End of Class Method CCommandHandler::ParseCommand() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CmdExecuteRoot()" /*=========================================================================== * * Function - boolean CmdExecuteRoot (pFunction, Parameters); * * Internal module helper function which attempts to execute the given * function with the supplied parameter information. Returns FALSE on * any error. * *=========================================================================*/ boolean CmdExecuteRoot (cmdfunc_record_t* pFunction, cmd_parameter_t& Parameters) { cmdfunction_u CmdFunction; int NumParameters; /* Set the function pointer in the union structure for proper typing */ CmdFunction.pFunction = pFunction->pRootFunction; /* Ensure a valid function address */ if (pFunction->pRootFunction == NULL) { SET_EXT_ERROR2(ERR_NULL, "Invalid NULL function address received!"); return (FALSE); } /* Ensure the correct number of parameters */ NumParameters = GetRequiredParameters (pFunction->Type); /* Invalid function type */ if (NumParameters < 0) return (FALSE); /* Too few parameters, abort the command call */ else if (NumParameters > Parameters.NumParameters) { SET_EXT_ERROR4(ERR_CUSTOM, "\tExpected %d parameters but received %d!", NumParameters, Parameters.NumParameters); return (FALSE); } /* Too many parameters, but just ignore the rest instead of fail */ else if (NumParameters < Parameters.NumParameters) { SystemLog.Printf ("\tExpected %d parameters but received %d...ignoring extra!", NumParameters, Parameters.NumParameters); } /* Do something different for each type */ switch (pFunction->Type) { case CMDFUNC_vv: { Parameters.pReturnValue = NULL; CmdFunction.pFunc_vv(); break; } case CMDFUNC_vc: { signed char Ch = CMDStringTo_c(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vc(Ch); break; } case CMDFUNC_vC: { unsigned char Ch = CMDStringTo_C(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vC(Ch); break; } case CMDFUNC_vi: { signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vi(Value); break; } case CMDFUNC_vI: { unsigned int Value = CMDStringTo_I(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vI(Value); break; } case CMDFUNC_vl: { signed long Value = CMDStringTo_l(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vl(Value); break; } case CMDFUNC_vL: { unsigned long Value = CMDStringTo_L(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vL(Value); break; } case CMDFUNC_vf: { float Value = CMDStringTo_f(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vf(Value); break; } case CMDFUNC_vb: { boolean Value = CMDStringTo_b(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vb(Value); break; } case CMDFUNC_vpv: { void* pValue = CMDStringTo_pv(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vpv(pValue); break; } case CMDFUNC_vpc: { char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; CmdFunction.pFunc_vpc(pValue); break; } case CMDFUNC_pcv: { char* pResult; pResult = CmdFunction.pFunc_pcv(); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcc: { char* pResult; signed char Ch = CMDStringTo_c(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcc(Ch); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcC: { char* pResult; unsigned char Ch = CMDStringTo_C(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcC(Ch); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pci: { char* pResult; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pci(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcI: { char* pResult; unsigned int Value = CMDStringTo_I(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcI(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcl: { char* pResult; signed long Value = CMDStringTo_l(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcl(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcL: { char* pResult; unsigned long Value = CMDStringTo_L(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcL(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcf: { char* pResult; float Value = CMDStringTo_f(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcf(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcb: { char* pResult; boolean Value = CMDStringTo_b(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcb(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcpv: { char* pResult; void* pValue = CMDStringTo_pv(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcpv(pValue); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcpc: { char* pResult; char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); pResult = CmdFunction.pFunc_pcpc(pValue); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_bc: { boolean Result; signed char Value = CMDStringTo_c(Parameters.pParameters[0]); Result = CmdFunction.pFunc_bc(Value); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bC: { boolean Result; unsigned char Value = CMDStringTo_C(Parameters.pParameters[0]); Result = CmdFunction.pFunc_bc(Value); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bpc: { boolean Result; char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); Result = CmdFunction.pFunc_bpc(pValue); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bpcpc: { boolean Result; char* pValue1 = CMDStringTo_pc(Parameters.pParameters[0]); char* pValue2 = CMDStringTo_pc(Parameters.pParameters[1]); Result = CmdFunction.pFunc_bpcpc(pValue2, pValue2); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_iv: { signed int Result; Result = CmdFunction.pFunc_iv(); CMDReturn_i(Result, Parameters); break; } case CMDFUNC_ii: { signed int Result; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Result = CmdFunction.pFunc_ii(Value); CMDReturn_i(Result, Parameters); break; } case CMDFUNC_Ii: { unsigned int Result; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Result = CmdFunction.pFunc_Ii(Value); CMDReturn_I(Result, Parameters); break; } case CMDFUNC_lv: { signed long Result; Result = CmdFunction.pFunc_lv(); CMDReturn_l(Result, Parameters); break; } case CMDFUNC_lpc: { signed long Result; char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); Result = CmdFunction.pFunc_lpc(pValue); CMDReturn_l(Result, Parameters); break; } case CMDFUNC_Li: { unsigned long Result; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Result = CmdFunction.pFunc_Li(Value); CMDReturn_L(Result, Parameters); break; } /* Handle an unknown or invalid type of function */ default: SET_EXT_ERROR3(ERR_CUSTOM, "\tUnknown or invalid function type %d!", pFunction->Type); return (FALSE); }; /* The compiler thinks this should be here */ return (FALSE); } /*=========================================================================== * End of Function CmdExecuteRoot() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CmdExecute()" /*=========================================================================== * * Function - boolean CmdExecute (pFunction, pObject, Parameters); * * Internal module helper function which attempts to execute the given * function with the supplied parameter information. Returns FALSE on * any error. * *=========================================================================*/ boolean CmdExecute (cmdfunc_record_t* pFunction, CCommandObject* pObject, cmd_parameter_t& Parameters) { cmdobjfunc_u CmdFunction; int NumParameters; /* Set the function pointer in the union structure for proper typing */ CmdFunction.pFunction = pFunction->pCmdFunction; /* Ensure a valid function address */ if (pFunction->pCmdFunction == NULL) { SET_EXT_ERROR2(ERR_NULL, "Invalid NULL function address received!"); return (FALSE); } /* Ensure the correct number of parameters */ NumParameters = GetRequiredParameters (pFunction->Type); /* Invalid function type */ if (NumParameters < 0) return (FALSE); /* Too few parameters, abort the command call */ else if (NumParameters > Parameters.NumParameters) { SET_EXT_ERROR4(ERR_CUSTOM, "\tExpected %d parameters but received %d!", NumParameters, Parameters.NumParameters); return (FALSE); } /* Too many parameters, but just ignore the rest instead of fail */ else if (NumParameters < Parameters.NumParameters) { SystemLog.Printf ("\tExpected %d parameters but received %d...ignoring extra!", NumParameters, Parameters.NumParameters); } /* Do something different for each type */ switch (pFunction->Type) { case CMDFUNC_vv: { Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vv)(); break; } case CMDFUNC_vc: { signed char Ch = CMDStringTo_c(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vc)(Ch); break; } case CMDFUNC_vC: { unsigned char Ch = CMDStringTo_C(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vC)(Ch); break; } case CMDFUNC_vi: { signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vi)(Value); break; } case CMDFUNC_vI: { unsigned int Value = CMDStringTo_I(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vI)(Value); break; } case CMDFUNC_vl: { signed long Value = CMDStringTo_l(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vl)(Value); break; } case CMDFUNC_vL: { unsigned long Value = CMDStringTo_L(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vL)(Value); break; } case CMDFUNC_vf: { float Value = CMDStringTo_f(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vf)(Value); break; } case CMDFUNC_vb: { boolean Value = CMDStringTo_b(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vb)(Value); break; } case CMDFUNC_vpv: { void* pValue = CMDStringTo_pv(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vpv)(pValue); break; } case CMDFUNC_vpc: { char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); Parameters.pReturnValue = NULL; (pObject->*CmdFunction.pFunc_vpc)(pValue); break; } case CMDFUNC_pcv: { char* pResult; pResult = (pObject->*CmdFunction.pFunc_pcv)(); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcc: { char* pResult; signed char Ch = CMDStringTo_c(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcc)(Ch); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcC: { char* pResult; unsigned char Ch = CMDStringTo_C(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcC)(Ch); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pci: { char* pResult; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pci)(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcI: { char* pResult; unsigned int Value = CMDStringTo_I(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcI)(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcl: { char* pResult; signed long Value = CMDStringTo_l(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcl)(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcL: { char* pResult; unsigned long Value = CMDStringTo_L(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcL)(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcf: { char* pResult; float Value = CMDStringTo_f(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcf)(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcb: { char* pResult; boolean Value = CMDStringTo_b(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcb)(Value); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcpv: { char* pResult; void* pValue = CMDStringTo_pv(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcpv)(pValue); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_pcpc: { char* pResult; char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); pResult = (pObject->*CmdFunction.pFunc_pcpc)(pValue); CMDReturn_pc(pResult, Parameters); break; } case CMDFUNC_bv: { boolean Result; Result = (pObject->*CmdFunction.pFunc_bv)(); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bc: { boolean Result; signed char Value = CMDStringTo_c(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_bc)(Value); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bC: { boolean Result; unsigned char Value = CMDStringTo_C(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_bc)(Value); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bpc: { boolean Result; char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_bpc)(pValue); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_bpcpc: { boolean Result; char* pValue1 = CMDStringTo_pc(Parameters.pParameters[0]); char* pValue2 = CMDStringTo_pc(Parameters.pParameters[1]); Result = (pObject->*CmdFunction.pFunc_bpcpc)(pValue1, pValue2); CMDReturn_b(Result, Parameters); break; } case CMDFUNC_iv: { signed int Result; Result = (pObject->*CmdFunction.pFunc_iv)(); CMDReturn_i(Result, Parameters); break; } case CMDFUNC_ii: { signed int Result; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_ii)(Value); CMDReturn_i(Result, Parameters); break; } case CMDFUNC_Ii: { unsigned int Result; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_Ii)(Value); CMDReturn_I(Result, Parameters); break; } case CMDFUNC_lv: { signed long Result; Result = (pObject->*CmdFunction.pFunc_lv)(); CMDReturn_l(Result, Parameters); break; } case CMDFUNC_lpc: { signed long Result; char* pValue = CMDStringTo_pc(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_lpc)(pValue); CMDReturn_l(Result, Parameters); break; } case CMDFUNC_Li: { unsigned long Result; signed int Value = CMDStringTo_i(Parameters.pParameters[0]); Result = (pObject->*CmdFunction.pFunc_Li)(Value); CMDReturn_L(Result, Parameters); break; } /* Handle an unknown or invalid type of function */ default: SET_EXT_ERROR3(ERR_CUSTOM, "\tUnknown or invalid function type %d!", pFunction->Type); return (FALSE); }; /* The compiler thinks this should be here */ return (FALSE); } /*=========================================================================== * End of Function CmdExecute() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "GetNumParameters()" /*=========================================================================== * * Function - int GetNumParameters (Type); * * Returns the number of parameters required for a particular function type. * Returns -1 if the function type is invalid. * *=========================================================================*/ int GetRequiredParameters (const cmdfunc_type_t Type) { switch (Type) { case CMDFUNC_vv: case CMDFUNC_pcv: case CMDFUNC_bv: case CMDFUNC_iv: case CMDFUNC_lv: return (0); case CMDFUNC_vc: case CMDFUNC_vC: case CMDFUNC_vi: case CMDFUNC_vI: case CMDFUNC_vl: case CMDFUNC_vL: case CMDFUNC_vf: case CMDFUNC_vb: case CMDFUNC_vpv: case CMDFUNC_vpc: case CMDFUNC_pcc: case CMDFUNC_pcC: case CMDFUNC_pci: case CMDFUNC_pcI: case CMDFUNC_pcl: case CMDFUNC_pcL: case CMDFUNC_pcf: case CMDFUNC_pcb: case CMDFUNC_pcpv: case CMDFUNC_pcpc: case CMDFUNC_bc: case CMDFUNC_bC: case CMDFUNC_bi: case CMDFUNC_bI: case CMDFUNC_bl: case CMDFUNC_bL: case CMDFUNC_bf: case CMDFUNC_bb: case CMDFUNC_bpv: case CMDFUNC_bpc: case CMDFUNC_Ii: case CMDFUNC_lpc: case CMDFUNC_Li: case CMDFUNC_ii: return (1); case CMDFUNC_bpcpc: return (2); /* Handle an unknown or invalid type of function */ default: SET_EXT_ERROR3(ERR_CUSTOM, "\tUnknown or invalid function type %d!", Type); return (-1); }; } /*=========================================================================== * End of Function GetRequiredParameters() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "ParseCommandString()" /*=========================================================================== * * Function - char* ParseCommandString (pString, Parameters); * * Parses a string into its command name and parameter lists. The command * name pointer is returned on success, or NULL on error. The input string * is modified. * *=========================================================================*/ char* ParseCommandString (char* pString, cmd_parameter_t& Parameters) { char* pParse; /* Initialize the parameter structure */ Parameters.AllocateReturn = TRUE; Parameters.pReturnValue = NULL; Parameters.NumParameters = 0; Parameters.NumObjects = 0; Parameters.pFunction = NULL; /* Ensure valid input */ if (pString == NULL) { SET_EXT_ERROR2(ERR_NULL, "\tReceived an invalid NULL input string!"); return (NULL); } /* Do any string preprocessing */ PreprocessCommandString(pString); /* Remove trailing/leading spaces */ pString = trim(pString); /* Start parsing the string by finding the command name */ pParse = strchr(pString, ' '); if (pParse != NULL) { *pParse = NULL_CHAR; pParse++; } else pParse = pString + strlen(pString); /* Parse the command objects frmo the command string */ Parameters.pFunction = rtrim(pString); ParseCommandObjects(Parameters.pFunction, Parameters); /* Start parsing the parameters, if any */ if (pParse == NULL) return (Parameters.pFunction); pParse = strtok(pParse, " "); while (pParse != NULL) { pParse = trim(pParse); /* Ensure the parameter is not empty */ if (*pParse == NULL_CHAR) { pParse = strtok(NULL, " "); continue; } /* Ensure the number of parameters does not overflow */ if (Parameters.NumParameters >= CMD_MAX_PARAMETERS) { SET_EXT_ERROR3(ERR_NULL, "\tMaximum number of parameters, %d, exceeded!", CMD_MAX_PARAMETERS); return (NULL); } /* Save the parameter location */ Parameters.pParameters[Parameters.NumParameters] = pParse; Parameters.NumParameters++; /* Find next parameter */ pParse = strtok(NULL, " "); } return (Parameters.pFunction); } /*=========================================================================== * End of Function ParseCommandString() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "ParseCommandObjects()" /*=========================================================================== * * Function - void ParseCommandObjects (pString, Parameters); * * Parse out the various command objects in the given command string and * fill out the parameters object. * *=========================================================================*/ void ParseCommandObjects (char* pString, cmd_parameter_t& Parameters) { char* pParse; char* pLastParse = pString; pParse = strtok(pString, "."); Parameters.NumObjects = 0; while (pParse != NULL) { pLastParse = pParse; pParse = strtok(NULL, "."); if (pParse != NULL) { Parameters.pObjects[Parameters.NumObjects] = pLastParse; Parameters.NumObjects++; } } Parameters.pFunction = pLastParse; } /*=========================================================================== * End of Function ParseCommandObjects() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "PreprocessCommandString()" /*=========================================================================== * * Function - void PreprocessCommandString (pString); * * Processes a command-parameter string before it is parsed. * *=========================================================================*/ void PreprocessCommandString (char* pString) { while (*pString != NULL_CHAR) { /* Parse out brackets for now */ if (*pString == ')') *pString = ' '; else if (*pString == '(') *pString = ' '; pString++; } } /*=========================================================================== * End of Function PreprocessCommandString() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CMDStringTo_b()" /*=========================================================================== * * Begin Internal Conversion Functions * * Convert strings to and from various types. Outputs conversion errors * to the log file. * *=========================================================================*/ boolean CMDStringTo_b (const char* pString) { /* Make sure the string is valid */ if (pString == NULL) { SystemLog.Printf ("\tError converting NULL string to boolean!"); return (FALSE); } /* See if the string contains TRUE/FALSE */ if (!stricmp(pString, "TRUE")) return (TRUE); if (!stricmp(pString, "FALSE")) return (FALSE); /* Convert the string to a number as a last resort */ char* pEnd; ulong Result = strtoul(pString, &pEnd, 0); if (*pEnd != NULL_CHAR) { SystemLog.Printf ("\tError converting to boolean starting at \"%s\"!", pEnd); return (FALSE); } /* Return base on the number */ if (Result == 0) return (FALSE); return (TRUE); } #undef __FUNC__ #define __FUNC__ "CMDStringTo_i()" signed int CMDStringTo_i (const char* pString) { char* pEnd; signed int Value; Value = (signed int) strtoul(pString, &pEnd, 0); if (*pEnd != NULL_CHAR) { SystemLog.Printf ("\tPossible error converting to signed int starting at \"%s\"!", pEnd); } return (Value); } #undef __FUNC__ #define __FUNC__ "CMDStringTo_I()" unsigned int CMDStringTo_I (const char* pString) { char* pEnd; unsigned int Value; Value = (unsigned int) strtoul(pString, &pEnd, 0); if (*pEnd != NULL_CHAR) { SystemLog.Printf ("\tPossible error converting to unsigned int starting at \"%s\"!", pEnd); } return (Value); } #undef __FUNC__ #define __FUNC__ "CMDStringTo_l()" signed long CMDStringTo_l (const char* pString) { char* pEnd; signed long Value; Value = (signed long) strtoul(pString, &pEnd, 0); if (*pEnd != NULL_CHAR) { SystemLog.Printf ("\tPossible error converting to signed long starting at \"%s\"!", pEnd); } return (Value); } #undef __FUNC__ #define __FUNC__ "CMDStringTo_L()" unsigned long CMDStringTo_L (const char* pString) { char* pEnd; unsigned long Value; Value = (unsigned long) strtoul(pString, &pEnd, 0); if (*pEnd != NULL_CHAR) { SystemLog.Printf ("\tPossible error converting to unsigned long starting at \"%s\"!", pEnd); } return (Value); } #undef __FUNC__ #define __FUNC__ "CMDStringTo_f()" float CMDStringTo_f (const char* pString) { char* pEnd; float Value; Value = (float) strtod(pString, &pEnd); if (*pEnd != NULL_CHAR) { SystemLog.Printf ("\tPossible error converting to float starting at \"%s\"!", pEnd); } return (Value); } /*=========================================================================== * End of Internal Conversion Functions *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CMDReturn_b()" /*=========================================================================== * * Begin Internal Return Conversion Functions * *=========================================================================*/ void CMDReturn_b (const boolean Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(BooleanToString(Result)); Parameters.ReturnSize = strlen(Parameters.pReturnValue); } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else strnncpy(Parameters.pReturnValue, BooleanToString(Result), Parameters.ReturnSize-1); } #undef __FUNC__ #define __FUNC__ "CMDReturn_c()" void CMDReturn_c (const signed char Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(2); Parameters.pReturnValue[0] = Result; Parameters.pReturnValue[1] = NULL_CHAR; Parameters.ReturnSize = 2; } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 2) SystemLog.Printf ("\tCommand return buffer too small!"); else { Parameters.pReturnValue[0] = Result; Parameters.pReturnValue[1] = NULL_CHAR; } } #undef __FUNC__ #define __FUNC__ "CMDReturn_C()" void CMDReturn_C (const unsigned char Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(2); Parameters.pReturnValue[0] = (signed char) Result; Parameters.pReturnValue[1] = NULL_CHAR; Parameters.ReturnSize = 2; } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 2) SystemLog.Printf ("\tCommand return buffer too small!"); else { Parameters.pReturnValue[0] = (signed char) Result; Parameters.pReturnValue[1] = NULL_CHAR; } } #undef __FUNC__ #define __FUNC__ "CMDReturn_i()" void CMDReturn_i (const signed int Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(16); itoa(Result, Parameters.pReturnValue, 10); Parameters.ReturnSize = 16; } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 16) SystemLog.Printf ("\tCommand return buffer too small!"); else { itoa(Result, Parameters.pReturnValue, 10); } } #undef __FUNC__ #define __FUNC__ "CMDReturn_I()" void CMDReturn_I (const unsigned int Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(16); ltoa( (signed long) (unsigned long) Result, Parameters.pReturnValue, 10); Parameters.ReturnSize = 16; } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 16) SystemLog.Printf ("\tCommand return buffer too small!"); else { ltoa( (signed long) (unsigned long) Result, Parameters.pReturnValue, 10); } } #undef __FUNC__ #define __FUNC__ "CMDReturn_l()" void CMDReturn_l (const signed long Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(16); ltoa( (signed long) Result, Parameters.pReturnValue, 10); Parameters.ReturnSize = 16; } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 16) SystemLog.Printf ("\tCommand return buffer too small!"); else { ltoa( (signed long) Result, Parameters.pReturnValue, 10); } } #undef __FUNC__ #define __FUNC__ "CMDReturn_L()" void CMDReturn_L (const unsigned long Result, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(16); ltoa( (unsigned long) Result, Parameters.pReturnValue, 10); Parameters.ReturnSize = 16; } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 16) SystemLog.Printf ("\tCommand return buffer too small!"); else ltoa( (unsigned long) Result, Parameters.pReturnValue, 10); } #undef __FUNC__ #define __FUNC__ "CMDReturn_pc()" void CMDReturn_pc (const char* pResult, cmd_parameter_t& Parameters) { if (Parameters.AllocateReturn) { Parameters.pReturnValue = CreateString(pResult); Parameters.ReturnSize = strlen(Parameters.pReturnValue); } else if (Parameters.pReturnValue == NULL) SystemLog.Printf ("\tInvalid NULL return buffer for command!"); else if (Parameters.ReturnSize < 16) SystemLog.Printf ("\tCommand return buffer too small!"); else strnncpy (Parameters.pReturnValue, pResult, Parameters.ReturnSize-1); } /*=========================================================================== * End of Internal Return Functions *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "GetMainCommandHandler()" /*=========================================================================== * * Function - CCommandHandler& GetMainCommandHandler (void); * * Returns the main static command handler object. This is done so that * it forces to the command handler to be constructed before used. A global * command handle object might be used before constructed. Use the * CommandHandler define to access the global object. * *=========================================================================*/ CCommandHandler& GetMainCommandHandler (void) { static CCommandHandler MainCommandHandler; return (MainCommandHandler); } /*=========================================================================== * End of Function GetMainCommandHandler() *=========================================================================*/