21 #define _XOPEN_SOURCE 700
25 #if defined(__FreeBSD__) || defined(__APPLE__)
28 #if defined(__FreeBSD__)
29 #include <sys/param.h>
37 #include "libsigrok-internal.h"
40 #define LOG_PREFIX "strutil"
71 SR_PRIV int sr_atol(
const char *str,
long *ret)
77 tmp = strtol(str, &endptr, 10);
79 while (endptr && isspace(*endptr))
82 if (!endptr || *endptr || errno) {
106 SR_PRIV int sr_atoi(
const char *str,
int *ret)
110 if (sr_atol(str, &tmp) !=
SR_OK)
113 if ((
int) tmp != tmp) {
136 SR_PRIV int sr_atod(
const char *str,
double *ret)
142 tmp = strtof(str, &endptr);
144 while (endptr && isspace(*endptr))
147 if (!endptr || *endptr || errno) {
171 SR_PRIV int sr_atof(
const char *str,
float *ret)
175 if (sr_atod(str, &tmp) !=
SR_OK)
178 if ((
float) tmp != tmp) {
201 SR_PRIV int sr_atod_ascii(
const char *str,
double *ret)
207 tmp = g_ascii_strtod(str, &endptr);
209 if (!endptr || *endptr || errno) {
233 SR_PRIV int sr_atof_ascii(
const char *str,
float *ret)
239 tmp = g_ascii_strtod(str, &endptr);
241 if (!endptr || *endptr || errno) {
291 va_start(args, format);
340 locale = _create_locale(LC_NUMERIC,
"C");
341 ret = _vsprintf_l(buf, format, locale, args);
342 _free_locale(locale);
346 ret = vsprintf(buf, format, args);
349 #elif defined(__APPLE__)
358 locale = newlocale(LC_NUMERIC_MASK,
"C", NULL);
359 ret = vsprintf_l(buf, locale, format, args);
363 #elif defined(__FreeBSD__) && __FreeBSD_version >= 901000
372 locale = newlocale(LC_NUMERIC_MASK,
"C", NULL);
373 ret = vsprintf_l(buf, locale, format, args);
377 #elif defined(__ANDROID__)
385 ret = vsprintf(buf, format, args);
388 #elif defined(__linux__)
390 locale_t old_locale, temp_locale;
393 temp_locale = newlocale(LC_NUMERIC,
"C", NULL);
394 old_locale = uselocale(temp_locale);
396 ret = vsprintf(buf, format, args);
399 uselocale(old_locale);
400 freelocale(temp_locale);
403 #elif defined(__unix__) || defined(__unix)
411 ret = vsprintf(buf, format, args);
451 const char *format, ...)
456 va_start(args, format);
498 const char *format, va_list args)
513 locale = _create_locale(LC_NUMERIC,
"C");
514 ret = _vsnprintf_l(buf, buf_size, format, locale, args);
515 _free_locale(locale);
519 ret = vsnprintf(buf, buf_size, format, args);
522 #elif defined(__APPLE__)
531 locale = newlocale(LC_NUMERIC_MASK,
"C", NULL);
532 ret = vsnprintf_l(buf, buf_size, locale, format, args);
536 #elif defined(__FreeBSD__) && __FreeBSD_version >= 901000
545 locale = newlocale(LC_NUMERIC_MASK,
"C", NULL);
546 ret = vsnprintf_l(buf, buf_size, locale, format, args);
550 #elif defined(__ANDROID__)
558 ret = vsnprintf(buf, buf_size, format, args);
561 #elif defined(__linux__)
563 locale_t old_locale, temp_locale;
566 temp_locale = newlocale(LC_NUMERIC,
"C", NULL);
567 old_locale = uselocale(temp_locale);
569 ret = vsnprintf(buf, buf_size, format, args);
572 uselocale(old_locale);
573 freelocale(temp_locale);
576 #elif defined(__unix__) || defined(__unix)
584 ret = vsnprintf(buf, buf_size, format, args);
608 s = g_string_sized_new(3 * len);
609 for (i = 0; i < len; i++) {
611 g_string_append_c(s,
' ');
612 g_string_append_printf(s,
"%02x", data[i]);
626 g_string_free(s, TRUE);
648 int64_t fractional = 0;
649 int64_t denominator = 1;
650 int32_t fractional_len = 0;
651 int32_t exponent = 0;
652 gboolean is_negative = FALSE;
653 gboolean no_integer, no_fractional;
655 while (isspace(*str))
659 integral = g_ascii_strtoll(str, &endptr, 10);
661 if (str == endptr && (str[0] ==
'-' || str[0] ==
'+') && str[1] ==
'.') {
664 }
else if (str == endptr && str[0] ==
'.') {
672 if (integral < 0 || str[0] ==
'-')
676 if (*endptr ==
'.') {
677 gboolean is_exp, is_eos;
678 const char *start = endptr + 1;
679 fractional = g_ascii_strtoll(start, &endptr, 10);
680 is_exp = *endptr ==
'E' || *endptr ==
'e';
681 is_eos = *endptr ==
'\0';
682 if (endptr == start && (is_exp || is_eos)) {
688 no_fractional = endptr == start;
689 if (no_integer && no_fractional)
691 fractional_len = endptr - start;
695 if ((*endptr ==
'E') || (*endptr ==
'e')) {
696 exponent = g_ascii_strtoll(endptr + 1, &endptr, 10);
704 for (
int i = 0; i < fractional_len; i++)
706 exponent -= fractional_len;
709 integral += fractional;
711 integral -= fractional;
713 while (exponent > 0) {
718 while (exponent < 0) {
724 ret->
q = denominator;
749 uint64_t quot, divisor[] = {
753 const char *p, prefix[] =
"\0kMGTPE";
754 char fmt[16], fract[20] =
"", *f;
759 for (i = 0; (quot = x / divisor[i]) >= 1000; i++);
762 sprintf(fmt,
".%%0%d"PRIu64, i * 3);
763 f = fract + sprintf(fract, fmt, x % divisor[i]) - 1;
765 while (f >= fract && strchr(
"0.", *f))
771 return g_strdup_printf(
"%" PRIu64
"%s %.1s%s", quot, fract, p, unit);
815 freq = 1 / ((double)v_p / v_q);
818 v = (double)v_p / v_q * 1000000000000.0;
819 prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3;
820 return g_strdup_printf(
"%.*f ps", prec, v);
821 }
else if (freq >
SR_MHZ(1)) {
822 v = (double)v_p / v_q * 1000000000.0;
823 prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3;
824 return g_strdup_printf(
"%.*f ns", prec, v);
825 }
else if (freq >
SR_KHZ(1)) {
826 v = (double)v_p / v_q * 1000000.0;
827 prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3;
828 return g_strdup_printf(
"%.*f us", prec, v);
829 }
else if (freq > 1) {
830 v = (double)v_p / v_q * 1000.0;
831 prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3;
832 return g_strdup_printf(
"%.*f ms", prec, v);
834 v = (double)v_p / v_q;
835 prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3;
836 return g_strdup_printf(
"%.*f s", prec, v);
859 return g_strdup_printf(
"%" PRIu64
" mV", v_p);
861 return g_strdup_printf(
"%" PRIu64
" V", v_p);
863 return g_strdup_printf(
"%g V", (
float)v_p / (
float)v_q);
890 *size = strtoull(sizestring, &s, 10);
894 while (s && *s && multiplier == 0 && !done) {
899 frac_part = g_ascii_strtod(s, &s);
915 multiplier =
SR_GHZ(1000);
919 multiplier =
SR_GHZ(1000 * 1000);
923 multiplier =
SR_GHZ(1000 * 1000 * 1000);
931 if (multiplier > 0) {
933 *size += frac_part * multiplier;
938 if (s && *s && g_ascii_strcasecmp(s,
"Hz"))
971 time_msec = strtoull(timestring, &s, 10);
972 if (time_msec == 0 && s == timestring)
980 else if (!strcmp(s,
"ms"))
997 if (!boolstr || !*boolstr)
1000 if (!g_ascii_strncasecmp(boolstr,
"true", 4) ||
1001 !g_ascii_strncasecmp(boolstr,
"yes", 3) ||
1002 !g_ascii_strncasecmp(boolstr,
"on", 2) ||
1003 !g_ascii_strncasecmp(boolstr,
"1", 1))
1014 *p = strtoull(periodstr, &s, 10);
1015 if (*p == 0 && s == periodstr)
1022 if (!strcmp(s,
"fs"))
1023 *q = UINT64_C(1000000000000000);
1024 else if (!strcmp(s,
"ps"))
1025 *q = UINT64_C(1000000000000);
1026 else if (!strcmp(s,
"ns"))
1027 *q = UINT64_C(1000000000);
1028 else if (!strcmp(s,
"us"))
1030 else if (!strcmp(s,
"ms"))
1032 else if (!strcmp(s,
"s"))
1047 *p = strtoull(voltstr, &s, 10);
1048 if (*p == 0 && s == voltstr)
1055 if (!g_ascii_strcasecmp(s,
"mv"))
1057 else if (!g_ascii_strcasecmp(s,
"v"))
Generic/unspecified error.
int sr_snprintf_ascii(char *buf, size_t buf_size, const char *format,...)
Composes a string with a format string (like printf) in the buffer pointed by buf (taking buf_size as...
int sr_parse_period(const char *periodstr, uint64_t *p, uint64_t *q)
char * sr_voltage_string(uint64_t v_p, uint64_t v_q)
Convert a numeric voltage value to the "natural" string representation of its voltage value...
The public libsigrok header file to be used by frontends.
SR_PRIV GString * sr_hexdump_new(const uint8_t *data, const size_t len)
Convert a sequence of bytes to its textual representation ("hex dump").
int sr_vsprintf_ascii(char *buf, const char *format, va_list args)
Compose a string with a format string in the buffer pointed to by buf.
SR_PRIV void sr_hexdump_free(GString *s)
Free a hex dump text that was created by sr_hexdump_new().
int sr_vsnprintf_ascii(char *buf, size_t buf_size, const char *format, va_list args)
Composes a string with a format string (like printf) in the buffer pointed by buf (taking buf_size as...
int sr_parse_sizestring(const char *sizestring, uint64_t *size)
Convert a "natural" string representation of a size value to uint64_t.
int sr_parse_voltage(const char *voltstr, uint64_t *p, uint64_t *q)
int sr_sprintf_ascii(char *buf, const char *format,...)
Compose a string with a format string in the buffer pointed to by buf.
char * sr_period_string(uint64_t v_p, uint64_t v_q)
Convert a numeric period value to the "natural" string representation of its period value...
uint64_t q
Denominator of the rational number.
gboolean sr_parse_boolstring(const char *boolstr)
int64_t p
Numerator of the rational number.
char * sr_samplerate_string(uint64_t samplerate)
Convert a numeric samplerate value to its "natural" string representation.
char * sr_si_string_u64(uint64_t x, const char *unit)
Convert a numeric value value to its "natural" string representation in SI units. ...
int sr_parse_rational(const char *str, struct sr_rational *ret)
Convert a string representation of a numeric value to a sr_rational.
uint64_t sr_parse_timestring(const char *timestring)
Convert a "natural" string representation of a time value to an uint64_t value in milliseconds...