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 /* Display version string. */
169 char *opt_version_and_exit(const char *version)
171 printf("%s\n", version);
172 /* Don't have valgrind complain! */
177 char *opt_usage_and_exit(const char *extra)
179 char *usage = opt_usage(opt_argv0, extra);
181 /* Don't have valgrind complain! */
182 opt_alloc.free(usage);
187 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
189 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
192 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
194 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
197 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
199 size_t len = strlen(*p);
201 if (len > OPT_SHOW_LEN - 2)
202 len = OPT_SHOW_LEN - 2;
203 strncpy(buf+1, *p, len);
205 if (len < OPT_SHOW_LEN - 2)
209 /* Show an integer value, various forms. */
210 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
212 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
215 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
217 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
220 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
222 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
225 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
227 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
230 /* a helper function that multiplies out an argument's kMGTPE suffix in the
231 * long long int range, and perform checks common to all integer destinations.
233 * The base will be either 1000 or 1024, corresponding with the '_si' and
237 static char *set_llong_with_suffix(const char *arg, long long *ll,
238 const long long base)
243 return arg_bad("'%s' (an empty string) is not a number", arg);
246 *ll = strtoll(arg, &endp, 0);
248 return arg_bad("'%s' is out of range", arg);
250 /*The string continues with non-digits. If there is just one
251 letter and it is a known multiplier suffix, use it.*/
253 return arg_bad("'%s' is not a number (suffix too long)", arg);
266 mul = base * base * base;
270 mul = base * base * base * base;
273 mul = base * base * base * base * base;
276 mul = base * base * base * base * base * base;
278 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
280 return arg_bad("'%s' is not a number (unknown suffix)",
283 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
284 return arg_bad("'%s' is out of range", arg);
290 /* Middle layer helpers that perform bounds checks for specific target sizes
293 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
297 char *err = set_llong_with_suffix(arg, &ll, base);
301 return arg_bad("'%s' is negative but destination is unsigned", arg);
306 static char * set_long_with_suffix(const char *arg, long *l, const long base)
309 char *err = set_llong_with_suffix(arg, &ll, base);
310 if (err != NULL) /*an error*/
314 /* Beware truncation, but don't generate untestable code. */
315 if (sizeof(*l) != sizeof(ll) && *l != ll)
316 return arg_bad("value '%s' does not fit into a long", arg);
320 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
323 char *err = set_llong_with_suffix(arg, &ll, base);
327 return arg_bad("'%s' is negative but destination is unsigned", arg);
329 /* Beware truncation, but don't generate untestable code. */
330 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
331 return arg_bad("value '%s' does not fit into an unsigned long", arg);
335 static char * set_int_with_suffix(const char *arg, int *i, const long base)
338 char *err = set_llong_with_suffix(arg, &ll, base);
339 if (err != NULL) /*an error*/
344 return arg_bad("value '%s' does not fit into an int", arg);
348 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
351 char *err = set_llong_with_suffix(arg, &ll, base);
355 return arg_bad("'%s' is negative but destination is unsigned", arg);
358 return arg_bad("value '%s' does not fit into an unsigned int", arg);
362 /*Set an integer, with decimal or binary suffixes.
363 The accepted suffixes are k/K, M/m, G/g, T, P, E.
365 The *_bi functions multiply the numeric value by a power of 1024, while the
366 *_si functions multiply by a power of 1000.
369 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
371 return set_ulonglong_with_suffix(arg, ll, 1024);
374 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
376 return set_ulonglong_with_suffix(arg, ll, 1000);
379 char * opt_set_longlongval_bi(const char *arg, long long *ll)
381 return set_llong_with_suffix(arg, ll, 1024);
384 char * opt_set_longlongval_si(const char *arg, long long *ll)
386 return set_llong_with_suffix(arg, ll, 1000);
389 char * opt_set_longval_bi(const char *arg, long *l)
391 return set_long_with_suffix(arg, l, 1024);
394 char * opt_set_longval_si(const char *arg, long *l)
396 return set_long_with_suffix(arg, l, 1000);
399 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
401 return set_ulong_with_suffix(arg, ul, 1024);
404 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
406 return set_ulong_with_suffix(arg, ul, 1000);
409 char * opt_set_intval_bi(const char *arg, int *i)
411 return set_int_with_suffix(arg, i, 1024);
414 char * opt_set_intval_si(const char *arg, int *i)
416 return set_int_with_suffix(arg, i, 1000);
419 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
421 return set_uint_with_suffix(arg, u, 1024);
424 char * opt_set_uintval_si(const char *arg, unsigned int *u)
426 return set_uint_with_suffix(arg, u, 1000);
429 /*static helpers for showing values with kMGTPE suffixes. In this case there
430 are separate but essentially identical functions for signed and unsigned
431 values, so that unsigned values greater than LLONG_MAX get suffixes.
433 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
434 const long long base)
436 const char *suffixes = "kMGTPE";
439 /*zero is special because everything divides it (you'd get "0E")*/
440 snprintf(buf, OPT_SHOW_LEN, "0");
443 for (i = 0; i < strlen(suffixes); i++){
444 long long tmp = ll / base;
445 if (tmp * base != ll)
450 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
452 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
455 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
458 const char *suffixes = "kMGTPE";
461 /*zero is special because everything divides it (you'd get "0E")*/
462 snprintf(buf, OPT_SHOW_LEN, "0");
465 for (i = 0; i < strlen(suffixes); i++){
466 unsigned long long tmp = ull / base;
467 if (tmp * base != ull)
472 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
474 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
478 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
480 show_llong_with_suffix(buf, *x, 1024);
483 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
485 show_llong_with_suffix(buf, *x, 1024);
488 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
490 show_llong_with_suffix(buf, *x, 1024);
494 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
496 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
499 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
501 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
504 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
506 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
510 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
512 show_llong_with_suffix(buf, (long long) *x, 1000);
515 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
517 show_llong_with_suffix(buf, (long long) *x, 1000);
520 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
522 show_llong_with_suffix(buf, *x, 1000);
526 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
528 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
531 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
533 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
536 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
538 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);