[number] Make hb_parse_double simpler now that we don't have to mimic strtod
diff --git a/src/hb-number-parser.hh b/src/hb-number-parser.hh
index 02f4f7f..afad228 100644
--- a/src/hb-number-parser.hh
+++ b/src/hb-number-parser.hh
@@ -96,7 +96,7 @@
/* Works only for n < 512 */
static inline double
-_pow10 (unsigned int exponent)
+_pow10 (unsigned exponent)
{
static const double _powers_of_10[] =
{
@@ -110,38 +110,39 @@
100.,
10.
};
- unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
+ unsigned mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
double result = 1;
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
if (exponent & mask) result *= *power;
return result;
}
+/* a variant of strtod that also gets end of buffer in its second argument */
static inline double
-strtod_rl (const char *buf, char **end_ptr)
+strtod_rl (const char *buf, const char **end_ptr /* IN/OUT */)
{
const char *p, *pe;
double value = 0;
double frac = 0;
double frac_count = 0;
- unsigned int exp = 0;
+ unsigned exp = 0;
bool neg = false, exp_neg = false, exp_overflow = false;
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 2^52-1 */
- const unsigned int MAX_EXP = 0x7FFu; /* 2^11-1 */
+ const unsigned MAX_EXP = 0x7FFu; /* 2^11-1 */
p = buf;
- pe = p + strlen (p);
+ pe = *end_ptr;
while (p < pe && ISSPACE (*p))
p++;
int cs;
-#line 140 "hb-number-parser.hh"
+#line 141 "hb-number-parser.hh"
{
cs = double_parser_start;
}
-#line 145 "hb-number-parser.hh"
+#line 146 "hb-number-parser.hh"
{
int _slen;
int _trans;
@@ -199,7 +200,7 @@
exp_overflow = true;
}
break;
-#line 203 "hb-number-parser.hh"
+#line 204 "hb-number-parser.hh"
}
_again:
@@ -211,10 +212,10 @@
_out: {}
}
-#line 114 "hb-number-parser.rl"
+#line 115 "hb-number-parser.rl"
- *end_ptr = (char *) p;
+ *end_ptr = (const char *) p;
if (frac_count) value += frac / _pow10 (frac_count);
if (neg) value *= -1.;
diff --git a/src/hb-number-parser.rl b/src/hb-number-parser.rl
index 28bbf94..1de262a 100644
--- a/src/hb-number-parser.rl
+++ b/src/hb-number-parser.rl
@@ -69,7 +69,7 @@
/* Works only for n < 512 */
static inline double
-_pow10 (unsigned int exponent)
+_pow10 (unsigned exponent)
{
static const double _powers_of_10[] =
{
@@ -83,26 +83,27 @@
100.,
10.
};
- unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
+ unsigned mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
double result = 1;
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
if (exponent & mask) result *= *power;
return result;
}
+/* a variant of strtod that also gets end of buffer in its second argument */
static inline double
-strtod_rl (const char *buf, char **end_ptr)
+strtod_rl (const char *buf, const char **end_ptr /* IN/OUT */)
{
const char *p, *pe;
double value = 0;
double frac = 0;
double frac_count = 0;
- unsigned int exp = 0;
+ unsigned exp = 0;
bool neg = false, exp_neg = false, exp_overflow = false;
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 2^52-1 */
- const unsigned int MAX_EXP = 0x7FFu; /* 2^11-1 */
+ const unsigned MAX_EXP = 0x7FFu; /* 2^11-1 */
p = buf;
- pe = p + strlen (p);
+ pe = *end_ptr;
while (p < pe && ISSPACE (*p))
p++;
@@ -113,7 +114,7 @@
write exec;
}%%
- *end_ptr = (char *) p;
+ *end_ptr = (const char *) p;
if (frac_count) value += frac / _pow10 (frac_count);
if (neg) value *= -1.;
diff --git a/src/hb-number.cc b/src/hb-number.cc
index e68b10d..6e4f3f7 100644
--- a/src/hb-number.cc
+++ b/src/hb-number.cc
@@ -34,8 +34,7 @@
bool whole_buffer, Func f)
{
char buf[32];
- unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
- (unsigned int) (end - *pp));
+ unsigned len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned) (end - *pp));
strncpy (buf, *pp, len);
buf[len] = '\0';
@@ -46,7 +45,8 @@
*pv = f (p, &pend);
if (unlikely (errno || p == pend ||
/* Check if consumed whole buffer if is requested */
- (whole_buffer && pend - p != end - *pp))) return false;
+ (whole_buffer && pend - p != end - *pp)))
+ return false;
*pp += pend - p;
return true;
@@ -61,19 +61,20 @@
}
bool
-hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
+hb_parse_uint (const char **pp, const char *end, unsigned *pv,
bool whole_buffer, int base)
{
- return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
- [base] (const char *p, char **end)
- { return strtoul (p, end, base); });
+ return _parse_number<unsigned> (pp, end, pv, whole_buffer,
+ [base] (const char *p, char **end)
+ { return strtoul (p, end, base); });
}
bool
-hb_parse_double (const char **pp, const char *end, double *pv,
- bool whole_buffer)
+hb_parse_double (const char **pp, const char *end, double *pv, bool whole_buffer)
{
- return _parse_number<double> (pp, end, pv, whole_buffer,
- [] (const char *p, char **end)
- { return strtod_rl (p, end); });
+ const char *pend = end;
+ *pv = strtod_rl (*pp, &pend);
+ if (unlikely (*pp == pend)) return false;
+ *pp = pend;
+ return !whole_buffer || end == pend;
}
diff --git a/src/test-number.cc b/src/test-number.cc
index 468de6f..5783528 100644
--- a/src/test-number.cc
+++ b/src/test-number.cc
@@ -25,7 +25,6 @@
#include "hb.hh"
#include "hb-number.hh"
-#include "hb-number-parser.hh"
int
@@ -170,10 +169,6 @@
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 7);
assert (end - pp == 0);
-
- char *pend;
- assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
- assert (pend - str == 7);
}
{
@@ -186,10 +181,6 @@
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 6);
assert (end - pp == 0);
-
- char *pend;
- assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
- assert (pend - str == 6);
}
{
@@ -202,10 +193,6 @@
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 10);
assert (end - pp == 0);
-
- char *pend;
- assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
- assert (pend - str == 10);
}
{
@@ -219,9 +206,6 @@
assert (pp - str == 13);
assert (end - pp == 0);
- char *pend;
- assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
- assert (pend - str == 13);
}
{
@@ -234,10 +218,6 @@
assert ((int) roundf (pv * 1000.) == -123);
assert (pp - str == 8);
assert (end - pp == 0);
-
- char *pend;
- assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
- assert (pend - str == 8);
}
return 0;