LUA_API const lua_WChar *lua_towstring (lua_State *L, int index) { StkId o = luaA_indexAcceptable(L, index); if (o == NULL) return NULL; else if (ttype(o) == LUA_TWSTRING) return wsvalue(o); else { const lua_WChar *s; lua_lock(L); /* `luaV_tostring' may create a new string */ s = (luaV_towstring(L, o) == 0) ? wsvalue(o) : NULL; lua_unlock(L); return s; } }
NAMESPACE_LUA_BEGIN /* limit for table tag-method chains (to avoid loops) */ #define MAXTAGLOOP 100 #if LUA_REFCOUNT const TValue *luaV_tonumber (lua_State *L, const TValue *obj, TValue *n) { #else const TValue *luaV_tonumber (const TValue *obj, TValue *n) { #endif /* LUA_REFCOUNT */ lua_Number num; if (ttisnumber(obj)) return obj; if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { setnvalue(n, num); return n; } #if LUA_WIDESTRING else if (ttiswstring(obj) && luaO_wstr2d(wsvalue(obj), &num)) { setnvalue(n, num); return n; } #endif /* LUA_WIDESTRING */ else return NULL; }
const TValue *luaV_tonumber (const TValue *obj, TValue *n) { lua_Number num; if (ttisnumber(obj)) return obj; if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { setnvalue(n, num); return n; } else if (ttiswstring(obj) && luaO_wstr2d(wsvalue(obj), &num)) { setnvalue(n, num); return n; } else return NULL; }
LUA_API const lua_WChar *lua_tolwstring (lua_State *L, int idx, size_t *len) { StkId o = index2adr(L, idx); if (!ttiswstring(o)) { lua_lock(L); /* `luaV_tostring' may create a new string */ if (!luaV_towstring(L, o)) { /* conversion failed? */ if (len != NULL) *len = 0; lua_unlock(L); return NULL; } luaC_checkGC(L); o = index2adr(L, idx); /* previous call may reallocate the stack */ lua_unlock(L); } if (len != NULL) *len = twsvalue(o)->len; return wsvalue(o); }
NAMESPACE_LUA_BEGIN /* limit for table tag-method chains (to avoid loops) */ #define MAXTAGLOOP 100 const TValue *luaV_tonumber(const TValue *obj, TValue *n) { lua_Number num = 0.0f; if (ttisnumber(obj)) return obj; if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { setnvalue(n, num); return n; } else if (ttiswstring(obj) && luaO_wstr2d(wsvalue(obj), &num)) { setnvalue(n, num); return n; } else return NULL; }
void luaV_concat (lua_State *L, int total, int last) { int useType = LUA_TSTRING; int i; StkId top = L->base + last + 1; for (i = 0; i < total; ++i) { if (ttype(top-1-i) == LUA_TSTRING || ttype(top-1-i) == LUA_TWSTRING) { useType = ttype(top-1-i); break; } } if (useType == LUA_TSTRING) { do { StkId top = L->base + last + 1; int n = 2; /* number of elements handled in this pass (at least 2) */ if (!tostring(L, top-2) || !tostring(L, top-1)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_concaterror(L, top-2, top-1); } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ /* at least two string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; int i; /* collect total length */ for (n = 1; n < total && tostring(L, top-n-1); n++) { size_t l = tsvalue(top-n-1)->len; if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); tl += l; } buffer = luaZ_openspace(L, &G(L)->buff, tl); tl = 0; for (i=n; i>0; i--) { /* concat all strings */ size_t l = tsvalue(top-i)->len; memcpy(buffer+tl, svalue(top-i), l); tl += l; #if LUA_REFCOUNT luarc_cleanvalue(top-i); #endif /* LUA_REFCOUNT */ } setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); } total -= n-1; /* got `n' strings to create 1 new */ last -= n-1; } while (total > 1); /* repeat until only 1 result left */ } else { do { StkId top = L->base + last + 1; int n = 2; /* number of elements handled in this pass (at least 2) */ if (!towstring(L, top-2) || !towstring(L, top-1)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_concaterror(L, top-2, top-1); } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ /* at least two string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; int i; /* collect total length */ for (n = 1; n < total && towstring(L, top-n-1); n++) { size_t l = tsvalue(top-n-1)->len; if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); tl += l; } buffer = luaZ_openspace(L, &G(L)->buff, tl*2); tl = 0; for (i=n; i>0; i--) { /* concat all strings */ size_t l = tsvalue(top-i)->len; memcpy(buffer+tl*2, wsvalue(top-i), l*2); tl += l; #if LUA_REFCOUNT luarc_cleanvalue(top-i); #endif /* LUA_REFCOUNT */ } setwsvalue2s(L, top-n, luaS_newlwstr(L, (const lua_WChar*)buffer, tl)); } total -= n-1; /* got `n' strings to create 1 new */ last -= n-1; } while (total > 1); /* repeat until only 1 result left */ } }