SR_PRIV int sr_atod(const char *str, double *ret);
SR_PRIV int sr_atof(const char *str, float *ret);
SR_PRIV int sr_atod_ascii(const char *str, double *ret);
+SR_PRIV int sr_atod_ascii_digits(const char *str, double *ret, int *digits);
SR_PRIV int sr_atof_ascii(const char *str, float *ret);
SR_PRIV GString *sr_hexdump_new(const uint8_t *data, const size_t len);
return SR_OK;
}
+/**
+ * Convert text to a floating point value, and get its precision.
+ *
+ * @param[in] str The input text to convert.
+ * @param[out] ret The conversion result, a double precision float number.
+ * @param[out] digits The number of significant decimals.
+ *
+ * @returns SR_OK in case of successful text to number conversion.
+ * @returns SR_ERR when conversion fails.
+ *
+ * @since 0.6.0
+ */
+SR_PRIV int sr_atod_ascii_digits(const char *str, double *ret, int *digits)
+{
+ const char *p;
+ int *dig_ref, m_dig, exp;
+ char c;
+ double f;
+
+ /*
+ * Convert floating point text to the number value, _and_ get
+ * the value's precision in the process. Steps taken to do it:
+ * - Skip leading whitespace.
+ * - Count the number of decimals after the mantissa's period.
+ * - Get the exponent's signed value.
+ *
+ * This implementation still uses common code for the actual
+ * conversion, but "violates API layers" by duplicating the
+ * text scan, to get the number of significant digits.
+ */
+ p = str;
+ while (*p && isspace(*p))
+ p++;
+ if (*p == '-' || *p == '+')
+ p++;
+ m_dig = 0;
+ exp = 0;
+ dig_ref = NULL;
+ while (*p) {
+ c = *p++;
+ if (toupper(c) == 'E') {
+ exp = strtol(p, NULL, 10);
+ break;
+ }
+ if (c == '.') {
+ m_dig = 0;
+ dig_ref = &m_dig;
+ continue;
+ }
+ if (isdigit(c)) {
+ if (dig_ref)
+ (*dig_ref)++;
+ continue;
+ }
+ /* Need not warn, conversion will fail. */
+ break;
+ }
+ sr_spew("atod digits: txt \"%s\" -> m %d, e %d -> digits %d",
+ str, m_dig, exp, m_dig + -exp);
+ m_dig += -exp;
+
+ if (sr_atod_ascii(str, &f) != SR_OK)
+ return SR_ERR;
+ if (ret)
+ *ret = f;
+ if (digits)
+ *digits = m_dig;
+
+ return SR_OK;
+}
+
/**
* Convert a string representation of a numeric value to a float. The
* conversion is strict and will fail if the complete string does not represent