|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
-** $Id: lobject.c,v 2.43 2010/10/29 15:54:55 roberto Exp roberto $
|
|
|
+** $Id: lobject.c,v 2.44 2010/12/06 21:08:36 roberto Exp roberto $
|
|
|
** Some generic functions over Lua objects
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -106,20 +106,87 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int checkend (const char *s, const char *e, const char *endptr) {
|
|
|
- if (endptr == s) return 0; /* no characters converted */
|
|
|
- while (lisspace(cast(unsigned char, *endptr))) endptr++;
|
|
|
- return (endptr == e); /* OK if no trailing characters */
|
|
|
+int luaO_hexavalue (int c) {
|
|
|
+ if (lisdigit(c)) return c - '0';
|
|
|
+ else if (lisupper(c)) return c - 'A' + 10;
|
|
|
+ else return c - 'a' + 10;
|
|
|
}
|
|
|
|
|
|
|
|
|
+#if !defined(lua_strx2number)
|
|
|
+
|
|
|
+#include <math.h>
|
|
|
+
|
|
|
+
|
|
|
+static int isneg (const char **s) {
|
|
|
+ if (**s == '-') { (*s)++; return 1; }
|
|
|
+ else if (**s == '+') (*s)++;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static lua_Number readhexa (const char **s, lua_Number r, int *count) {
|
|
|
+ while (lisxdigit(cast_uchar(**s))) { /* read integer part */
|
|
|
+ r = (r * 16.0) + (double)luaO_hexavalue(*(*s)++);
|
|
|
+ (*count)++;
|
|
|
+ }
|
|
|
+ return r;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+** convert an hexadecimal numeric string to a number, following
|
|
|
+** C99 specification for 'strtod'
|
|
|
+*/
|
|
|
+static lua_Number lua_strx2number (const char *s, char **endptr) {
|
|
|
+ lua_Number r = 0.0;
|
|
|
+ int e = 0, i = 0;
|
|
|
+ int neg = 0; /* 1 if number is negative */
|
|
|
+ *endptr = cast(char *, s); /* nothing is valid yet */
|
|
|
+ while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
|
|
|
+ neg = isneg(&s); /* check signal */
|
|
|
+ if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
|
|
|
+ return 0.0; /* invalid format (no '0x') */
|
|
|
+ s += 2; /* skip '0x' */
|
|
|
+ r = readhexa(&s, r, &i); /* read integer part */
|
|
|
+ if (*s == '.') {
|
|
|
+ s++; /* skip dot */
|
|
|
+ r = readhexa(&s, r, &e); /* read fractional part */
|
|
|
+ }
|
|
|
+ if (i == 0 && e == 0)
|
|
|
+ return 0.0; /* invalid format (no digit) */
|
|
|
+ e *= -4; /* each fractional digit divides value by 2^-4 */
|
|
|
+ *endptr = cast(char *, s); /* valid up to here */
|
|
|
+ if (*s == 'p' || *s == 'P') { /* exponent part? */
|
|
|
+ int exp1 = 0;
|
|
|
+ int neg1;
|
|
|
+ s++; /* skip 'p' */
|
|
|
+ neg1 = isneg(&s); /* signal */
|
|
|
+ if (!lisdigit(cast_uchar(*s)))
|
|
|
+ goto ret; /* must have at least one digit */
|
|
|
+ while (lisdigit(cast_uchar(*s))) /* read exponent */
|
|
|
+ exp1 = exp1 * 10 + *(s++) - '0';
|
|
|
+ if (neg1) exp1 = -exp1;
|
|
|
+ e += exp1;
|
|
|
+ }
|
|
|
+ *endptr = cast(char *, s); /* valid up to here */
|
|
|
+ ret:
|
|
|
+ if (neg) r = -r;
|
|
|
+ return ldexp(r, e);
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
int luaO_str2d (const char *s, size_t len, lua_Number *result) {
|
|
|
char *endptr;
|
|
|
- const char *e = s + len; /* string 's' ends here */
|
|
|
- *result = lua_str2number(s, &endptr);
|
|
|
- if (checkend(s, e, endptr)) return 1; /* conversion OK? */
|
|
|
- *result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */
|
|
|
- return checkend(s, e, endptr);
|
|
|
+ if (strpbrk(s, "xX")) /* hexa? */
|
|
|
+ *result = lua_strx2number(s, &endptr);
|
|
|
+ else
|
|
|
+ *result = lua_str2number(s, &endptr);
|
|
|
+ if (endptr == s) return 0; /* nothing recognized */
|
|
|
+ while (lisspace(cast_uchar(*endptr))) endptr++;
|
|
|
+ return (endptr == s + len); /* OK if no trailing characters */
|
|
|
}
|
|
|
|
|
|
|