** Convert string 's' to a Lua number (put in 'result') handling the ** current locale. ** This function accepts both the current locale or a dot as the radix ** mark. If the conversion 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
| 312 | ** - '.' just optimizes the search for the common case (no special chars) |
| 313 | */ |
| 314 | static const char *l_str2d (const char *s, lua_Number *result) { |
| 315 | const char *endptr; |
| 316 | const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */ |
| 317 | int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; |
| 318 | if (mode == 'n') /* reject 'inf' and 'nan' */ |
| 319 | return NULL; |
| 320 | endptr = l_str2dloc(s, result, mode); /* try to convert */ |
| 321 | if (endptr == NULL) { /* failed? may be a different locale */ |
| 322 | char buff[L_MAXLENNUM + 1]; |
| 323 | const char *pdot = strchr(s, '.'); |
| 324 | if (pdot == NULL || strlen(s) > L_MAXLENNUM) |
| 325 | return NULL; /* string too long or no dot; fail */ |
| 326 | strcpy(buff, s); /* copy string to buffer */ |
| 327 | buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ |
| 328 | endptr = l_str2dloc(buff, result, mode); /* try again */ |
| 329 | if (endptr != NULL) |
| 330 | endptr = s + (endptr - buff); /* make relative to 's' */ |
| 331 | } |
| 332 | return endptr; |
| 333 | } |
| 334 | |
| 335 | |
| 336 | #define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) |
no test coverage detected