[master] 7b04840 More strtod() -> VNUM() conversions.
Poul-Henning Kamp
phk at FreeBSD.org
Tue Feb 24 00:05:16 CET 2015
commit 7b0484025785acd664e1f260b1f43e631df5a08f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Feb 23 23:04:40 2015 +0000
More strtod() -> VNUM() conversions.
Add a VNUMpfx() variant which does not barf NAN on suffixes.
diff --git a/include/vnum.h b/include/vnum.h
index 02ca517..8446dae 100644
--- a/include/vnum.h
+++ b/include/vnum.h
@@ -30,4 +30,5 @@
/* from libvarnish/vnum.c */
double VNUM(const char *p);
+double VNUMpfx(const char *p, const char **e);
const char *VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel);
diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am
index 9275fd2..b592cff 100644
--- a/lib/libvarnish/Makefile.am
+++ b/lib/libvarnish/Makefile.am
@@ -44,7 +44,7 @@ TESTS = vnum_c_test
noinst_PROGRAMS = ${TESTS}
-vnum_c_test_SOURCES = vnum.c
+vnum_c_test_SOURCES = vnum.c vas.c
vnum_c_test_CFLAGS = -DNUM_C_TEST -include config.h
vnum_c_test_LDADD = ${LIBM}
diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c
index 98451b3..6d5d002 100644
--- a/lib/libvarnish/vnum.c
+++ b/lib/libvarnish/vnum.c
@@ -31,12 +31,14 @@
#include "config.h"
#include <ctype.h>
+#include <errno.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "vnum.h"
+#include "vas.h"
static const char err_miss_num[] = "Missing number";
static const char err_invalid_num[] = "Invalid number";
@@ -49,12 +51,15 @@ static const char err_invalid_suff[] = "Invalid suffix";
*/
double
-VNUM(const char *p)
+VNUMpfx(const char *p, const char **t)
{
intmax_t m = 0, ee = 0;
double ms = 1.0;
double es = 1.0, e = 1.0, ne = 0.0;
+ AN(p);
+ AN(t);
+ *t = NULL;
while (isspace(*p))
p++;
@@ -86,26 +91,38 @@ VNUM(const char *p)
while (isspace(*p))
p++;
if (*p != '\0')
- return (nan(""));
+ *t = p;
return (ms * m * pow(10., e + es * ee));
}
+double
+VNUM(const char *p)
+{
+ const char *t;
+ double r;
+
+ r = VNUMpfx(p, &t);
+ if (t != NULL)
+ r = nan("");
+ return (r);
+}
+
/**********************************************************************/
const char *
VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel)
{
double fval;
- char *end;
+ const char *end;
if (p == NULL || *p == '\0')
return (err_miss_num);
- fval = strtod(p, &end);
- if (end == p || !isfinite(fval))
+ fval = VNUMpfx(p, &end);
+ if (!isfinite(fval))
return (err_invalid_num);
- if (*end == '\0') {
+ if (end == NULL) {
*r = (uintmax_t)fval;
return (NULL);
}
diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c
index d27ad44..e201eb9 100644
--- a/lib/libvmod_std/vmod_std_conversions.c
+++ b/lib/libvmod_std/vmod_std_conversions.c
@@ -39,6 +39,7 @@
#include "cache/cache.h"
+#include "vnum.h"
#include "vrt.h"
#include "vsa.h"
#include "vtim.h"
@@ -47,7 +48,7 @@
VCL_DURATION __match_proto__(td_std_duration)
vmod_duration(VRT_CTX, VCL_STRING p, VCL_DURATION d)
{
- char *e;
+ const char *e;
double r;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
@@ -63,12 +64,9 @@ vmod_duration(VRT_CTX, VCL_STRING p, VCL_DURATION d)
e = NULL;
- r = strtod(p, &e);
-
- if (!isfinite(r))
- return (d);
+ r = VNUMpfx(p, &e);
- if (e == NULL)
+ if (!isfinite(r) || e == NULL)
return (d);
while(isspace(*e))
@@ -170,7 +168,6 @@ vmod_ip(VRT_CTX, VCL_STRING s, VCL_IP d)
VCL_REAL __match_proto__(td_std_real)
vmod_real(VRT_CTX, VCL_STRING p, VCL_REAL d)
{
- char *e;
double r;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
@@ -178,22 +175,11 @@ vmod_real(VRT_CTX, VCL_STRING p, VCL_REAL d)
if (p == NULL)
return (d);
- while (isspace(*p))
- p++;
-
- if (*p != '+' && *p != '-' && !isdigit(*p))
- return (d);
-
- e = NULL;
-
- r = strtod(p, &e);
+ r = VNUM(p);
if (!isfinite(r))
return (d);
- if (e == NULL || *e != '\0')
- return (d);
-
return (r);
}
More information about the varnish-commit
mailing list