Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum
ReedN
Wizard


Joined: 04 Jan 2006
Posts: 1279
Location: Portland, Oregon

PostPosted: Sun Apr 26, 2009 11:04 pm   

[3.06] Weird Lua problem found while trying to use Lua for search and replace
 
I've been getting very strange issues when trying this code. Sometimes it will give AV errors, but it is definitely not working according to design.

Steps:

1) Go into a clean session.
2) Import the code below.
3) Type: SearchAndReplace "hello" "hello1"
4) Observe that it totally obliterated the code for the SearchAndReplace alias that was just run. I've tried digging to the heart of this but I just keep getting AVs and a ton of strange errors.

Code:
Code:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <alias name="SearchAndReplace" copy="yes">
    <value>#IF ($Search="") {#SHOW Search string required!;#EXIT}
#IF ($Replace="") {#SHOW Replacement string required!;#EXIT}
#IF ($Type="") {
 $Type="alias|var|event|button|menu"
} {
 $Type=%subregex($Type,"( |,)|(?:\b(?:(al(?:i(?:a(?:s)?)?)?)|(va(?:r(?:i(?:a(?:b(?:l(?:e)?))?)?)?)?)|(ev(?:e(?:n(?:t)?)?)?)|(bu(?:t(?:t(?:o(?:n)?)?)?)?)|(me(?:n(?:u)?)?)|(.*))\b)","(?(1)\||(?(2)alias|(?(3)var|(?(4)event|(?(5)button|(?(6)menu)|(?(7)ERROR\|\7))))))")
 #DELITEM $Type {}
}
$ERROR=%ismember("ERROR",$Type)
#IF ($ERROR) {
 #SHOW {Unknown type %item($Type,($ERROR+1))}
 #EXIT
}
#IF (%yesno(%concat("Confirm replacement of ",$Search," with ",$Replace," in ",$Type))) {
 #FORALL $Type {
  #LUA %concat("i=zs.num",%i,%crlf,"while i>0 do",%crlf,"x=zs.get",%i,"(i)",%crlf,"y=x.value",%crlf,"x.value=zs.func.subregex(y,'",$Search,"','",$Replace,"')",%crlf,"i=i-1",%crlf,"end")
 }
}</value>
    <arglist>$Search, $Replace, $Type</arglist>
  </alias>
</cmud>
Reply with quote
wrym
Magician


Joined: 06 Jul 2007
Posts: 349
Location: The big palace, My own lil world

PostPosted: Mon Apr 27, 2009 5:11 am   
 
Thats actually not a bug as these commands show.

Code:
#lua {print(zs.getalias(1).value)}
#lua {print(type(zs.getalias(1).value))}

#alias test {single line of text}
#lua {print(type(zs.getalias(2).value))}


I think you've 2 problems going on here,
First Lua specific characters aren't getting escaped, = namely possibly quotes brackets, parenths, and a few others
Secondly,multi-line values in lua are returned as a table, and your not searching thou the table, just the first line.

I think you might be able to get around this by:
A escape = ' " { } = . and maybe a few other characters
B use a type on your value, if it's a string AND matches your regex, then subregex it, else loop throu table and then check if it matches, then subregex it

I'ld probably put all the lua stuff in a function to make it more readable, would be a nasty %concat
Reply with quote
ReedN
Wizard


Joined: 04 Jan 2006
Posts: 1279
Location: Portland, Oregon

PostPosted: Mon Apr 27, 2009 6:29 am   
 
That would explain why all but the first line is missing.
Reply with quote
ReedN
Wizard


Joined: 04 Jan 2006
Posts: 1279
Location: Portland, Oregon

PostPosted: Mon Apr 27, 2009 6:16 pm   
 
Wrym, could you post a little more on the two issues you highlighted?

1) When do I need to escape these characters? ='"{}
Only in the subregex or in other locations as well?

2) How do I start treating the returned result as a table? Could you give me some starter tips for this?

Thanks again.
Reply with quote
wrym
Magician


Joined: 06 Jul 2007
Posts: 349
Location: The big palace, My own lil world

PostPosted: Mon Apr 27, 2009 7:07 pm   
 
The reason I noticed needing to escape some of the lua command chars was because the first line of your alias got snuffed to "#IF ($Search" and gave away some sort of problem there. As for other characters, Lua uses {} for tables and obviously ' and " for denoting strings, Fang I think would know exactly what would need to be escaped, i'ld just keep escaping chars till it started workng. But as i was thinking about this, i think the better route might be to perform the in Zscript so that escaping characters largely becomes unnecessary. Unfortunately i don't believe there is a LUA interface for local variables....

As for tables, there is a number of methods for manipulating them, loops with ipairs(t) or for loops with pairs(t) are probably your best bet. table.getn or the length of a table could return false end of setting.

Give me a bit and i'll write up some code. This actually will be a neat way to also display the line that is getting changed like you posted on the other forum.
Reply with quote
wrym
Magician


Joined: 06 Jul 2007
Posts: 349
Location: The big palace, My own lil world

PostPosted: Mon Apr 27, 2009 8:39 pm   
 
Mkay, here is what i ended up with,
Code:
<func name="sar" language="Lua" id="6">
  <value><![CDATA[i=zs[zs.concat("num",zs.param(1))]  --get count of setting type
print("\n\n   <color green>Searching for:'"..zs.param(2).."'</color>")
local setting
while i>0 do --for all settings of this type
  setting = zs[zs.concat("get",zs.param(1))](i)  --get setting
  if (zs.func.regex( setting.value , zs.param(2)) ~= 0 ) then  --check setting if it matches
    if (type(setting.value) == "string") then
      print("\n<color blue>Replacing:</color> "..setting.value.."\n   in "..zs.param(1).." "..setting.name)
      setting.value = zs.func.subregex(setting.value,zs.param(2),zs.param(3))
    else  --setting is table, search all keys and replace
      for l = 0,setting.value.maxn do
        if (zs.func.regex( setting.value[l] , zs.param(2)) ~= 0 ) then
          print("\n<color blue>Replacing:</color> "..setting.value[l].."\n   in "..zs.param(1).." "..setting.name)
          setting.value[l] = zs.func.subregex(setting.value[l],zs.param(2),zs.param(3))
        end -- end of setting.value[l] pool
      end -- end for loop of setting.value table
    end --end setting type if
  end    --end if setting matches
  i=i-1 -- increment setting count
end]]></value>
  <arglist>$type $search $replace</arglist>
</func>


NOT THOROUGHLY TESTED

Set it up to work with your alias,
Code:
#call @sar($type,$search,$replace)


tested on a few test scripts, but not my full package set.. I don't trust it that much yet, nor do I have anything to replace.... put in a few comments but not complete. Didn't end up needing to escape any characters, that i know of yet. Might have been some interaction still being in a table stated instead of a string in your code.

Thoughts questions, bugs lemme know
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net