helpers.c 11 KB

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