mirror of
https://github.com/lua/lua
synced 2025-05-07 20:58:23 +03:00
'luaO_str2num' (and, therefore, 'lua_stringtonumber', 'number',
and coercions) accepts both the locale point and a dot as its radix character
This commit is contained in:
parent
22093f9c6e
commit
ed110f66c5
56
lobject.c
56
lobject.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.c,v 2.108 2015/11/02 16:09:30 roberto Exp roberto $
|
** $Id: lobject.c,v 2.109 2015/12/14 11:53:27 roberto Exp roberto $
|
||||||
** Some generic functions over Lua objects
|
** Some generic functions over Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -243,17 +243,53 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
|||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
static const char *l_str2d (const char *s, lua_Number *result) {
|
/* maximum length of a numeral */
|
||||||
|
#if !defined (L_MAXLENNUM)
|
||||||
|
#define L_MAXLENNUM 200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
|
*result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
|
||||||
|
: lua_str2number(s, &endptr);
|
||||||
|
if (endptr == s) return NULL; /* nothing recognized? */
|
||||||
|
while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
|
||||||
|
return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert string 's' to a Lua number (put in 'result'). Return NULL
|
||||||
|
** on fail or the address of the ending '\0' on success.
|
||||||
|
** 'pmode' points to (and 'mode' contains) special things in the string:
|
||||||
|
** - 'x'/'X' means an hexadecimal numeral
|
||||||
|
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
|
||||||
|
** - '.' just optimizes the search for the common case (nothing special)
|
||||||
|
** This function accepts both the current locale or a dot as the radix
|
||||||
|
** mark. If the convertion fails, it may mean number has a dot but
|
||||||
|
** locale accepts something else. In that case, the code copies 's'
|
||||||
|
** to a buffer (because 's' is read-only), changes the dot to the
|
||||||
|
** current locale radix mark, and tries to convert again.
|
||||||
|
*/
|
||||||
|
static const char *l_str2d (const char *s, lua_Number *result) {
|
||||||
|
const char *endptr;
|
||||||
|
const char *pmode = strpbrk(s, ".xXnN");
|
||||||
|
int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
|
||||||
|
if (mode == 'n') /* reject 'inf' and 'nan' */
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (strpbrk(s, "xX")) /* hex? */
|
endptr = l_str2dloc(s, result, mode); /* try to convert */
|
||||||
*result = lua_strx2number(s, &endptr);
|
if (endptr == NULL) { /* failed? may be a different locale */
|
||||||
else
|
char buff[L_MAXLENNUM + 1];
|
||||||
*result = lua_str2number(s, &endptr);
|
char *pdot = strchr(s, '.');
|
||||||
if (endptr == s) return NULL; /* nothing recognized */
|
if (strlen(s) > L_MAXLENNUM || pdot == NULL)
|
||||||
while (lisspace(cast_uchar(*endptr))) endptr++;
|
return NULL; /* string too long or no dot; fail */
|
||||||
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
|
strcpy(buff, s); /* copy string to buffer */
|
||||||
|
buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
|
||||||
|
endptr = l_str2dloc(buff, result, mode); /* try again */
|
||||||
|
if (endptr != NULL)
|
||||||
|
endptr = s + (endptr - buff); /* make relative to 's' */
|
||||||
|
}
|
||||||
|
return endptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user