--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecmgmt/ucc/Source/Uccs.v2/Core/UCCS_CExecuteCommand.cpp Mon Mar 08 15:04:18 2010 +0800
@@ -0,0 +1,754 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Switches
+*
+*/
+
+
+/****************************************************************************************
+ *
+ * System Includes
+ *
+ ***************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <windows.h>
+
+/****************************************************************************************
+ *
+ * Local Includes
+ *
+ ***************************************************************************************/
+#include "UCCS_CExecuteCommand.h"
+
+
+/****************************************************************************************
+ *
+ * Definitions
+ *
+ ***************************************************************************************/
+#define REPEATCOMMANDWAITPERIOD 2000
+
+
+/********************************************************************************
+ *
+ * Macro Functions
+ *
+ ********************************************************************************/
+#define NOT_IS_WHITESPACE(c) ((c != '\t')&&(c != '\n')&&(c != 0)&&(c != ' '))
+
+/****************************************************************************************
+ *
+ * File-scope variables
+ *
+ ***************************************************************************************/
+static const char *iCommandStrings[] = { "<invalid>",
+ "quit",
+ "runcmd",
+ "assign",
+ "waitfor",
+ "waitforsignal",
+ "rendezvous",
+ "require",
+ "requirenot",
+ "check",
+ "checknot",
+ "showenvironment",
+ "waitfornot",
+ "signal",
+ NULL };
+
+/****************************************************************************************
+ *
+ * PUBLIC FUNCTION: GetScriptCommandString
+ *
+ ***************************************************************************************/
+const char *GetScriptCommandString( int aCommandID )
+{
+ // make sure the command ID is valid
+ if( (aCommandID < UC_QUIT) || (aCommandID > UC_SIGNAL) ) {
+ return NULL;
+ }
+
+ // return the string
+ return iCommandStrings[aCommandID];
+}
+
+
+/****************************************************************************************
+ *
+ * Construction
+ *
+ ***************************************************************************************/
+CExecuteCommand::CExecuteCommand( CSynchronisation *aSync, IOutput *aOutput )
+{
+ // check params
+ assert( aOutput != NULL );
+ assert( aSync != NULL );
+
+ // init vars
+ iSync = aSync;
+ iOutput = aOutput;
+ iLastResult = NULL;
+ iCommandContextSize = 0;
+
+ // create objs
+ iEnvironment = new CDataRecord();
+ assert( iEnvironment != NULL );
+ iServiceManager = new CServiceManager( aOutput );
+ assert( iServiceManager != NULL );
+ iCommandDecoder = new CCommandDecoder( iEnvironment );
+ assert( iCommandDecoder != NULL );
+}
+
+
+CExecuteCommand::~CExecuteCommand()
+{
+ ClearCommandContext();
+ if( iLastResult != NULL ) {
+ delete iLastResult;
+ }
+ delete iCommandDecoder;
+ delete iServiceManager;
+ delete iEnvironment;
+}
+
+
+/****************************************************************************************
+ *
+ * Public Methoid: Execute Command -- parse into (command, argument)
+ *
+ ***************************************************************************************/
+int CExecuteCommand::ExecuteCommand( char *aCommandLine )
+{
+ char *command, *arguments;
+
+ // check the params
+ assert( aCommandLine != NULL );
+
+ // parse the line into (commandPtr, argumentPtr)
+ for( command = aCommandLine, arguments = aCommandLine; NOT_IS_WHITESPACE(*arguments) && (*arguments != 0); arguments++ )
+ ;
+
+ // check for no arguments (fine for quit) -- otherwise null the command and set the arg ptr
+ if( *arguments == 0 ) {
+ arguments = NULL;
+ } else {
+ *arguments = 0;
+ arguments++;
+ }
+
+
+ // call the handler
+ return ExecuteCommand( command, arguments );
+}
+
+
+/****************************************************************************************
+ *
+ * Public Method: Execute Command -- deals with contexts and waitfors
+ *
+ ***************************************************************************************/
+int CExecuteCommand::ExecuteCommand( char *aCommand, char *aArgs )
+{
+ int i;
+ int err;
+ int match;
+ TUccsCommand command;
+ CDataRecord *command_arguments;
+
+ // resolve the command
+ for( i = 0; iCommandStrings[i] != NULL; i++ ) {
+ match = strcmp( aCommand, iCommandStrings[i] );
+ if( match == 0 ) {
+ break;
+ }
+ }
+
+ // if no match is found then error
+ if( iCommandStrings[i] == 0 ) {
+ return UCCS_UNKNOWNCOMMAND;
+ }
+ command = (TUccsCommand)i;
+
+ // create a new request record
+ command_arguments = new CDataRecord();
+
+ // create a data object from the argument string
+ err = iCommandDecoder->ParseCommandToRecord(aArgs, command_arguments);
+ if( err != UCCS_OK ) {
+ return err;
+ }
+
+ // if the command is a run command then we clear the context
+ if( command == UC_RUNCMD ) {
+ ClearCommandContext();
+ }
+
+ // add the command to the context
+ AddToCommandContext( command, command_arguments );
+
+ // now execute the command for the first time
+ err = InternalExecuteCommand( command, command_arguments );
+
+ // if the result was NOT UCCS_REPLAYCOMMAND then just return
+ if( err != UCCS_REPLAYCOMMAND ) {
+ return err;
+ }
+
+
+ // NOTE: if we get here then we are asked to replay
+
+ // Run each command in the context again in order. If an error occurs then exit. If someone
+ // asks to wait again then start agani
+ for( i = 0; i < iCommandContextSize; i++ ) {
+ err = InternalExecuteCommand( iCommandContextCommands[i], iCommandContextArgs[i] );
+ if( err == UCCS_REPLAYCOMMAND ) {
+ i = -1;
+ continue;
+ } else if( err != UCCS_OK ) {
+ return err;
+ }
+ }
+
+ // done
+ return UCCS_OK;
+}
+
+/****************************************************************************************
+ *
+ * Public Method: Execute Command -- dispatch commands to appropriate
+ * handlers
+ *
+ ***************************************************************************************/
+int CExecuteCommand::InternalExecuteCommand( TUccsCommand aCmd, CDataRecord *aArgs )
+{
+ int err;
+
+ // let the output know that we are executing a command
+ if( aCmd != UC_RUNCMD )
+ {
+ iOutput->ExecuteCommand( aCmd, aArgs );
+ }
+
+ // pass the command to the appropriate handler
+ switch( aCmd ) {
+
+ case UC_QUIT:
+ err = UCCS_QUIT;
+ break;
+
+ case UC_RUNCMD:
+ err = HandleRunCmd( aArgs );
+ break;
+
+ case UC_ASSIGN:
+ err = HandleAssignment( aArgs );
+ break;
+
+ case UC_WAITFOR:
+ err = HandleWaitFor( aArgs );
+ break;
+
+ case UC_REQUIRE:
+ err = HandleRequire( aArgs );
+ break;
+
+ case UC_REQUIRENOT:
+ err = HandleRequireNot( aArgs );
+ break;
+
+ case UC_CHECK:
+ err = HandleCheck( aArgs );
+ break;
+
+ case UC_CHECKNOT:
+ err = HandleCheckNot( aArgs );
+ break;
+
+ case UC_WAITFORSIGNAL:
+ err = HandleWaitForSignal( aArgs );
+ break;
+
+ case UC_RENDEZVOUS:
+ err = HandleRendezvous( aArgs );
+ break;
+
+ case UC_PRINTENVIRONMENT:
+ iOutput->DisplayEnvironment( iEnvironment );
+ err = UCCS_OK;
+ break;
+
+ case UC_WAITFORNOT:
+ err = HandleWaitForNot( aArgs );
+ break;
+
+ case UC_SIGNAL:
+ err = HandleSignal( aArgs );
+ break;
+ }
+
+ // output the result
+ iOutput->ExecuteCommandResult( err );
+
+ // should always get here
+ return err;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleRunCmd
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleRunCmd( CDataRecord *aArgs )
+{
+ int err;
+ CDataRecord *result = NULL;
+
+ // run the command
+ err = iServiceManager->IssueCommand( aArgs, &result );
+
+ // if the command fails then return the error
+ if( err != UCCS_OK && err != UCCS_ERROR_NONE ) {
+ return err;
+ }
+ assert( result != NULL );
+
+ // otherwise this is success -- let the output know
+ iOutput->ExecuteCommandReply( result );
+
+ // otherwise we clear the previous saved command and result
+ if( iLastResult != NULL ) {
+ delete iLastResult;
+ }
+
+ // now save this command and result
+ iLastResult = result;
+ iCommandDecoder->SetLastReply( iLastResult );
+
+ // done
+ return err;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandlePrintLastCommand
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandlePrintLastCommand( CDataRecord *aArgs )
+{
+ iOutput->DisplayLastCommand( iCommandContextArgs[0] );
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandlePrintLastResult
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandlePrintLastResult( CDataRecord *aArgs )
+{
+ iOutput->DisplayLastReply( iLastResult );
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleAssignment -- allows elements of the reply to be assigned. For
+ * each field (name1, value1) in the passed record we:
+ *
+ * field_value = reply->GetField( name1 );
+ * environment->NewField( value1, field_value );
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleAssignment( CDataRecord *aArgs )
+{
+ int err;
+// char *source_field_name;
+ char *dest_field_name;
+ char *dest_field_value;
+ CDataField *element = NULL;
+
+ // now do the assignment -- first try and update, then a new
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+ dest_field_name = element->GetName();
+ dest_field_value = element->GetStrValue();
+ err = iEnvironment->ChangeFieldData( dest_field_name, dest_field_value );
+ if( err == UCCS_FIELDNOTFOUND ) {
+ err = iEnvironment->NewField( dest_field_name, dest_field_value );
+ if( err != UCCS_OK ) {
+ return err;
+ }
+ } else if( err != UCCS_OK ) {
+ return err;
+ }
+ element = aArgs->GetNextField();
+ }
+
+
+ // done
+ return UCCS_OK;
+}
+
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleWaitFor. For each field in the args (namei, valuei)
+ *
+ * rv = reply->GetField(namei);
+ * if( rv != valuei )
+ * repeat the last command with X second wait
+ *
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleWaitFor( CDataRecord *aArgs )
+{
+ char *field_name;
+ char *reference_value;
+ char *actual_value;
+ int err, match;
+ CDataField *element = NULL;
+
+ // make sure there is a previous reply and request
+ if( iLastResult == NULL ) {
+ return UCCS_NORESULT;
+ }
+
+ // now do the waitfor
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+
+ field_name = element->GetName();
+ reference_value = element->GetStrValue();
+ err = iLastResult->GetFieldAsString( field_name, &actual_value );
+ if( err != UCCS_OK ) {
+ return err;
+ }
+ match = strcmp( reference_value, actual_value );
+ if( match != 0 ) {
+ Sleep( REPEATCOMMANDWAITPERIOD );
+ return UCCS_REPLAYCOMMAND;
+ }
+
+ element = aArgs->GetNextField();
+ }
+
+ // done
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleWaitForNot. For each field in the args (namei, valuei)
+ *
+ * rv = reply->GetField(namei);
+ * if( rv != valuei )
+ * repeat the last command with X second wait
+ *
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleWaitForNot( CDataRecord *aArgs )
+{
+ char *field_name;
+ char *reference_value;
+ char *actual_value;
+ int err, match;
+ CDataField *element = NULL;
+
+ // make sure there is a previous reply and request
+ if( iLastResult == NULL ) {
+ return UCCS_NORESULT;
+ }
+
+ // now do the waitfornot
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+
+ field_name = element->GetName();
+ reference_value = element->GetStrValue();
+ err = iLastResult->GetFieldAsString( field_name, &actual_value );
+ if( err != UCCS_OK ) {
+ return err;
+ }
+ match = strcmp( reference_value, actual_value );
+ if( match == 0 ) {
+ Sleep( REPEATCOMMANDWAITPERIOD );
+ return UCCS_REPLAYCOMMAND;
+ }
+
+ element = aArgs->GetNextField();
+ }
+
+ // done
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleRequire.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleRequire( CDataRecord *aArgs )
+{
+ int err, match;
+ char *field_name, *field_value, *actual_value;
+ CDataField *element;
+
+ // make sure there is a previous reply
+ if( iLastResult == NULL ) {
+ return UCCS_NORESULT;
+ }
+
+ // now do the require
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+
+ field_name = element->GetName();
+ field_value = element->GetStrValue();
+ err = iLastResult->GetFieldAsString( field_name, &actual_value );
+ if( err != UCCS_OK ) {
+ return UCCS_REQUIREDVALUEERROR;
+ }
+ match = strcmp( actual_value, field_value );
+ if( match != 0 ) {
+ return UCCS_REQUIREDVALUEINCORRECT;
+ }
+
+ element = aArgs->GetNextField();
+ }
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleRequireNot.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleRequireNot( CDataRecord *aArgs )
+{
+ int err, match;
+ char *field_name, *field_value, *actual_value;
+ CDataField *element;
+
+ // make sure there is a previous reply
+ if( iLastResult == NULL ) {
+ return UCCS_NORESULT;
+ }
+
+ // now do the requirenot
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+
+ field_name = element->GetName();
+ field_value = element->GetStrValue();
+ err = iLastResult->GetFieldAsString( field_name, &actual_value );
+ if( err != UCCS_OK ) {
+ return UCCS_REQUIREDNOTVALUEERROR;
+ }
+ match = strcmp( actual_value, field_value );
+ if( match == 0 ) {
+ return UCCS_REQUIREDNOTVALUEMATCH;
+ }
+
+ element = aArgs->GetNextField();
+ }
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleCheck.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleCheck( CDataRecord *aArgs )
+{
+ int err, match;
+ char *field_name, *field_value, *actual_value;
+ CDataField *element;
+
+ // make sure there is a previous reply
+ if( iLastResult == NULL ) {
+ return UCCS_NORESULT;
+ }
+
+ // now do the check
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+
+ field_name = element->GetName();
+ field_value = element->GetStrValue();
+ err = iLastResult->GetFieldAsString( field_name, &actual_value );
+ if( err != UCCS_OK ) {
+ return UCCS_CHECKVALUEERROR;
+ }
+ match = strcmp( actual_value, field_value );
+ if( match != 0 ) {
+ return UCCS_CHECKVALUEINCORRECT;
+ }
+
+ element = aArgs->GetNextField();
+ }
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleCheckNot.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleCheckNot( CDataRecord *aArgs )
+{
+ int err, match;
+ char *field_name, *field_value, *actual_value;
+ CDataField *element;
+
+ // make sure there is a previous reply
+ if( iLastResult == NULL ) {
+ return UCCS_NORESULT;
+ }
+
+ // now do the checknot
+ element = aArgs->GetFirstField();
+ while( element != NULL ) {
+
+ field_name = element->GetName();
+ field_value = element->GetStrValue();
+ err = iLastResult->GetFieldAsString( field_name, &actual_value );
+ if( err != UCCS_OK ) {
+ return UCCS_CHECKNOTVALUEERROR;
+ }
+ match = strcmp( actual_value, field_value );
+ if( match == 0 ) {
+ return UCCS_CHECKNOTVALUEMATCH;
+ }
+
+ element = aArgs->GetNextField();
+ }
+ return UCCS_OK;
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleWaitForSignal.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleWaitForSignal( CDataRecord *aArgs )
+{
+ return iSync->WaitFromScript();
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleSignal.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleSignal( CDataRecord *aArgs )
+{
+ return iSync->SignalFromScript();
+}
+
+
+/****************************************************************************************
+ *
+ * Private Method: HandleRendezvous.
+ *
+ ***************************************************************************************/
+int CExecuteCommand::HandleRendezvous( CDataRecord *aArgs )
+{
+ return iSync->RendezvousFromScript();
+}
+
+
+/****************************************************************************************
+ *
+ * PRIVATE METHODS: Manage the command contexts
+ *
+ ***************************************************************************************/
+void CExecuteCommand::ClearCommandContext()
+{
+ int i;
+ for( i = 0; i <iCommandContextSize; i++ ) {
+ assert( iCommandContextArgs[i] != NULL );
+ delete iCommandContextArgs[i];
+ iCommandContextArgs[i] = NULL;
+ }
+ iCommandContextSize = 0;
+}
+
+
+void CExecuteCommand::AddToCommandContext( TUccsCommand aCommand, CDataRecord *aRec )
+{
+ assert( aRec != NULL );
+ assert( iCommandContextSize < MAXRECENTCOMMANDS );
+ iCommandContextCommands[iCommandContextSize] = aCommand;
+ iCommandContextArgs[iCommandContextSize++] = aRec;
+}
+
+
+/****************************************************************************************
+ *
+ * PUBLIC METHODS: To get the value of an varible in the environment
+ *
+ ***************************************************************************************/
+int CExecuteCommand::GetEnvironmentVariable ( char *aVariableName, char *aOutputBuffer, int aOutputBufferSize )
+{
+ int ret, len;
+ char* fieldValue;
+
+ // Check params
+ assert ( aVariableName != NULL );
+ assert ( aOutputBuffer != NULL );
+ assert ( aOutputBufferSize > 0 );
+
+ // If there is nothing in the environment then return that env var not found Error
+ if ( iEnvironment == NULL )
+ return UCCS_NOENVIRONMENT;
+
+ // Query the environment for this variable name
+ ret = iEnvironment->GetFieldAsString( aVariableName, &fieldValue );
+ assert ( (ret == UCCS_OK) || (ret == UCCS_FIELDNOTFOUND) );
+ if( ret == UCCS_FIELDNOTFOUND )
+ return UCCS_VARIABLEDOESNOTEXIST;
+
+ // Now copy the fieldValue returned into the return output buffer
+ // First check we have sufficient memory to hold the value in the return buffer
+ len = strlen (fieldValue) + 1;
+
+ if ( len > aOutputBufferSize )
+ return UCCS_VARIABLEVALTOOLONG;
+
+ // Else we copy the data
+ memcpy( aOutputBuffer, fieldValue, len );
+
+ return UCCS_OK;
+}
+
+
+