strutil.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * This file is part of the libsigrok project.
  3. *
  4. * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <stdint.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include "libsigrok.h"
  25. #include "libsigrok-internal.h"
  26. /** @cond PRIVATE */
  27. #define LOG_PREFIX "strutil"
  28. /** @endcond */
  29. /**
  30. * @file
  31. *
  32. * Helper functions for handling or converting libsigrok-related strings.
  33. */
  34. /**
  35. * @defgroup grp_strutil String utilities
  36. *
  37. * Helper functions for handling or converting libsigrok-related strings.
  38. *
  39. * @{
  40. */
  41. /**
  42. * @private
  43. *
  44. * Convert a string representation of a numeric value to a long integer. The
  45. * conversion is strict and will fail if the complete string does not represent
  46. * a valid long integer. The function sets errno according to the details of the
  47. * failure.
  48. *
  49. * @param str The string representation to convert.
  50. * @param ret Pointer to long where the result of the conversion will be stored.
  51. *
  52. * @return SR_OK if conversion is successful, otherwise SR_ERR.
  53. *
  54. * @since 0.3.0
  55. */
  56. SR_PRIV int sr_atol(const char *str, long *ret)
  57. {
  58. long tmp;
  59. char *endptr = NULL;
  60. errno = 0;
  61. tmp = strtol(str, &endptr, 0);
  62. if (!endptr || *endptr || errno) {
  63. if (!errno)
  64. errno = EINVAL;
  65. return SR_ERR;
  66. }
  67. *ret = tmp;
  68. return SR_OK;
  69. }
  70. /**
  71. * @private
  72. *
  73. * Convert a string representation of a numeric value to an integer. The
  74. * conversion is strict and will fail if the complete string does not represent
  75. * a valid integer. The function sets errno according to the details of the
  76. * failure.
  77. *
  78. * @param str The string representation to convert.
  79. * @param ret Pointer to int where the result of the conversion will be stored.
  80. *
  81. * @return SR_OK if conversion is successful, otherwise SR_ERR.
  82. *
  83. * @since 0.3.0
  84. */
  85. SR_PRIV int sr_atoi(const char *str, int *ret)
  86. {
  87. long tmp;
  88. if (sr_atol(str, &tmp) != SR_OK)
  89. return SR_ERR;
  90. if ((int) tmp != tmp) {
  91. errno = ERANGE;
  92. return SR_ERR;
  93. }
  94. *ret = (int) tmp;
  95. return SR_OK;
  96. }
  97. /**
  98. * @private
  99. *
  100. * Convert a string representation of a numeric value to a double. The
  101. * conversion is strict and will fail if the complete string does not represent
  102. * a valid double. The function sets errno according to the details of the
  103. * failure.
  104. *
  105. * @param str The string representation to convert.
  106. * @param ret Pointer to double where the result of the conversion will be stored.
  107. *
  108. * @return SR_OK if conversion is successful, otherwise SR_ERR.
  109. *
  110. * @since 0.3.0
  111. */
  112. SR_PRIV int sr_atod(const char *str, double *ret)
  113. {
  114. double tmp;
  115. char *endptr = NULL;
  116. errno = 0;
  117. tmp = strtof(str, &endptr);
  118. if (!endptr || *endptr || errno) {
  119. if (!errno)
  120. errno = EINVAL;
  121. return SR_ERR;
  122. }
  123. *ret = tmp;
  124. return SR_OK;
  125. }
  126. /**
  127. * @private
  128. *
  129. * Convert a string representation of a numeric value to a float. The
  130. * conversion is strict and will fail if the complete string does not represent
  131. * a valid float. The function sets errno according to the details of the
  132. * failure.
  133. *
  134. * @param str The string representation to convert.
  135. * @param ret Pointer to float where the result of the conversion will be stored.
  136. *
  137. * @return SR_OK if conversion is successful, otherwise SR_ERR.
  138. *
  139. * @since 0.3.0
  140. */
  141. SR_PRIV int sr_atof(const char *str, float *ret)
  142. {
  143. double tmp;
  144. if (sr_atod(str, &tmp) != SR_OK)
  145. return SR_ERR;
  146. if ((float) tmp != tmp) {
  147. errno = ERANGE;
  148. return SR_ERR;
  149. }
  150. *ret = (float) tmp;
  151. return SR_OK;
  152. }
  153. /**
  154. * @private
  155. *
  156. * Convert a string representation of a numeric value to a float. The
  157. * conversion is strict and will fail if the complete string does not represent
  158. * a valid float. The function sets errno according to the details of the
  159. * failure. This version ignores the locale.
  160. *
  161. * @param str The string representation to convert.
  162. * @param ret Pointer to float where the result of the conversion will be stored.
  163. *
  164. * @return SR_OK if conversion is successful, otherwise SR_ERR.
  165. *
  166. * @since 0.3.0
  167. */
  168. SR_PRIV int sr_atof_ascii(const char *str, float *ret)
  169. {
  170. double tmp;
  171. char *endptr = NULL;
  172. errno = 0;
  173. tmp = g_ascii_strtod(str, &endptr);
  174. if (!endptr || *endptr || errno) {
  175. if (!errno)
  176. errno = EINVAL;
  177. return SR_ERR;
  178. }
  179. /* FIXME This fails unexpectedly. Some other method to safel downcast
  180. * needs to be found. Checking against FLT_MAX doesn't work as well. */
  181. /*
  182. if ((float) tmp != tmp) {
  183. errno = ERANGE;
  184. sr_dbg("ERANGEEEE %e != %e", (float) tmp, tmp);
  185. return SR_ERR;
  186. }
  187. */
  188. *ret = (float) tmp;
  189. return SR_OK;
  190. }
  191. /**
  192. * Convert a numeric value value to its "natural" string representation
  193. * in SI units.
  194. *
  195. * E.g. a value of 3000000, with units set to "W", would be converted
  196. * to "3 MW", 20000 to "20 kW", 31500 would become "31.5 kW".
  197. *
  198. * @param x The value to convert.
  199. * @param unit The unit to append to the string, or NULL if the string
  200. * has no units.
  201. *
  202. * @return A g_try_malloc()ed string representation of the samplerate value,
  203. * or NULL upon errors. The caller is responsible to g_free() the
  204. * memory.
  205. *
  206. * @since 0.2.0
  207. */
  208. SR_API char *sr_si_string_u64(uint64_t x, const char *unit)
  209. {
  210. uint8_t i;
  211. uint64_t quot, divisor[] = {
  212. SR_HZ(1), SR_KHZ(1), SR_MHZ(1), SR_GHZ(1),
  213. SR_GHZ(1000), SR_GHZ(1000 * 1000), SR_GHZ(1000 * 1000 * 1000),
  214. };
  215. const char *p, prefix[] = "\0kMGTPE";
  216. char fmt[16], fract[20] = "", *f;
  217. if (unit == NULL)
  218. unit = "";
  219. for (i = 0; (quot = x / divisor[i]) >= 1000; i++);
  220. if (i) {
  221. sprintf(fmt, ".%%0%d"PRIu64, i * 3);
  222. f = fract + sprintf(fract, fmt, x % divisor[i]) - 1;
  223. while (f >= fract && strchr("0.", *f))
  224. *f-- = 0;
  225. }
  226. p = prefix + i;
  227. return g_strdup_printf("%" PRIu64 "%s %.1s%s", quot, fract, p, unit);
  228. }
  229. /**
  230. * Convert a numeric samplerate value to its "natural" string representation.
  231. *
  232. * E.g. a value of 3000000 would be converted to "3 MHz", 20000 to "20 kHz",
  233. * 31500 would become "31.5 kHz".
  234. *
  235. * @param samplerate The samplerate in Hz.
  236. *
  237. * @return A g_try_malloc()ed string representation of the samplerate value,
  238. * or NULL upon errors. The caller is responsible to g_free() the
  239. * memory.
  240. *
  241. * @since 0.1.0
  242. */
  243. SR_API char *sr_samplerate_string(uint64_t samplerate)
  244. {
  245. return sr_si_string_u64(samplerate, "Hz");
  246. }
  247. /**
  248. * Convert a numeric frequency value to the "natural" string representation
  249. * of its period.
  250. *
  251. * E.g. a value of 3000000 would be converted to "3 us", 20000 to "50 ms".
  252. *
  253. * @param frequency The frequency in Hz.
  254. *
  255. * @return A g_try_malloc()ed string representation of the frequency value,
  256. * or NULL upon errors. The caller is responsible to g_free() the
  257. * memory.
  258. *
  259. * @since 0.1.0
  260. */
  261. SR_API char *sr_period_string(uint64_t frequency)
  262. {
  263. char *o;
  264. int r;
  265. /* Allocate enough for a uint64_t as string + " ms". */
  266. if (!(o = g_try_malloc0(30 + 1))) {
  267. sr_err("%s: o malloc failed", __func__);
  268. return NULL;
  269. }
  270. if (frequency >= SR_GHZ(1))
  271. r = snprintf(o, 30, "%" PRIu64 " ns", frequency / 1000000000);
  272. else if (frequency >= SR_MHZ(1))
  273. r = snprintf(o, 30, "%" PRIu64 " us", frequency / 1000000);
  274. else if (frequency >= SR_KHZ(1))
  275. r = snprintf(o, 30, "%" PRIu64 " ms", frequency / 1000);
  276. else
  277. r = snprintf(o, 30, "%" PRIu64 " s", frequency);
  278. if (r < 0) {
  279. /* Something went wrong... */
  280. g_free(o);
  281. return NULL;
  282. }
  283. return o;
  284. }
  285. /**
  286. * Convert a numeric voltage value to the "natural" string representation
  287. * of its voltage value. The voltage is specified as a rational number's
  288. * numerator and denominator.
  289. *
  290. * E.g. a value of 300000 would be converted to "300mV", 2 to "2V".
  291. *
  292. * @param v_p The voltage numerator.
  293. * @param v_q The voltage denominator.
  294. *
  295. * @return A g_try_malloc()ed string representation of the voltage value,
  296. * or NULL upon errors. The caller is responsible to g_free() the
  297. * memory.
  298. *
  299. * @since 0.2.0
  300. */
  301. SR_API char *sr_voltage_string(uint64_t v_p, uint64_t v_q)
  302. {
  303. int r;
  304. char *o;
  305. if (!(o = g_try_malloc0(30 + 1))) {
  306. sr_err("%s: o malloc failed", __func__);
  307. return NULL;
  308. }
  309. if (v_q == 1000)
  310. r = snprintf(o, 30, "%" PRIu64 "mV", v_p);
  311. else if (v_q == 1)
  312. r = snprintf(o, 30, "%" PRIu64 "V", v_p);
  313. else
  314. r = snprintf(o, 30, "%gV", (float)v_p / (float)v_q);
  315. if (r < 0) {
  316. /* Something went wrong... */
  317. g_free(o);
  318. return NULL;
  319. }
  320. return o;
  321. }
  322. /**
  323. * Parse a trigger specification string.
  324. *
  325. * @param sdi The device instance for which the trigger specification is
  326. * intended. Must not be NULL. Also, sdi->driver and
  327. * sdi->driver->info_get must not be NULL.
  328. * @param triggerstring The string containing the trigger specification for
  329. * one or more channels of this device. Entries for multiple channels are
  330. * comma-separated. Triggers are specified in the form key=value,
  331. * where the key is a channel number (or channel name) and the value is
  332. * the requested trigger type. Valid trigger types currently
  333. * include 'r' (rising edge), 'f' (falling edge), 'c' (any pin value
  334. * change), '0' (low value), or '1' (high value).
  335. * Example: "1=r,sck=f,miso=0,7=c"
  336. *
  337. * @return Pointer to a list of trigger types (strings), or NULL upon errors.
  338. * The pointer list (if non-NULL) has as many entries as the
  339. * respective device has channels (all physically available channels,
  340. * not just enabled ones). Entries of the list which don't have
  341. * a trigger value set in 'triggerstring' are NULL, the other entries
  342. * contain the respective trigger type which is requested for the
  343. * respective channel (e.g. "r", "c", and so on).
  344. *
  345. * @since 0.2.0
  346. */
  347. SR_API char **sr_parse_triggerstring(const struct sr_dev_inst *sdi,
  348. const char *triggerstring)
  349. {
  350. GSList *l;
  351. GVariant *gvar;
  352. struct sr_channel *ch;
  353. int max_channels, channelnum, i;
  354. char **tokens, **triggerlist, *trigger, *tc;
  355. const char *trigger_types;
  356. gboolean error;
  357. max_channels = g_slist_length(sdi->channels);
  358. error = FALSE;
  359. if (!(triggerlist = g_try_malloc0(max_channels * sizeof(char *)))) {
  360. sr_err("%s: triggerlist malloc failed", __func__);
  361. return NULL;
  362. }
  363. if (sdi->driver->config_list(SR_CONF_TRIGGER_TYPE,
  364. &gvar, sdi, NULL) != SR_OK) {
  365. sr_err("%s: Device doesn't support any triggers.", __func__);
  366. return NULL;
  367. }
  368. trigger_types = g_variant_get_string(gvar, NULL);
  369. tokens = g_strsplit(triggerstring, ",", max_channels);
  370. for (i = 0; tokens[i]; i++) {
  371. channelnum = -1;
  372. for (l = sdi->channels; l; l = l->next) {
  373. ch = (struct sr_channel *)l->data;
  374. if (ch->enabled
  375. && !strncmp(ch->name, tokens[i],
  376. strlen(ch->name))) {
  377. channelnum = ch->index;
  378. break;
  379. }
  380. }
  381. if (channelnum < 0 || channelnum >= max_channels) {
  382. sr_err("Invalid channel.");
  383. error = TRUE;
  384. break;
  385. }
  386. if ((trigger = strchr(tokens[i], '='))) {
  387. for (tc = ++trigger; *tc; tc++) {
  388. if (strchr(trigger_types, *tc) == NULL) {
  389. sr_err("Unsupported trigger "
  390. "type '%c'.", *tc);
  391. error = TRUE;
  392. break;
  393. }
  394. }
  395. if (!error)
  396. triggerlist[channelnum] = g_strdup(trigger);
  397. }
  398. }
  399. g_strfreev(tokens);
  400. g_variant_unref(gvar);
  401. if (error) {
  402. for (i = 0; i < max_channels; i++)
  403. g_free(triggerlist[i]);
  404. g_free(triggerlist);
  405. triggerlist = NULL;
  406. }
  407. return triggerlist;
  408. }
  409. /**
  410. * Convert a "natural" string representation of a size value to uint64_t.
  411. *
  412. * E.g. a value of "3k" or "3 K" would be converted to 3000, a value
  413. * of "15M" would be converted to 15000000.
  414. *
  415. * Value representations other than decimal (such as hex or octal) are not
  416. * supported. Only 'k' (kilo), 'm' (mega), 'g' (giga) suffixes are supported.
  417. * Spaces (but not other whitespace) between value and suffix are allowed.
  418. *
  419. * @param sizestring A string containing a (decimal) size value.
  420. * @param size Pointer to uint64_t which will contain the string's size value.
  421. *
  422. * @return SR_OK upon success, SR_ERR upon errors.
  423. *
  424. * @since 0.1.0
  425. */
  426. SR_API int sr_parse_sizestring(const char *sizestring, uint64_t *size)
  427. {
  428. int multiplier, done;
  429. double frac_part;
  430. char *s;
  431. *size = strtoull(sizestring, &s, 10);
  432. multiplier = 0;
  433. frac_part = 0;
  434. done = FALSE;
  435. while (s && *s && multiplier == 0 && !done) {
  436. switch (*s) {
  437. case ' ':
  438. break;
  439. case '.':
  440. frac_part = g_ascii_strtod(s, &s);
  441. break;
  442. case 'k':
  443. case 'K':
  444. multiplier = SR_KHZ(1);
  445. break;
  446. case 'm':
  447. case 'M':
  448. multiplier = SR_MHZ(1);
  449. break;
  450. case 'g':
  451. case 'G':
  452. multiplier = SR_GHZ(1);
  453. break;
  454. default:
  455. done = TRUE;
  456. s--;
  457. }
  458. s++;
  459. }
  460. if (multiplier > 0) {
  461. *size *= multiplier;
  462. *size += frac_part * multiplier;
  463. } else
  464. *size += frac_part;
  465. if (*s && strcasecmp(s, "Hz"))
  466. return SR_ERR;
  467. return SR_OK;
  468. }
  469. /**
  470. * Convert a "natural" string representation of a time value to an
  471. * uint64_t value in milliseconds.
  472. *
  473. * E.g. a value of "3s" or "3 s" would be converted to 3000, a value
  474. * of "15ms" would be converted to 15.
  475. *
  476. * Value representations other than decimal (such as hex or octal) are not
  477. * supported. Only lower-case "s" and "ms" time suffixes are supported.
  478. * Spaces (but not other whitespace) between value and suffix are allowed.
  479. *
  480. * @param timestring A string containing a (decimal) time value.
  481. * @return The string's time value as uint64_t, in milliseconds.
  482. *
  483. * @todo Add support for "m" (minutes) and others.
  484. * @todo Add support for picoseconds?
  485. * @todo Allow both lower-case and upper-case? If no, document it.
  486. *
  487. * @since 0.1.0
  488. */
  489. SR_API uint64_t sr_parse_timestring(const char *timestring)
  490. {
  491. uint64_t time_msec;
  492. char *s;
  493. /* TODO: Error handling, logging. */
  494. time_msec = strtoull(timestring, &s, 10);
  495. if (time_msec == 0 && s == timestring)
  496. return 0;
  497. if (s && *s) {
  498. while (*s == ' ')
  499. s++;
  500. if (!strcmp(s, "s"))
  501. time_msec *= 1000;
  502. else if (!strcmp(s, "ms"))
  503. ; /* redundant */
  504. else
  505. return 0;
  506. }
  507. return time_msec;
  508. }
  509. /** @since 0.1.0 */
  510. SR_API gboolean sr_parse_boolstring(const char *boolstr)
  511. {
  512. if (!boolstr)
  513. return FALSE;
  514. if (!g_ascii_strncasecmp(boolstr, "true", 4) ||
  515. !g_ascii_strncasecmp(boolstr, "yes", 3) ||
  516. !g_ascii_strncasecmp(boolstr, "on", 2) ||
  517. !g_ascii_strncasecmp(boolstr, "1", 1))
  518. return TRUE;
  519. return FALSE;
  520. }
  521. /** @since 0.2.0 */
  522. SR_API int sr_parse_period(const char *periodstr, uint64_t *p, uint64_t *q)
  523. {
  524. char *s;
  525. *p = strtoull(periodstr, &s, 10);
  526. if (*p == 0 && s == periodstr)
  527. /* No digits found. */
  528. return SR_ERR_ARG;
  529. if (s && *s) {
  530. while (*s == ' ')
  531. s++;
  532. if (!strcmp(s, "fs"))
  533. *q = 1000000000000000ULL;
  534. else if (!strcmp(s, "ps"))
  535. *q = 1000000000000ULL;
  536. else if (!strcmp(s, "ns"))
  537. *q = 1000000000ULL;
  538. else if (!strcmp(s, "us"))
  539. *q = 1000000;
  540. else if (!strcmp(s, "ms"))
  541. *q = 1000;
  542. else if (!strcmp(s, "s"))
  543. *q = 1;
  544. else
  545. /* Must have a time suffix. */
  546. return SR_ERR_ARG;
  547. }
  548. return SR_OK;
  549. }
  550. /** @since 0.2.0 */
  551. SR_API int sr_parse_voltage(const char *voltstr, uint64_t *p, uint64_t *q)
  552. {
  553. char *s;
  554. *p = strtoull(voltstr, &s, 10);
  555. if (*p == 0 && s == voltstr)
  556. /* No digits found. */
  557. return SR_ERR_ARG;
  558. if (s && *s) {
  559. while (*s == ' ')
  560. s++;
  561. if (!strcasecmp(s, "mv"))
  562. *q = 1000L;
  563. else if (!strcasecmp(s, "v"))
  564. *q = 1;
  565. else
  566. /* Must have a base suffix. */
  567. return SR_ERR_ARG;
  568. }
  569. return SR_OK;
  570. }
  571. /** @} */