1 /* Licensed under GPLv3+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
10 /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
11 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
13 /* FIXME: asprintf module? */
14 static char *arg_bad(const char *fmt, const char *arg)
16 char *str = malloc(strlen(fmt) + strlen(arg));
17 sprintf(str, fmt, arg);
21 char *opt_set_bool(bool *b)
27 char *opt_set_invbool(bool *b)
33 char *opt_set_bool_arg(const char *arg, bool *b)
35 if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
36 return opt_set_bool(b);
37 if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
38 return opt_set_invbool(b);
40 return opt_invalid_argument(arg);
43 char *opt_set_invbool_arg(const char *arg, bool *b)
45 char *err = opt_set_bool_arg(arg, b);
53 char *opt_set_charp(const char *arg, char **p)
59 /* Set an integer value, various forms.
60 FIXME: set to 1 on arg == NULL ? */
61 char *opt_set_intval(const char *arg, int *i)
64 char *err = opt_set_longval(arg, &l);
69 /* Beware truncation, but don't generate untestable code. */
70 if (sizeof(*i) != sizeof(l) && *i != l)
71 return arg_bad("value '%s' does not fit into an integer", arg);
75 char *opt_set_uintval(const char *arg, unsigned int *ui)
78 char *err = opt_set_intval(arg, &i);
83 return arg_bad("'%s' is negative but destination is unsigned", arg);
88 char *opt_set_longval(const char *arg, long *l)
92 /* This is how the manpage says to do it. Yech. */
94 *l = strtol(arg, &endp, 0);
96 return arg_bad("'%s' is not a number", arg);
98 return arg_bad("'%s' is out of range", arg);
102 char *opt_set_ulongval(const char *arg, unsigned long *ul)
107 err = opt_set_longval(arg, &l);
112 return arg_bad("'%s' is negative but destination is unsigned", arg);
116 char *opt_inc_intval(int *i)
122 /* Display version string. */
123 char *opt_version_and_exit(const char *version)
125 printf("%s\n", version);
126 /* Don't have valgrind complain! */
131 char *opt_usage_and_exit(const char *extra)
133 char *usage = opt_usage(opt_argv0, extra);
135 /* Don't have valgrind complain! */
141 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
143 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
146 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
148 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
151 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
153 size_t len = strlen(*p);
155 if (len > OPT_SHOW_LEN - 2)
156 len = OPT_SHOW_LEN - 2;
157 strncpy(buf+1, *p, len);
159 if (len < OPT_SHOW_LEN - 2)
163 /* Show an integer value, various forms. */
164 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
166 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
169 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
171 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
174 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
176 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
179 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
181 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
184 /* a helper function that multiplies out an argument's kMGTPE suffix in the
185 * long long int range, and perform checks common to all integer destinations.
187 * The base will be either 1000 or 1024, corresponding with the '_si' and
191 static char *set_llong_with_suffix(const char *arg, long long *ll,
192 const long long base)
196 return arg_bad("'%s' (an empty string) is not a number", arg);
199 *ll = strtoll(arg, &endp, 0);
201 return arg_bad("'%s' is out of range", arg);
203 /*The string continues with non-digits. If there is just one
204 letter and it is a known multiplier suffix, use it.*/
206 return arg_bad("'%s' is not a number (suffix too long)", arg);
219 mul = base * base * base;
223 mul = base * base * base * base;
226 mul = base * base * base * base * base;
229 mul = base * base * base * base * base * base;
231 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
233 return arg_bad("'%s' is not a number (unknown suffix)",
236 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
237 return arg_bad("'%s' is out of range", arg);
243 /* Middle layer helpers that perform bounds checks for specific target sizes
246 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
250 char *err = set_llong_with_suffix(arg, &ll, base);
254 return arg_bad("'%s' is negative but destination is unsigned", arg);
259 static char * set_long_with_suffix(const char *arg, long *l, const long base)
262 char *err = set_llong_with_suffix(arg, &ll, base);
263 if (err != NULL) /*an error*/
267 /* Beware truncation, but don't generate untestable code. */
268 if (sizeof(*l) != sizeof(ll) && *l != ll)
269 return arg_bad("value '%s' does not fit into a long", arg);
273 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
276 char *err = set_llong_with_suffix(arg, &ll, base);
280 return arg_bad("'%s' is negative but destination is unsigned", arg);
282 /* Beware truncation, but don't generate untestable code. */
283 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
284 return arg_bad("value '%s' does not fit into an unsigned long", arg);
288 static char * set_int_with_suffix(const char *arg, int *i, const long base)
291 char *err = set_llong_with_suffix(arg, &ll, base);
292 if (err != NULL) /*an error*/
297 return arg_bad("value '%s' does not fit into an int", arg);
301 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
304 char *err = set_llong_with_suffix(arg, &ll, base);
308 return arg_bad("'%s' is negative but destination is unsigned", arg);
311 return arg_bad("value '%s' does not fit into an unsigned int", arg);
315 /*Set an integer, with decimal or binary suffixes.
316 The accepted suffixes are k/K, M/m, G/g, T, P, E.
318 The *_bi functions multiply the numeric value by a power of 1024, while the
319 *_si functions multiply by a power of 1000.
322 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
324 return set_ulonglong_with_suffix(arg, ll, 1024);
327 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
329 return set_ulonglong_with_suffix(arg, ll, 1000);
332 char * opt_set_longlongval_bi(const char *arg, long long *ll)
334 return set_llong_with_suffix(arg, ll, 1024);
337 char * opt_set_longlongval_si(const char *arg, long long *ll)
339 return set_llong_with_suffix(arg, ll, 1000);
342 char * opt_set_longval_bi(const char *arg, long *l)
344 return set_long_with_suffix(arg, l, 1024);
347 char * opt_set_longval_si(const char *arg, long *l)
349 return set_long_with_suffix(arg, l, 1000);
352 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
354 return set_ulong_with_suffix(arg, ul, 1024);
357 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
359 return set_ulong_with_suffix(arg, ul, 1000);
362 char * opt_set_intval_bi(const char *arg, int *i)
364 return set_int_with_suffix(arg, i, 1024);
367 char * opt_set_intval_si(const char *arg, int *i)
369 return set_int_with_suffix(arg, i, 1000);
372 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
374 return set_uint_with_suffix(arg, u, 1024);
377 char * opt_set_uintval_si(const char *arg, unsigned int *u)
379 return set_uint_with_suffix(arg, u, 1000);
382 /*static helpers for showing values with kMGTPE suffixes. In this case there
383 are separate but essentially identical functions for signed and unsigned
384 values, so that unsigned values greater than LLONG_MAX get suffixes.
386 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
387 const long long base)
389 const char *suffixes = "kMGTPE";
392 /*zero is special because everything divides it (you'd get "0E")*/
393 snprintf(buf, OPT_SHOW_LEN, "0");
396 for (i = 0; i < strlen(suffixes); i++){
397 long long tmp = ll / base;
398 if (tmp * base != ll)
403 snprintf(buf, OPT_SHOW_LEN, "%lld", ll);
405 snprintf(buf, OPT_SHOW_LEN, "%lld%c", ll, suffixes[i - 1]);
408 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
411 const char *suffixes = "kMGTPE";
414 /*zero is special because everything divides it (you'd get "0E")*/
415 snprintf(buf, OPT_SHOW_LEN, "0");
418 for (i = 0; i < strlen(suffixes); i++){
419 unsigned long long tmp = ull / base;
420 if (tmp * base != ull)
425 snprintf(buf, OPT_SHOW_LEN, "%llu", ull);
427 snprintf(buf, OPT_SHOW_LEN, "%llu%c", ull, suffixes[i - 1]);
431 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
433 show_llong_with_suffix(buf, *x, 1024);
436 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
438 show_llong_with_suffix(buf, *x, 1024);
441 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
443 show_llong_with_suffix(buf, *x, 1024);
447 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
449 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
452 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
454 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
457 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
459 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
463 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
465 show_llong_with_suffix(buf, (long long) *x, 1000);
468 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
470 show_llong_with_suffix(buf, (long long) *x, 1000);
473 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
475 show_llong_with_suffix(buf, *x, 1000);
479 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
481 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
484 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
486 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
489 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
491 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);