static const char* FormatConstant(const Value* value, char buffer[64]) { if (Value_GetIsNumber(value)) { lua_number2str(buffer, value->number); } else if (Value_GetIsString(value)) { return String_GetData(value->string); } else if (Value_GetIsBoolean(value)) { strcpy(buffer, value->boolean ? "true" : "false"); } else if (Value_GetIsNil(value)) { strcpy(buffer, "nil"); } else { // Some other type of constant was stored that can't be saved into // the file. If this happens, it means we've introduced some new type // of constant but haven't handled it here. ASSERT(0); return "Unknown"; } return buffer; }
int luaV_tostring (lua_State *L, StkId obj) { if (!ttisnumber(obj)) return 0; else { char s[LUAI_MAXNUMBER2STR]; lua_Number n = nvalue(obj); // SPRING -- synced safety change // -- need a custom number formatter? if (math::isfinite(n)) { lua_number2str(s, n); } else { if (math::isnan(n)) { strcpy(s, "nan"); } else { const int inf_type = math::isinf(n); if (inf_type == 1) { strcpy(s, "+inf"); } else if (inf_type == -1) { strcpy(s, "-inf"); } else { strcpy(s, "weird_number"); } } } setsvalue2s(L, obj, luaS_new(L, s)); return 1; } }
static void ConvSimpleType(lua_State *L, int index, rbuf_t *tb) { int type = lua_type(L, index); switch(type) { case LUA_TSTRING: { size_t len=0; const char * key = luaL_checklstring(L, index, &len); rbuf_catrepr(tb, key, len); break; } //这儿不能够直接使用lua_tostring,因为这个api会修改栈内容,将导致array的lua_next访问异常。 //也不能够强行把lua_Number转换为%d输出。 case LUA_TNUMBER: { char s[LUAI_MAXNUMBER2STR]; size_t len = lua_number2str(s, luaL_checknumber(L, index)); rbuf_catlen(tb, s, len); break; } case LUA_TBOOLEAN: { rbuf_cat(tb, (lua_toboolean(L, index) ? "true" : "false")); break; } case LUA_TNIL: { rbuf_catlen(tb, "nil", 3); break; } default: luaL_error(L, "type error Type:%d,Name:%s.table can not be key", type, lua_typename(L, type)); break; } }
static void ConvKey(lua_State *L, int index, rbuf_t *tb) { int type = lua_type(L, index); switch(type) { case LUA_TSTRING: { size_t len=0; const char * key = luaL_checklstring(L, index, &len); rbuf_catlen(tb, "[", 1); rbuf_catrepr(tb, key, len); rbuf_catlen(tb, "]", 1); break; } case LUA_TNUMBER: { char s[LUAI_MAXNUMBER2STR]; size_t len = lua_number2str(s, luaL_checknumber(L, index)); //整数类型才加上[] rbuf_catlen(tb, "[", 1); rbuf_catlen(tb, s, len); rbuf_catlen(tb, "]", 1); break; } default: luaL_error(L, "type error:%d", type); break; } }
/* (weet: convert number to string)*/ int luaV_tostring (lua_State *L, StkId obj) { if (!ttisnumber(obj)) return 0; else { char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ lua_number2str(s, nvalue(obj)); setsvalue2s(obj, luaS_new(L, s)); return 1; } }
int luaV_tostring (lua_State *L, StkId obj) { if (!ttisnumber(obj)) return 0; else { char s[LUAI_MAXNUMBER2STR]; lua_Number n = nvalue(obj); lua_number2str(s, n); setsvalue2s(L, obj, luaS_new(L, s)); return 1; } }
int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ if (ttype(obj) != LUA_TNUMBER) return 1; else { char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ lua_number2str(s, nvalue(obj)); /* convert `s' to number */ tsvalue(obj) = luaS_new(L, s); ttype(obj) = LUA_TSTRING; return 0; } }
static int LuaJsonWriteNumber(lua_State* L) { LuaJsonWriter* self = (LuaJsonWriter*) luaL_checkudata(L, 1, "tundra_jsonw"); lua_Number num = luaL_checknumber(L, 2); WriteCommon(L, self, 3); char buffer[64]; lua_number2str(buffer, num); BufferedWriterAppendString(&self->m_Writer, buffer); return 0; }
/* 转换成字符串对象 * L lua虚拟机状态 * obj 要转换的对象的栈索引 */ int luaV_tostring (lua_State *L, StkId obj) { /* 如果对象不是数字类型对象则失败 */ if (!ttisnumber(obj)) return 0; else { char s[LUAI_MAXNUMBER2STR]; lua_Number n = nvalue(obj); /* 返回整型的值 */ int l = lua_number2str(s, n); setsvalue2s(L, obj, luaS_newlstr(L, s, l)); return 1; } }
int luaV_tostring (lua_State *L, StkId obj) { if (!ttisnumber(obj)) return 0; else { char buff[MAXNUMBER2STR]; size_t len; if (ttisinteger(obj)) len = lua_integer2str(buff, ivalue(obj)); else { len = lua_number2str(buff, fltvalue(obj)); if (strspn(buff, "-0123456789") == len) { /* look like an integer? */ buff[len++] = '.'; /* add a '.0' */ buff[len++] = '0'; buff[len] = '\0'; } } setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); return 1; } }
//----------------------------------------------------------------// json_t* MOAIHarness::ConvertStackIndexToJSON(lua_State * L, int idx, bool shallow, std::vector<const void*> * carried_references) { // Check to see if idx is negative. if (idx < 0) idx = lua_gettop(L) + (idx + 1); // What we do is going to be based on what is located at // the specified index. switch (lua_type(L, idx)) { case LUA_TNIL: return json_null(); case LUA_TNUMBER: return json_real(lua_tonumber(L, idx)); case LUA_TSTRING: return json_string(lua_tostring(L, idx)); case LUA_TBOOLEAN: return (lua_toboolean(L, idx) == 0) ? json_false() : json_true(); case LUA_TFUNCTION: // Todo: fix pointer encoding for datapairs so that this will work // correctly on 64 bit systems return json_datapair("function", json_integer((int)lua_topointer(L, idx))); case LUA_TUSERDATA: return json_datapair("userdata", json_integer((int)lua_topointer(L, idx))); case LUA_TTHREAD: return json_datapair("thread", json_integer((int)lua_topointer(L, idx))); case LUA_TLIGHTUSERDATA: return json_datapair("lightuserdata", json_integer((int)lua_topointer(L, idx))); case LUA_TTABLE: // Unlike other data values, table must be recursively evaluated. In addition // we must check for circular references since it's possible they may occur. char s[LUAI_MAXNUMBER2STR]; std::vector<const void*> * references = (carried_references == NULL) ? new std::vector<const void*>() : carried_references; json_t* holder = shallow ? json_array() : json_object(); lua_pushnil(L); while (lua_next(L, idx) != 0) { // Key is at index -2 // Value is at index -1 json_t* key = NULL; json_t* value = NULL; // Safely convert the key into a string if needed (we // can't use lua_tostring with lua_next). if (lua_isnumber(L, -2)) { lua_Number n = lua_tonumber(L, -2); if (shallow) { key = json_real(n); } else { lua_number2str(s, n); key = json_string((const char*)&s); } } else if (lua_isboolean(L, -2)) { key = json_string(lua_toboolean(L, -2) ? "true" : "false"); } else if (!lua_isstring(L, -2)) { int type = lua_type(L, -2); key = json_datapair(lua_typename(L, type), json_integer((int)lua_topointer(L, -2))); } else key = json_string(lua_tostring(L, -2)); // If only a shallow result is requested, just add the key to an array if (shallow) { json_array_append_new(holder, key); lua_pop(L, 1); continue; } // Recursively convert the value ONLY if it doesn't // appear in our references vector. bool evaluate = true; if (lua_type(L, -1) == LUA_TTABLE) { const void* ptr = lua_topointer(L, -1); for (std::vector<const void*>::iterator it = references->begin(); it != references->end(); ++it) { if (*it == ptr) { evaluate = false; break; } } } // Now evaluate the value if we should. if (evaluate) { if (lua_type(L, -1) == LUA_TTABLE) references->insert(references->end(), lua_topointer(L, -1)); value = MOAIHarness::ConvertStackIndexToJSON(L, -1, shallow, references); } else value = json_datapair("recursive", json_integer((int)lua_topointer(L, -1))); // Assign the key value pair to the holder object. json_object_set(holder, json_string_value(key), value); json_decref(key); json_decref(value); // Pop the value from the stack (lua_next will consume // the key on the next iterator). lua_pop(L, 1); } if (carried_references == NULL) delete references; return holder; } return json_datapair("unknown", json_integer((int)lua_topointer(L, idx))); }