testexecmgmt/ucc/Source/Uccs.v2/Core/UCCS_CExecuteCommand.cpp
changeset 0 3da2a79470a7
--- /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;
+}
+
+
+