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);
129 char *opt_usage_and_exit(const char *extra)
131 printf("%s", opt_usage(opt_argv0, extra));
135 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
137 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
140 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
142 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
145 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
147 size_t len = strlen(*p);
149 if (len > OPT_SHOW_LEN - 2)
150 len = OPT_SHOW_LEN - 2;
151 strncpy(buf+1, *p, len);
153 if (len < OPT_SHOW_LEN - 2)
157 /* Show an integer value, various forms. */
158 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
160 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
163 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
165 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
168 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
170 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
173 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
175 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
178 /* a helper function that multiplies out an argument's kMGTPE suffix in the
179 * long long int range, and perform checks common to all integer destinations.
181 * The base will be either 1000 or 1024, corresponding with the '_si' and
185 static char *set_llong_with_suffix(const char *arg, long long *ll,
186 const long long base)
190 return arg_bad("'%s' (an empty string) is not a number", arg);
193 *ll = strtoll(arg, &endp, 0);
195 return arg_bad("'%s' is out of range", arg);
197 /*The string continues with non-digits. If there is just one
198 letter and it is a known multiplier suffix, use it.*/
200 return arg_bad("'%s' is not a number (suffix too long)", arg);
213 mul = base * base * base;
217 mul = base * base * base * base;
220 mul = base * base * base * base * base;
223 mul = base * base * base * base * base * base;
225 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
227 return arg_bad("'%s' is not a number (unknown suffix)",
230 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
231 return arg_bad("'%s' is out of range", arg);
237 /* Middle layer helpers that perform bounds checks for specific target sizes
240 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
244 char *err = set_llong_with_suffix(arg, &ll, base);
248 return arg_bad("'%s' is negative but destination is unsigned", arg);
253 static char * set_long_with_suffix(const char *arg, long *l, const long base)
256 char *err = set_llong_with_suffix(arg, &ll, base);
257 if (err != NULL) /*an error*/
261 /* Beware truncation, but don't generate untestable code. */
262 if (sizeof(*l) != sizeof(ll) && *l != ll)
263 return arg_bad("value '%s' does not fit into a long", arg);
267 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
270 char *err = set_llong_with_suffix(arg, &ll, base);
274 return arg_bad("'%s' is negative but destination is unsigned", arg);
276 /* Beware truncation, but don't generate untestable code. */
277 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
278 return arg_bad("value '%s' does not fit into an unsigned long", arg);
282 static char * set_int_with_suffix(const char *arg, int *i, const long base)
285 char *err = set_llong_with_suffix(arg, &ll, base);
286 if (err != NULL) /*an error*/
291 return arg_bad("value '%s' does not fit into an int", arg);
295 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
298 char *err = set_llong_with_suffix(arg, &ll, base);
302 return arg_bad("'%s' is negative but destination is unsigned", arg);
305 return arg_bad("value '%s' does not fit into an unsigned int", arg);
309 /*Set an integer, with decimal or binary suffixes.
310 The accepted suffixes are k/K, M/m, G/g, T, P, E.
312 The *_bi functions multiply the numeric value by a power of 1024, while the
313 *_si functions multiply by a power of 1000.
316 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
318 return set_ulonglong_with_suffix(arg, ll, 1024);
321 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
323 return set_ulonglong_with_suffix(arg, ll, 1000);
326 char * opt_set_longlongval_bi(const char *arg, long long *ll)
328 return set_llong_with_suffix(arg, ll, 1024);
331 char * opt_set_longlongval_si(const char *arg, long long *ll)
333 return set_llong_with_suffix(arg, ll, 1000);
336 char * opt_set_longval_bi(const char *arg, long *l)
338 return set_long_with_suffix(arg, l, 1024);
341 char * opt_set_longval_si(const char *arg, long *l)
343 return set_long_with_suffix(arg, l, 1000);
346 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
348 return set_ulong_with_suffix(arg, ul, 1024);
351 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
353 return set_ulong_with_suffix(arg, ul, 1000);
356 char * opt_set_intval_bi(const char *arg, int *i)
358 return set_int_with_suffix(arg, i, 1024);
361 char * opt_set_intval_si(const char *arg, int *i)
363 return set_int_with_suffix(arg, i, 1000);
366 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
368 return set_uint_with_suffix(arg, u, 1024);
371 char * opt_set_uintval_si(const char *arg, unsigned int *u)
373 return set_uint_with_suffix(arg, u, 1000);
376 /*static helpers for showing values with kMGTPE suffixes. In this case there
377 are separate but essentially identical functions for signed and unsigned
378 values, so that unsigned values greater than LLONG_MAX get suffixes.
380 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
381 const long long base)
383 const char *suffixes = "kMGTPE";
386 /*zero is special because everything divides it (you'd get "0E")*/
387 snprintf(buf, OPT_SHOW_LEN, "0");
390 for (i = 0; i < strlen(suffixes); i++){
391 long long tmp = ll / base;
392 if (tmp * base != ll)
397 snprintf(buf, OPT_SHOW_LEN, "%lld", ll);
399 snprintf(buf, OPT_SHOW_LEN, "%lld%c", ll, suffixes[i - 1]);
402 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
405 const char *suffixes = "kMGTPE";
408 /*zero is special because everything divides it (you'd get "0E")*/
409 snprintf(buf, OPT_SHOW_LEN, "0");
412 for (i = 0; i < strlen(suffixes); i++){
413 unsigned long long tmp = ull / base;
414 if (tmp * base != ull)
419 snprintf(buf, OPT_SHOW_LEN, "%llu", ull);
421 snprintf(buf, OPT_SHOW_LEN, "%llu%c", ull, suffixes[i - 1]);
425 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
427 show_llong_with_suffix(buf, *x, 1024);
430 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
432 show_llong_with_suffix(buf, *x, 1024);
435 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
437 show_llong_with_suffix(buf, *x, 1024);
441 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
443 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
446 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
448 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
451 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
453 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
457 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
459 show_llong_with_suffix(buf, (long long) *x, 1000);
462 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
464 show_llong_with_suffix(buf, (long long) *x, 1000);
467 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
469 show_llong_with_suffix(buf, *x, 1000);
473 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
475 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
478 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
480 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
483 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
485 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);