1 /* Licensed under GPLv3+ - 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_inc_intval(int *i)
125 /* Display version string. */
126 char *opt_version_and_exit(const char *version)
128 printf("%s\n", version);
129 /* Don't have valgrind complain! */
134 char *opt_usage_and_exit(const char *extra)
136 char *usage = opt_usage(opt_argv0, extra);
138 /* Don't have valgrind complain! */
139 opt_alloc.free(usage);
144 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
146 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
149 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
151 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
154 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
156 size_t len = strlen(*p);
158 if (len > OPT_SHOW_LEN - 2)
159 len = OPT_SHOW_LEN - 2;
160 strncpy(buf+1, *p, len);
162 if (len < OPT_SHOW_LEN - 2)
166 /* Show an integer value, various forms. */
167 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
169 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
172 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
174 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
177 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
179 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
182 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
184 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
187 /* a helper function that multiplies out an argument's kMGTPE suffix in the
188 * long long int range, and perform checks common to all integer destinations.
190 * The base will be either 1000 or 1024, corresponding with the '_si' and
194 static char *set_llong_with_suffix(const char *arg, long long *ll,
195 const long long base)
199 return arg_bad("'%s' (an empty string) is not a number", arg);
202 *ll = strtoll(arg, &endp, 0);
204 return arg_bad("'%s' is out of range", arg);
206 /*The string continues with non-digits. If there is just one
207 letter and it is a known multiplier suffix, use it.*/
209 return arg_bad("'%s' is not a number (suffix too long)", arg);
222 mul = base * base * base;
226 mul = base * base * base * base;
229 mul = base * base * base * base * base;
232 mul = base * base * base * base * base * base;
234 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
236 return arg_bad("'%s' is not a number (unknown suffix)",
239 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
240 return arg_bad("'%s' is out of range", arg);
246 /* Middle layer helpers that perform bounds checks for specific target sizes
249 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
253 char *err = set_llong_with_suffix(arg, &ll, base);
257 return arg_bad("'%s' is negative but destination is unsigned", arg);
262 static char * set_long_with_suffix(const char *arg, long *l, const long base)
265 char *err = set_llong_with_suffix(arg, &ll, base);
266 if (err != NULL) /*an error*/
270 /* Beware truncation, but don't generate untestable code. */
271 if (sizeof(*l) != sizeof(ll) && *l != ll)
272 return arg_bad("value '%s' does not fit into a long", arg);
276 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
279 char *err = set_llong_with_suffix(arg, &ll, base);
283 return arg_bad("'%s' is negative but destination is unsigned", arg);
285 /* Beware truncation, but don't generate untestable code. */
286 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
287 return arg_bad("value '%s' does not fit into an unsigned long", arg);
291 static char * set_int_with_suffix(const char *arg, int *i, const long base)
294 char *err = set_llong_with_suffix(arg, &ll, base);
295 if (err != NULL) /*an error*/
300 return arg_bad("value '%s' does not fit into an int", arg);
304 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
307 char *err = set_llong_with_suffix(arg, &ll, base);
311 return arg_bad("'%s' is negative but destination is unsigned", arg);
314 return arg_bad("value '%s' does not fit into an unsigned int", arg);
318 /*Set an integer, with decimal or binary suffixes.
319 The accepted suffixes are k/K, M/m, G/g, T, P, E.
321 The *_bi functions multiply the numeric value by a power of 1024, while the
322 *_si functions multiply by a power of 1000.
325 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
327 return set_ulonglong_with_suffix(arg, ll, 1024);
330 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
332 return set_ulonglong_with_suffix(arg, ll, 1000);
335 char * opt_set_longlongval_bi(const char *arg, long long *ll)
337 return set_llong_with_suffix(arg, ll, 1024);
340 char * opt_set_longlongval_si(const char *arg, long long *ll)
342 return set_llong_with_suffix(arg, ll, 1000);
345 char * opt_set_longval_bi(const char *arg, long *l)
347 return set_long_with_suffix(arg, l, 1024);
350 char * opt_set_longval_si(const char *arg, long *l)
352 return set_long_with_suffix(arg, l, 1000);
355 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
357 return set_ulong_with_suffix(arg, ul, 1024);
360 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
362 return set_ulong_with_suffix(arg, ul, 1000);
365 char * opt_set_intval_bi(const char *arg, int *i)
367 return set_int_with_suffix(arg, i, 1024);
370 char * opt_set_intval_si(const char *arg, int *i)
372 return set_int_with_suffix(arg, i, 1000);
375 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
377 return set_uint_with_suffix(arg, u, 1024);
380 char * opt_set_uintval_si(const char *arg, unsigned int *u)
382 return set_uint_with_suffix(arg, u, 1000);
385 /*static helpers for showing values with kMGTPE suffixes. In this case there
386 are separate but essentially identical functions for signed and unsigned
387 values, so that unsigned values greater than LLONG_MAX get suffixes.
389 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
390 const long long base)
392 const char *suffixes = "kMGTPE";
395 /*zero is special because everything divides it (you'd get "0E")*/
396 snprintf(buf, OPT_SHOW_LEN, "0");
399 for (i = 0; i < strlen(suffixes); i++){
400 long long tmp = ll / base;
401 if (tmp * base != ll)
406 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
408 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
411 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
414 const char *suffixes = "kMGTPE";
417 /*zero is special because everything divides it (you'd get "0E")*/
418 snprintf(buf, OPT_SHOW_LEN, "0");
421 for (i = 0; i < strlen(suffixes); i++){
422 unsigned long long tmp = ull / base;
423 if (tmp * base != ull)
428 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
430 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
434 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
436 show_llong_with_suffix(buf, *x, 1024);
439 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
441 show_llong_with_suffix(buf, *x, 1024);
444 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
446 show_llong_with_suffix(buf, *x, 1024);
450 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
452 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
455 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
457 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
460 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
462 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
466 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
468 show_llong_with_suffix(buf, (long long) *x, 1000);
471 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
473 show_llong_with_suffix(buf, (long long) *x, 1000);
476 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
478 show_llong_with_suffix(buf, *x, 1000);
482 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
484 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
487 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
489 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
492 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
494 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);