/* ** Read a number: first reads a valid prefix of a numeral into a buffer. ** Then it calls 'lua_stringtonumber' to check whether the format is ** correct and to convert it to a Lua number */ static int read_number (lua_State *L, FILE *f) { RN rn; int count = 0; int hex = 0; char decp[2]; rn.f = f; rn.n = 0; decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */ decp[1] = '.'; /* always accept a dot */ l_lockfile(rn.f); do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ test2(&rn, "-+"); /* optional signal */ if (test2(&rn, "00")) { if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ else count = 1; /* count initial '0' as a valid digit */ } count += readdigits(&rn, hex); /* integral part */ if (test2(&rn, decp)) /* decimal point? */ count += readdigits(&rn, hex); /* fractional part */ if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ test2(&rn, "-+"); /* exponent signal */ readdigits(&rn, 0); /* exponent digits */ } ungetc(rn.c, rn.f); /* unread look-ahead char */ l_unlockfile(rn.f); rn.buff[rn.n] = '\0'; /* finish string */ if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */ return 1; /* ok */ else { /* invalid format */ lua_pushnil(L); /* "result" to be removed */ return 0; /* read fails */ } }
static int luaB_tonumber (lua_State *L) { if (lua_isnoneornil(L, 2)) { /* standard conversion? */ luaL_checkany(L, 1); if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ lua_settop(L, 1); /* yes; return it */ return 1; } else { size_t l; const char *s = luaL_tolstring(L, 1, &l); if (s != NULL && lua_stringtonumber(L, s) == l + 1) return 1; /* successful conversion to number */ /* else not a number */ } } else { size_t l; const char *s; lua_Integer n = 0; /* to avoid warnings */ lua_Integer base = luaL_checkinteger(L, 2); luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */ s = luaL_checklstring(L, 1, &l); luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); if (b_str2int(s, (int)base, &n) == s + l) { lua_pushinteger(L, n); return 1; } /* else not a number */ } /* else not a number */ lua_pushnil(L); /* not a number */ return 1; }
static int tonum (lua_State *L, int arg) { if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */ lua_pushvalue(L, arg); return 1; } else { /* check whether it is a numerical string */ size_t len; const char *s = lua_tolstring(L, arg, &len); return (s != NULL && lua_stringtonumber(L, s) == len + 1); } }
static int l_loadvalue( lua_State* L ) { gwlua_t* state = get_state( L ); const char* key = luaL_checkstring( L, 1 ); int type; const char* value = gwlua_load_value( state, key, &type ); if ( value ) { switch ( type ) { case GWLUA_NULL: default: lua_pushnil( L ); break; case GWLUA_BOOLEAN: lua_pushboolean( L, !strcmp( value, "true" ) ); break; case GWLUA_NUMBER: if ( !lua_stringtonumber( L, value ) ) { lua_pushinteger( L, 0 ); } break; case GWLUA_STRING: lua_pushstring( L, value ); break; } } else { lua_pushnil( L ); } return 1; }
static int luaB_tointeger (lua_State *L) { if (lua_type(L, 1) == LUA_TNUMBER){ if (lua_isinteger(L, 1)) { lua_settop(L, 1); return 1; } else { lua_Number n = lua_tonumber(L, 1); lua_pushinteger(L, (lua_Integer)n); return 1; } } else { size_t l; const char *s = luaL_tolstring(L, 1, &l); if (s != NULL && lua_stringtonumber(L, s) == l + 1) { lua_Number n = lua_tonumber(L, 1); lua_pushinteger(L, (lua_Integer)n); return 1; } } lua_pushnil(L); return 1; }