From cb38dba9fe0344b02f4b183152263fe3c0066290 Mon Sep 17 00:00:00 2001 From: Iztok Jeras <iztok.jeras@redpitaya.com> Date: ćšć, 08 10æ 2015 03:00:34 +0800 Subject: [PATCH] integer parse: added support for float --- libscpi/src/parser.c | 90 ++++++++++++++++++++++++++++- libscpi/test/test_scpi_utils.c | 18 ++++++ libscpi/inc/scpi/config.h | 6 ++ libscpi/src/utils_private.h | 1 libscpi/inc/scpi/parser.h | 3 + libscpi/inc/scpi/utils.h | 1 libscpi/src/utils.c | 26 ++++++++ 7 files changed, 138 insertions(+), 7 deletions(-) diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index 0ee0454..c3f4e7e 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -166,6 +166,12 @@ #endif #if HAVE_DTOSTRE +#define SCPIDEFINE_floatToStr(v, s, l) strlen(dtostre((double)(v), (s), 6, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE)) +#else +#define SCPIDEFINE_floatToStr(v, s, l) snprintf((s), (l), "%g", (v)) +#endif + +#if HAVE_DTOSTRE #define SCPIDEFINE_doubleToStr(v, s, l) strlen(dtostre((v), (s), 6, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE)) #else #define SCPIDEFINE_doubleToStr(v, s, l) snprintf((s), (l), "%lg", (v)) diff --git a/libscpi/inc/scpi/parser.h b/libscpi/inc/scpi/parser.h index cfa944b..c3c98ef 100644 --- a/libscpi/inc/scpi/parser.h +++ b/libscpi/inc/scpi/parser.h @@ -55,6 +55,7 @@ size_t SCPI_ResultInt32(scpi_t * context, int32_t val); size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base); size_t SCPI_ResultInt64(scpi_t * context, int64_t val); + size_t SCPI_ResultFloat(scpi_t * context, float val); size_t SCPI_ResultDouble(scpi_t * context, double val); size_t SCPI_ResultText(scpi_t * context, const char * data); size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len); @@ -69,6 +70,7 @@ scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value); scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value); scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value); + scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value); scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value); scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value); scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text); @@ -78,6 +80,7 @@ scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory); scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory); scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory); scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory); scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); diff --git a/libscpi/inc/scpi/utils.h b/libscpi/inc/scpi/utils.h index 66e5cda..be538e1 100644 --- a/libscpi/inc/scpi/utils.h +++ b/libscpi/inc/scpi/utils.h @@ -47,6 +47,7 @@ size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len); size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base); size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len); + size_t SCPI_FloatToStr(float val, char * str, size_t len); size_t SCPI_DoubleToStr(double val, char * str, size_t len); // deprecated finction, should be removed later diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index ba8b74a..033535b 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -424,7 +424,23 @@ } /** - * Write double value to the result + * Write float (32 bit) value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultFloat(scpi_t * context, float val) { + char buffer[32]; + size_t result = 0; + size_t len = SCPI_FloatToStr(val, buffer, sizeof (buffer)); + result += writeDelimiter(context); + result += writeData(context, buffer, len); + context->output_count++; + return result; +} + +/** + * Write double (64bit) value to the result * @param context * @param val * @return @@ -437,7 +453,6 @@ result += writeData(context, buffer, len); context->output_count++; return result; - } /** @@ -696,14 +711,14 @@ } /** - * Convert parameter to double + * Convert parameter to float (32 bit) * @param context * @param parameter * @param value result * @return TRUE if succesful */ #include "stdio.h" -scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value) { +scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value) { scpi_bool_t result; uint32_t valint; @@ -721,6 +736,40 @@ break; case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + result = strToFloat(parameter->ptr, value) > 0 ? TRUE : FALSE; + break; + default: + result = FALSE; + } + return result; +} + +/** + * Convert parameter to double (64 bit) + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +#include "stdio.h" +scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value) { + scpi_bool_t result; + uint64_t valint; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + case SCPI_TOKEN_OCTNUM: + case SCPI_TOKEN_BINNUM: + result = SCPI_ParamToUInt64(context, parameter, &valint); + *value = valint; + break; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: result = strToDouble(parameter->ptr, value) > 0 ? TRUE : FALSE; break; default: @@ -730,7 +779,38 @@ } /** - * Read floating point parameter + * Read floating point float (32 bit) parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + if (SCPI_ParamIsNumber(¶m, FALSE)) { + SCPI_ParamToFloat(context, ¶m, value); + } else if (SCPI_ParamIsNumber(¶m, TRUE)) { + SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED); + result = FALSE; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + return result; +} + +/** + * Read floating point double (64 bit) parameter * @param context * @param value * @param mandatory diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 456e8f3..205bea6 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -245,7 +245,18 @@ } /** - * Converts double value to string + * Converts float (32 bit) value to string + * @param val long value + * @param str converted textual representation + * @param len string buffer length + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_FloatToStr(float val, char * str, size_t len) { + return SCPIDEFINE_floatToStr(val, str, len); +} + +/** + * Converts double (64 bit) value to string * @param val double value * @param str converted textual representation * @param len string buffer length @@ -303,9 +314,20 @@ return endptr - str; } +/** + * Converts string to float (32 bit) representation + * @param str string value + * @param val float result + * @return number of bytes used in string + */ +size_t strToFloat(const char * str, float * val) { + char * endptr; + *val = strtof(str, &endptr); + return endptr - str; +} /** - * Converts string to double representation + * Converts string to double (64 bit) representation * @param str string value * @param val double result * @return number of bytes used in string diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index 51b38be..e7909e5 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -60,6 +60,7 @@ size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) LOCAL; size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) LOCAL; size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) LOCAL; + size_t strToFloat(const char * str, float * val) LOCAL; size_t strToDouble(const char * str, double * val) LOCAL; scpi_bool_t locateText(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; scpi_bool_t locateStr(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; diff --git a/libscpi/test/test_scpi_utils.c b/libscpi/test/test_scpi_utils.c index f3302c3..3a48d94 100644 --- a/libscpi/test/test_scpi_utils.c +++ b/libscpi/test/test_scpi_utils.c @@ -215,6 +215,23 @@ CU_ASSERT_STRING_EQUAL(str, "1111111011011100101110101001100001110110010101000011001000010000"); } +static void test_floatToStr() { + const size_t max=49+1; + float val[] = {1, -1, 1.1, -1.1, 1e3, 1e30, -1.3e30, -1.3e-30}; + int N = sizeof(val) / sizeof(float); + int i; + char str[max]; + char ref[max]; + size_t len; + + for (i=0; i<N; i++) { + len = SCPI_FloatToStr(val[i], str, max); + snprintf(ref, max, "%g", val[i]); + CU_ASSERT(len == strlen(ref)); + CU_ASSERT_STRING_EQUAL(str, ref); + } +} + static void test_doubleToStr() { const size_t max=49+1; double val[] = {1, -1, 1.1, -1.1, 1e3, 1e30, -1.3e30, -1.3e-30}; @@ -652,6 +669,7 @@ || (NULL == CU_add_test(pSuite, "UInt32ToStrBase", test_UInt32ToStrBase)) || (NULL == CU_add_test(pSuite, "Int64ToStr", test_Int64ToStr)) || (NULL == CU_add_test(pSuite, "UInt64ToStrBase", test_UInt64ToStrBase)) + || (NULL == CU_add_test(pSuite, "floatToStr", test_floatToStr)) || (NULL == CU_add_test(pSuite, "doubleToStr", test_doubleToStr)) || (NULL == CU_add_test(pSuite, "strBaseToInt32", test_strBaseToInt32)) || (NULL == CU_add_test(pSuite, "strBaseToUInt32", test_strBaseToUInt32)) -- Gitblit v1.9.1