From fcd46814f20f213a0b63df4791b14b998dae7bd2 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Thu, 8 Dec 2011 10:46:16 +0000 Subject: [PATCH] Command interpreter code updated to pass the command string into command hander functions. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1650 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/Common/Utils/CommandInterpreter.c | 127 +++++++++++++++++++++++-- Demo/Common/Utils/CommandInterpreter.h | 18 ++-- 2 files changed, 130 insertions(+), 15 deletions(-) diff --git a/Demo/Common/Utils/CommandInterpreter.c b/Demo/Common/Utils/CommandInterpreter.c index 94a8020ea..ab78f100f 100644 --- a/Demo/Common/Utils/CommandInterpreter.c +++ b/Demo/Common/Utils/CommandInterpreter.c @@ -71,7 +71,12 @@ typedef struct xCOMMAND_INPUT_LIST * The callback function that is executed when "help" is entered. This is the * only default command that is always present. */ -static portBASE_TYPE prvHelpCommand( signed char *pcWriteBuffer, size_t xWriteBufferLen ); +static portBASE_TYPE prvHelpCommand( signed char *pcWriteBuffer, size_t xWriteBufferLen, const signed char *pcCommandString ); + +/* + * Return the number of parameters that follow the command name. + */ +static signed char prvGetNumberOfParameters( const signed char * pcCommandString ); /* The definition of the "help" command. This command is always at the front of the list of registered commands. */ @@ -79,7 +84,8 @@ static const xCommandLineInput xHelpCommand = { ( const signed char * const ) "help", ( const signed char * const ) "help: Lists all the registered commands\r\n", - prvHelpCommand + prvHelpCommand, + 0 }; /* The definition of the list of commands. Commands that are registered are @@ -146,7 +152,8 @@ portBASE_TYPE xReturn = pdFAIL; portBASE_TYPE xCmdIntProcessCommand( const signed char * const pcCommandInput, signed char * pcWriteBuffer, size_t xWriteBufferLen ) { static const xCommandLineInputListItem *pxCommand = NULL; -portBASE_TYPE xReturn; +portBASE_TYPE xReturn = pdTRUE; +const signed char *pcRegisteredCommandString; /* Note: This function is not re-entrant. It must not be called from more thank one task. */ @@ -156,19 +163,37 @@ portBASE_TYPE xReturn; /* Search for the command string in the list of registered commands. */ for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext ) { - if( strcmp( ( const char * ) pcCommandInput, ( const char * ) pxCommand->pxCommandLineDefinition->pcCommand ) == 0 ) + pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand; + if( strncmp( ( const char * ) pcCommandInput, ( const char * ) pcRegisteredCommandString, strlen( ( const char * ) pcRegisteredCommandString ) ) == 0 ) { - /* The command has been found, the loop can exit so the command - can be executed. */ + /* The command has been found. Check it has the expected + number of parameters. If cExpectedNumberOfParameters is -1, + then there could be a variable number of parameters and no + check is made. */ + if( pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters >= 0 ) + { + if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters ) + { + xReturn = pdFALSE; + } + } + break; } } } - if( pxCommand != NULL ) + if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) ) + { + /* The command was found, but the number of parameters with the command + was incorrect. */ + strncpy( ( char * ) pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen ); + pxCommand = NULL; + } + else if( pxCommand != NULL ) { /* Call the callback function that is registered to this command. */ - xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen ); + xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput ); /* If xReturn is pdFALSE, then no further strings will be returned after this one, and pxCommand can be reset to NULL ready to search @@ -180,6 +205,7 @@ portBASE_TYPE xReturn; } else { + /* pxCommand was NULL, the command was not found. */ strncpy( ( char * ) pcWriteBuffer, ( const char * const ) "Command not recognised. Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen ); xReturn = pdFALSE; } @@ -200,11 +226,64 @@ unsigned portBASE_TYPE uxCmdIntGetOutputBufferSizeBytes( void ) } /*-----------------------------------------------------------*/ -static portBASE_TYPE prvHelpCommand( signed char *pcWriteBuffer, size_t xWriteBufferLen ) +const signed char *pcCmdIntGetParameter( const signed char *pcCommandString, unsigned portBASE_TYPE uxWantedParameter, portBASE_TYPE *pxParameterStringLength ) +{ +unsigned portBASE_TYPE uxParametersFound = 0; +const signed char *pcReturn = NULL; + + *pxParameterStringLength = 0; + + while( uxParametersFound < uxWantedParameter ) + { + /* Index the character pointer past the current word. If this is the start + of the command string then the first word is the command itself. */ + while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) ) + { + pcCommandString++; + } + + /* Find the start of the next string. */ + while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) ) + { + pcCommandString++; + } + + /* Was a string found? */ + if( *pcCommandString != 0x00 ) + { + /* Is this the start of the required parameter? */ + uxParametersFound++; + + if( uxParametersFound == uxWantedParameter ) + { + /* How long is the parameter? */ + pcReturn = pcCommandString; + while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) ) + { + ( *pxParameterStringLength )++; + pcCommandString++; + } + + break; + } + } + else + { + break; + } + } + + return pcReturn; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvHelpCommand( signed char *pcWriteBuffer, size_t xWriteBufferLen, const signed char *pcCommandString ) { static const xCommandLineInputListItem * pxCommand = NULL; signed portBASE_TYPE xReturn; + ( void ) pcCommandString; + if( pxCommand == NULL ) { /* Reset the pxCommand pointer back to the start of the list. */ @@ -229,4 +308,34 @@ signed portBASE_TYPE xReturn; return xReturn; } +/*-----------------------------------------------------------*/ + +static signed char prvGetNumberOfParameters( const signed char * pcCommandString ) +{ +signed char cParameters = 0; +portBASE_TYPE xLastCharacterWasSpace = pdFALSE; + + /* Count the number of space delimited words in pcCommandString. */ + while( *pcCommandString != 0x00 ) + { + if( ( *pcCommandString ) == ' ' ) + { + if( xLastCharacterWasSpace != pdTRUE ) + { + cParameters++; + xLastCharacterWasSpace = pdTRUE; + } + } + else + { + xLastCharacterWasSpace = pdFALSE; + } + + pcCommandString++; + } + + /* The value returned is one less than the number of space delimited words, + as the first word should be the command itself. */ + return cParameters; +} diff --git a/Demo/Common/Utils/CommandInterpreter.h b/Demo/Common/Utils/CommandInterpreter.h index 6501451d8..613a8cd72 100644 --- a/Demo/Common/Utils/CommandInterpreter.h +++ b/Demo/Common/Utils/CommandInterpreter.h @@ -1,6 +1,6 @@ /* FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. - + *************************************************************************** * * @@ -55,11 +55,11 @@ #define COMMAND_INTERPRETER_H /* The prototype to which callback functions used to process command line -commands must comply. This type will change when commands with parameters -are included. pcWriteBuffer is a buffer into which the output from executing -the command can be written, xWriteBufferLen is the length, in bytes, of the -pcWriteBuffer buffer. */ -typedef portBASE_TYPE (*pdCOMMAND_LINE_CALLBACK)( signed char *pcWriteBuffer, size_t xWriteBufferLen ); +commands must comply. pcWriteBuffer is a buffer into which the output from +executing the command can be written, xWriteBufferLen is the length, in bytes of +the pcWriteBuffer buffer, and pcCommandString is the entire string as input by +the user (from which parameters can be extracted.*/ +typedef portBASE_TYPE (*pdCOMMAND_LINE_CALLBACK)( signed char *pcWriteBuffer, size_t xWriteBufferLen, const signed char * pcCommandString ); /* The structure that defines command line commands. A command line command should be defined by declaring a const structure of this type. */ @@ -68,6 +68,7 @@ typedef struct xCOMMAND_LINE_INPUT const signed char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */ const signed char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */ const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */ + signed char cExpectedNumberOfParameters; /* Commands expect a fixed number of parameters, which may be zero. */ } xCommandLineInput; /* @@ -110,6 +111,11 @@ portBASE_TYPE xCmdIntProcessCommand( const signed char * const pcCommandInput, s signed char *pcCmdIntGetOutputBuffer( void ); unsigned portBASE_TYPE uxCmdIntGetOutputBufferSizeBytes( void ); +/* + * Return a pointer to the xParameterNumber'th word in pcCommandString. + */ +const signed char *pcCmdIntGetParameter( const signed char *pcCommandString, unsigned portBASE_TYPE uxWantedParameter, portBASE_TYPE *pxParameterStringLength ); + #endif /* COMMAND_INTERPRETER_H */ -- 2.39.5