[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