]> git.ozlabs.org Git - ccan/blob - ccan/opt/helpers.c
base64: fix for unsigned chars (e.g. ARM).
[ccan] / ccan / opt / helpers.c
1 /* Licensed under GPLv2+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
3 #include <ccan/cast/cast.h>
4 #include <inttypes.h>
5 #include <string.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <limits.h>
11 #include "private.h"
12 #include <float.h>
13
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)
16
17 static char *arg_bad(const char *fmt, const char *arg)
18 {
19         char *str = opt_alloc.alloc(strlen(fmt) + strlen(arg));
20         sprintf(str, fmt, arg);
21         return str;
22 }
23
24 char *opt_set_bool(bool *b)
25 {
26         *b = true;
27         return NULL;
28 }
29
30 char *opt_set_invbool(bool *b)
31 {
32         *b = false;
33         return NULL;
34 }
35
36 char *opt_set_bool_arg(const char *arg, bool *b)
37 {
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);
42
43         return opt_invalid_argument(arg);
44 }
45
46 char *opt_set_invbool_arg(const char *arg, bool *b)
47 {
48         char *err = opt_set_bool_arg(arg, b);
49
50         if (!err)
51                 *b = !*b;
52         return err;
53 }
54
55 /* Set a char *. */
56 char *opt_set_charp(const char *arg, char **p)
57 {
58         *p = cast_const(char *, arg);
59         return NULL;
60 }
61
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)
65 {
66         long l;
67         char *err = opt_set_longval(arg, &l);
68
69         if (err)
70                 return err;
71         *i = 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);
75         return err;
76 }
77
78 char *opt_set_uintval(const char *arg, unsigned int *ui)
79 {
80         int i;
81         char *err = opt_set_intval(arg, &i);
82
83         if (err)
84                 return err;
85         if (i < 0)
86                 return arg_bad("'%s' is negative but destination is unsigned", arg);
87         *ui = i;
88         return NULL;
89 }
90
91 char *opt_set_longval(const char *arg, long *l)
92 {
93         char *endp;
94
95         /* This is how the manpage says to do it.  Yech. */
96         errno = 0;
97         *l = strtol(arg, &endp, 0);
98         if (*endp || !arg[0])
99                 return arg_bad("'%s' is not a number", arg);
100         if (errno)
101                 return arg_bad("'%s' is out of range", arg);
102         return NULL;
103 }
104
105 char *opt_set_ulongval(const char *arg, unsigned long *ul)
106 {
107         long int l;
108         char *err;
109
110         err = opt_set_longval(arg, &l);
111         if (err)
112                 return err;
113         *ul = l;
114         if (l < 0)
115                 return arg_bad("'%s' is negative but destination is unsigned", arg);
116         return NULL;
117 }
118
119 char *opt_set_floatval(const char *arg, float *f)
120 {
121         double d;
122         char *err;
123
124         err = opt_set_doubleval(arg, &d);
125         if (err)
126                 return err;
127
128         *f = d;
129
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);
137
138         return NULL;
139 }
140
141 void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
142 {
143         double d = *f;
144         opt_show_doubleval(buf, &d);
145 }
146
147 char *opt_set_doubleval(const char *arg, double *d)
148 {
149         char *endp;
150
151         /* This is how the manpage says to do it.  Yech. */
152         errno = 0;
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);
157         if (errno)
158                 return arg_bad("'%s' is out of range", arg);
159
160         return NULL;
161 }
162
163 void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
164 {
165         snprintf(buf, OPT_SHOW_LEN, "%f", *d);
166 }
167
168 char *opt_inc_intval(int *i)
169 {
170         (*i)++;
171         return NULL;
172 }
173
174 char *opt_dec_intval(int *i)
175 {
176         (*i)--;
177         return NULL;
178 }
179
180 /* Display version string. */
181 char *opt_version_and_exit(const char *version)
182 {
183         printf("%s\n", version);
184         /* Don't have valgrind complain! */
185         opt_free_table();
186         exit(0);
187 }
188
189 char *opt_usage_and_exit(const char *extra)
190 {
191         char *usage = opt_usage(opt_argv0, extra);
192         printf("%s", usage);
193         /* Don't have valgrind complain! */
194         opt_alloc.free(usage);
195         opt_free_table();
196         exit(0);
197 }
198
199 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
200 {
201         strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
202 }
203
204 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
205 {
206         strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
207 }
208
209 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
210 {
211         if (*p){
212                 size_t len = strlen(*p);
213                 buf[0] = '"';
214                 if (len > OPT_SHOW_LEN - 2)
215                         len = OPT_SHOW_LEN - 2;
216                 strncpy(buf+1, *p, len);
217                 buf[1+len] = '"';
218                 if (len < OPT_SHOW_LEN - 2)
219                         buf[2+len] = '\0';
220         }
221         else {
222                 strncpy(buf, "(nil)", OPT_SHOW_LEN);
223         }
224 }
225
226 /* Show an integer value, various forms. */
227 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
228 {
229         snprintf(buf, OPT_SHOW_LEN, "%i", *i);
230 }
231
232 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
233 {
234         snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
235 }
236
237 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
238 {
239         snprintf(buf, OPT_SHOW_LEN, "%li", *l);
240 }
241
242 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
243 {
244         snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
245 }
246
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.
249  *
250  * The base will be either 1000 or 1024, corresponding with the '_si' and
251  * '_bi' functions.
252  */
253
254 static char *set_llong_with_suffix(const char *arg, long long *ll,
255                                    const long long base)
256 {
257         char *endp;
258         if (!arg[0]){
259                 *ll = 0;
260                 return arg_bad("'%s' (an empty string) is not a number", arg);
261         }
262         errno = 0;
263         *ll = strtoll(arg, &endp, 0);
264         if (errno)
265                 return arg_bad("'%s' is out of range", arg);
266         if (*endp){
267                 /*The string continues with non-digits.  If there is just one
268                   letter and it is a known multiplier suffix, use it.*/
269                 if (endp[1])
270                         return arg_bad("'%s' is not a number (suffix too long)", arg);
271                 long long mul;
272                 switch(*endp){
273                 case 'K':
274                 case 'k':
275                         mul = base;
276                         break;
277                 case 'M':
278                 case 'm':
279                         mul = base * base;
280                         break;
281                 case 'G':
282                 case 'g':
283                         mul = base * base * base;
284                         break;
285                 case 'T':
286                 case 't':
287                         mul = base * base * base * base;
288                         break;
289                 case 'P':
290                         mul = base * base * base * base * base;
291                         break;
292                 case 'E':
293                         mul = base * base * base * base * base * base;
294                         break;
295                 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
296                 default:
297                         return arg_bad("'%s' is not a number (unknown suffix)",
298                                        arg);
299                 }
300                 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
301                         return arg_bad("'%s' is out of range", arg);
302                 *ll *= mul;
303         }
304         return NULL;
305 }
306
307 /* Middle layer helpers that perform bounds checks for specific target sizes
308  * and signednesses.
309  */
310 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
311                                         const long base)
312 {
313         long long ll;
314         char *err = set_llong_with_suffix(arg, &ll, base);
315         if (err != NULL)
316                 return err;
317         if (ll < 0)
318                 return arg_bad("'%s' is negative but destination is unsigned", arg);
319         *ull = ll;
320         return NULL;
321 }
322
323 static char * set_long_with_suffix(const char *arg, long *l, const long base)
324 {
325         long long ll;
326         char *err = set_llong_with_suffix(arg, &ll, base);
327         if (err != NULL) /*an error*/
328                 return err;
329
330         *l = ll;
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);
334         return NULL;
335 }
336
337 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
338 {
339         long long ll;
340         char *err = set_llong_with_suffix(arg, &ll, base);
341         if (err != NULL)
342                 return err;
343         if (ll < 0)
344                 return arg_bad("'%s' is negative but destination is unsigned", arg);
345         *ul = ll;
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);
349         return NULL;
350 }
351
352 static char * set_int_with_suffix(const char *arg, int *i, const long base)
353 {
354         long long ll;
355         char *err = set_llong_with_suffix(arg, &ll, base);
356         if (err != NULL) /*an error*/
357                 return err;
358
359         *i = ll;
360         if (*i != ll)
361                 return arg_bad("value '%s' does not fit into an int", arg);
362         return NULL;
363 }
364
365 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
366 {
367         long long ll;
368         char *err = set_llong_with_suffix(arg, &ll, base);
369         if (err != NULL)
370                 return err;
371         if (ll < 0)
372                 return arg_bad("'%s' is negative but destination is unsigned", arg);
373         *u = ll;
374         if (*u != ll)
375                 return arg_bad("value '%s' does not fit into an unsigned int", arg);
376         return NULL;
377 }
378
379 /*Set an integer, with decimal or binary suffixes.
380   The accepted suffixes are k/K, M/m, G/g, T, P, E.
381
382   The *_bi functions multiply the numeric value by a power of 1024, while the
383   *_si functions multiply by a power of 1000.
384  */
385
386 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
387 {
388         return set_ulonglong_with_suffix(arg, ll, 1024);
389 }
390
391 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
392 {
393         return set_ulonglong_with_suffix(arg, ll, 1000);
394 }
395
396 char * opt_set_longlongval_bi(const char *arg, long long *ll)
397 {
398         return set_llong_with_suffix(arg, ll, 1024);
399 }
400
401 char * opt_set_longlongval_si(const char *arg, long long *ll)
402 {
403         return set_llong_with_suffix(arg, ll, 1000);
404 }
405
406 char * opt_set_longval_bi(const char *arg, long *l)
407 {
408         return set_long_with_suffix(arg, l, 1024);
409 }
410
411 char * opt_set_longval_si(const char *arg, long *l)
412 {
413         return set_long_with_suffix(arg, l, 1000);
414 }
415
416 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
417 {
418         return set_ulong_with_suffix(arg, ul, 1024);
419 }
420
421 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
422 {
423         return set_ulong_with_suffix(arg, ul, 1000);
424 }
425
426 char * opt_set_intval_bi(const char *arg, int *i)
427 {
428         return set_int_with_suffix(arg, i, 1024);
429 }
430
431 char * opt_set_intval_si(const char *arg, int *i)
432 {
433         return set_int_with_suffix(arg, i, 1000);
434 }
435
436 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
437 {
438         return set_uint_with_suffix(arg, u, 1024);
439 }
440
441 char * opt_set_uintval_si(const char *arg, unsigned int *u)
442 {
443         return set_uint_with_suffix(arg, u, 1000);
444 }
445
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.
449  */
450 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
451                                     const long long base)
452 {
453         const char *suffixes = "kMGTPE";
454         int i;
455         if (ll == 0){
456                 /*zero is special because everything divides it (you'd get "0E")*/
457                 snprintf(buf, OPT_SHOW_LEN, "0");
458                 return;
459         }
460         for (i = 0; i < strlen(suffixes); i++){
461                 long long tmp = ll / base;
462                 if (tmp * base != ll)
463                         break;
464                 ll = tmp;
465         }
466         if (i == 0)
467                 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
468         else
469                 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
470 }
471
472 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
473                                     const unsigned base)
474 {
475         const char *suffixes = "kMGTPE";
476         int i;
477         if (ull == 0){
478                 /*zero is special because everything divides it (you'd get "0E")*/
479                 snprintf(buf, OPT_SHOW_LEN, "0");
480                 return;
481         }
482         for (i = 0; i < strlen(suffixes); i++){
483                 unsigned long long tmp = ull / base;
484                 if (tmp * base != ull)
485                         break;
486                 ull = tmp;
487         }
488         if (i == 0)
489                 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
490         else
491                 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
492 }
493
494 /* _bi, signed */
495 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
496 {
497         show_llong_with_suffix(buf, *x, 1024);
498 }
499
500 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
501 {
502         show_llong_with_suffix(buf, *x, 1024);
503 }
504
505 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
506 {
507         show_llong_with_suffix(buf, *x, 1024);
508 }
509
510 /* _bi, unsigned */
511 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
512 {
513         show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
514 }
515
516 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
517 {
518         show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
519 }
520
521 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
522 {
523         show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
524 }
525
526 /* _si, signed */
527 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
528 {
529         show_llong_with_suffix(buf, (long long) *x, 1000);
530 }
531
532 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
533 {
534         show_llong_with_suffix(buf, (long long) *x, 1000);
535 }
536
537 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
538 {
539         show_llong_with_suffix(buf, *x, 1000);
540 }
541
542 /* _si, unsigned */
543 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
544 {
545         show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
546 }
547
548 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
549 {
550         show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
551 }
552
553 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
554 {
555         show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
556 }
557