| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #ifndef SCPI_ARGS_HELPER_H
- #define SCPI_ARGS_HELPER_H
- // SCPI Command Argument parser helper header.
- // Include only to the command handler file like 'idn.c' or similar.
- // ------------------------------------------------------------------------
- #include "app/scpi/scpi_base.h" // SCPI_MAX_ARGS
- #include "app/scpi/scpi_commands.h" // processCharacterArgument
- #include "app/scpi/scpi_numeric_types.h" // sProcessNumericEntry_t, sStrToken_t, sNumericRange_t
- #include "app/scpi/scpi_numeric.h"
- #include "app/scpi/scpi_args.h"
- #include <stdint.h> // uint8_t
- // ------------------------------------------------------------------------
- // @SCPI_ARGS_N macro:
- // Defines amount of SCPI-command arguments including optional ones.
- // The command handler module must include this header either after defining this macro,
- // or after defining a pair of SCPI_ARGS_N_Q + SCPI_ARGS_N_C.
- //
- // @SCPI_ARGS_N_Q macro:
- // Defines amount of SCPI-command arguments including optional ones for QUERY.
- // The command handler module must include this header after defining this macro.
- // It is required to be defined together with SCPI_ARGS_N_C.
- // Useless if SCPI_ARGS_N is defined.
- //
- // @SCPI_ARGS_N_C macro:
- // Defines amount of SCPI-command arguments including optional ones for COMMNAD(non-query).
- // The command handler module must include this header after defining this macro.
- // It is required to be defined together with SCPI_ARGS_N_Q.
- // Useless if SCPI_ARGS_N is defined.
- // @SCPI_ARGS_MANDATORY_N macro:
- // Defines amount of mandatory SCPI-command arguments, not including optional ones.
- // If the command requires all the parameters and does not allow to omit any argument,
- // this value must be equal to SCPI_ARGS_N, or must be undefined. The command handler module
- // must include this header after defining this macro. All the optional command parameters
- // are located in the end of the argument set.
- // The command handler module must include this header either after defining this macro,
- // or after defining a pair of SCPI_ARGS_MANDATORY_N_Q + SCPI_ARGS_MANDATORY_N_C.
- // @SCPI_ARGS_MANDATORY_N_Q macro:
- // Defines amount of mandatory SCPI-command arguments, not including optional ones, for QUERY.
- // If the command requires all the parameters and does not allow to omit any argument,
- // this value must be equal to SCPI_ARGS_N_Q, or must be undefined. The command handler module
- // must include this header after defining this macro. All the optional command parameters are
- // located in the end of the argument set.
- // It is required to be defined together with SCPI_ARGS_MANDATORY_N_C.
- // Useless if SCPI_ARGS_MANDATORY_N is defined.
- // @SCPI_ARGS_MANDATORY_N_C macro:
- // Defines amount of mandatory SCPI-command arguments, not including optional ones, for COMMAND.
- // If the command requires all the parameters and does not allow to omit any argument,
- // this value must be be equal to SCPI_ARGS_N_C, or must be undefined. The command handler module
- // must include this header after defining this macro. All the optional command parameters are
- // located in the end of the argument set.
- // It is required to be defined together with SCPI_ARGS_MANDATORY_N_Q.
- // Useless if SCPI_ARGS_MANDATORY_N is defined.
- #define GC(_common_ctx_) ((sScpiParserContext_t*)((_common_ctx_)->global_ctx))
- #if !defined(SCPI_ARGS_HELPER_C)
- #ifndef SCPI_ARGS_N
- #if defined(SCPI_ARGS_N_Q) && !defined(SCPI_ARGS_N_C)
- #error The macro 'SCPI_ARGS_N_C' is undefined.
- #elif defined(SCPI_ARGS_N_C) && !defined(SCPI_ARGS_N_Q)
- #error The macro 'SCPI_ARGS_N_Q' is undefined.
- #elif !defined(SCPI_ARGS_N_C) && !defined(SCPI_ARGS_N_Q)
- #error The macro 'SCPI_ARGS_N' shall be defined to the amount of command parameters or 'SCPI_ARGS_N_Q' and 'SCPI_ARGS_N_C' shall be used instead.
- #endif
- #endif
- #if defined(SCPI_ARGS_N) && (SCPI_ARGS_N > SCPI_MAX_ARGS)
- #error Invalid value 'SCPI_ARGS_N'. Limit exceeded. See the limit 'SCPI_MAX_ARGS'.
- #endif
- #if defined(SCPI_ARGS_N_Q) && (SCPI_ARGS_N_Q > SCPI_MAX_ARGS)
- #error Invalid value 'SCPI_ARGS_N_Q'. Limit exceeded. See the limit 'SCPI_MAX_ARGS'.
- #endif
- #if defined(SCPI_ARGS_N_C) && (SCPI_ARGS_N_C > SCPI_MAX_ARGS)
- #error Invalid value 'SCPI_ARGS_N_C'. Limit exceeded. See the limit 'SCPI_MAX_ARGS'.
- #endif
- #if defined(SCPI_ARGS_N)
- #ifndef SCPI_ARGS_MANDATORY_N
- #define SCPI_ARGS_MANDATORY_N SCPI_ARGS_N
- #elif SCPI_ARGS_MANDATORY_N > SCPI_ARGS_N
- #error The value 'SCPI_ARGS_MANDATORY_N' shall not be greater than 'SCPI_ARGS_N'
- #endif
- #endif
- #if defined(SCPI_ARGS_N_Q) && defined(SCPI_ARGS_N_C)
- #ifndef SCPI_ARGS_MANDATORY_N_C
- #define SCPI_ARGS_MANDATORY_N_C SCPI_ARGS_N_C
- #elif SCPI_ARGS_MANDATORY_N_C > SCPI_ARGS_N_C
- #error The value 'SCPI_ARGS_MANDATORY_N_C' shall not be greater than 'SCPI_ARGS_N_C'
- #endif
- #ifndef SCPI_ARGS_MANDATORY_N_Q
- #define SCPI_ARGS_MANDATORY_N_Q SCPI_ARGS_N_Q
- #elif SCPI_ARGS_MANDATORY_N_Q > SCPI_ARGS_N_Q
- #error The value 'SCPI_ARGS_MANDATORY_N_Q' shall not be greater than 'SCPI_ARGS_N_Q'
- #endif
- #endif
- #else // scpi_args_helper.c
-
- #endif
- // ------------------------------------------------------------------------
- // @SCPI_ARGS_VAR_TOKENS
- // Default variable name for the string tokens array
- #define SCPI_ARGS_VAR_TOKENS argTokens
- #if defined(SCPI_ARGS_N)
- // @SCPI_ARGS_VAR_TYPES
- // Default variable name for the argument types array
- #define SCPI_ARGS_VAR_TYPES argTypes
- #endif
- #if defined(SCPI_ARGS_N_C) && defined(SCPI_ARGS_N_Q)
- // @SCPI_ARGS_VAR_TYPES_C
- // Default variable name for the argument types array (command only)
- #define SCPI_ARGS_VAR_TYPES_C argTypesCommand
- // @SCPI_ARGS_VAR_TYPES_Q
- // Default variable name for the argument types array (query only)
- #define SCPI_ARGS_VAR_TYPES_Q argTypesQuery
- #endif
- // ------------------------------------------------------------------------
- // @DECLARE_SCPI_ARGS macro:
- // Use this macro to decalre parser entities for command arguments.
- // @_VariableTypes_ - the name of the argument types array
- // The rest arguments of this macro are the set of SCPI_ARGS_N types of command
- // arguments (eScpiArgType_t), e.g.:
- // #define SCPI_ARGS_N 1
- // DECLARE_SCPI_ARGS( SCPI_ARGS_VAR_TYPES, eScpiArg_Character );
- #if defined(SCPI_ARGS_N)
- #if SCPI_ARGS_N == 0
- #define DECLARE_SCPI_ARGS(...)
- #else
- #define DECLARE_SCPI_ARGS(...) \
- static const uint8_t SCPI_ARGS_VAR_TYPES[ SCPI_ARGS_N ] = { __VA_ARGS__ };
- #endif
- #elif defined(SCPI_ARGS_N_C) && defined(SCPI_ARGS_N_Q)
- #if SCPI_ARGS_N_C == 0
- #define DECLARE_SCPI_ARGS_C(...)
- #else
- #define DECLARE_SCPI_ARGS_C(...) \
- static const uint8_t SCPI_ARGS_VAR_TYPES_C[ SCPI_ARGS_N_C ] = { __VA_ARGS__ };
- #endif
- #if SCPI_ARGS_N_Q == 0
- #define DECLARE_SCPI_ARGS_Q(...)
- #else
- #define DECLARE_SCPI_ARGS_Q(...) \
- static const uint8_t SCPI_ARGS_VAR_TYPES_Q[ SCPI_ARGS_N_Q ] = { __VA_ARGS__ };
- #endif
- #endif
- // Routine @parseArguments call helper
- #if defined(SCPI_ARGS_N)
- #define SCPI_PARSE_ARGUMENTS_C(_common_ctx_) (assert(false), 0)
- #define SCPI_PARSE_ARGUMENTS_Q(_common_ctx_) (assert(false), 0)
- #if SCPI_ARGS_N == 0
- #define SCPI_PARSE_ARGUMENTS(_common_ctx_) parseArguments_helper( (_common_ctx_), NULL, SCPI_ARGS_N, 0 )
- #else
- #define SCPI_PARSE_ARGUMENTS(_common_ctx_) parseArguments_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES, SCPI_ARGS_N, (SCPI_ARGS_N) - (SCPI_ARGS_MANDATORY_N) )
- #define SCPI_PARSE_ARRAY_ARGUMENTS(_common_ctx_) parseArrayArguments_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES, SCPI_ARGS_N, SCPI_ARGS_MANDATORY_N )
- #endif
- #elif defined(SCPI_ARGS_N_C) && defined(SCPI_ARGS_N_Q)
- #define SCPI_PARSE_ARGUMENTS(_common_ctx_) ((GC(_common_ctx_)->sMessage.bQuery)?\
- SCPI_PARSE_ARGUMENTS_Q(_common_ctx_):\
- SCPI_PARSE_ARGUMENTS_C(_common_ctx_))
- #if SCPI_ARGS_N_C == 0
- #define SCPI_PARSE_ARGUMENTS_C(_common_ctx_) parseArguments_helper( (_common_ctx_), NULL, SCPI_ARGS_N_C, 0 )
- #else
- #define SCPI_PARSE_ARGUMENTS_C(_common_ctx_) parseArguments_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_C, SCPI_ARGS_N_C, (SCPI_ARGS_N_C) - (SCPI_ARGS_MANDATORY_N_C) )
- #endif
- #if SCPI_ARGS_N_Q == 0
- #define SCPI_PARSE_ARGUMENTS_Q(_common_ctx_) parseArguments_helper( (_common_ctx_), NULL, SCPI_ARGS_N_Q, 0 )
- #else
- #define SCPI_PARSE_ARGUMENTS_Q(_common_ctx_) parseArguments_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_Q, SCPI_ARGS_N_Q, (SCPI_ARGS_N_Q) - (SCPI_ARGS_MANDATORY_N_Q) )
- #endif
- #endif
- // ------------------------------------------------------------------------
- // @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST
- // Declares an array of elements for SCPI Character Parameter value allowed list
- // Use this macro together with @processCharacterArgument to interpretate passed parameter.
- // @_name_ - variable name
- // @... - rest arguments is a "strings" that contain allowed values, e.g. "NORMal"
- #define DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST(_name_, ...) static const xArgument_t _name_[] = { __VA_ARGS__, NULL }
- // @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST_EXPORT - the same as @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST but declare
- // global variable that can be imported to another module.
- #define DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST_EXPORT(_name_, ...) const xArgument_t _name_[] = { __VA_ARGS__, NULL }
- // @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST_IMPORT
- // Imports an array of elements for SCPI Character Parameter value allowed list that have been
- // declared with @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST_EXPORT in other module.
- // Use this macro together with @processCharacterArgument to interpretate passed parameter.
- #define DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST_IMPORT(_name_) extern const xArgument_t _name_[];
- #define SCPI_ARGUMENT_CHARACTER_VALUE_TOKEN(_list_,_valueN_,_token_) scpi_argument_value_token(_list_,_valueN_,_token_)
- // ------------------------------------------------------------------------
- // @DECLARE_ARGUMENT_NUMERIC_VALUES_F64
- //
- #define DECLARE_ARGUMENT_NUMERIC_VALUES_F64(_name_, _min_, _max_) static const sNumericRange_t _name_ = { .type = SCPI_NUMERIC_LIMIT_TYPE_F64, .min.f = (_min_), .max.f = (_max_) }
- // @DECLARE_ARGUMENT_NUMERIC_VALUES_F32
- //
- #define DECLARE_ARGUMENT_NUMERIC_VALUES_F32(_name_, _min_, _max_) static const sNumericRange_t _name_ = { .type = SCPI_NUMERIC_LIMIT_TYPE_F32, .min.f = (_min_), .max.f = (_max_) }
- // @DECLARE_ARGUMENT_NUMERIC_VALUES_I64
- //
- #define DECLARE_ARGUMENT_NUMERIC_VALUES_I64(_name_, _min_, _max_) static const sNumericRange_t _name_ = { .type = SCPI_NUMERIC_LIMIT_TYPE_I64, .min.i = (_min_), .max.i = (_max_) }
- // @DECLARE_ARGUMENT_NUMERIC_VALUES_I32
- //
- #define DECLARE_ARGUMENT_NUMERIC_VALUES_I32(_name_, _min_, _max_) static const sNumericRange_t _name_ = { .type = SCPI_NUMERIC_LIMIT_TYPE_I32, .min.i = (_min_), .max.i = (_max_) }
- // @DECLARE_ARGUMENT_NUMERIC_VALUES_I16
- //
- #define DECLARE_ARGUMENT_NUMERIC_VALUES_I16(_name_, _min_, _max_) static const sNumericRange_t _name_ = { .type = SCPI_NUMERIC_LIMIT_TYPE_I16, .min.i = (_min_), .max.i = (_max_) }
- // @DECLARE_ARGUMENT_NUMERIC_VALUES_I8
- //
- #define DECLARE_ARGUMENT_NUMERIC_VALUES_I8(_name_, _min_, _max_) static const sNumericRange_t _name_ = { .type = SCPI_NUMERIC_LIMIT_TYPE_I8 , .min.i = (_min_), .max.i = (_max_) }
- // ------------------------------------------------------------------------
- // Routine @processCharacterArgument call helper
- // * Macro group @SCPI_PROCESS_ARGUMENT_NUMERIC, @SCPI_PROCESS_ARGUMENT_C_NUMERIC, @SCPI_PROCESS_ARGUMENT_Q_NUMERIC
- // Process the numeric argument token and convert to the integer or float representation.
- // The result is the pointer to [sNumericEntry_t] structure, where the result is stored together the
- // value type and conversion error result.
- #if defined(SCPI_ARGS_N)
- #define SCPI_PROCESS_ARGUMENT_C_CHARACTER(_common_ctx_, _list_, _id_) (assert(false), 0)
- #define SCPI_PROCESS_ARGUMENT_Q_CHARACTER(_common_ctx_, _list_, _id_) (assert(false), 0)
- #define SCPI_PROCESS_ARGUMENT_C_NUMERIC(_common_ctx_, _range_, _id_) (assert(false), 0)
- #define SCPI_PROCESS_ARGUMENT_Q_NUMERIC(_common_ctx_, _range_, _id_) (assert(false), 0)
- #if SCPI_ARGS_N == 0
- #define SCPI_PROCESS_ARGUMENT_CHARACTER(_common_ctx_, _list_, _id_) (SCPI_ARGUMENT_CHARACTER_INVALID_ID)
- #define SCPI_PROCESS_ARGUMENT_NUMERIC(_common_ctx_, _range_, _id_) (false)
- #define SCPI_PROCESS_ARGUMENT_NUMERIC(_common_ctx_, _range_, _id_) (false)
- #define SCPI_PROCESS_ARGUMENT_ARRAY(_common_ctx_, _range_, _id_) (SCPI_ARGUMENT_CHARACTER_INVALID_ID)
- #else
- #define SCPI_PROCESS_ARGUMENT_CHARACTER(_common_ctx_, _list_, _id_) processArgument_Character_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES, _list_, _id_ )
- #define SCPI_PROCESS_ARGUMENT_NUMERIC(_common_ctx_, _range_, _id_) processArgument_Numeric_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES, _range_, _id_)
- #define SCPI_PROCESS_ARGUMENT_ARRAY(_common_ctx_, _range_, _id_, _result_arg_, _result_size_) processArgument_Array_helper( (_common_ctx_), _range_, _id_, _result_arg_, _result_size_)
- #endif
- #elif defined(SCPI_ARGS_N_C) && defined(SCPI_ARGS_N_Q)
- #define SCPI_PROCESS_ARGUMENT_CHARACTER(_common_ctx_, _list_, _id_) ((GC(_common_ctx_)->sMessage.bQuery)?\
- SCPI_PROCESS_ARGUMENT_Q_CHARACTER(_common_ctx_,_list_,_id_):\
- SCPI_PROCESS_ARGUMENT_C_CHARACTER(_common_ctx_,_list_,_id_))
- #define SCPI_PROCESS_ARGUMENT_NUMERIC(_common_ctx_, _range_, _id_) ((GC(_common_ctx_)->sMessage.bQuery)?\
- SCPI_PROCESS_ARGUMENT_Q_NUMERIC(_common_ctx_,_range_,_id_):\
- SCPI_PROCESS_ARGUMENT_C_NUMERIC(_common_ctx_,_range_,_id_))
- #if SCPI_ARGS_N_C == 0
- #define SCPI_PROCESS_ARGUMENT_C_CHARACTER(_common_ctx_, _list_, _id_) (SCPI_ARGUMENT_CHARACTER_INVALID_ID)
- #define SCPI_PROCESS_ARGUMENT_C_NUMERIC(_common_ctx_, _range_, _id_) (false)
- #else
- #define SCPI_PROCESS_ARGUMENT_C_CHARACTER(_common_ctx_, _list_, _id_) processArgument_Character_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_C, _list_, _id_ )
- #define SCPI_PROCESS_ARGUMENT_C_NUMERIC(_common_ctx_, _range_, _id_) processArgument_Numeric_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_C, _range_, _id_ )
- #endif
- #if SCPI_ARGS_N_Q == 0
- #define SCPI_PROCESS_ARGUMENT_Q_CHARACTER(_common_ctx_, _list_, _id_) (SCPI_ARGUMENT_CHARACTER_INVALID_ID)
- #define SCPI_PROCESS_ARGUMENT_Q_NUMERIC(_common_ctx_, _range_, _id_) (false)
- #else
- #define SCPI_PROCESS_ARGUMENT_Q_CHARACTER(_common_ctx_, _list_, _id_) processArgument_Character_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_Q, _list_, _id_ )
- #define SCPI_PROCESS_ARGUMENT_Q_NUMERIC(_common_ctx_, _range_, _id_) processArgument_Numeric_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_Q, _range_, _id_ )
- #define SCPI_PROCESS_ARGUMENT_Q_ARRAY(_common_ctx_, _range_, _id_) processArgument_Numeric_helper( (_common_ctx_), SCPI_ARGS_VAR_TYPES_Q, _range_, _id_ )
- #endif
- #endif
- #define SCPI_ARGUMENT_CHARACTER_INVALID_ID (-1)
- // @processArgument_Character_helper
- // Helper function. Used for convenient call of the other helper functions
- // 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 );
- // @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 );
- const sNumericEntry_t * processArgument_Array_helper( void * common_ctx, const sNumericRange_t * range, uint8_t argId, void * result_arg, uint16_t result_size);
- // @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 );
- #endif
|