static TString* LoadWString (LoadState* S) { size_t size=LoadSize(S); if (size==0) return NULL; else { lua_WChar* s=(lua_WChar *)luaZ_openspace(S->L,S->b,size*2); ezread(S,s,size*2); return luaS_newlwstr(S->L,(const lua_WChar*)s,size-1); /* remove trailing '\0' */ } }
static TString* LoadWString(LoadState* S) { size_t size; LoadVar(S,size); if (size==0) return NULL; else { lua_WChar* s=(lua_WChar*)luaZ_openspace(S->L,S->b,size*2); LoadVector(S,s,size,2); return luaS_newlwstr(S->L,s,size-1); /* remove trailing '\0' */ } }
LUA_API void lua_pushlwstring (lua_State *L, const lua_WChar *s, size_t len) { lua_lock(L); setwsvalue(L->top, luaS_newlwstr(L, s, len)); api_incr_top(L); lua_unlock(L); }
static void read_wstring (LexState *LS, int del, SemInfo *seminfo) { size_t l = 0; checkbuffer(LS, l * 2); wsave_and_next(LS, l); while (LS->current != del) { checkbuffer(LS, l * 2); switch (LS->current) { case EOZ: wsave(LS, '\0', l); luaX_lexerror(LS, "unfinished string", TK_EOS); break; /* to avoid warnings */ case '\n': wsave(LS, '\0', l); luaX_lexerror(LS, "unfinished string", TK_STRING); break; /* to avoid warnings */ case '\\': next(LS); /* do not save the `\' */ switch (LS->current) { case 'a': wsave(LS, '\a', l); next(LS); break; case 'b': wsave(LS, '\b', l); next(LS); break; case 'f': wsave(LS, '\f', l); next(LS); break; case 'n': wsave(LS, '\n', l); next(LS); break; case 'r': wsave(LS, '\r', l); next(LS); break; case 't': wsave(LS, '\t', l); next(LS); break; case 'v': wsave(LS, '\v', l); next(LS); break; case '\n': wsave(LS, '\n', l); inclinenumber(LS); break; case EOZ: break; /* will raise an error next loop */ case 'x': { int ch; next(LS); ch = tolower(LS->current); if (!lex_isdigit(ch) && !(ch >= 'a' && ch <= 'f') ) save(LS, 'x', l); /* handles \\, \", \', and \? */ else { /* \xxx */ int c = 0; int i = 0; int numDigits = 4; do { ch = tolower(LS->current); if (lex_isdigit(ch)) c = 16*c + (ch-'0'); else if (ch >= 'a' && ch <= 'f') c = 16*c + (ch-'a') + 10; next(LS); ch = tolower(LS->current); } while (++i<numDigits && (lex_isdigit(ch) || (ch >= 'a' && ch <= 'f'))); wsave(LS, c, l); } break; } default: { if (!lex_isdigit(LS->current)) wsave_and_next(LS, l); /* handles \\, \", \', and \? */ else { /* \xxx */ int c = 0; int i = 0; do { c = 10*c + (LS->current-'0'); next(LS); } while (++i<3 && lex_isdigit(LS->current)); if (c > UCHAR_MAX) { wsave(LS, '\0', l); luaX_lexerror(LS, "escape sequence too large", TK_STRING); } wsave(LS, c, l); } } } break; default: wsave_and_next(LS, l); } } wsave_and_next(LS, l); /* skip delimiter */ wsave(LS, '\0', l); seminfo->ts = luaS_newlwstr(LS->L, (const lua_WChar*)(luaZ_buffer(LS->buff) + 1 * 2), (l - 3 * 2) / 2); }
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 */ } }