From 6bc097eba30c30c45bd7c89d97991428b53660dc Mon Sep 17 00:00:00 2001 From: Jan Breuer <jan.breuer@jaybee.cz> Date: 周三, 24 9月 2014 22:50:27 +0800 Subject: [PATCH] Update units.c - add support for INFinity --- libscpi/src/parser.c | 170 +++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 125 insertions(+), 45 deletions(-) diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 99de301..42f0231 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -39,9 +39,10 @@ #include "scpi/config.h" #include "scpi/parser.h" -#include "scpi/lexer.h" -#include "utils.h" +#include "parser_private.h" +#include "lexer_private.h" #include "scpi/error.h" +#include "scpi/constants.h" /** * Write data to SCPI output @@ -74,7 +75,7 @@ */ static size_t writeDelimiter(scpi_t * context) { if (context->output_count > 0) { - return writeData(context, ", ", 2); + return writeData(context, ",", 2); } else { return 0; } @@ -130,7 +131,7 @@ * @param context * @result TRUE if context->paramlist is filled with correct values */ -static bool_t findCommandHeader(scpi_t * context, const char * header, int len) { +static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) { int32_t i; const scpi_command_t * cmd; @@ -165,9 +166,11 @@ while (1) { result = 0; - r = SCPI_DetectProgramMessageUnit(state, data, len); + r = detectProgramMessageUnit(state, data, len); - if (state->programHeader.len > 0) { + if (state->programHeader.type == TokInvalid) { + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_CHARACTER); + } else if (state->programHeader.len > 0) { if (findCommandHeader(context, state->programHeader.ptr, state->programHeader.len)) { context->param_list.lex_state.buffer = state->programData.ptr; @@ -201,6 +204,19 @@ * @param interface */ void SCPI_Init(scpi_t * context) { + if (context->idn[0] == NULL) { + context->idn[0] = SCPI_DEFAULT_1_MANUFACTURE; + } + if (context->idn[1] == NULL) { + context->idn[1] = SCPI_DEFAULT_2_MODEL; + } + if (context->idn[2] == NULL) { + context->idn[2] = SCPI_DEFAULT_3; + } + if (context->idn[3] == NULL) { + context->idn[3] = SCPI_DEFAULT_4_REVISION; + } + context->buffer.position = 0; SCPI_ErrorInit(context); } @@ -237,7 +253,7 @@ while (1) { - cmdlen = SCPI_DetectProgramMessageUnit(&context->parser_state, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen); + cmdlen = 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; @@ -340,9 +356,20 @@ return result; } +/** + * Write boolean value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val) { + return SCPI_ResultIntBase(context, val ? 1 : 0, 10); +} + + /* parsing parameters */ -bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, bool_t mandatory) { +scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory) { token_t token; lex_state_t * state; int32_t value; @@ -367,7 +394,7 @@ return FALSE; } if (context->input_count != 0) { - SCPI_LexComma(state, &token); + lexComma(state, &token); if (token.type != TokComma) { SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SEPARATOR); return FALSE; @@ -376,7 +403,7 @@ context->input_count++; - SCPI_ParseProgramData(&context->param_list.lex_state, &token); + parseProgramData(&context->param_list.lex_state, &token); parameter->type = token.type; parameter->data.ptr = token.ptr; @@ -420,7 +447,7 @@ parameter->type = TokUnknown; parameter->data.ptr = NULL; parameter->data.len = 0; - SCPI_ErrorPush(context, SCPI_ERROR_UNKNOWN_PARAMETER); + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_STRING_DATA); return FALSE; } } @@ -434,7 +461,7 @@ case TokDecimalNumericProgramDataWithSuffix: return parameter->number.value; default: - SCPI_ErrorPush(context, SCPI_ERROR_INVALID_PARAMETER); + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); return 0; } } @@ -448,21 +475,67 @@ *len = parameter->data.len; } -int SCPI_ParseProgramData(lex_state_t * state, token_t * token) { +/* SCPI-99 7.3 Boolean Program Data */ +scpi_bool_t SCPI_ParamGetBoolVal(scpi_t * context, scpi_parameter_t * parameter) { + switch (parameter->type) { + case TokDecimalNumericProgramData: + return parameter->number.value ? 1 : 0; + case TokProgramMnemonic: + if (compareStr("ON", 2, parameter->data.ptr, parameter->data.len)) { + return TRUE; + } else if (compareStr("OFF", 3, parameter->data.ptr, parameter->data.len)) { + return FALSE; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + return FALSE; + } + default: + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + return FALSE; + } +} + +/** + * Get choice parameter + */ +int32_t SCPI_ParamGetChoiceVal(scpi_t * context, scpi_parameter_t * parameter, const char * options[]) { + size_t res; + + if (!options) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return -1; + } + + switch(parameter->type) { + case TokProgramMnemonic: + for (res = 0; options[res]; ++res) { + if (matchPattern(options[res], strlen(options[res]), parameter->data.ptr, parameter->data.len)) { + return res; + } + } + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + return -1; + default: + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + return -1; + } +} + +int parseProgramData(lex_state_t * state, token_t * token) { token_t tmp; int result = 0; int wsLen; int suffixLen; int realLen = 0; - realLen += SCPI_LexWhiteSpace(state, &tmp); + realLen += lexWhiteSpace(state, &tmp); - if (result == 0) result = SCPI_LexNondecimalNumericData(state, token); - if (result == 0) result = SCPI_LexCharacterProgramData(state, token); + if (result == 0) result = lexNondecimalNumericData(state, token); + if (result == 0) result = lexCharacterProgramData(state, token); if (result == 0) { - result = SCPI_LexDecimalNumericProgramData(state, token); + result = lexDecimalNumericProgramData(state, token); if (result != 0) { - wsLen = SCPI_LexWhiteSpace(state, &tmp); - suffixLen = SCPI_LexSuffixProgramData(state, &tmp); + wsLen = lexWhiteSpace(state, &tmp); + suffixLen = lexSuffixProgramData(state, &tmp); if (suffixLen > 0) { token->len += wsLen + suffixLen; token->type = TokDecimalNumericProgramDataWithSuffix; @@ -471,16 +544,16 @@ } } - if (result == 0) result = SCPI_LexStringProgramData(state, token); - if (result == 0) result = SCPI_LexArbitraryBlockProgramData(state, token); - if (result == 0) result = SCPI_LexProgramExpression(state, token); + if (result == 0) result = lexStringProgramData(state, token); + if (result == 0) result = lexArbitraryBlockProgramData(state, token); + if (result == 0) result = lexProgramExpression(state, token); - realLen += SCPI_LexWhiteSpace(state, &tmp); + realLen += lexWhiteSpace(state, &tmp); return result + realLen; } -int SCPI_ParseAllProgramData(lex_state_t * state, token_t * token, int * numberOfParameters) { +int parseAllProgramData(lex_state_t * state, token_t * token, int * numberOfParameters) { int result; token_t tmp; @@ -491,7 +564,7 @@ token->ptr = state->pos; - for (result = 1; result != 0; result = SCPI_LexComma(state, &tmp)) { + for (result = 1; result != 0; result = lexComma(state, &tmp)) { token->len += result; if (result == 0) { @@ -501,7 +574,7 @@ break; } - result = SCPI_ParseProgramData(state, &tmp); + result = parseProgramData(state, &tmp); if (tmp.type != TokUnknown) { token->len += result; } else { @@ -523,39 +596,46 @@ return token->len; } -int SCPI_DetectProgramMessageUnit(scpi_parser_state_t * state, const char * buffer, int len) { +static void invalidateToken(token_t * token, const char * ptr) { + token->len = 0; + token->ptr = ptr; + token->type = TokUnknown; +} + +int detectProgramMessageUnit(scpi_parser_state_t * state, const char * buffer, int len) { lex_state_t lex_state; token_t tmp; int result = 0; lex_state.buffer = lex_state.pos = buffer; lex_state.len = len; + state->numberOfParameters = 0; /* ignore whitespace at the begginig */ - SCPI_LexWhiteSpace(&lex_state, &tmp); + lexWhiteSpace(&lex_state, &tmp); - if (SCPI_LexProgramHeader(&lex_state, &state->programHeader) >= 0) { - if (SCPI_LexWhiteSpace(&lex_state, &tmp) > 0) { - SCPI_ParseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters); + if (lexProgramHeader(&lex_state, &state->programHeader) >= 0) { + if (lexWhiteSpace(&lex_state, &tmp) > 0) { + parseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters); } else { - state->programData.len = 0; - state->programData.ptr = lex_state.pos; - state->programData.type = TokUnknown; - state->numberOfParameters = 0; + invalidateToken(&state->programData, lex_state.pos); } } else { - state->programHeader.len = 0; - state->programData.ptr = lex_state.buffer; - state->programHeader.type = TokUnknown; - - state->programData.len = 0; - state->programData.ptr = lex_state.buffer; - state->programData.type = TokUnknown; - state->numberOfParameters = 0; + invalidateToken(&state->programHeader, lex_state.buffer); + invalidateToken(&state->programData, lex_state.buffer); } - if (result == 0) result = SCPI_LexNewLine(&lex_state, &tmp); - if (result == 0) result = SCPI_LexSemicolon(&lex_state, &tmp); + if (result == 0) result = lexNewLine(&lex_state, &tmp); + if (result == 0) result = lexSemicolon(&lex_state, &tmp); + + if (!lexIsEos(&lex_state) && (result == 0)) { + lex_state.pos++; + + state->programHeader.len = 1; + state->programHeader.type = TokInvalid; + + invalidateToken(&state->programData, lex_state.buffer); + } if (TokSemicolon == tmp.type) { state->termination = PmutSemicolon; -- Gitblit v1.9.1