rzel / kahlua

Automatically exported from code.google.com/p/kahlua
0 stars 0 forks source link

string.gsub function/table replacing is broken when no captures are present #15

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
from lua reference:
"""
If repl is a table, then the table is queried for every match, using the
first capture as the key; *if the pattern specifies no captures, then the
whole match is used as the key.*

If repl is a function, then this function is called every time a match
occurs, with all captured substrings passed as arguments, in order; *if the
pattern specifies no captures, then the whole match is passed as a sole
argument.*

If the value returned by the table query or by the function call is a
string or a number, then it is used as the replacement string; *otherwise,
if it is false or nil, then there is no replacement (that is, the original
match is kept in the string).*
"""

this was not true in kahlua. the attached patch fixes this.

also, the Lua throws error if something else than string/number/false/nil
is found for replacement. the patch doesn't copy this behavior and instead
assumes that everything that is not string/number means false.

Original issue reported on code.google.com by matej...@gmail.com on 29 Jun 2009 at 1:04

Attachments:

GoogleCodeExporter commented 8 years ago
and the patch is even better now that i discovered BaseLib.rawTostring ;e)

Original comment by matej...@gmail.com on 30 Jun 2009 at 1:37

Attachments:

GoogleCodeExporter commented 8 years ago
Confirmed.

I am not quite ready to commit my changes, but here is my proposed fix:

--- a/src/se/krka/kahlua/stdlib/StringLib.java
+++ b/src/se/krka/kahlua/stdlib/StringLib.java
@@ -809,6 +809,9 @@ public final class StringLib implements JavaFunction {
                }

                public Object[] getCaptures() {
+                       if (level <= 0) {
+                               return null;
+                       }
                        Object[] caps = new String[level];
                        for (int i = 0; i < level; i++) {
                                if (capture[i].len == CAP_POSITION) {
@@ -1432,12 +1435,22 @@ public final class StringLib implements JavaFunction {
                String type = BaseLib.type(repl);
                if (type == BaseLib.TYPE_NUMBER || type == BaseLib.TYPE_STRING) {
                        b.append(addString (ms, repl, src, e));
-               } else if (type == BaseLib.TYPE_FUNCTION) {
-                       Object res =
ms.callFrame.thread.state.call(repl,ms.getCaptures());
-                       b.append(res);
-               } else if (type == BaseLib.TYPE_TABLE) {
-                       Object cap = ms.getCaptures()[0];
-                       b.append(((LuaTable)repl).rawget(cap));
+               } else {
+                       String match = src.getString().substring(0, 
e.getIndex() -
src.getIndex());
+                       Object[] captures = ms.getCaptures();
+                       if (captures != null) {
+                               match = BaseLib.rawTostring(captures[0]);
+                       }
+                       Object res = null;
+                       if (type == BaseLib.TYPE_FUNCTION) {
+                               res = ms.callFrame.thread.state.call(repl, 
match,
null, null);
+                       } else if (type == BaseLib.TYPE_TABLE) {
+                               res = ((LuaTable)repl).rawget(match);
+                       }
+                       if (res == null) {
+                               res = match;
+                       }
+                       b.append(BaseLib.rawTostring(res));
                }
        }

Original comment by kristofer.karlsson@gmail.com on 2 Jul 2009 at 10:38

GoogleCodeExporter commented 8 years ago
Fixed in subversion.

Original comment by kristofer.karlsson@gmail.com on 6 Jul 2009 at 11:01