| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- #define SCPI_ARGS_HELPER_C
- #define SCPI_CORE_PRIVATE // access to 'scpi_core_private.h'
- #include "app/scpi/scpi_core.h"
- #include "app/scpi/scpi_core_private.h"
- #include "app/scpi/scpi_parser.h"
- #include "app/scpi/scpi_commands.h" // processCharacterArgument
- #include "app/scpi/scpi_numeric.h" // processNumericArgument
- #include "app/scpi/scpi_args_helper.h"
- #include "app/fseq/fseq.h" // tFSeqCtx_t
- #include "app/scpi/CommandParserStates/process_data.h" // sProcessProgramDataCommonContext_t
- #include "my_assert.h"
- // [1] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992)
- // "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE
- // @parseArguments_helper
- // Helper function. Used for convenient call of @parseArguments inside command handler module
- // Parameters:
- // @common_ctx - process program data state context, see @sProcessProgramDataCommonContext_t
- // @argTypes - array of argument types to set the parameters parsing methods (see @parseArguments, @eScpiArgType_t)
- // Other parameters: refer @parseArguments
- // Returns: refer @parseArguments
- eScpiParserStatus_t parseArguments_helper( void * common_ctx, const uint8_t * argTypes, size_t argN, size_t argOptionalN)
- {
- assert( argN <= SCPI_MAX_ARGS );
-
- sProcessProgramDataCommonContext_t * _common_ctx = common_ctx;
- sScpiParserContext_t * global_ctx = _common_ctx->global_ctx;
- // parse command parameters
- eScpiParserStatus_t status = parseArguments( &(global_ctx->sParser.xCtxObj), _common_ctx->argTokens, argTypes, _common_ctx->argEntityTypes, argN, argOptionalN, &_common_ctx->args );
- // Modify state status value
- // This status can be used inside Dispatch routine of command handler
- _common_ctx->argsParserStatus = status;
- // check the parser status result
- if( eScpiParserStatus_success != status )
- {
- // _common_ctx->args is index of parameter
- assert( _common_ctx->args < SCPI_MAX_ARGS );
- // assign whole arguments chain token
- global_ctx->sParser.xArgToken.shead = _common_ctx->argTokens[_common_ctx->args].shead;
- global_ctx->sParser.xArgToken.stail = _common_ctx->argTokens[_common_ctx->args].stail;
- }
- else
- {
- // _common_ctx->args is amount of parameters
- assert( _common_ctx->args <= SCPI_MAX_ARGS );
- // assign whole arguments chain token
- global_ctx->sParser.xArgToken.shead = _common_ctx->argTokens[0].shead;
- global_ctx->sParser.xArgToken.stail = _common_ctx->argTokens[_common_ctx->args - 1].stail;
- }
- // Reset indicator: end-of-command has been parsed
- _common_ctx->needParseEndOfCommand = false;
- return status;
- }
- // [1] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992)
- // "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE
- // @parseArrayArguments_helper
- // Helper function. Used for convenient call of @parseArguments inside command handler module
- // Parameters:
- // @common_ctx - process program data state context, see @sProcessProgramDataCommonContext_t
- // @argTypes - array of argument types to set the parameters parsing methods (see @parseArguments, @eScpiArgType_t)
- // Other parameters: refer @parseArguments
- // Returns: refer @parseArguments
- eScpiParserStatus_t parseArrayArguments_helper( void * common_ctx, const uint8_t * argTypes, size_t argN, size_t argOptionalN)
- {
- assert( argN <= SCPI_MAX_ARGS );
-
- sProcessProgramDataCommonContext_t * _common_ctx = common_ctx;
- sScpiParserContext_t * global_ctx = _common_ctx->global_ctx;
- size_t argNumber = sizeof(_common_ctx->argArray)/sizeof(_common_ctx->argArray[0]);
- // parse command parameters
- eScpiParserStatus_t status = parseArrayArguments( &(global_ctx->sParser.xCtxObj), _common_ctx->argArray, &argNumber, argTypes, _common_ctx->argEntityTypes, argN, argOptionalN, &_common_ctx->args );
- // Modify state status value
- // This status can be used inside Dispatch routine of command handler
- _common_ctx->argsParserStatus = status;
- // check the parser status result
- if( eScpiParserStatus_success != status )
- {
- // _common_ctx->args is index of parameter
- //assert( _common_ctx->args < SCPI_MAX_ARGS );
- // assign whole arguments chain token
- global_ctx->sParser.xArgToken.shead = _common_ctx->argTokens[_common_ctx->args].shead;
- global_ctx->sParser.xArgToken.stail = _common_ctx->argTokens[_common_ctx->args].stail;
- }
- else
- {
- // _common_ctx->args is amount of parameters
- //assert( _common_ctx->args <= SCPI_MAX_ARGS );
- // assign whole arguments chain token
- global_ctx->sParser.xArgToken.shead = _common_ctx->argTokens[0].shead;
- global_ctx->sParser.xArgToken.stail = _common_ctx->argTokens[_common_ctx->args - 1].stail;
- }
- // Reset indicator: end-of-command has been parsed
- _common_ctx->needParseEndOfCommand = false;
- return status;
- }
- // @processArgument_Character_helper
- // Helper function. Used for convenient call of the other helper functions.
- // Processes the CHARACTER argument. See @processCharacterArgument
- // Parameters:
- // @common_ctx - process program data state context, see @sProcessProgramDataCommonContext_t
- // @argTypes - array of argument types to set the parameters parsing methods (see @parseArguments, @eScpiArgType_t)
- // Other parameters: refer @processCharacterArgument
- // Returns: SCPI_ARGUMENT_CHARACTER_INVALID_ID in error case, or argument option index in @allowedList
- int8_t processArgument_Character_helper( void * common_ctx, const uint8_t * argTypes, const xArgument_t * allowedList, uint8_t argId )
- {
- assert( common_ctx );
- assert( argTypes );
- if( NULL == common_ctx || NULL == argTypes )
- {
- return SCPI_ARGUMENT_CHARACTER_INVALID_ID;
- }
- assert( argTypes[ argId ] == eScpiArg_Character );
- // analyze argument type
- if( argTypes[ argId ] != eScpiArg_Character )
- {
- return SCPI_ARGUMENT_CHARACTER_INVALID_ID;
- }
- bool state = false;
- int8_t argument_idx = 0;
- sProcessProgramDataCommonContext_t * _common_ctx = common_ctx;
- sScpiParserContext_t * global_ctx = _common_ctx->global_ctx;
- state = processCharacterArgument( allowedList, &_common_ctx->argTokens[argId], &argument_idx );
-
- // assign current argument token (success or failed)
- global_ctx->sParser.xArgToken.shead = _common_ctx->argTokens[argId].shead;
- global_ctx->sParser.xArgToken.stail = _common_ctx->argTokens[argId].stail;
- if( ! state )
- {
- argument_idx = SCPI_ARGUMENT_CHARACTER_INVALID_ID;
- }
- return argument_idx;
- }
- // @processArgument_Numeric_helper
- // Helper function. Used for convenient call of the other helper functions.
- // Processes the NUMERIC argument. See @processNumericArgument
- // Parameters:
- // @common_ctx - process program data state context, see @sProcessProgramDataCommonContext_t
- // @argTypes - array of argument types to set the parameters parsing methods (see @parseArguments, @eScpiArgType_t)
- // Other parameters: refer @processNumericArgument
- // Returns: pointer to the numeric entry descriptor with value and type, and the error code, or NULL
- // if @common_ctx is set to NULL.
- const sNumericEntry_t * processArgument_Numeric_helper( void * common_ctx, const uint8_t * argTypes, const sNumericRange_t * range, uint8_t argId )
- {
- assert( common_ctx );
- assert( argTypes );
- sProcessProgramDataCommonContext_t * _common_ctx = common_ctx;
- if( NULL == common_ctx )
- {
- (void)_common_ctx->numericProcessContext.valueEntry.error; // inaccessible
- assert(false);
- return NULL;
- }
- else
- if( NULL == argTypes )
- {
- _common_ctx->numericProcessContext.valueEntry.error = ScpiNumericInvalidArg;
- assert(false);
- }
- else
- {
- // analyze argument type
- switch( argTypes[ argId ] )
- {
- case eScpiArg_Numeric:
- case eScpiArg_Numeric_Demical:
- case eScpiArg_Numeric_NonDemical:
- case eScpiArg_Array_Decimal:
- {
- bool state = false;
- sScpiParserContext_t * global_ctx = _common_ctx->global_ctx;
-
- _common_ctx->numericProcessContext.valueEntry.error = ScpiNumericInvalidArg;
-
- state = processNumericArgument( &_common_ctx->numericProcessContext,
- &_common_ctx->argTokens[argId],
- _common_ctx->argEntityTypes[argId],
- range );
-
- // assign current argument token (success or failed)
- global_ctx->sParser.xArgToken.shead = _common_ctx->argTokens[argId].shead;
- global_ctx->sParser.xArgToken.stail = _common_ctx->argTokens[argId].stail;
- if( !state )
- {(void)_common_ctx->numericProcessContext.valueEntry.error;}
- }
- break;
- default:
- _common_ctx->numericProcessContext.valueEntry.error = ScpiNumericInvalidArg; // invalid type
- assert(false);
- }
- }
- // error code set helper
- switch( _common_ctx->numericProcessContext.valueEntry.error )
- {
- case ScpiNumericSuccess:
- {
- (void)_common_ctx->status; // caller dependent
- }
- break;
- // "11.5.1.1.5", [1]
- case ScpiNumericError_DEVICE_RANGE: // the value is out of range supported by device
- {
- _common_ctx->status = eProgramDataArgumentRange; // parameter value range error, caller should generate error message
- }
- break;
- // "11.5.1.1.5", [1]
- // "10.10.6 Error Handling", [1]
- // "<...> An out-of-range integer shall cause an Execution Error, see 11.5.1.1.5. <...>"
- case ScpiNumericError_USER_RANGE: // the value is out of user specified range: // the value is out of range supported by device
- {
- _common_ctx->status = eProgramDataArgumentValue; // parameter value range error, caller should generate error message
- }
- break;
- case ScpiNumericError_USER_TYPE: // the value does not match to the user expectation
- {
- _common_ctx->status = eProgramDataArgumentType; // parameter type error, caller should generate error message
- }
- break;
- case ScpiNumericInvalidArg: assert(false); // forbidden case: design bug
- case ScpiNumericError: // generic numeric conversion error
- {
- _common_ctx->status = eProgramDataRuntimeError; // parameter syntax error, caller should generate error message
- }
- break;
- }
- return &_common_ctx->numericProcessContext.valueEntry;
- }
- const sNumericEntry_t * processArgument_Array_helper( void * common_ctx, const sNumericRange_t * range, uint8_t argId, void * result_arg, uint16_t result_size)
- {
- assert( common_ctx );
-
- // sProcessProgramDataCommonContext_t * _common_ctx = common_ctx;
- // uint16_t * _result_arg = result_arg;
- // for(uint8_t i = 0; i < _common_ctx->args; i++)
- // {
- // bool state = processNumericArgument( &_common_ctx->numericProcessContext,
- // &_common_ctx->argArray[i],
- // _common_ctx->argEntityTypes[0],
- // range );
- // if(state && i < result_size)
- // {
- // *_result_arg = _common_ctx->numericProcessContext.valueEntry.Value.demicalInteger;
- // _result_arg++;
- // }
- // else
- // {
- // _common_ctx->status = eProgramDataRuntimeError; // parameter syntax error, caller should generate error message
- // }
- // }
- sNumericEntry_t zagl;
- return &zagl;
- }
- // @scpi_argument_value_token
- // Get the string tokens of the specified value in the allowed CHARACTER value list.
- // Parameters:
- // @list - allowed values list, see @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST
- // @valueIndex - index in the array;
- // @pOutToken - string token to fill, can not be NULL;
- // Returns: filled string token (@pOutToken).
- // Note: if @valueList is out of range, NULL pointer is returned, and @pOutToken is unchanged.
- const sStrToken_t * scpi_argument_value_token( const xArgument_t * list, size_t valueIndex, sStrToken_t * pOutToken )
- {
- if( NULL == list || NULL == pOutToken ) return NULL;
- // walk in the list
- while( (*list != NULL) && (valueIndex>0) )
- {
- valueIndex--; list++;
- }
- if( NULL == *list ) return NULL;
- pOutToken->shead = *list;
- pOutToken->stail = strlen(*list) + *list;
- return pOutToken;
- }
|