From ed07df16da675c4c123e02a996822daf13d69c63 Mon Sep 17 00:00:00 2001 From: lhoerl <coder@lolux.de> Date: 周一, 03 8月 2015 22:42:07 +0800 Subject: [PATCH] added full SCPI error messages added list for device dependent error messages some minor changes to get rid of compiler warnings added support for Keil ARM compiler added support for National Instruments CVI compiler removed bug if(c = '\0')... --- libscpi/src/units.c | 271 ++++++++++++++++++++++++++++++++--------------------- 1 files changed, 164 insertions(+), 107 deletions(-) diff --git a/libscpi/src/units.c b/libscpi/src/units.c index a22f770..517bb1a 100644 --- a/libscpi/src/units.c +++ b/libscpi/src/units.c @@ -37,8 +37,10 @@ #include <string.h> #include "scpi/parser.h" #include "scpi/units.h" -#include "utils.h" +#include "utils_private.h" +#include "scpi/utils.h" #include "scpi/error.h" +#include "lexer_private.h" /* @@ -62,94 +64,73 @@ */ const scpi_unit_def_t scpi_units_def[] = { /* voltage */ - { .name = "UV", .unit = SCPI_UNIT_VOLT, .mult = 1e-6}, - { .name = "MV", .unit = SCPI_UNIT_VOLT, .mult = 1e-3}, - { .name = "V", .unit = SCPI_UNIT_VOLT, .mult = 1}, - { .name = "KV", .unit = SCPI_UNIT_VOLT, .mult = 1e3}, + {/* name */ "UV", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1e-6}, + {/* name */ "MV", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1e-3}, + {/* name */ "V", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1}, + {/* name */ "KV", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1e3}, /* current */ - { .name = "UA", .unit = SCPI_UNIT_AMPER, .mult = 1e-6}, - { .name = "MA", .unit = SCPI_UNIT_AMPER, .mult = 1e-3}, - { .name = "A", .unit = SCPI_UNIT_AMPER, .mult = 1}, - { .name = "KA", .unit = SCPI_UNIT_AMPER, .mult = 1e3}, + {/* name */ "UA", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1e-6}, + {/* name */ "MA", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1e-3}, + {/* name */ "A", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1}, + {/* name */ "KA", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1e3}, /* resistance */ - { .name = "OHM", .unit = SCPI_UNIT_OHM, .mult = 1}, - { .name = "KOHM", .unit = SCPI_UNIT_OHM, .mult = 1e3}, - { .name = "MOHM", .unit = SCPI_UNIT_OHM, .mult = 1e6}, + {/* name */ "OHM", /* unit */ SCPI_UNIT_OHM, /* mult */ 1}, + {/* name */ "KOHM", /* unit */ SCPI_UNIT_OHM, /* mult */ 1e3}, + {/* name */ "MOHM", /* unit */ SCPI_UNIT_OHM, /* mult */ 1e6}, /* frequency */ - { .name = "HZ", .unit = SCPI_UNIT_HERTZ, .mult = 1}, - { .name = "KHZ", .unit = SCPI_UNIT_HERTZ, .mult = 1e3}, - { .name = "MHZ", .unit = SCPI_UNIT_HERTZ, .mult = 1e6}, - { .name = "GHZ", .unit = SCPI_UNIT_HERTZ, .mult = 1e9}, + {/* name */ "HZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1}, + {/* name */ "KHZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1e3}, + {/* name */ "MHZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1e6}, + {/* name */ "GHZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1e9}, /* temperature */ - { .name = "CEL", .unit = SCPI_UNIT_CELSIUS, .mult = 1}, + {/* name */ "CEL", /* unit */ SCPI_UNIT_CELSIUS, /* mult */ 1}, /* time */ - { .name = "PS", .unit = SCPI_UNIT_SECONDS, .mult = 1e-12}, - { .name = "NS", .unit = SCPI_UNIT_SECONDS, .mult = 1e-9}, - { .name = "US", .unit = SCPI_UNIT_SECONDS, .mult = 1e-6}, - { .name = "MS", .unit = SCPI_UNIT_SECONDS, .mult = 1e-3}, - { .name = "S", .unit = SCPI_UNIT_SECONDS, .mult = 1}, - { .name = "MIN", .unit = SCPI_UNIT_SECONDS, .mult = 60}, - { .name = "HR", .unit = SCPI_UNIT_SECONDS, .mult = 3600}, + {/* name */ "PS", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 1e-12}, + {/* name */ "NS", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 1e-9}, + {/* name */ "US", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 1e-6}, + {/* name */ "MS", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 1e-3}, + {/* name */ "S", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 1}, + {/* name */ "MIN", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 60}, + {/* name */ "HR", /* unit */ SCPI_UNIT_SECONDS, /* mult */ 3600}, SCPI_UNITS_LIST_END, }; -const scpi_special_number_def_t scpi_special_numbers_def[] = { - { .name = "MINimum", .type = SCPI_NUM_MIN}, - { .name = "MAXimum", .type = SCPI_NUM_MAX}, - { .name = "DEFault", .type = SCPI_NUM_DEF}, - { .name = "UP", .type = SCPI_NUM_UP}, - { .name = "DOWN", .type = SCPI_NUM_DOWN}, - { .name = "NAN", .type = SCPI_NUM_NAN}, - { .name = "INF", .type = SCPI_NUM_INF}, - { .name = "NINF", .type = SCPI_NUM_NINF}, - SCPI_SPECIAL_NUMBERS_LIST_END, +/* + * Special number values definition + */ +const scpi_choice_def_t scpi_special_numbers_def[] = { + {/* name */ "MINimum", /* type */ SCPI_NUM_MIN}, + {/* name */ "MAXimum", /* type */ SCPI_NUM_MAX}, + {/* name */ "DEFault", /* type */ SCPI_NUM_DEF}, + {/* name */ "UP", /* type */ SCPI_NUM_UP}, + {/* name */ "DOWN", /* type */ SCPI_NUM_DOWN}, + {/* name */ "NAN", /* type */ SCPI_NUM_NAN}, + {/* name */ "INFinity", /* type */ SCPI_NUM_INF}, + {/* name */ "NINF", /* type */ SCPI_NUM_NINF}, + {/* name */ "AUTO", /* type */ SCPI_NUM_AUTO}, + SCPI_CHOICE_LIST_END, }; -static scpi_special_number_t translateSpecialNumber(const scpi_special_number_def_t * specs, const char * str, size_t len) { - int i; - - if (specs == NULL) { - return SCPI_NUM_NUMBER; - } - - for (i = 0; specs[i].name != NULL; i++) { - if (matchPattern(specs[i].name, strlen(specs[i].name), str, len)) { - return specs[i].type; - } - } - - return SCPI_NUM_NUMBER; -} - -static const char * translateSpecialNumberInverse(const scpi_special_number_def_t * specs, scpi_special_number_t type) { - int i; - - if (specs == NULL) { - return NULL; - } - - for (i = 0; specs[i].name != NULL; i++) { - if (specs[i].type == type) { - return specs[i].name; - } - } - - return NULL; -} - +/** + * Convert string describing unit to its representation + * @param units units patterns + * @param unit text representation of unknown unit + * @param len length of text representation + * @return pointer of related unit definition or NULL + */ static const scpi_unit_def_t * translateUnit(const scpi_unit_def_t * units, const char * unit, size_t len) { int i; - + if (units == NULL) { return NULL; } - + for (i = 0; units[i].name != NULL; i++) { if (compareStr(unit, len, units[i].name, strlen(units[i].name))) { return &units[i]; @@ -159,13 +140,19 @@ return NULL; } +/** + * Convert unit definition to string + * @param units units definitions (patterns) + * @param unit type of unit + * @return string representation of unit + */ static const char * translateUnitInverse(const scpi_unit_def_t * units, const scpi_unit_t unit) { int i; - + if (units == NULL) { return NULL; } - + for (i = 0; units[i].name != NULL; i++) { if ((units[i].unit == unit) && (units[i].mult == 1)) { return units[i].name; @@ -175,7 +162,15 @@ return NULL; } -static bool_t transformNumber(const scpi_unit_def_t * units, const char * unit, size_t len, scpi_number_t * value) { +/** + * Transform number to base units + * @param context + * @param unit text representation of unit + * @param len length of text representation + * @param value preparsed numeric value + * @return TRUE if value parameter was converted to base units + */ +static scpi_bool_t transformNumber(scpi_t * context, const char * unit, size_t len, scpi_number_t * value) { size_t s; const scpi_unit_def_t * unitDef; s = skipWhitespace(unit, len); @@ -185,9 +180,10 @@ return TRUE; } - unitDef = translateUnit(units, unit + s, len - s); + unitDef = translateUnit(context->units, unit + s, len - s); if (unitDef == NULL) { + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX); return FALSE; } @@ -204,50 +200,108 @@ * @param mandatory if the parameter is mandatory * @return */ -bool_t SCPI_ParamNumber(scpi_t * context, scpi_number_t * value, bool_t mandatory) { - bool_t result; - char * param; - size_t len; - size_t numlen; - - result = SCPI_ParamString(context, ¶m, &len, mandatory); +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) { - if (mandatory) { - return FALSE; - } else { - value->type = SCPI_NUM_DEF; - return TRUE; - } + return result; } - value->unit = SCPI_UNIT_NONE; - value->value = 0.0; - value->type = translateSpecialNumber(context->special_numbers, param, len); + state.buffer = param.ptr; + state.pos = state.buffer; + state.len = param.len; - if (value->type != SCPI_NUM_NUMBER) { - // found special type - return TRUE; + 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; } - numlen = strToDouble(param, &value->value); - - if (numlen <= len) { - if (transformNumber(context->units, param + numlen, len - numlen, value)) { - return TRUE; - } else { - SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX); - } + 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; } - return FALSE; + 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; } -size_t SCPI_NumberToStr(scpi_t * context, scpi_number_t * value, char * str, size_t len) { +/** + * Convert scpi_number_t to string + * @param context + * @param value number value + * @param str target string + * @param len max length of string + * @return number of chars written to string + */ +size_t SCPI_NumberToStr(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, char * str, size_t len) { const char * type; const char * unit; size_t result; @@ -256,14 +310,17 @@ return 0; } - type = translateSpecialNumberInverse(context->special_numbers, value->type); - - if (type) { - strncpy(str, type, len); - return min(strlen(type), len); + if (value->special) { + if (SCPI_ChoiceToName(special, value->tag, &type)) { + strncpy(str, type, len); + return min(strlen(type), len); + } else { + str[0] = 0; + return 0; + } } - result = doubleToStr(value->value, str, len); + result = SCPI_DoubleToStr(value->value, str, len); unit = translateUnitInverse(context->units, value->unit); -- Gitblit v1.9.1