aboutsummaryrefslogtreecommitdiff
path: root/lobject.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-05-02 11:00:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-05-02 11:00:32 -0300
commited110f66c5af4fd804567a3cd5a7250eb5eb239b (patch)
tree5c42ce39d025ae11c6da2938985f1677fa27f8ed /lobject.c
parent22093f9c6ef0e21244603883eed740d34d9fd63f (diff)
downloadlua-ed110f66c5af4fd804567a3cd5a7250eb5eb239b.tar.gz
lua-ed110f66c5af4fd804567a3cd5a7250eb5eb239b.tar.bz2
lua-ed110f66c5af4fd804567a3cd5a7250eb5eb239b.zip
'luaO_str2num' (and, therefore, 'lua_stringtonumber', 'number',
and coercions) accepts both the locale point and a dot as its radix character
Diffstat (limited to 'lobject.c')
-rw-r--r--lobject.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/lobject.c b/lobject.c
index ca299f92..41a50df1 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.108 2015/11/02 16:09:30 roberto Exp roberto $ 2** $Id: lobject.c,v 2.109 2015/12/14 11:53:27 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*/
@@ -243,17 +243,53 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
243/* }====================================================== */ 243/* }====================================================== */
244 244
245 245
246static const char *l_str2d (const char *s, lua_Number *result) { 246/* maximum length of a numeral */
247#if !defined (L_MAXLENNUM)
248#define L_MAXLENNUM 200
249#endif
250
251static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
247 char *endptr; 252 char *endptr;
248 if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ 253 *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
254 : lua_str2number(s, &endptr);
255 if (endptr == s) return NULL; /* nothing recognized? */
256 while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
257 return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
258}
259
260
261/*
262** Convert string 's' to a Lua number (put in 'result'). Return NULL
263** on fail or the address of the ending '\0' on success.
264** 'pmode' points to (and 'mode' contains) special things in the string:
265** - 'x'/'X' means an hexadecimal numeral
266** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
267** - '.' just optimizes the search for the common case (nothing special)
268** This function accepts both the current locale or a dot as the radix
269** mark. If the convertion fails, it may mean number has a dot but
270** locale accepts something else. In that case, the code copies 's'
271** to a buffer (because 's' is read-only), changes the dot to the
272** current locale radix mark, and tries to convert again.
273*/
274static const char *l_str2d (const char *s, lua_Number *result) {
275 const char *endptr;
276 const char *pmode = strpbrk(s, ".xXnN");
277 int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
278 if (mode == 'n') /* reject 'inf' and 'nan' */
249 return NULL; 279 return NULL;
250 else if (strpbrk(s, "xX")) /* hex? */ 280 endptr = l_str2dloc(s, result, mode); /* try to convert */
251 *result = lua_strx2number(s, &endptr); 281 if (endptr == NULL) { /* failed? may be a different locale */
252 else 282 char buff[L_MAXLENNUM + 1];
253 *result = lua_str2number(s, &endptr); 283 char *pdot = strchr(s, '.');
254 if (endptr == s) return NULL; /* nothing recognized */ 284 if (strlen(s) > L_MAXLENNUM || pdot == NULL)
255 while (lisspace(cast_uchar(*endptr))) endptr++; 285 return NULL; /* string too long or no dot; fail */
256 return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */ 286 strcpy(buff, s); /* copy string to buffer */
287 buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
288 endptr = l_str2dloc(buff, result, mode); /* try again */
289 if (endptr != NULL)
290 endptr = s + (endptr - buff); /* make relative to 's' */
291 }
292 return endptr;
257} 293}
258 294
259 295