/** * Parse one parameter and detect type * @param state * @param token * @return */ 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 += scpiLex_WhiteSpace(state, &tmp); if (result == 0) result = scpiLex_NondecimalNumericData(state, token); if (result == 0) result = scpiLex_CharacterProgramData(state, token); if (result == 0) { result = scpiLex_DecimalNumericProgramData(state, token); if (result != 0) { wsLen = scpiLex_WhiteSpace(state, &tmp); suffixLen = scpiLex_SuffixProgramData(state, &tmp); if (suffixLen > 0) { token->len += wsLen + suffixLen; token->type = SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX; result = token->len; } } } 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 += scpiLex_WhiteSpace(state, &tmp); return result + realLen; }
/** * Skip complete command line - program header and parameters * @param state * @param buffer * @param len * @return */ int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) { lex_state_t lex_state; scpi_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 */ scpiLex_WhiteSpace(&lex_state, &tmp); 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); } } else { invalidateToken(&state->programHeader, lex_state.buffer); invalidateToken(&state->programData, lex_state.buffer); } if (result == 0) result = scpiLex_NewLine(&lex_state, &tmp); if (result == 0) result = scpiLex_Semicolon(&lex_state, &tmp); if (!scpiLex_IsEos(&lex_state) && (result == 0)) { lex_state.pos++; state->programHeader.len = 1; state->programHeader.type = SCPI_TOKEN_INVALID; invalidateToken(&state->programData, lex_state.buffer); } if (SCPI_TOKEN_SEMICOLON == tmp.type) { state->termination = SCPI_MESSAGE_TERMINATION_SEMICOLON; } else if (SCPI_TOKEN_NL == tmp.type) { state->termination = SCPI_MESSAGE_TERMINATION_NL; } else { state->termination = SCPI_MESSAGE_TERMINATION_NONE; } return lex_state.pos - lex_state.buffer; }
/** * Parse parameter as number, number with unit or special value (min, max, default, ...) * @param context * @param value return value * @param mandatory if the parameter is mandatory * @return */ scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory) { scpi_token_t token; lex_state_t state; scpi_parameter_t param; scpi_bool_t result; int32_t tag; if (!value) { SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); return FALSE; } result = SCPI_Parameter(context, ¶m, mandatory); if (!result) { return result; } state.buffer = param.ptr; state.pos = state.buffer; state.len = param.len; switch(param.type) { case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: case SCPI_TOKEN_HEXNUM: case SCPI_TOKEN_OCTNUM: case SCPI_TOKEN_BINNUM: case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: case SCPI_TOKEN_PROGRAM_MNEMONIC: value->unit = SCPI_UNIT_NONE; value->special = FALSE; result = TRUE; break; } switch(param.type) { case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: case SCPI_TOKEN_PROGRAM_MNEMONIC: value->base = 10; break; case SCPI_TOKEN_BINNUM: value->base = 2; break; case SCPI_TOKEN_HEXNUM: value->base = 16; break; case SCPI_TOKEN_OCTNUM: value->base = 8; break; } switch(param.type) { case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_HEXNUM: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_OCTNUM: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_BINNUM: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: scpiLex_DecimalNumericProgramData(&state, &token); scpiLex_WhiteSpace(&state, &token); scpiLex_SuffixProgramData(&state, &token); SCPI_ParamToDouble(context, ¶m, &(value->value)); result = transformNumber(context, token.ptr, token.len, value); break; case SCPI_TOKEN_PROGRAM_MNEMONIC: scpiLex_WhiteSpace(&state, &token); scpiLex_CharacterProgramData(&state, &token); /* convert string to special number type */ SCPI_ParamToChoice(context, &token, special, &tag); value->special = TRUE; value->tag = tag; break; default: result = FALSE; } return result; }