aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lobject.c87
-rw-r--r--lstrlib.c5
-rw-r--r--luaconf.h20
3 files changed, 99 insertions, 13 deletions
diff --git a/lobject.c b/lobject.c
index 598520ac..cb8ead92 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.43 2010/10/29 15:54:55 roberto Exp roberto $ 2** $Id: lobject.c,v 2.44 2010/12/06 21:08:36 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -106,20 +106,87 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
106} 106}
107 107
108 108
109static int checkend (const char *s, const char *e, const char *endptr) { 109int luaO_hexavalue (int c) {
110 if (endptr == s) return 0; /* no characters converted */ 110 if (lisdigit(c)) return c - '0';
111 while (lisspace(cast(unsigned char, *endptr))) endptr++; 111 else if (lisupper(c)) return c - 'A' + 10;
112 return (endptr == e); /* OK if no trailing characters */ 112 else return c - 'a' + 10;
113} 113}
114 114
115 115
116#if !defined(lua_strx2number)
117
118#include <math.h>
119
120
121static int isneg (const char **s) {
122 if (**s == '-') { (*s)++; return 1; }
123 else if (**s == '+') (*s)++;
124 return 0;
125}
126
127
128static lua_Number readhexa (const char **s, lua_Number r, int *count) {
129 while (lisxdigit(cast_uchar(**s))) { /* read integer part */
130 r = (r * 16.0) + (double)luaO_hexavalue(*(*s)++);
131 (*count)++;
132 }
133 return r;
134}
135
136
137/*
138** convert an hexadecimal numeric string to a number, following
139** C99 specification for 'strtod'
140*/
141static lua_Number lua_strx2number (const char *s, char **endptr) {
142 lua_Number r = 0.0;
143 int e = 0, i = 0;
144 int neg = 0; /* 1 if number is negative */
145 *endptr = cast(char *, s); /* nothing is valid yet */
146 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
147 neg = isneg(&s); /* check signal */
148 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
149 return 0.0; /* invalid format (no '0x') */
150 s += 2; /* skip '0x' */
151 r = readhexa(&s, r, &i); /* read integer part */
152 if (*s == '.') {
153 s++; /* skip dot */
154 r = readhexa(&s, r, &e); /* read fractional part */
155 }
156 if (i == 0 && e == 0)
157 return 0.0; /* invalid format (no digit) */
158 e *= -4; /* each fractional digit divides value by 2^-4 */
159 *endptr = cast(char *, s); /* valid up to here */
160 if (*s == 'p' || *s == 'P') { /* exponent part? */
161 int exp1 = 0;
162 int neg1;
163 s++; /* skip 'p' */
164 neg1 = isneg(&s); /* signal */
165 if (!lisdigit(cast_uchar(*s)))
166 goto ret; /* must have at least one digit */
167 while (lisdigit(cast_uchar(*s))) /* read exponent */
168 exp1 = exp1 * 10 + *(s++) - '0';
169 if (neg1) exp1 = -exp1;
170 e += exp1;
171 }
172 *endptr = cast(char *, s); /* valid up to here */
173 ret:
174 if (neg) r = -r;
175 return ldexp(r, e);
176}
177
178#endif
179
180
116int luaO_str2d (const char *s, size_t len, lua_Number *result) { 181int luaO_str2d (const char *s, size_t len, lua_Number *result) {
117 char *endptr; 182 char *endptr;
118 const char *e = s + len; /* string 's' ends here */ 183 if (strpbrk(s, "xX")) /* hexa? */
119 *result = lua_str2number(s, &endptr); 184 *result = lua_strx2number(s, &endptr);
120 if (checkend(s, e, endptr)) return 1; /* conversion OK? */ 185 else
121 *result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */ 186 *result = lua_str2number(s, &endptr);
122 return checkend(s, e, endptr); 187 if (endptr == s) return 0; /* nothing recognized */
188 while (lisspace(cast_uchar(*endptr))) endptr++;
189 return (endptr == s + len); /* OK if no trailing characters */
123} 190}
124 191
125 192
diff --git a/lstrlib.c b/lstrlib.c
index 7ca7ea39..3acaf875 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.158 2010/11/16 20:39:41 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.159 2010/11/19 16:25:51 roberto Exp roberto $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -861,6 +861,9 @@ static int str_format (lua_State *L) {
861 break; 861 break;
862 } 862 }
863 case 'e': case 'E': case 'f': 863 case 'e': case 'E': case 'f':
864#if defined(LUA_USE_AFORMAT)
865 case 'a': case 'A':
866#endif
864 case 'g': case 'G': { 867 case 'g': case 'G': {
865 addlenmod(form, LUA_FLTFRMLEN); 868 addlenmod(form, LUA_FLTFRMLEN);
866 nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); 869 nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
diff --git a/luaconf.h b/luaconf.h
index e79421b6..f7b242f9 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luaconf.h,v 1.151 2010/11/12 15:48:30 roberto Exp roberto $ 2** $Id: luaconf.h,v 1.152 2010/12/08 12:58:04 roberto Exp roberto $
3** Configuration file for Lua 3** Configuration file for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -35,6 +35,7 @@
35 35
36#if defined(LUA_WIN) 36#if defined(LUA_WIN)
37#define LUA_DL_DLL 37#define LUA_DL_DLL
38#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
38#endif 39#endif
39 40
40 41
@@ -43,6 +44,8 @@
43#define LUA_USE_POSIX 44#define LUA_USE_POSIX
44#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ 45#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
45#define LUA_USE_READLINE /* needs some extra libraries */ 46#define LUA_USE_READLINE /* needs some extra libraries */
47#define LUA_USE_HEXAFLOAT /* assume 'strtod' handles hexa formats */
48#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
46#endif 49#endif
47 50
48#if defined(LUA_USE_MACOSX) 51#if defined(LUA_USE_MACOSX)
@@ -377,14 +380,27 @@
377@@ LUA_NUMBER_FMT is the format for writing numbers. 380@@ LUA_NUMBER_FMT is the format for writing numbers.
378@@ lua_number2str converts a number to a string. 381@@ lua_number2str converts a number to a string.
379@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. 382@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
380@@ lua_str2number converts a string to a number.
381*/ 383*/
382#define LUA_NUMBER_SCAN "%lf" 384#define LUA_NUMBER_SCAN "%lf"
383#define LUA_NUMBER_FMT "%.14g" 385#define LUA_NUMBER_FMT "%.14g"
384#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) 386#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
385#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ 387#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
388
389
390/*
391@@ lua_str2number converts a decimal numeric string to a number.
392@@ lua_strx2number converts an hexadecimal numeric string to a number.
393** In C99, 'strtod' do both conversions. C89, however, has no function
394** to convert floating hexadecimal strings to numbers. For these
395** systems, you can leave 'lua_strx2number' undefined and Lua will
396** provide its own implementation.
397*/
386#define lua_str2number(s,p) strtod((s), (p)) 398#define lua_str2number(s,p) strtod((s), (p))
387 399
400#if defined(LUA_USE_HEXAFLOAT)
401#define lua_strx2number(s,p) strtod((s), (p))
402#endif
403
388 404
389/* 405/*
390@@ The luai_num* macros define the primitive operations over numbers. 406@@ The luai_num* macros define the primitive operations over numbers.