void luaV_strconc (lua_State *L, int total, StkId top) { do { 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, TM_CONCAT)) luaG_binerror(L, top-2, LUA_TSTRING, "concat"); } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ /* at least two string values; get as many as possible */ lint32 tl = (lint32)tsvalue(top-1)->len + (lint32)tsvalue(top-2)->len; char *buffer; int i; while (n < total && !tostring(L, top-n-1)) { /* collect total length */ tl += tsvalue(top-n-1)->len; n++; } if (tl > MAX_SIZET) lua_error(L, "string size overflow"); buffer = luaO_openspace(L, tl); tl = 0; for (i=n; i>0; i--) { /* concat all strings */ size_t l = tsvalue(top-i)->len; memcpy(buffer+tl, tsvalue(top-i)->str, l); tl += l; } tsvalue(top-n) = luaS_newlstr(L, buffer, tl); } total -= n-1; /* got `n' strings to create 1 new */ top -= n-1; } while (total > 1); /* repeat until only 1 result left */ }
static TString* LoadString (lua_State* L, ZIO* Z, int swap) { size_t size=LoadSize(L,Z,swap); if (size==0) return NULL; else { char* s=luaO_openspace(L,size); LoadBlock(L,s,size,Z,0); return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */ } }