helpers.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /* Licensed under GPLv2+ - see LICENSE file for details */
  2. #include <ccan/opt/opt.h>
  3. #include <ccan/cast/cast.h>
  4. #include <inttypes.h>
  5. #include <string.h>
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <errno.h>
  9. #include <stdio.h>
  10. #include <limits.h>
  11. #include "private.h"
  12. #include <float.h>
  13. /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
  14. #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
  15. /* FIXME: asprintf module? */
  16. static char *arg_bad(const char *fmt, const char *arg)
  17. {
  18. char *str = malloc(strlen(fmt) + strlen(arg));
  19. sprintf(str, fmt, arg);
  20. return str;
  21. }
  22. char *opt_set_bool(bool *b)
  23. {
  24. *b = true;
  25. return NULL;
  26. }
  27. char *opt_set_invbool(bool *b)
  28. {
  29. *b = false;
  30. return NULL;
  31. }
  32. char *opt_set_bool_arg(const char *arg, bool *b)
  33. {
  34. if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
  35. return opt_set_bool(b);
  36. if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
  37. return opt_set_invbool(b);
  38. return opt_invalid_argument(arg);
  39. }
  40. char *opt_set_invbool_arg(const char *arg, bool *b)
  41. {
  42. char *err = opt_set_bool_arg(arg, b);
  43. if (!err)
  44. *b = !*b;
  45. return err;
  46. }
  47. /* Set a char *. */
  48. char *opt_set_charp(const char *arg, char **p)
  49. {
  50. *p = cast_const(char *, arg);
  51. return NULL;
  52. }
  53. /* Set an integer value, various forms.
  54. FIXME: set to 1 on arg == NULL ? */
  55. char *opt_set_intval(const char *arg, int *i)
  56. {
  57. long l;
  58. char *err = opt_set_longval(arg, &l);
  59. if (err)
  60. return err;
  61. *i = l;
  62. /* Beware truncation, but don't generate untestable code. */
  63. if (sizeof(*i) != sizeof(l) && *i != l)
  64. return arg_bad("value '%s' does not fit into an integer", arg);
  65. return err;
  66. }
  67. char *opt_set_uintval(const char *arg, unsigned int *ui)
  68. {
  69. int i;
  70. char *err = opt_set_intval(arg, &i);
  71. if (err)
  72. return err;
  73. if (i < 0)
  74. return arg_bad("'%s' is negative but destination is unsigned", arg);
  75. *ui = i;
  76. return NULL;
  77. }
  78. char *opt_set_longval(const char *arg, long *l)
  79. {
  80. char *endp;
  81. /* This is how the manpage says to do it. Yech. */
  82. errno = 0;
  83. *l = strtol(arg, &endp, 0);
  84. if (*endp || !arg[0])
  85. return arg_bad("'%s' is not a number", arg);
  86. if (errno)
  87. return arg_bad("'%s' is out of range", arg);
  88. return NULL;
  89. }
  90. char *opt_set_ulongval(const char *arg, unsigned long *ul)
  91. {
  92. long int l;
  93. char *err;
  94. err = opt_set_longval(arg, &l);
  95. if (err)
  96. return err;
  97. *ul = l;
  98. if (l < 0)
  99. return arg_bad("'%s' is negative but destination is unsigned", arg);
  100. return NULL;
  101. }
  102. char *opt_set_floatval(const char *arg, float *f)
  103. {
  104. double d;
  105. char *err;
  106. err = opt_set_doubleval(arg, &d);
  107. if (err)
  108. return err;
  109. *f = d;
  110. /*allow true infinity via --foo=INF, while avoiding isinf() from math.h
  111. because it wasn't standard 25 years ago.*/
  112. double inf = 1e300 * 1e300; /*direct 1e600 annoys -Woverflow*/
  113. if ((d > FLT_MAX || d < -FLT_MAX) && d != inf && d != -inf)
  114. return arg_bad("'%s' is out of range for a 32 bit float", arg);
  115. if (d != 0 && *f == 0)
  116. return arg_bad("'%s' is out of range (truncated to zero)", arg);
  117. return NULL;
  118. }
  119. void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
  120. {
  121. double d = *f;
  122. opt_show_doubleval(buf, &d);
  123. }
  124. char *opt_set_doubleval(const char *arg, double *d)
  125. {
  126. char *endp;
  127. /* This is how the manpage says to do it. Yech. */
  128. errno = 0;
  129. /* Don't assume strtof */
  130. *d = strtod(arg, &endp);
  131. if (*endp || !arg[0])
  132. return arg_bad("'%s' is not a number", arg);
  133. if (errno)
  134. return arg_bad("'%s' is out of range", arg);
  135. return NULL;
  136. }
  137. void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
  138. {
  139. snprintf(buf, OPT_SHOW_LEN, "%f", *d);
  140. }
  141. char *opt_inc_intval(int *i)
  142. {
  143. (*i)++;
  144. return NULL;
  145. }
  146. char *opt_dec_intval(int *i)
  147. {
  148. (*i)--;
  149. return NULL;
  150. }
  151. /* Display version string. */
  152. char *opt_version_and_exit(const char *version)
  153. {
  154. printf("%s\n", version);
  155. /* Don't have valgrind complain! */
  156. opt_free_table();
  157. exit(0);
  158. }
  159. char *opt_usage_and_exit(const char *extra)
  160. {
  161. char *usage = opt_usage(opt_argv0, extra);
  162. printf("%s", usage);
  163. /* Don't have valgrind complain! */
  164. opt_alloc.free(usage);
  165. opt_free_table();
  166. exit(0);
  167. }
  168. void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
  169. {
  170. strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
  171. }
  172. void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
  173. {
  174. strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
  175. }
  176. void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
  177. {
  178. if (*p){
  179. size_t len = strlen(*p);
  180. buf[0] = '"';
  181. if (len > OPT_SHOW_LEN - 2)
  182. len = OPT_SHOW_LEN - 2;
  183. strncpy(buf+1, *p, len);
  184. buf[1+len] = '"';
  185. if (len < OPT_SHOW_LEN - 2)
  186. buf[2+len] = '\0';
  187. }
  188. else {
  189. strncpy(buf, "(nil)", OPT_SHOW_LEN);
  190. }
  191. }
  192. /* Show an integer value, various forms. */
  193. void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
  194. {
  195. snprintf(buf, OPT_SHOW_LEN, "%i", *i);
  196. }
  197. void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
  198. {
  199. snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
  200. }
  201. void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
  202. {
  203. snprintf(buf, OPT_SHOW_LEN, "%li", *l);
  204. }
  205. void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
  206. {
  207. snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
  208. }
  209. /* a helper function that multiplies out an argument's kMGTPE suffix in the
  210. * long long int range, and perform checks common to all integer destinations.
  211. *
  212. * The base will be either 1000 or 1024, corresponding with the '_si' and
  213. * '_bi' functions.
  214. */
  215. static char *set_llong_with_suffix(const char *arg, long long *ll,
  216. const long long base)
  217. {
  218. char *endp;
  219. if (!arg[0]){
  220. *ll = 0;
  221. return arg_bad("'%s' (an empty string) is not a number", arg);
  222. }
  223. errno = 0;
  224. *ll = strtoll(arg, &endp, 0);
  225. if (errno)
  226. return arg_bad("'%s' is out of range", arg);
  227. if (*endp){
  228. /*The string continues with non-digits. If there is just one
  229. letter and it is a known multiplier suffix, use it.*/
  230. if (endp[1])
  231. return arg_bad("'%s' is not a number (suffix too long)", arg);
  232. long long mul;
  233. switch(*endp){
  234. case 'K':
  235. case 'k':
  236. mul = base;
  237. break;
  238. case 'M':
  239. case 'm':
  240. mul = base * base;
  241. break;
  242. case 'G':
  243. case 'g':
  244. mul = base * base * base;
  245. break;
  246. case 'T':
  247. case 't':
  248. mul = base * base * base * base;
  249. break;
  250. case 'P':
  251. mul = base * base * base * base * base;
  252. break;
  253. case 'E':
  254. mul = base * base * base * base * base * base;
  255. break;
  256. /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
  257. default:
  258. return arg_bad("'%s' is not a number (unknown suffix)",
  259. arg);
  260. }
  261. if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
  262. return arg_bad("'%s' is out of range", arg);
  263. *ll *= mul;
  264. }
  265. return NULL;
  266. }
  267. /* Middle layer helpers that perform bounds checks for specific target sizes
  268. * and signednesses.
  269. */
  270. static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
  271. const long base)
  272. {
  273. long long ll;
  274. char *err = set_llong_with_suffix(arg, &ll, base);
  275. if (err != NULL)
  276. return err;
  277. if (ll < 0)
  278. return arg_bad("'%s' is negative but destination is unsigned", arg);
  279. *ull = ll;
  280. return NULL;
  281. }
  282. static char * set_long_with_suffix(const char *arg, long *l, const long base)
  283. {
  284. long long ll;
  285. char *err = set_llong_with_suffix(arg, &ll, base);
  286. if (err != NULL) /*an error*/
  287. return err;
  288. *l = ll;
  289. /* Beware truncation, but don't generate untestable code. */
  290. if (sizeof(*l) != sizeof(ll) && *l != ll)
  291. return arg_bad("value '%s' does not fit into a long", arg);
  292. return NULL;
  293. }
  294. static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
  295. {
  296. long long ll;
  297. char *err = set_llong_with_suffix(arg, &ll, base);
  298. if (err != NULL)
  299. return err;
  300. if (ll < 0)
  301. return arg_bad("'%s' is negative but destination is unsigned", arg);
  302. *ul = ll;
  303. /* Beware truncation, but don't generate untestable code. */
  304. if (sizeof(*ul) != sizeof(ll) && *ul != ll)
  305. return arg_bad("value '%s' does not fit into an unsigned long", arg);
  306. return NULL;
  307. }
  308. static char * set_int_with_suffix(const char *arg, int *i, const long base)
  309. {
  310. long long ll;
  311. char *err = set_llong_with_suffix(arg, &ll, base);
  312. if (err != NULL) /*an error*/
  313. return err;
  314. *i = ll;
  315. if (*i != ll)
  316. return arg_bad("value '%s' does not fit into an int", arg);
  317. return NULL;
  318. }
  319. static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
  320. {
  321. long long ll;
  322. char *err = set_llong_with_suffix(arg, &ll, base);
  323. if (err != NULL)
  324. return err;
  325. if (ll < 0)
  326. return arg_bad("'%s' is negative but destination is unsigned", arg);
  327. *u = ll;
  328. if (*u != ll)
  329. return arg_bad("value '%s' does not fit into an unsigned int", arg);
  330. return NULL;
  331. }
  332. /*Set an integer, with decimal or binary suffixes.
  333. The accepted suffixes are k/K, M/m, G/g, T, P, E.
  334. The *_bi functions multiply the numeric value by a power of 1024, while the
  335. *_si functions multiply by a power of 1000.
  336. */
  337. char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
  338. {
  339. return set_ulonglong_with_suffix(arg, ll, 1024);
  340. }
  341. char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
  342. {
  343. return set_ulonglong_with_suffix(arg, ll, 1000);
  344. }
  345. char * opt_set_longlongval_bi(const char *arg, long long *ll)
  346. {
  347. return set_llong_with_suffix(arg, ll, 1024);
  348. }
  349. char * opt_set_longlongval_si(const char *arg, long long *ll)
  350. {
  351. return set_llong_with_suffix(arg, ll, 1000);
  352. }
  353. char * opt_set_longval_bi(const char *arg, long *l)
  354. {
  355. return set_long_with_suffix(arg, l, 1024);
  356. }
  357. char * opt_set_longval_si(const char *arg, long *l)
  358. {
  359. return set_long_with_suffix(arg, l, 1000);
  360. }
  361. char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
  362. {
  363. return set_ulong_with_suffix(arg, ul, 1024);
  364. }
  365. char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
  366. {
  367. return set_ulong_with_suffix(arg, ul, 1000);
  368. }
  369. char * opt_set_intval_bi(const char *arg, int *i)
  370. {
  371. return set_int_with_suffix(arg, i, 1024);
  372. }
  373. char * opt_set_intval_si(const char *arg, int *i)
  374. {
  375. return set_int_with_suffix(arg, i, 1000);
  376. }
  377. char * opt_set_uintval_bi(const char *arg, unsigned int *u)
  378. {
  379. return set_uint_with_suffix(arg, u, 1024);
  380. }
  381. char * opt_set_uintval_si(const char *arg, unsigned int *u)
  382. {
  383. return set_uint_with_suffix(arg, u, 1000);
  384. }
  385. /*static helpers for showing values with kMGTPE suffixes. In this case there
  386. are separate but essentially identical functions for signed and unsigned
  387. values, so that unsigned values greater than LLONG_MAX get suffixes.
  388. */
  389. static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
  390. const long long base)
  391. {
  392. const char *suffixes = "kMGTPE";
  393. int i;
  394. if (ll == 0){
  395. /*zero is special because everything divides it (you'd get "0E")*/
  396. snprintf(buf, OPT_SHOW_LEN, "0");
  397. return;
  398. }
  399. for (i = 0; i < strlen(suffixes); i++){
  400. long long tmp = ll / base;
  401. if (tmp * base != ll)
  402. break;
  403. ll = tmp;
  404. }
  405. if (i == 0)
  406. snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
  407. else
  408. snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
  409. }
  410. static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
  411. const unsigned base)
  412. {
  413. const char *suffixes = "kMGTPE";
  414. int i;
  415. if (ull == 0){
  416. /*zero is special because everything divides it (you'd get "0E")*/
  417. snprintf(buf, OPT_SHOW_LEN, "0");
  418. return;
  419. }
  420. for (i = 0; i < strlen(suffixes); i++){
  421. unsigned long long tmp = ull / base;
  422. if (tmp * base != ull)
  423. break;
  424. ull = tmp;
  425. }
  426. if (i == 0)
  427. snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
  428. else
  429. snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
  430. }
  431. /* _bi, signed */
  432. void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
  433. {
  434. show_llong_with_suffix(buf, *x, 1024);
  435. }
  436. void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
  437. {
  438. show_llong_with_suffix(buf, *x, 1024);
  439. }
  440. void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
  441. {
  442. show_llong_with_suffix(buf, *x, 1024);
  443. }
  444. /* _bi, unsigned */
  445. void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
  446. {
  447. show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
  448. }
  449. void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
  450. {
  451. show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
  452. }
  453. void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
  454. {
  455. show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
  456. }
  457. /* _si, signed */
  458. void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
  459. {
  460. show_llong_with_suffix(buf, (long long) *x, 1000);
  461. }
  462. void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
  463. {
  464. show_llong_with_suffix(buf, (long long) *x, 1000);
  465. }
  466. void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
  467. {
  468. show_llong_with_suffix(buf, *x, 1000);
  469. }
  470. /* _si, unsigned */
  471. void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
  472. {
  473. show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
  474. }
  475. void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
  476. {
  477. show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
  478. }
  479. void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
  480. {
  481. show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
  482. }