]> git.ozlabs.org Git - ccan/blobdiff - ccan/opt/helpers.c
crypto/hkdf_sha256: new module.
[ccan] / ccan / opt / helpers.c
index 747a78e9139b875e7f7f6620d194510418c2c300..118e543602e06b981e6faee7dd5f416cf819d5cd 100644 (file)
@@ -9,14 +9,14 @@
 #include <stdio.h>
 #include <limits.h>
 #include "private.h"
+#include <float.h>
 
 /* Upper bound to sprintf this simple type?  Each 3 bits < 1 digit. */
 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
 
-/* FIXME: asprintf module? */
 static char *arg_bad(const char *fmt, const char *arg)
 {
-       char *str = malloc(strlen(fmt) + strlen(arg));
+       char *str = opt_alloc.alloc(strlen(fmt) + strlen(arg));
        sprintf(str, fmt, arg);
        return str;
 }
@@ -126,8 +126,14 @@ char *opt_set_floatval(const char *arg, float *f)
                return err;
 
        *f = d;
-       if (*f != d)
-               return arg_bad("'%s' is out of range", arg);
+
+       /*allow true infinity via --foo=INF, while avoiding isinf() from math.h
+         because it wasn't standard 25 years ago.*/
+       double inf = 1e300 * 1e300; /*direct 1e600 annoys -Woverflow*/
+       if ((d > FLT_MAX || d < -FLT_MAX) && d != inf && d != -inf)
+               return arg_bad("'%s' is out of range for a 32 bit float", arg);
+       if (d != 0 && *f == 0)
+               return arg_bad("'%s' is out of range (truncated to zero)", arg);
 
        return NULL;
 }
@@ -165,6 +171,12 @@ char *opt_inc_intval(int *i)
        return NULL;
 }
 
+char *opt_dec_intval(int *i)
+{
+       (*i)--;
+       return NULL;
+}
+
 /* Display version string. */
 char *opt_version_and_exit(const char *version)
 {
@@ -196,14 +208,19 @@ void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
 
 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
 {
-       size_t len = strlen(*p);
-       buf[0] = '"';
-       if (len > OPT_SHOW_LEN - 2)
-               len = OPT_SHOW_LEN - 2;
-       strncpy(buf+1, *p, len);
-       buf[1+len] = '"';
-       if (len < OPT_SHOW_LEN - 2)
-               buf[2+len] = '\0';
+       if (*p){
+               size_t len = strlen(*p);
+               buf[0] = '"';
+               if (len > OPT_SHOW_LEN - 2)
+                       len = OPT_SHOW_LEN - 2;
+               strncpy(buf+1, *p, len);
+               buf[1+len] = '"';
+               if (len < OPT_SHOW_LEN - 2)
+                       buf[2+len] = '\0';
+       }
+       else {
+               strncpy(buf, "(nil)", OPT_SHOW_LEN);
+       }
 }
 
 /* Show an integer value, various forms. */
@@ -238,9 +255,10 @@ static char *set_llong_with_suffix(const char *arg, long long *ll,
                                   const long long base)
 {
        char *endp;
-       if (!arg[0])
+       if (!arg[0]){
+               *ll = 0;
                return arg_bad("'%s' (an empty string) is not a number", arg);
-
+       }
        errno = 0;
        *ll = strtoll(arg, &endp, 0);
        if (errno)