static void add_s (MatchState *ms, luaL_Buffer *b, const lua_WChar *s, const lua_WChar *e) { lua_State *L = ms->L; if (lua_iswstring(L, 3)) { const lua_WChar *news = lua_towstring(L, 3); size_t l = lua_strlen(L, 3); size_t i; for (i=0; i<l; i++) { if (news[i] != ESC) luaL_putwchar(b, news[i]); else { i++; /* skip ESC */ if (!iswdigit(news[i])) luaL_putwchar(b, news[i]); else { int level = check_capture(ms, news[i]); push_onecapture(ms, level); luaL_addvalue(b); /* add capture to accumulated result */ } } } } else { /* is a function */ int n; lua_pushvalue(L, 3); n = push_captures(ms, s, e); lua_call(L, n, 1); if (lua_iswstring(L, -1)) luaL_addvalue(b); /* add return to accumulated result */ else lua_pop(L, 1); /* function result is not a string: pop it */ } }
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 int str_gsub (lua_State *L) { size_t srcl; const lua_WChar *src = luaL_checklwstring(L, 1, &srcl); const lua_WChar *p = luaL_checkwstring(L, 2); int max_s = luaL_optint(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; int n = 0; MatchState ms; luaL_Buffer b; luaL_argcheck(L, lua_gettop(L) >= 3 && (lua_iswstring(L, 3) || lua_isfunction(L, 3)), 3, "string or function expected"); luaL_wbuffinit(L, &b); ms.L = L; ms.src_init = src; ms.src_end = src+srcl; while (n < max_s) { const lua_WChar *e; ms.level = 0; e = match(&ms, src, p); if (e) { n++; add_s(&ms, &b, src, e); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_putwchar(&b, *src++); else break; if (anchor) break; } luaL_addlwstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushnumber(L, n); /* number of substitutions */ return 2; }