1 /* Licensed under GPLv2+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
3 #include <ccan/cast/cast.h>
14 /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
15 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
17 static char *arg_bad(const char *fmt, const char *arg)
19 char *str = opt_alloc.alloc(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 /*allow true infinity via --foo=INF, while avoiding isinf() from math.h
131 because it wasn't standard 25 years ago.*/
132 double inf = 1e300 * 1e300; /*direct 1e600 annoys -Woverflow*/
133 if ((d > FLT_MAX || d < -FLT_MAX) && d != inf && d != -inf)
134 return arg_bad("'%s' is out of range for a 32 bit float", arg);
135 if (d != 0 && *f == 0)
136 return arg_bad("'%s' is out of range (truncated to zero)", arg);
141 void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
144 opt_show_doubleval(buf, &d);
147 char *opt_set_doubleval(const char *arg, double *d)
151 /* This is how the manpage says to do it. Yech. */
153 /* Don't assume strtof */
154 *d = strtod(arg, &endp);
155 if (*endp || !arg[0])
156 return arg_bad("'%s' is not a number", arg);
158 return arg_bad("'%s' is out of range", arg);
163 void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
165 snprintf(buf, OPT_SHOW_LEN, "%f", *d);
168 char *opt_inc_intval(int *i)
174 char *opt_dec_intval(int *i)
180 /* Display version string. */
181 char *opt_version_and_exit(const char *version)
183 printf("%s\n", version);
184 /* Don't have valgrind complain! */
189 char *opt_usage_and_exit(const char *extra)
191 char *usage = opt_usage(opt_argv0, extra);
193 /* Don't have valgrind complain! */
194 opt_alloc.free(usage);
199 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
201 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
204 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
206 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
209 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
212 size_t len = strlen(*p);
214 if (len > OPT_SHOW_LEN - 2)
215 len = OPT_SHOW_LEN - 2;
216 strncpy(buf+1, *p, len);
218 if (len < OPT_SHOW_LEN - 2)
222 strncpy(buf, "(nil)", OPT_SHOW_LEN);
226 /* Show an integer value, various forms. */
227 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
229 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
232 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
234 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
237 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
239 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
242 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
244 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
247 /* a helper function that multiplies out an argument's kMGTPE suffix in the
248 * long long int range, and perform checks common to all integer destinations.
250 * The base will be either 1000 or 1024, corresponding with the '_si' and
254 static char *set_llong_with_suffix(const char *arg, long long *ll,
255 const long long base)
260 return arg_bad("'%s' (an empty string) is not a number", arg);
263 *ll = strtoll(arg, &endp, 0);
265 return arg_bad("'%s' is out of range", arg);
267 /*The string continues with non-digits. If there is just one
268 letter and it is a known multiplier suffix, use it.*/
270 return arg_bad("'%s' is not a number (suffix too long)", arg);
283 mul = base * base * base;
287 mul = base * base * base * base;
290 mul = base * base * base * base * base;
293 mul = base * base * base * base * base * base;
295 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
297 return arg_bad("'%s' is not a number (unknown suffix)",
300 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
301 return arg_bad("'%s' is out of range", arg);
307 /* Middle layer helpers that perform bounds checks for specific target sizes
310 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
314 char *err = set_llong_with_suffix(arg, &ll, base);
318 return arg_bad("'%s' is negative but destination is unsigned", arg);
323 static char * set_long_with_suffix(const char *arg, long *l, const long base)
326 char *err = set_llong_with_suffix(arg, &ll, base);
327 if (err != NULL) /*an error*/
331 /* Beware truncation, but don't generate untestable code. */
332 if (sizeof(*l) != sizeof(ll) && *l != ll)
333 return arg_bad("value '%s' does not fit into a long", arg);
337 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
340 char *err = set_llong_with_suffix(arg, &ll, base);
344 return arg_bad("'%s' is negative but destination is unsigned", arg);
346 /* Beware truncation, but don't generate untestable code. */
347 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
348 return arg_bad("value '%s' does not fit into an unsigned long", arg);
352 static char * set_int_with_suffix(const char *arg, int *i, const long base)
355 char *err = set_llong_with_suffix(arg, &ll, base);
356 if (err != NULL) /*an error*/
361 return arg_bad("value '%s' does not fit into an int", arg);
365 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
368 char *err = set_llong_with_suffix(arg, &ll, base);
372 return arg_bad("'%s' is negative but destination is unsigned", arg);
375 return arg_bad("value '%s' does not fit into an unsigned int", arg);
379 /*Set an integer, with decimal or binary suffixes.
380 The accepted suffixes are k/K, M/m, G/g, T, P, E.
382 The *_bi functions multiply the numeric value by a power of 1024, while the
383 *_si functions multiply by a power of 1000.
386 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
388 return set_ulonglong_with_suffix(arg, ll, 1024);
391 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
393 return set_ulonglong_with_suffix(arg, ll, 1000);
396 char * opt_set_longlongval_bi(const char *arg, long long *ll)
398 return set_llong_with_suffix(arg, ll, 1024);
401 char * opt_set_longlongval_si(const char *arg, long long *ll)
403 return set_llong_with_suffix(arg, ll, 1000);
406 char * opt_set_longval_bi(const char *arg, long *l)
408 return set_long_with_suffix(arg, l, 1024);
411 char * opt_set_longval_si(const char *arg, long *l)
413 return set_long_with_suffix(arg, l, 1000);
416 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
418 return set_ulong_with_suffix(arg, ul, 1024);
421 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
423 return set_ulong_with_suffix(arg, ul, 1000);
426 char * opt_set_intval_bi(const char *arg, int *i)
428 return set_int_with_suffix(arg, i, 1024);
431 char * opt_set_intval_si(const char *arg, int *i)
433 return set_int_with_suffix(arg, i, 1000);
436 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
438 return set_uint_with_suffix(arg, u, 1024);
441 char * opt_set_uintval_si(const char *arg, unsigned int *u)
443 return set_uint_with_suffix(arg, u, 1000);
446 /*static helpers for showing values with kMGTPE suffixes. In this case there
447 are separate but essentially identical functions for signed and unsigned
448 values, so that unsigned values greater than LLONG_MAX get suffixes.
450 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
451 const long long base)
453 const char *suffixes = "kMGTPE";
456 /*zero is special because everything divides it (you'd get "0E")*/
457 snprintf(buf, OPT_SHOW_LEN, "0");
460 for (i = 0; i < strlen(suffixes); i++){
461 long long tmp = ll / base;
462 if (tmp * base != ll)
467 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
469 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
472 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
475 const char *suffixes = "kMGTPE";
478 /*zero is special because everything divides it (you'd get "0E")*/
479 snprintf(buf, OPT_SHOW_LEN, "0");
482 for (i = 0; i < strlen(suffixes); i++){
483 unsigned long long tmp = ull / base;
484 if (tmp * base != ull)
489 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
491 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
495 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
497 show_llong_with_suffix(buf, *x, 1024);
500 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
502 show_llong_with_suffix(buf, *x, 1024);
505 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
507 show_llong_with_suffix(buf, *x, 1024);
511 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
513 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
516 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
518 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
521 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
523 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
527 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
529 show_llong_with_suffix(buf, (long long) *x, 1000);
532 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
534 show_llong_with_suffix(buf, (long long) *x, 1000);
537 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
539 show_llong_with_suffix(buf, *x, 1000);
543 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
545 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
548 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
550 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
553 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
555 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);