From 27a1dcdd114a0d95a8513de1bd27ccb3b74ea456 Mon Sep 17 00:00:00 2001 From: Enyby Date: Fri, 14 Sep 2018 02:04:56 +0300 Subject: [PATCH] Fix gmatch for pass testsuites Test suites from lua.org: ``` -- tests for gmatch local a = 0 for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end assert(a==6) t = {n=0} for w in string.gmatch("first second word", "%w+") do t.n=t.n+1; t[t.n] = w end assert(t[1] == "first" and t[2] == "second" and t[3] == "word") t = {3, 6, 9} for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do assert(i == table.remove(t, 1)) end assert(#t == 0) t = {} for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do t[tonumber(i)] = tonumber(j) end a = 0 for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end assert(a == 3) -- tests for `%f' (`frontiers') assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[") assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3") assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.") assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction") assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.") assert(string.find("a", "%f[a]") == 1) assert(string.find("a", "%f[^%z]") == 1) assert(string.find("a", "%f[^%l]") == 2) assert(string.find("aba", "%f[a%z]") == 3) assert(string.find("aba", "%f[%z]") == 4) assert(not string.find("aba", "%f[%l%z]")) assert(not string.find("aba", "%f[^%l%z]")) local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]") assert(i == 2 and e == 5) local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])") assert(k == 'alo ') local a = {1, 5, 9, 14, 17,} for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do assert(table.remove(a, 1) == k) end assert(#a == 0) ``` Code from lua: https://www.lua.org/source/5.2/lstrlib.c.html ``` static int gmatch_aux (lua_State *L) { MatchState ms; size_t ls, lp; const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); const char *src; ms.L = L; ms.matchdepth = MAXCCALLS; ms.src_init = s; ms.src_end = s+ls; ms.p_end = p + lp; for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); src <= ms.src_end; src++) { const char *e; ms.level = 0; lua_assert(ms.matchdepth == MAXCCALLS); if ((e = match(&ms, src, p)) != NULL) { lua_Integer newstart = e-s; if (e == src) newstart++; /* empty match? go at least one position */ lua_pushinteger(L, newstart); lua_replace(L, lua_upvalueindex(3)); return push_captures(&ms, src, e); } } return 0; /* not found */ } ``` On empty match need increase string offset. --- src/core/org/luaj/vm2/lib/StringLib.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/org/luaj/vm2/lib/StringLib.java b/src/core/org/luaj/vm2/lib/StringLib.java index 1189fc7e..0b1f755f 100644 --- a/src/core/org/luaj/vm2/lib/StringLib.java +++ b/src/core/org/luaj/vm2/lib/StringLib.java @@ -525,12 +525,13 @@ public class StringLib extends TwoArgFunction { this.soffset = 0; } public Varargs invoke(Varargs args) { - for ( ; soffset=0 ) { int soff = soffset; soffset = res; + if (soff == res) soffset++; /* empty match? go at least one position */ return ms.push_captures( true, soff, res ); } }