1 /* Licensed under GPLv2+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
3 #include <ccan/cast/cast.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)
16 /* FIXME: asprintf module? */
17 static char *arg_bad(const char *fmt, const char *arg)
19 char *str = malloc(strlen(fmt) + strlen(arg));
20 sprintf(str, fmt, arg);
24 char *opt_set_bool(bool *b)
30 char *opt_set_invbool(bool *b)
36 char *opt_set_bool_arg(const char *arg, bool *b)
38 if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
39 return opt_set_bool(b);
40 if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
41 return opt_set_invbool(b);
43 return opt_invalid_argument(arg);
46 char *opt_set_invbool_arg(const char *arg, bool *b)
48 char *err = opt_set_bool_arg(arg, b);
56 char *opt_set_charp(const char *arg, char **p)
58 *p = cast_const(char *, arg);
62 /* Set an integer value, various forms.
63 FIXME: set to 1 on arg == NULL ? */
64 char *opt_set_intval(const char *arg, int *i)
67 char *err = opt_set_longval(arg, &l);
72 /* Beware truncation, but don't generate untestable code. */
73 if (sizeof(*i) != sizeof(l) && *i != l)
74 return arg_bad("value '%s' does not fit into an integer", arg);
78 char *opt_set_uintval(const char *arg, unsigned int *ui)
81 char *err = opt_set_intval(arg, &i);
86 return arg_bad("'%s' is negative but destination is unsigned", arg);
91 char *opt_set_longval(const char *arg, long *l)
95 /* This is how the manpage says to do it. Yech. */
97 *l = strtol(arg, &endp, 0);
99 return arg_bad("'%s' is not a number", arg);
101 return arg_bad("'%s' is out of range", arg);
105 char *opt_set_ulongval(const char *arg, unsigned long *ul)
110 err = opt_set_longval(arg, &l);
115 return arg_bad("'%s' is negative but destination is unsigned", arg);
119 char *opt_set_floatval(const char *arg, float *f)
124 err = opt_set_doubleval(arg, &d);
130 return arg_bad("'%s' is out of range", arg);
135 void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
138 opt_show_doubleval(buf, &d);
141 char *opt_set_doubleval(const char *arg, double *d)
145 /* This is how the manpage says to do it. Yech. */
147 /* Don't assume strtof */
148 *d = strtod(arg, &endp);
149 if (*endp || !arg[0])
150 return arg_bad("'%s' is not a number", arg);
152 return arg_bad("'%s' is out of range", arg);
157 void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
159 snprintf(buf, OPT_SHOW_LEN, "%f", *d);
162 char *opt_inc_intval(int *i)
168 char *opt_dec_intval(int *i)
174 /* Display version string. */
175 char *opt_version_and_exit(const char *version)
177 printf("%s\n", version);
178 /* Don't have valgrind complain! */
183 char *opt_usage_and_exit(const char *extra)
185 char *usage = opt_usage(opt_argv0, extra);
187 /* Don't have valgrind complain! */
188 opt_alloc.free(usage);
193 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
195 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
198 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
200 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
203 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
206 size_t len = strlen(*p);
208 if (len > OPT_SHOW_LEN - 2)
209 len = OPT_SHOW_LEN - 2;
210 strncpy(buf+1, *p, len);
212 if (len < OPT_SHOW_LEN - 2)
216 strncpy(buf, "(nil)", OPT_SHOW_LEN);
220 /* Show an integer value, various forms. */
221 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
223 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
226 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
228 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
231 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
233 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
236 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
238 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
241 /* a helper function that multiplies out an argument's kMGTPE suffix in the
242 * long long int range, and perform checks common to all integer destinations.
244 * The base will be either 1000 or 1024, corresponding with the '_si' and
248 static char *set_llong_with_suffix(const char *arg, long long *ll,
249 const long long base)
254 return arg_bad("'%s' (an empty string) is not a number", arg);
257 *ll = strtoll(arg, &endp, 0);
259 return arg_bad("'%s' is out of range", arg);
261 /*The string continues with non-digits. If there is just one
262 letter and it is a known multiplier suffix, use it.*/
264 return arg_bad("'%s' is not a number (suffix too long)", arg);
277 mul = base * base * base;
281 mul = base * base * base * base;
284 mul = base * base * base * base * base;
287 mul = base * base * base * base * base * base;
289 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
291 return arg_bad("'%s' is not a number (unknown suffix)",
294 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
295 return arg_bad("'%s' is out of range", arg);
301 /* Middle layer helpers that perform bounds checks for specific target sizes
304 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
308 char *err = set_llong_with_suffix(arg, &ll, base);
312 return arg_bad("'%s' is negative but destination is unsigned", arg);
317 static char * set_long_with_suffix(const char *arg, long *l, const long base)
320 char *err = set_llong_with_suffix(arg, &ll, base);
321 if (err != NULL) /*an error*/
325 /* Beware truncation, but don't generate untestable code. */
326 if (sizeof(*l) != sizeof(ll) && *l != ll)
327 return arg_bad("value '%s' does not fit into a long", arg);
331 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
334 char *err = set_llong_with_suffix(arg, &ll, base);
338 return arg_bad("'%s' is negative but destination is unsigned", arg);
340 /* Beware truncation, but don't generate untestable code. */
341 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
342 return arg_bad("value '%s' does not fit into an unsigned long", arg);
346 static char * set_int_with_suffix(const char *arg, int *i, const long base)
349 char *err = set_llong_with_suffix(arg, &ll, base);
350 if (err != NULL) /*an error*/
355 return arg_bad("value '%s' does not fit into an int", arg);
359 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
362 char *err = set_llong_with_suffix(arg, &ll, base);
366 return arg_bad("'%s' is negative but destination is unsigned", arg);
369 return arg_bad("value '%s' does not fit into an unsigned int", arg);
373 /*Set an integer, with decimal or binary suffixes.
374 The accepted suffixes are k/K, M/m, G/g, T, P, E.
376 The *_bi functions multiply the numeric value by a power of 1024, while the
377 *_si functions multiply by a power of 1000.
380 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
382 return set_ulonglong_with_suffix(arg, ll, 1024);
385 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
387 return set_ulonglong_with_suffix(arg, ll, 1000);
390 char * opt_set_longlongval_bi(const char *arg, long long *ll)
392 return set_llong_with_suffix(arg, ll, 1024);
395 char * opt_set_longlongval_si(const char *arg, long long *ll)
397 return set_llong_with_suffix(arg, ll, 1000);
400 char * opt_set_longval_bi(const char *arg, long *l)
402 return set_long_with_suffix(arg, l, 1024);
405 char * opt_set_longval_si(const char *arg, long *l)
407 return set_long_with_suffix(arg, l, 1000);
410 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
412 return set_ulong_with_suffix(arg, ul, 1024);
415 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
417 return set_ulong_with_suffix(arg, ul, 1000);
420 char * opt_set_intval_bi(const char *arg, int *i)
422 return set_int_with_suffix(arg, i, 1024);
425 char * opt_set_intval_si(const char *arg, int *i)
427 return set_int_with_suffix(arg, i, 1000);
430 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
432 return set_uint_with_suffix(arg, u, 1024);
435 char * opt_set_uintval_si(const char *arg, unsigned int *u)
437 return set_uint_with_suffix(arg, u, 1000);
440 /*static helpers for showing values with kMGTPE suffixes. In this case there
441 are separate but essentially identical functions for signed and unsigned
442 values, so that unsigned values greater than LLONG_MAX get suffixes.
444 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
445 const long long base)
447 const char *suffixes = "kMGTPE";
450 /*zero is special because everything divides it (you'd get "0E")*/
451 snprintf(buf, OPT_SHOW_LEN, "0");
454 for (i = 0; i < strlen(suffixes); i++){
455 long long tmp = ll / base;
456 if (tmp * base != ll)
461 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
463 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
466 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
469 const char *suffixes = "kMGTPE";
472 /*zero is special because everything divides it (you'd get "0E")*/
473 snprintf(buf, OPT_SHOW_LEN, "0");
476 for (i = 0; i < strlen(suffixes); i++){
477 unsigned long long tmp = ull / base;
478 if (tmp * base != ull)
483 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
485 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
489 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
491 show_llong_with_suffix(buf, *x, 1024);
494 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
496 show_llong_with_suffix(buf, *x, 1024);
499 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
501 show_llong_with_suffix(buf, *x, 1024);
505 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
507 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
510 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
512 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
515 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
517 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
521 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
523 show_llong_with_suffix(buf, (long long) *x, 1000);
526 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
528 show_llong_with_suffix(buf, (long long) *x, 1000);
531 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
533 show_llong_with_suffix(buf, *x, 1000);
537 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
539 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
542 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
544 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
547 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
549 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);