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 |  173 ++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 97 insertions(+), 76 deletions(-)

diff --git a/libscpi/src/units.c b/libscpi/src/units.c
index 615147c..517bb1a 100644
--- a/libscpi/src/units.c
+++ b/libscpi/src/units.c
@@ -38,6 +38,7 @@
 #include "scpi/parser.h"
 #include "scpi/units.h"
 #include "utils_private.h"
+#include "scpi/utils.h"
 #include "scpi/error.h"
 #include "lexer_private.h"
 
@@ -103,7 +104,7 @@
 /*
  * Special number values definition
  */
-const scpi_special_number_def_t scpi_special_numbers_def[] = {
+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},
@@ -112,59 +113,9 @@
     {/* name */ "NAN", /* type */ SCPI_NUM_NAN},
     {/* name */ "INFinity", /* type */ SCPI_NUM_INF},
     {/* name */ "NINF", /* type */ SCPI_NUM_NINF},
-    SCPI_SPECIAL_NUMBERS_LIST_END,
+    {/* name */ "AUTO", /* type */ SCPI_NUM_AUTO},
+    SCPI_CHOICE_LIST_END,
 };
-
-/**
- * Match string constant to one of special number values
- * @param specs specifications of special numbers (patterns)
- * @param str string to be recognised
- * @param len length of string
- * @param value resultin value
- * @return TRUE if str matches one of specs patterns
- */
-static scpi_bool_t translateSpecialNumber(const scpi_special_number_def_t * specs, const char * str, size_t len, scpi_number_parameter_t * value) {
-    int i;
-
-    value->value = 0.0;
-    value->unit = SCPI_UNIT_NONE;
-    value->type = SCPI_NUM_NUMBER;
-
-    if (specs == NULL) {
-        return FALSE;
-    }
-
-    for (i = 0; specs[i].name != NULL; i++) {
-        if (matchPattern(specs[i].name, strlen(specs[i].name), str, len)) {
-            value->type = specs[i].type;
-            return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-/**
- * Convert special number type to its string representation
- * @param specs specifications of special numbers (patterns)
- * @param type type of special number
- * @return String representing special number or NULL
- */
-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
@@ -219,7 +170,7 @@
  * @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_parameter_t * value) {
+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);
@@ -249,30 +200,97 @@
  * @param mandatory if the parameter is mandatory
  * @return 
  */
-scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter) {
-    token_t token;
+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;
 
-    state.buffer = parameter->data.ptr;
+    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 = parameter->data.len;
+    state.len = param.len;
 
-    switch(parameter->type) {
-        case TokDecimalNumericProgramDataWithSuffix:
-            lexDecimalNumericProgramData(&state, &token);
-            lexWhiteSpace(&state, &token);
-            lexSuffixProgramData(&state, &token);
+    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;
+    }
 
-            return transformNumber(context, token.ptr, token.len, &parameter->number);
-        case TokProgramMnemonic:
-            lexWhiteSpace(&state, &token);
-            lexCharacterProgramData(&state, &token);
+    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 */
-            return translateSpecialNumber(context->special_numbers, token.ptr, token.len, &parameter->number);
+            SCPI_ParamToChoice(context, &token, special, &tag);
+
+            value->special = TRUE;
+            value->tag = tag;
+
+            break;
         default:
-            return FALSE;
+            result = FALSE;
     }
+
+    return result;
 }
 
 /**
@@ -283,7 +301,7 @@
  * @param len max length of string
  * @return number of chars written to string
  */
-size_t SCPI_NumberToStr(scpi_t * context, scpi_number_parameter_t * value, char * str, size_t len) {
+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;
@@ -292,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