예제 #1
0
/**
 * 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;
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
파일: units.c 프로젝트: zuban/scpi-parser
/**
 * 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, &param, 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, &param, &(value->value));
            break;
        case SCPI_TOKEN_HEXNUM:
            SCPI_ParamToDouble(context, &param, &(value->value));
            break;
        case SCPI_TOKEN_OCTNUM:
            SCPI_ParamToDouble(context, &param, &(value->value));
            break;
        case SCPI_TOKEN_BINNUM:
            SCPI_ParamToDouble(context, &param, &(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, &param, &(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;
}