summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2014-02-24 13:56:32 +1030
committerRusty Russell <rusty@rustcorp.com.au>2014-02-24 13:57:10 +1030
commitb989e06c093fb7a2befae277f684fa75b64b9ef5 (patch)
tree9288ac69101df924a52e2093b9d77ceff228274d
parent79715b8c08446fe5e74d2ab9e9db00175169eab3 (diff)
opt: add float/double helpers.
bfgminer/cgminer/sgminer want these. Con implemented some, but these are independently written (with tests!) Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--ccan/opt/helpers.c43
-rw-r--r--ccan/opt/opt.h6
-rw-r--r--ccan/opt/test/run-helpers.c62
3 files changed, 110 insertions, 1 deletions
diff --git a/ccan/opt/helpers.c b/ccan/opt/helpers.c
index 2c771bc3..747a78e9 100644
--- a/ccan/opt/helpers.c
+++ b/ccan/opt/helpers.c
@@ -116,6 +116,49 @@ char *opt_set_ulongval(const char *arg, unsigned long *ul)
return NULL;
}
+char *opt_set_floatval(const char *arg, float *f)
+{
+ double d;
+ char *err;
+
+ err = opt_set_doubleval(arg, &d);
+ if (err)
+ return err;
+
+ *f = d;
+ if (*f != d)
+ return arg_bad("'%s' is out of range", arg);
+
+ return NULL;
+}
+
+void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
+{
+ double d = *f;
+ opt_show_doubleval(buf, &d);
+}
+
+char *opt_set_doubleval(const char *arg, double *d)
+{
+ char *endp;
+
+ /* This is how the manpage says to do it. Yech. */
+ errno = 0;
+ /* Don't assume strtof */
+ *d = strtod(arg, &endp);
+ if (*endp || !arg[0])
+ return arg_bad("'%s' is not a number", arg);
+ if (errno)
+ return arg_bad("'%s' is out of range", arg);
+
+ return NULL;
+}
+
+void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
+{
+ snprintf(buf, OPT_SHOW_LEN, "%f", *d);
+}
+
char *opt_inc_intval(int *i)
{
(*i)++;
diff --git a/ccan/opt/opt.h b/ccan/opt/opt.h
index 3dd4edc6..f891002f 100644
--- a/ccan/opt/opt.h
+++ b/ccan/opt/opt.h
@@ -409,6 +409,12 @@ void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l);
char *opt_set_ulongval(const char *arg, unsigned long *ul);
void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul);
+/* Set an floating point value, various forms. */
+char *opt_set_floatval(const char *arg, float *f);
+void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f);
+char *opt_set_doubleval(const char *arg, double *d);
+void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d);
+
/* the following setting functions accept k, M, G, T, P, or E suffixes, which
multiplies the numeric value by the corresponding power of 1000 or 1024
(for the _si and _bi versions, respectively).
diff --git a/ccan/opt/test/run-helpers.c b/ccan/opt/test/run-helpers.c
index 10b24190..49fb2062 100644
--- a/ccan/opt/test/run-helpers.c
+++ b/ccan/opt/test/run-helpers.c
@@ -77,7 +77,7 @@ static void set_args(int *argc, char ***argv, ...)
/* Test helpers. */
int main(int argc, char *argv[])
{
- plan_tests(454);
+ plan_tests(476);
/* opt_set_bool */
{
@@ -206,6 +206,32 @@ int main(int argc, char *argv[])
else
fail("FIXME: Handle other long sizes");
}
+ /* opt_set_floatval */
+ {
+ float arg = 1000;
+ reset_options();
+ opt_register_arg("-a", opt_set_floatval, NULL, &arg, "All");
+ ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
+ ok1(arg == 9999);
+ ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
+ ok1(arg == -9999);
+ ok1(parse_args(&argc, &argv, "-a", "0", NULL));
+ ok1(arg == 0);
+ ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
+ }
+ /* opt_set_doubleval */
+ {
+ double arg = 1000;
+ reset_options();
+ opt_register_arg("-a", opt_set_doubleval, NULL, &arg, "All");
+ ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
+ ok1(arg == 9999);
+ ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
+ ok1(arg == -9999);
+ ok1(parse_args(&argc, &argv, "-a", "0", NULL));
+ ok1(arg == 0);
+ ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
+ }
{
const long long k = 1024;
@@ -1140,6 +1166,40 @@ int main(int argc, char *argv[])
ok1(buf[OPT_SHOW_LEN] == '!');
}
+ /* opt_show_floatval */
+ {
+ float f;
+ char buf[OPT_SHOW_LEN+2] = { 0 };
+ buf[OPT_SHOW_LEN] = '!';
+
+ f = -77.5;
+ opt_show_floatval(buf, &f);
+ ok1(strcmp(buf, "-77.500000") == 0);
+ ok1(buf[OPT_SHOW_LEN] == '!');
+
+ f = 77.5;
+ opt_show_floatval(buf, &f);
+ ok1(strcmp(buf, "77.500000") == 0);
+ ok1(buf[OPT_SHOW_LEN] == '!');
+ }
+
+ /* opt_show_doubleval */
+ {
+ double d;
+ char buf[OPT_SHOW_LEN+2] = { 0 };
+ buf[OPT_SHOW_LEN] = '!';
+
+ d = -77;
+ opt_show_doubleval(buf, &d);
+ ok1(strcmp(buf, "-77.000000") == 0);
+ ok1(buf[OPT_SHOW_LEN] == '!');
+
+ d = 77;
+ opt_show_doubleval(buf, &d);
+ ok1(strcmp(buf, "77.000000") == 0);
+ ok1(buf[OPT_SHOW_LEN] == '!');
+ }
+
/* opt_log_stderr. */
{
reset_options();