| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #define SCPI_CORE_STATE__SEARCH4COMMAND_GUARD
- #include "app/scpi/CommandParserStates/search_for_command.h"
- #define SCPI_CORE_PRIVATE // access to 'scpi_core_private.h'
- #include "app/scpi/scpi_core_private.h"
- // =================================================================================
- // @sSearchForCommandHeaderContext_t
- // State's private context typedef
- typedef struct
- {
- bool bKeepParserContext;
- }
- sSearchForCommandHeaderContext_t;
- // =================================================================================
- // @ctx_SearchForCommandHeader
- // State's private context
- sSearchForCommandHeaderContext_t ctx_SearchForCommandHeader;
- // =================================================================================
- // @fsqvbl_SearchForCommandHeader
- // State's virtual table
- static void fsqe_SearchForCommandHeader( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
- static void fsql_SearchForCommandHeader( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
- static const struct fFSeqEntry_t * fsqf_SearchForCommandHeader( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pnext );
- const fFSeqVTable_t fsqvbl_SearchForCommandHeader =
- {
- .f = fsqf_SearchForCommandHeader,
- .enter = fsqe_SearchForCommandHeader,
- .leave = fsql_SearchForCommandHeader
- };
- // =================================================================================
- // @fsqe_SearchForCommandHeader
- // State's enter routine
- static void fsqe_SearchForCommandHeader( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
- {
- sScpiParserContext_t * global_ctx = ctx;
- sSearchForCommandHeaderContext_t * private_ctx = fsq_GetPrivateCtxRef(this);
- private_ctx->bKeepParserContext = false;
- (void)global_ctx;
- }
- // =================================================================================
- // @fsql_SearchForCommandHeader
- // State's leave routine
- static void fsql_SearchForCommandHeader( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
- {
- sScpiParserContext_t * global_ctx = ctx;
- sSearchForCommandHeaderContext_t * private_ctx = fsq_GetPrivateCtxRef(this);
- (void)ctx, (void)private_ctx;
- (void)global_ctx;
- }
- // =================================================================================
- // @fsqf_SearchForCommandHeader
- // State's body routine
- static const struct fFSeqEntry_t * fsqf_SearchForCommandHeader( const struct fFSeqEntry_t * this,
- tFSeqCtx_t ctx,
- const struct fFSeqEntry_t * * pDeferredNext )
- {
- // --------------------------------------------------------------------------
- const struct fFSeqEntry_t * nextstate = NULL; // do not change state, do not call next state
- sScpiParserContext_t * global_ctx = ctx;
- sSearchForCommandHeaderContext_t * private_ctx = fsq_GetPrivateCtxRef(this);
- // --------------------------------------------------------------------------
- // Handle events:
- switch( global_ctx->sEvent.eCode )
- {
- case eScpiEventRestart:
- {
- nextstate = fsq_GetStateById(this,eParserResetState);
- }
- break;
- case eScpiEventWrite: // Handle the WRITE event
- case eScpiEventRead: // Handle the READ event
- {
- // prepare parser context
- if( !prepareParserContext( &(global_ctx->sParser.xCtxObj),
- global_ctx->sMessage.pStr, // pass input buffer
- (ptrdiff_t)global_ctx->sMessage.pEnd - (ptrdiff_t)global_ctx->sMessage.pStr, // pass input buffer size
- global_ctx->sMessage.w_bEndOfMessage, // pass end-of-message by identifying the event
- private_ctx->bKeepParserContext ) )
- {
- global_ctx->sEvent.eStatus = eScpiStatus_invalid;
- }
- else
- {
- // parse the command program header
- global_ctx->sEvent.eStatus = parseCommandProgramHeader( &(global_ctx->sParser.xCtxObj) );
- switch( global_ctx->sEvent.eStatus )
- {
- case eScpiStatus_success:
- {
- // successfully parsed
- // go to next state: eProcessCommandHeader
- nextstate = fsq_GetStateById(this,eProcessCommandHeader);
- }
- break;
- case eScpiStatus_need_data:
- {
- private_ctx->bKeepParserContext = true;
- (void)nextstate; // keep NULL, do not change state
- }
- break;
-
- case eScpiStatus_failed:
- case eScpiStatus_invalid:
- {
- const char * start = NULL;
- const char * stop = NULL;
- uint8_t type;
-
- if( getParsedEntityDetails( &(global_ctx->sParser.xCtxObj), (const void**)&start, (const void**)&stop, &type ) )
- {
- // check for empty-line command string
- if( scpi_isnl(*start) )
- {
- // requested string is an empty-line command string, and the parser error is obviously can not be generated
- // But it is required to enter the error state because only the error state is legal next state.
- // It is impossible to restart the parser because maybe there are some data in output buffer to sent.
- }
- else
- {
- // Check if the last character is '\n' and cut it off
- if( scpi_isnl((*(stop-1))) && (0 < (stop - start)) ) stop--;
- int32_t error;
- const char * msg = getParserError( &(global_ctx->sParser.xCtxObj), &error );
- if( NULL == msg )
- {
- error = SCPI_ERROR_COMMAND_HEADER;
- msg = SCPI_ERROR_COMMAND_HEADER_MSG;
- }
- fsq_RaiseError( error, msg, start, stop );
- }
- }
- else
- {
- #if 0
- int32_t error;
- const char * msg = getParserError( &(global_ctx->sParser.xCtxObj), &error );
- if( NULL == msg )
- {
- error = SCPI_ERROR_COMMAND_HEADER;
- msg = SCPI_ERROR_COMMAND_HEADER_MSG;
- }
- fsq_RaiseError( error, msg, NULL, 0 );
- #else
- assert( false );
- #endif
- }
-
- nextstate = fsq_GetStateById(this,eHandleError); // enter the error state
- }
- break;
-
- }
- }
- }
- break;
- case eScpiEventError: // Transport error.
- {
- // Enter error state
- nextstate = fsq_GetStateById(this,eHandleError); // enter the error state
- }
- break;
- }
- (void)global_ctx->sEvent.eCode; // keep event code, it will be reused in @eProcessProgramData state
- return nextstate;
- }
|