static void wadd_value (WMatchState *ms, luaL_Buffer *b, const lua_WChar *s, const lua_WChar *e) { lua_State *L = ms->L; switch (lua_type(L, 3)) { case LUA_TNUMBER: case LUA_TSTRING: case LUA_TWSTRING: { wadd_s(ms, b, s, e); return; } case LUA_TFUNCTION: { int n; lua_pushvalue(L, 3); n = wpush_captures(ms, s, e); lua_call(L, n, 1); break; } case LUA_TTABLE: { wpush_onecapture(ms, 0, s, e); lua_gettable(L, 3); break; } default: { luaL_argerror(L, 3, "string/wstring/function/table expected"); return; } } if (!lua_toboolean(L, -1)) { /* nil or false? */ lua_pop(L, 1); lua_pushlwstring(L, s, e - s); /* keep original text */ } else if (!lua_iswstring(L, -1)) luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); luaL_addvalue(b); /* add result to accumulator */ }
static void push_onecapture (MatchState *ms, int i) { int l = ms->capture[i].len; if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); if (l == CAP_POSITION) lua_pushnumber(ms->L, ms->capture[i].init - ms->src_init + 1); else lua_pushlwstring(ms->L, ms->capture[i].init, l); }
static void wpush_onecapture (WMatchState *ms, int i, const lua_WChar *s, const lua_WChar *e) { if (i >= ms->level) { if (i == 0) /* ms->level == 0, too */ lua_pushlwstring(ms->L, s, e - s); /* add whole wmatch */ else luaL_error(ms->L, "invalid capture index"); } else { ptrdiff_t l = ms->capture[i].len; if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); if (l == CAP_POSITION) lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); else lua_pushlwstring(ms->L, ms->capture[i].init, l); } }
static int str_sub (lua_State *L) { size_t l; const lua_WChar *s = luaL_checklwstring(L, 1, &l); sint32 start = posrelat(luaL_checklong(L, 2), l); sint32 end = posrelat(luaL_optlong(L, 3, -1), l); if (start < 1) start = 1; if (end > (sint32)l) end = l; if (start <= end) lua_pushlwstring(L, s+start-1, end-start+1); else lua_pushwliteral(L, L""); return 1; }
static int wstr_sub (lua_State *L) { size_t l; const lua_WChar *s = luaL_checklwstring(L, 1, &l); ptrdiff_t start = wstr_posrelat(luaL_checkinteger(L, 2), l); ptrdiff_t end = wstr_posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; if (start <= end) lua_pushlwstring(L, s+start-1, end-start+1); else lua_pushwliteral(L, L""); return 1; }
static int push_captures (MatchState *ms, const lua_WChar *s, const lua_WChar *e) { int i; luaL_checkstack(ms->L, ms->level, "too many captures"); if (ms->level == 0 && s) { /* no explicit captures? */ lua_pushlwstring(ms->L, s, e-s); /* return whole match */ return 1; } else { /* return all captures */ for (i=0; i<ms->level; i++) push_onecapture(ms, i); return ms->level; /* number of strings pushed */ } }
static int emptybuffer (luaL_Buffer *B) { size_t l = bufflen(B); if (l == 0) return 0; /* put nothing on stack */ else { if (B->isWide) lua_pushlwstring(B->L, (const lua_WChar*)B->buffer, l / 2); else lua_pushlstring(B->L, B->buffer, l); B->p = B->buffer; B->lvl++; return 1; } }
LUA_API void lua_pushwstring (lua_State *L, const lua_WChar *s) { if (s == NULL) lua_pushnil(L); else lua_pushlwstring(L, s, wcslen(s)); }