X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fdmm%2Fasycii.c;h=96a462c5e6d2b4a666a220e319be58f1bf024d9e;hb=82b9f3d116ce0c982291a2dfdd15cd8a1c4cc16e;hp=8f5770f5e4eff6b32a3e307ffe7370dadb8ab13e;hpb=4ba4d52a8f9c66f6b941a545e17c684e65356aff;p=libsigrok.git diff --git a/src/dmm/asycii.c b/src/dmm/asycii.c index 8f5770f5..96a462c5 100644 --- a/src/dmm/asycii.c +++ b/src/dmm/asycii.c @@ -60,8 +60,8 @@ static int parse_value(const char *buf, struct asycii_info *info, { char valstr[7 + 1]; const char *valp; - int i, cnt, is_ol, dot_pos; - char *endp; + int i, cnt, is_ol; + const char *dot_pos; /* * Strip all spaces from bytes 0-6. By copying all @@ -96,22 +96,20 @@ static int parse_value(const char *buf, struct asycii_info *info, /* * Convert the textual number representation to a float, and - * an exponent. Apply sanity checks (optional sign, digits and - * dot expected here, exclusively). + * an exponent. */ - endp = NULL; - *result = strtof(valp, &endp); - if (endp == NULL || *endp != '\0') { + if (sr_atof_ascii(valp, result) != SR_OK) { info->is_invalid = TRUE; sr_spew("%s(), cannot convert number", __func__); return SR_ERR_DATA; } - dot_pos = strcspn(valstr, "."); - if (dot_pos < cnt) - *exponent = -(cnt - dot_pos - 1); + dot_pos = g_strstr_len(valstr, -1, "."); + if (dot_pos) + *exponent = -(valstr + strlen(valstr) - dot_pos - 1); else *exponent = 0; - sr_spew("%s(), display value is %f", __func__, *result); + sr_spew("%s(), display value is %f, exponent %d", + __func__, *result, *exponent); return SR_OK; } @@ -124,12 +122,16 @@ static int parse_value(const char *buf, struct asycii_info *info, * variable length. Flags immediately follow the unit. The remainder * of the text buffer is SPACE padded, and terminated with CR. * - * Notice the implementation detail of case *sensitive* comparison. - * This would break correct operation. It's essential that e.g. "Vac" - * gets split into the "V" unit and the "ac" flag, not into "VA" and - * the unknown "c" flag! In the absence of separators or fixed - * positions and with ambiguous text (when abbreviated), order of - * comparison matters, too. + * Notice the implementation detail of case @b sensitive comparison. + * Since the measurement unit and flags are directly adjacent and are + * not separated from each other, case insensitive comparison would + * yield wrong results. It's essential that e.g. "Vac" gets split into + * the "V" unit and the "ac" flag, not into "VA" and the unknown "c" + * flag! + * + * Notice, too, that order of comparison matters in the absence of + * separators or fixed positions and with ambiguous text (note that we do + * partial comparison). It's essential to e.g. correctly tell "VA" from "V". * * @param[in] buf The text buffer received from the DMM. * @param[out] info Broken down measurement details. @@ -180,32 +182,32 @@ static void parse_flags(const char *buf, struct asycii_info *info) /* Scan for the measurement unit. */ sr_spew("%s(): scanning unit, buffer [%s]", __func__, u); - if (strncmp(u, "A", strlen("A")) == 0) { + if (g_str_has_prefix(u, "A")) { u += strlen("A"); info->is_ampere = TRUE; - } else if (strncmp(u, "VA", strlen("VA")) == 0) { + } else if (g_str_has_prefix(u, "VA")) { u += strlen("VA"); info->is_volt_ampere = TRUE; - } else if (strncmp(u, "V", strlen("V")) == 0) { + } else if (g_str_has_prefix(u, "V")) { u += strlen("V"); info->is_volt = TRUE; - } else if (strncmp(u, "ohm", strlen("ohm")) == 0) { + } else if (g_str_has_prefix(u, "ohm")) { u += strlen("ohm"); info->is_resistance = TRUE; info->is_ohm = TRUE; - } else if (strncmp(u, "F", strlen("F")) == 0) { + } else if (g_str_has_prefix(u, "F")) { u += strlen("F"); info->is_capacitance = TRUE; info->is_farad = TRUE; - } else if (strncmp(u, "dB", strlen("dB")) == 0) { + } else if (g_str_has_prefix(u, "dB")) { u += strlen("dB"); info->is_gain = TRUE; info->is_decibel = TRUE; - } else if (strncmp(u, "Hz", strlen("Hz")) == 0) { + } else if (g_str_has_prefix(u, "Hz")) { u += strlen("Hz"); info->is_frequency = TRUE; info->is_hertz = TRUE; - } else if (strncmp(u, "%", strlen("%")) == 0) { + } else if (g_str_has_prefix(u, "%")) { u += strlen("%"); info->is_duty_cycle = TRUE; if (*u == '+') { @@ -217,7 +219,7 @@ static void parse_flags(const char *buf, struct asycii_info *info) } else { info->is_invalid = TRUE; } - } else if (strncmp(u, "Cnt", strlen("Cnt")) == 0) { + } else if (g_str_has_prefix(u, "Cnt")) { u += strlen("Cnt"); info->is_pulse_count = TRUE; info->is_unitless = TRUE; @@ -230,7 +232,7 @@ static void parse_flags(const char *buf, struct asycii_info *info) } else { info->is_invalid = TRUE; } - } else if (strncmp(u, "s", strlen("s")) == 0) { + } else if (g_str_has_prefix(u, "s")) { u += strlen("s"); info->is_pulse_width = TRUE; info->is_seconds = TRUE; @@ -251,19 +253,19 @@ static void parse_flags(const char *buf, struct asycii_info *info) /* Scan for additional flags. */ sr_spew("%s(): scanning flags, buffer [%s]", __func__, u); - if (strncmp(u, "ac+dc", strlen("ac+dc")) == 0) { + if (g_str_has_prefix(u, "ac+dc")) { u += strlen("ac+dc"); info->is_ac_and_dc = TRUE; - } else if (strncmp(u, "ac", strlen("ac")) == 0) { + } else if (g_str_has_prefix(u, "ac")) { u += strlen("ac"); info->is_ac = TRUE; - } else if (strncmp(u, "dc", strlen("dc")) == 0) { + } else if (g_str_has_prefix(u, "dc")) { u += strlen("dc"); info->is_dc = TRUE; - } else if (strncmp(u, "d", strlen("d")) == 0) { + } else if (g_str_has_prefix(u, "d")) { u += strlen("d"); info->is_diode = TRUE; - } else if (strncmp(u, "Pk", strlen("Pk")) == 0) { + } else if (g_str_has_prefix(u, "Pk")) { u += strlen("Pk"); if (*u == '+') { u++; @@ -274,7 +276,7 @@ static void parse_flags(const char *buf, struct asycii_info *info) } else { info->is_invalid = TRUE; } - } else if (strcmp(u, "") == 0) { + } else if (*u == '\0') { /* Absence of any flags is acceptable. */ } else { /* Presence of unknown flags is not. */ @@ -377,7 +379,7 @@ static void handle_flags(struct sr_datafeed_analog *analog, float *floatval, if (info->is_dc) analog->meaning->mqflags |= SR_MQFLAG_DC; if (info->is_diode) - analog->meaning->mqflags |= SR_MQFLAG_DIODE; + analog->meaning->mqflags |= SR_MQFLAG_DIODE | SR_MQFLAG_DC; if (info->is_peak_max) analog->meaning->mqflags |= SR_MQFLAG_MAX; if (info->is_peak_min) @@ -444,7 +446,7 @@ static gboolean flags_valid(const struct asycii_info *info) return TRUE; } -#ifdef HAVE_LIBSERIALPORT +#ifdef HAVE_SERIAL_COMM /** * Arrange for the reception of another measurement from the DMM. * @@ -453,8 +455,6 @@ static gboolean flags_valid(const struct asycii_info *info) * without the PC's intervention. * * @param[in] serial The serial connection. - * - * @private */ SR_PRIV int sr_asycii_packet_request(struct sr_serial_dev_inst *serial) { @@ -517,7 +517,7 @@ SR_PRIV int sr_asycii_parse(const uint8_t *buf, float *floatval, int ret, exponent; struct asycii_info *info_local; - info_local = (struct asycii_info *)info; + info_local = info; /* Don't print byte 15. That one contains the carriage return. */ sr_dbg("DMM packet: \"%.15s\"", buf);