Refactor private lexer and private parser API
| | |
| | | #include "fifo_private.h" |
| | | |
| | | /* basic FIFO */ |
| | | static fifo_t local_error_queue; |
| | | static scpi_fifo_t local_error_queue; |
| | | |
| | | |
| | | |
| | |
| | | |
| | | /* basic FIFO */ |
| | | context->error_queue = (scpi_error_queue_t)&local_error_queue; |
| | | fifo_init((fifo_t *)context->error_queue); |
| | | fifo_init((scpi_fifo_t *)context->error_queue); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_clear((fifo_t *)context->error_queue); |
| | | fifo_clear((scpi_fifo_t *)context->error_queue); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_remove((fifo_t *)context->error_queue, &result); |
| | | fifo_remove((scpi_fifo_t *)context->error_queue, &result); |
| | | |
| | | return result; |
| | | } |
| | |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_count((fifo_t *)context->error_queue, &result); |
| | | fifo_count((scpi_fifo_t *)context->error_queue, &result); |
| | | |
| | | return result; |
| | | } |
| | |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_add((fifo_t *)context->error_queue, err); |
| | | fifo_add((scpi_fifo_t *)context->error_queue, err); |
| | | } |
| | | |
| | | struct error_reg { |
| | |
| | | |
| | | #include "fifo_private.h" |
| | | |
| | | void fifo_init(fifo_t * fifo) { |
| | | void fifo_init(scpi_fifo_t * fifo) { |
| | | fifo->wr = 0; |
| | | fifo->rd = 0; |
| | | fifo->size = FIFO_SIZE; |
| | | } |
| | | |
| | | void fifo_clear(fifo_t * fifo) { |
| | | void fifo_clear(scpi_fifo_t * fifo) { |
| | | fifo->wr = 0; |
| | | fifo->rd = 0; |
| | | } |
| | | |
| | | scpi_bool_t fifo_add(fifo_t * fifo, int16_t value) { |
| | | scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t value) { |
| | | /* FIFO full? */ |
| | | if (fifo->wr == ((fifo->rd + fifo->size) % (fifo->size + 1))) { |
| | | fifo_remove(fifo, NULL); |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | scpi_bool_t fifo_remove(fifo_t * fifo, int16_t * value) { |
| | | scpi_bool_t fifo_remove(scpi_fifo_t * fifo, int16_t * value) { |
| | | /* FIFO empty? */ |
| | | if (fifo->wr == fifo->rd) { |
| | | return FALSE; |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | scpi_bool_t fifo_count(fifo_t * fifo, int16_t * value) { |
| | | scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) { |
| | | *value = fifo->wr - fifo->rd; |
| | | if (*value < 0) { |
| | | *value += (fifo->size + 1); |
| | |
| | | |
| | | #define FIFO_SIZE 16 |
| | | |
| | | struct _fifo_t { |
| | | struct _scpi_fifo_t { |
| | | int16_t wr; |
| | | int16_t rd; |
| | | int16_t size; |
| | | int16_t data[FIFO_SIZE]; |
| | | }; |
| | | typedef struct _fifo_t fifo_t; |
| | | typedef struct _scpi_fifo_t scpi_fifo_t; |
| | | |
| | | void fifo_init(fifo_t * fifo) LOCAL; |
| | | void fifo_clear(fifo_t * fifo) LOCAL; |
| | | scpi_bool_t fifo_add(fifo_t * fifo, int16_t value) LOCAL; |
| | | scpi_bool_t fifo_remove(fifo_t * fifo, int16_t * value) LOCAL; |
| | | scpi_bool_t fifo_count(fifo_t * fifo, int16_t * value) LOCAL; |
| | | void fifo_init(scpi_fifo_t * fifo) LOCAL; |
| | | void fifo_clear(scpi_fifo_t * fifo) LOCAL; |
| | | scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t value) LOCAL; |
| | | scpi_bool_t fifo_remove(scpi_fifo_t * fifo, int16_t * value) LOCAL; |
| | | scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) LOCAL; |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | int lexIsEos(lex_state_t * state) { |
| | | int scpiLex_IsEos(lex_state_t * state) { |
| | | return iseos(state); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /* tokens */ |
| | | int lexWhiteSpace(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | skipWs(state); |
| | |
| | | } |
| | | } |
| | | |
| | | int lexProgramHeader(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) { |
| | | int res; |
| | | token->ptr = state->pos; |
| | | token->type = TokUnknown; |
| | |
| | | } |
| | | |
| | | /* 7.7.1 <CHARACTER PROGRAM DATA> */ |
| | | int lexCharacterProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | if (!iseos(state) && isalpha(state->pos[0])) { |
| | |
| | | return someNumbers; |
| | | } |
| | | |
| | | int lexDecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | const char * rollback; |
| | | token->ptr = state->pos; |
| | | |
| | |
| | | } |
| | | |
| | | /* 7.7.3 <SUFFIX PROGRAM DATA> */ |
| | | int lexSuffixProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | skipChr(state, '/'); |
| | |
| | | return someNumbers; |
| | | } |
| | | |
| | | int lexNondecimalNumericData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | int someNumbers = 0; |
| | | if (skipChr(state, '#')) { |
| | |
| | | skipQuoteProgramData(state, '\''); |
| | | } |
| | | |
| | | int lexStringProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | if (!iseos(state)) { |
| | |
| | | return isdigit(c) && (c != '0'); |
| | | } |
| | | |
| | | int lexArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int i; |
| | | int j = 0; |
| | | const char * ptr = state->pos; |
| | |
| | | |
| | | // TODO: 7.7.7.2-2 recursive - any program data |
| | | |
| | | int lexProgramExpression(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | if (!iseos(state) && ischr(state, '(')) { |
| | |
| | | return token->len; |
| | | } |
| | | |
| | | int lexComma(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | if (skipChr(state, ',')) { |
| | |
| | | return token->len; |
| | | } |
| | | |
| | | int lexSemicolon(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | if (skipChr(state, ';')) { |
| | |
| | | return token->len; |
| | | } |
| | | |
| | | int lexNewLine(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) { |
| | | token->ptr = state->pos; |
| | | |
| | | skipChr(state, '\r'); |
| | |
| | | extern "C" { |
| | | #endif |
| | | |
| | | int lexIsEos(lex_state_t * state) LOCAL; |
| | | int lexWhiteSpace(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexProgramHeader(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexCharacterProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexDecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexSuffixProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexNondecimalNumericData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexStringProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexProgramExpression(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexComma(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexSemicolon(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int lexNewLine(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_IsEos(lex_state_t * state) LOCAL; |
| | | int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | while (1) { |
| | | result = 0; |
| | | |
| | | r = detectProgramMessageUnit(state, data, len); |
| | | r = scpiParser_detectProgramMessageUnit(state, data, len); |
| | | |
| | | if (state->programHeader.type == TokInvalid) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_INVALID_CHARACTER); |
| | |
| | | |
| | | |
| | | while (1) { |
| | | cmdlen = detectProgramMessageUnit(&context->parser_state, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen); |
| | | cmdlen = scpiParser_detectProgramMessageUnit(&context->parser_state, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen); |
| | | totcmdlen += cmdlen; |
| | | if (context->parser_state.termination == PmutNewLine) break; |
| | | if (context->parser_state.programHeader.type == TokUnknown) break; |
| | |
| | | return FALSE; |
| | | } |
| | | if (context->input_count != 0) { |
| | | lexComma(state, &token); |
| | | scpiLex_Comma(state, &token); |
| | | if (token.type != TokComma) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SEPARATOR); |
| | | return FALSE; |
| | |
| | | |
| | | context->input_count++; |
| | | |
| | | parseProgramData(&context->param_list.lex_state, &token); |
| | | scpiParser_parseProgramData(&context->param_list.lex_state, &token); |
| | | |
| | | parameter->type = token.type; |
| | | parameter->data.ptr = token.ptr; |
| | |
| | | return result; |
| | | } |
| | | |
| | | int parseProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) { |
| | | scpi_token_t tmp; |
| | | int result = 0; |
| | | int wsLen; |
| | | int suffixLen; |
| | | int realLen = 0; |
| | | realLen += lexWhiteSpace(state, &tmp); |
| | | realLen += scpiLex_WhiteSpace(state, &tmp); |
| | | |
| | | if (result == 0) result = lexNondecimalNumericData(state, token); |
| | | if (result == 0) result = lexCharacterProgramData(state, token); |
| | | if (result == 0) result = scpiLex_NondecimalNumericData(state, token); |
| | | if (result == 0) result = scpiLex_CharacterProgramData(state, token); |
| | | if (result == 0) { |
| | | result = lexDecimalNumericProgramData(state, token); |
| | | result = scpiLex_DecimalNumericProgramData(state, token); |
| | | if (result != 0) { |
| | | wsLen = lexWhiteSpace(state, &tmp); |
| | | suffixLen = lexSuffixProgramData(state, &tmp); |
| | | wsLen = scpiLex_WhiteSpace(state, &tmp); |
| | | suffixLen = scpiLex_SuffixProgramData(state, &tmp); |
| | | if (suffixLen > 0) { |
| | | token->len += wsLen + suffixLen; |
| | | token->type = TokDecimalNumericProgramDataWithSuffix; |
| | |
| | | } |
| | | } |
| | | |
| | | if (result == 0) result = lexStringProgramData(state, token); |
| | | if (result == 0) result = lexArbitraryBlockProgramData(state, token); |
| | | if (result == 0) result = lexProgramExpression(state, token); |
| | | if (result == 0) result = scpiLex_StringProgramData(state, token); |
| | | if (result == 0) result = scpiLex_ArbitraryBlockProgramData(state, token); |
| | | if (result == 0) result = scpiLex_ProgramExpression(state, token); |
| | | |
| | | realLen += lexWhiteSpace(state, &tmp); |
| | | realLen += scpiLex_WhiteSpace(state, &tmp); |
| | | |
| | | return result + realLen; |
| | | } |
| | | |
| | | int parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) { |
| | | int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) { |
| | | |
| | | int result; |
| | | scpi_token_t tmp; |
| | |
| | | token->ptr = state->pos; |
| | | |
| | | |
| | | for (result = 1; result != 0; result = lexComma(state, &tmp)) { |
| | | for (result = 1; result != 0; result = scpiLex_Comma(state, &tmp)) { |
| | | token->len += result; |
| | | |
| | | if (result == 0) { |
| | |
| | | break; |
| | | } |
| | | |
| | | result = parseProgramData(state, &tmp); |
| | | result = scpiParser_parseProgramData(state, &tmp); |
| | | if (tmp.type != TokUnknown) { |
| | | token->len += result; |
| | | } else { |
| | |
| | | token->type = TokUnknown; |
| | | } |
| | | |
| | | int detectProgramMessageUnit(scpi_parser_state_t * state, const char * buffer, int len) { |
| | | int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, const char * buffer, int len) { |
| | | lex_state_t lex_state; |
| | | scpi_token_t tmp; |
| | | int result = 0; |
| | |
| | | state->numberOfParameters = 0; |
| | | |
| | | /* ignore whitespace at the begginig */ |
| | | lexWhiteSpace(&lex_state, &tmp); |
| | | scpiLex_WhiteSpace(&lex_state, &tmp); |
| | | |
| | | if (lexProgramHeader(&lex_state, &state->programHeader) >= 0) { |
| | | if (lexWhiteSpace(&lex_state, &tmp) > 0) { |
| | | parseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters); |
| | | if (scpiLex_ProgramHeader(&lex_state, &state->programHeader) >= 0) { |
| | | if (scpiLex_WhiteSpace(&lex_state, &tmp) > 0) { |
| | | scpiParser_parseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters); |
| | | } else { |
| | | invalidateToken(&state->programData, lex_state.pos); |
| | | } |
| | |
| | | invalidateToken(&state->programData, lex_state.buffer); |
| | | } |
| | | |
| | | if (result == 0) result = lexNewLine(&lex_state, &tmp); |
| | | if (result == 0) result = lexSemicolon(&lex_state, &tmp); |
| | | if (result == 0) result = scpiLex_NewLine(&lex_state, &tmp); |
| | | if (result == 0) result = scpiLex_Semicolon(&lex_state, &tmp); |
| | | |
| | | if (!lexIsEos(&lex_state) && (result == 0)) { |
| | | if (!scpiLex_IsEos(&lex_state) && (result == 0)) { |
| | | lex_state.pos++; |
| | | |
| | | state->programHeader.len = 1; |
| | |
| | | extern "C" { |
| | | #endif |
| | | |
| | | int parseProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) LOCAL; |
| | | int detectProgramMessageUnit(scpi_parser_state_t * state, const char * buffer, int len) LOCAL; |
| | | int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; |
| | | int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) LOCAL; |
| | | int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, const char * buffer, int len) LOCAL; |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | result = TRUE; |
| | | break; |
| | | case TokDecimalNumericProgramDataWithSuffix: |
| | | lexDecimalNumericProgramData(&state, &token); |
| | | lexWhiteSpace(&state, &token); |
| | | lexSuffixProgramData(&state, &token); |
| | | scpiLex_DecimalNumericProgramData(&state, &token); |
| | | scpiLex_WhiteSpace(&state, &token); |
| | | scpiLex_SuffixProgramData(&state, &token); |
| | | |
| | | result = transformNumber(context, token.ptr, token.len, ¶m.number); |
| | | break; |
| | | case TokProgramMnemonic: |
| | | lexWhiteSpace(&state, &token); |
| | | lexCharacterProgramData(&state, &token); |
| | | scpiLex_WhiteSpace(&state, &token); |
| | | scpiLex_CharacterProgramData(&state, &token); |
| | | |
| | | /* convert string to special number type */ |
| | | result = translateSpecialNumber(context->special_numbers, token.ptr, token.len, ¶m.number); |
| | |
| | | } |
| | | |
| | | void testFifo() { |
| | | fifo_t fifo; |
| | | scpi_fifo_t fifo; |
| | | fifo_init(&fifo); |
| | | int16_t value; |
| | | |
| | |
| | | |
| | | |
| | | void testWhiteSpace(void) { |
| | | TEST_TOKEN(" \t MEAS", lexWhiteSpace, 0, 4, TokWhiteSpace); |
| | | TEST_TOKEN("MEAS", lexWhiteSpace, 0, 0, TokUnknown); |
| | | TEST_TOKEN(" \t MEAS", scpiLex_WhiteSpace, 0, 4, TokWhiteSpace); |
| | | TEST_TOKEN("MEAS", scpiLex_WhiteSpace, 0, 0, TokUnknown); |
| | | } |
| | | |
| | | void testNondecimal(void) { |
| | | TEST_TOKEN("#H123fe5A", lexNondecimalNumericData, 2, 7, TokHexnum); |
| | | TEST_TOKEN("#B0111010101", lexNondecimalNumericData, 2, 10, TokBinnum); |
| | | TEST_TOKEN("#Q125725433", lexNondecimalNumericData, 2, 9, TokOctnum); |
| | | TEST_TOKEN("#H123fe5A", scpiLex_NondecimalNumericData, 2, 7, TokHexnum); |
| | | TEST_TOKEN("#B0111010101", scpiLex_NondecimalNumericData, 2, 10, TokBinnum); |
| | | TEST_TOKEN("#Q125725433", scpiLex_NondecimalNumericData, 2, 9, TokOctnum); |
| | | } |
| | | |
| | | void testCharacterProgramData(void) { |
| | | TEST_TOKEN("abc_213as564", lexCharacterProgramData, 0, 12, TokProgramMnemonic); |
| | | TEST_TOKEN("abc_213as564 , ", lexCharacterProgramData, 0, 12, TokProgramMnemonic); |
| | | TEST_TOKEN("abc_213as564", scpiLex_CharacterProgramData, 0, 12, TokProgramMnemonic); |
| | | TEST_TOKEN("abc_213as564 , ", scpiLex_CharacterProgramData, 0, 12, TokProgramMnemonic); |
| | | } |
| | | |
| | | void testDecimal(void) { |
| | | TEST_TOKEN("10", lexDecimalNumericProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("10 , ", lexDecimalNumericProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-10.5 , ", lexDecimalNumericProgramData, 0, 5, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("+.5 , ", lexDecimalNumericProgramData, 0, 3, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-. , ", lexDecimalNumericProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("-1 e , ", lexDecimalNumericProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-1 e 3, ", lexDecimalNumericProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("1.5E12", lexDecimalNumericProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("10", scpiLex_DecimalNumericProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("10 , ", scpiLex_DecimalNumericProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-10.5 , ", scpiLex_DecimalNumericProgramData, 0, 5, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("+.5 , ", scpiLex_DecimalNumericProgramData, 0, 3, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-. , ", scpiLex_DecimalNumericProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("-1 e , ", scpiLex_DecimalNumericProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-1 e 3, ", scpiLex_DecimalNumericProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("1.5E12", scpiLex_DecimalNumericProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | } |
| | | |
| | | void testSuffix(void) { |
| | | TEST_TOKEN("A/V , ", lexSuffixProgramData, 0, 3, TokSuffixProgramData); |
| | | TEST_TOKEN("mA.h", lexSuffixProgramData, 0, 4, TokSuffixProgramData); |
| | | TEST_TOKEN("A/V , ", scpiLex_SuffixProgramData, 0, 3, TokSuffixProgramData); |
| | | TEST_TOKEN("mA.h", scpiLex_SuffixProgramData, 0, 4, TokSuffixProgramData); |
| | | } |
| | | |
| | | void testProgramHeader(void) { |
| | | TEST_TOKEN("*IDN? ", lexProgramHeader, 0, 5, TokCommonQueryProgramHeader); |
| | | TEST_TOKEN("*RST ", lexProgramHeader, 0, 4, TokCommonProgramHeader); |
| | | TEST_TOKEN("*?; ", lexProgramHeader, 0, 1, TokIncompleteCommonProgramHeader); |
| | | TEST_TOKEN(":*IDN?; ", lexProgramHeader, 0, 1, TokIncompleteCompoundProgramHeader); |
| | | TEST_TOKEN("MEAS:VOLT:DC? ", lexProgramHeader, 0, 13, TokCompoundQueryProgramHeader); |
| | | TEST_TOKEN("CONF:VOLT:DC ", lexProgramHeader, 0, 12, TokCompoundProgramHeader); |
| | | TEST_TOKEN(":MEAS:VOLT:DC? ", lexProgramHeader, 0, 14, TokCompoundQueryProgramHeader); |
| | | TEST_TOKEN(":MEAS::VOLT:DC? ", lexProgramHeader, 0, 6, TokIncompleteCompoundProgramHeader); |
| | | TEST_TOKEN("*IDN?", lexProgramHeader, 0, 5, TokCommonQueryProgramHeader); |
| | | TEST_TOKEN("*RST", lexProgramHeader, 0, 4, TokCommonProgramHeader); |
| | | TEST_TOKEN("CONF:VOLT:DC", lexProgramHeader, 0, 12, TokCompoundProgramHeader); |
| | | TEST_TOKEN("]]", lexProgramHeader, 0, 0, TokUnknown); |
| | | TEST_TOKEN("*IDN? ", scpiLex_ProgramHeader, 0, 5, TokCommonQueryProgramHeader); |
| | | TEST_TOKEN("*RST ", scpiLex_ProgramHeader, 0, 4, TokCommonProgramHeader); |
| | | TEST_TOKEN("*?; ", scpiLex_ProgramHeader, 0, 1, TokIncompleteCommonProgramHeader); |
| | | TEST_TOKEN(":*IDN?; ", scpiLex_ProgramHeader, 0, 1, TokIncompleteCompoundProgramHeader); |
| | | TEST_TOKEN("MEAS:VOLT:DC? ", scpiLex_ProgramHeader, 0, 13, TokCompoundQueryProgramHeader); |
| | | TEST_TOKEN("CONF:VOLT:DC ", scpiLex_ProgramHeader, 0, 12, TokCompoundProgramHeader); |
| | | TEST_TOKEN(":MEAS:VOLT:DC? ", scpiLex_ProgramHeader, 0, 14, TokCompoundQueryProgramHeader); |
| | | TEST_TOKEN(":MEAS::VOLT:DC? ", scpiLex_ProgramHeader, 0, 6, TokIncompleteCompoundProgramHeader); |
| | | TEST_TOKEN("*IDN?", scpiLex_ProgramHeader, 0, 5, TokCommonQueryProgramHeader); |
| | | TEST_TOKEN("*RST", scpiLex_ProgramHeader, 0, 4, TokCommonProgramHeader); |
| | | TEST_TOKEN("CONF:VOLT:DC", scpiLex_ProgramHeader, 0, 12, TokCompoundProgramHeader); |
| | | TEST_TOKEN("]]", scpiLex_ProgramHeader, 0, 0, TokUnknown); |
| | | } |
| | | |
| | | void testArbitraryBlock(void) { |
| | | TEST_TOKEN("#12AB", lexArbitraryBlockProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#12AB, ", lexArbitraryBlockProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#13AB", lexArbitraryBlockProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("#12\r\n, ", lexArbitraryBlockProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#02AB, ", lexArbitraryBlockProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("#12AB", scpiLex_ArbitraryBlockProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#12AB, ", scpiLex_ArbitraryBlockProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#13AB", scpiLex_ArbitraryBlockProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("#12\r\n, ", scpiLex_ArbitraryBlockProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#02AB, ", scpiLex_ArbitraryBlockProgramData, 0, 0, TokUnknown); |
| | | } |
| | | |
| | | void testExpression(void) { |
| | | TEST_TOKEN("( 1 + 2 )", lexProgramExpression, 0, 9, TokProgramExpression); |
| | | TEST_TOKEN("( 1 + 2 ) , ", lexProgramExpression, 0, 9, TokProgramExpression); |
| | | TEST_TOKEN("( 1 + 2 , ", lexProgramExpression, 0, 0, TokUnknown); |
| | | TEST_TOKEN("( 1 + 2 )", scpiLex_ProgramExpression, 0, 9, TokProgramExpression); |
| | | TEST_TOKEN("( 1 + 2 ) , ", scpiLex_ProgramExpression, 0, 9, TokProgramExpression); |
| | | TEST_TOKEN("( 1 + 2 , ", scpiLex_ProgramExpression, 0, 0, TokUnknown); |
| | | } |
| | | |
| | | void testString(void) { |
| | | TEST_TOKEN("\"ahoj\"", lexStringProgramData, 1, 4, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("\"ahoj\" ", lexStringProgramData, 1, 4, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj' ", lexStringProgramData, 1, 4, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj ", lexStringProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("'ah''oj' ", lexStringProgramData, 1, 6, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ah\"oj' ", lexStringProgramData, 1, 5, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("\"ah\"\"oj\" ", lexStringProgramData, 1, 6, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("\"ahoj\"", scpiLex_StringProgramData, 1, 4, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("\"ahoj\" ", scpiLex_StringProgramData, 1, 4, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj' ", scpiLex_StringProgramData, 1, 4, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj ", scpiLex_StringProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("'ah''oj' ", scpiLex_StringProgramData, 1, 6, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ah\"oj' ", scpiLex_StringProgramData, 1, 5, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("\"ah\"\"oj\" ", scpiLex_StringProgramData, 1, 6, TokDoubleQuoteProgramData); |
| | | } |
| | | |
| | | void testProgramData(void) { |
| | | TEST_TOKEN("#H123fe5A", parseProgramData, 2, 7, TokHexnum); |
| | | TEST_TOKEN(" #H123fe5A ", parseProgramData, 4, 7, TokHexnum); |
| | | TEST_TOKEN("#B0111010101", parseProgramData, 2, 10, TokBinnum); |
| | | TEST_TOKEN("#Q125725433", parseProgramData, 2, 9, TokOctnum); |
| | | TEST_TOKEN("#H123fe5A", scpiParser_parseProgramData, 2, 7, TokHexnum); |
| | | TEST_TOKEN(" #H123fe5A ", scpiParser_parseProgramData, 4, 7, TokHexnum); |
| | | TEST_TOKEN("#B0111010101", scpiParser_parseProgramData, 2, 10, TokBinnum); |
| | | TEST_TOKEN("#Q125725433", scpiParser_parseProgramData, 2, 9, TokOctnum); |
| | | |
| | | TEST_TOKEN("10", parseProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("10 , ", parseProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-10.5 , ", parseProgramData, 0, 5, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("+.5 , ", parseProgramData, 0, 3, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-. , ", parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("-1 e , ", parseProgramData, 0, 4, TokDecimalNumericProgramDataWithSuffix); |
| | | TEST_TOKEN("-1 e 3, ", parseProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("1.5E12", parseProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("10", scpiParser_parseProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("10 , ", scpiParser_parseProgramData, 0, 2, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-10.5 , ", scpiParser_parseProgramData, 0, 5, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("+.5 , ", scpiParser_parseProgramData, 0, 3, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("-. , ", scpiParser_parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("-1 e , ", scpiParser_parseProgramData, 0, 4, TokDecimalNumericProgramDataWithSuffix); |
| | | TEST_TOKEN("-1 e 3, ", scpiParser_parseProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | TEST_TOKEN("1.5E12", scpiParser_parseProgramData, 0, 6, TokDecimalNumericProgramData); |
| | | |
| | | TEST_TOKEN("#12AB", parseProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#12AB, ", parseProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#13AB", parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("#12\r\n, ", parseProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#02AB, ", parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("#12AB", scpiParser_parseProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#12AB, ", scpiParser_parseProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#13AB", scpiParser_parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("#12\r\n, ", scpiParser_parseProgramData, 3, 2, TokArbitraryBlockProgramData); |
| | | TEST_TOKEN("#02AB, ", scpiParser_parseProgramData, 0, 0, TokUnknown); |
| | | |
| | | TEST_TOKEN("( 1 + 2 ) , ", parseProgramData, 0, 9, TokProgramExpression); |
| | | TEST_TOKEN("( 1 + 2 , ", parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("( 1 + 2 ) , ", scpiParser_parseProgramData, 0, 9, TokProgramExpression); |
| | | TEST_TOKEN("( 1 + 2 , ", scpiParser_parseProgramData, 0, 0, TokUnknown); |
| | | |
| | | TEST_TOKEN("\"ahoj\" ", parseProgramData, 1, 4, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj' ", parseProgramData, 1, 4, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj ", parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("'ah''oj' ", parseProgramData, 1, 6, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ah\"oj' ", parseProgramData, 1, 5, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("\"ah\"\"oj\" ", parseProgramData, 1, 6, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("\"ahoj\" ", scpiParser_parseProgramData, 1, 4, TokDoubleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj' ", scpiParser_parseProgramData, 1, 4, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ahoj ", scpiParser_parseProgramData, 0, 0, TokUnknown); |
| | | TEST_TOKEN("'ah''oj' ", scpiParser_parseProgramData, 1, 6, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("'ah\"oj' ", scpiParser_parseProgramData, 1, 5, TokSingleQuoteProgramData); |
| | | TEST_TOKEN("\"ah\"\"oj\" ", scpiParser_parseProgramData, 1, 6, TokDoubleQuoteProgramData); |
| | | |
| | | TEST_TOKEN("abc_213as564 , ", lexCharacterProgramData, 0, 12, TokProgramMnemonic); |
| | | TEST_TOKEN("abc_213as564 , ", scpiLex_CharacterProgramData, 0, 12, TokProgramMnemonic); |
| | | |
| | | TEST_TOKEN("1.5E12 V", parseProgramData, 0, 8, TokDecimalNumericProgramDataWithSuffix); |
| | | TEST_TOKEN("1.5E12 V", scpiParser_parseProgramData, 0, 8, TokDecimalNumericProgramDataWithSuffix); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | void testAllProgramData(void) { |
| | | TEST_ALL_TOKEN("1.5E12 V", parseAllProgramData, 0, 8, TokAllProgramData, 1); |
| | | TEST_ALL_TOKEN("1.5E12 V, abc_213as564, 10, #H123fe5A", parseAllProgramData, 0, 37, TokAllProgramData, 4); |
| | | TEST_ALL_TOKEN("1.5E12 V, ", parseAllProgramData, 0, 0, TokUnknown, -1); |
| | | TEST_ALL_TOKEN("#12\r\n, 1.5E12 V", parseAllProgramData, 0, 15, TokAllProgramData, 2); |
| | | TEST_ALL_TOKEN(" ( 1 + 2 ) ,#12\r\n, 1.5E12 V", parseAllProgramData, 0, 27, TokAllProgramData, 3); |
| | | TEST_ALL_TOKEN("\"ahoj\" , #12AB", parseAllProgramData, 0, 14, TokAllProgramData, 2); |
| | | TEST_ALL_TOKEN("1.5E12 V", scpiParser_parseAllProgramData, 0, 8, TokAllProgramData, 1); |
| | | TEST_ALL_TOKEN("1.5E12 V, abc_213as564, 10, #H123fe5A", scpiParser_parseAllProgramData, 0, 37, TokAllProgramData, 4); |
| | | TEST_ALL_TOKEN("1.5E12 V, ", scpiParser_parseAllProgramData, 0, 0, TokUnknown, -1); |
| | | TEST_ALL_TOKEN("#12\r\n, 1.5E12 V", scpiParser_parseAllProgramData, 0, 15, TokAllProgramData, 2); |
| | | TEST_ALL_TOKEN(" ( 1 + 2 ) ,#12\r\n, 1.5E12 V", scpiParser_parseAllProgramData, 0, 27, TokAllProgramData, 3); |
| | | TEST_ALL_TOKEN("\"ahoj\" , #12AB", scpiParser_parseAllProgramData, 0, 14, TokAllProgramData, 2); |
| | | } |
| | | |
| | | |
| | |
| | | const char * str = s; \ |
| | | scpi_parser_state_t state; \ |
| | | int result; \ |
| | | result = detectProgramMessageUnit(&state, str, strlen(str)); \ |
| | | result = scpiParser_detectProgramMessageUnit(&state, str, strlen(str)); \ |
| | | CU_ASSERT_EQUAL(state.programHeader.ptr, str + h); \ |
| | | CU_ASSERT_EQUAL(state.programHeader.len, hl); \ |
| | | CU_ASSERT_EQUAL(state.programHeader.type, ht); \ |
| | |
| | | } |
| | | |
| | | void testBoolParameter(void) { |
| | | TEST_TOKEN(" 1", parseProgramData, 1, 1, TokDecimalNumericProgramData); |
| | | TEST_TOKEN(" 0", parseProgramData, 1, 1, TokDecimalNumericProgramData); |
| | | TEST_TOKEN(" ON", parseProgramData, 1, 2, TokProgramMnemonic); |
| | | TEST_TOKEN("OFF ", parseProgramData, 0, 3, TokProgramMnemonic); |
| | | TEST_TOKEN(" 1", scpiParser_parseProgramData, 1, 1, TokDecimalNumericProgramData); |
| | | TEST_TOKEN(" 0", scpiParser_parseProgramData, 1, 1, TokDecimalNumericProgramData); |
| | | TEST_TOKEN(" ON", scpiParser_parseProgramData, 1, 2, TokProgramMnemonic); |
| | | TEST_TOKEN("OFF ", scpiParser_parseProgramData, 0, 3, TokProgramMnemonic); |
| | | |
| | | // TODO: finish bool test |
| | | } |