integer parse: added support for float
| | |
| | | #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)) |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | result += writeData(context, buffer, len); |
| | | context->output_count++; |
| | | return result; |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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; |
| | | |
| | |
| | | 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: |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | 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 |
| | |
| | | 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; |
| | |
| | | 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}; |
| | |
| | | || (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)) |