[Iup-users] interpreter crash
Merick
Merick_TeVaran at comcast.net
Mon Oct 8 20:53:28 GMT+3 2007
Alright, I'm having trouble with my script crashing my interpreter in
winXP. I'm trying to use the table.save functions from the code snippets
in the lua users wiki:
http://lua-users.org/wiki/SaveTableToFile
When I use this with a a generic test script in my interpreter, it works
fine. However, when I attempt to use it with a filename taken from an
iup.filedlg popup, it crashes with a genereic error from winXP. Here's
my code, I know it's a bit of a mess if someone could take a look at it
(i've marked the spot where the crash happens)?
--[[
Save Table to File/Stringtable
Load Table from File/Stringtable
v 0.94
Lua 5.1 compatible
Userdata and indices of these are not saved
Functions are saved via string.dump, so make sure it has no upvalues
References are saved
----------------------------------------------------
table.save( table [, filename] )
Saves a table so it can be called via the table.load function again
table must a object of type 'table'
filename is optional, and may be a string representing a filename
or true/1
table.save( table )
on success: returns a string representing the table (stringtable)
(uses a string as buffer, ideal for smaller tables)
table.save( table, true or 1 )
on success: returns a string representing the table (stringtable)
(uses io.tmpfile() as buffer, ideal for bigger tables)
table.save( table, "filename" )
on success: returns 1
(saves the table to file "filename")
on failure: returns as second argument an error msg
----------------------------------------------------
table.load( filename or stringtable )
Loads a table that has been saved via the table.save function
on success: returns a previously saved table
on failure: returns as second argument an error msg
----------------------------------------------------
chillcode, http://lua-users.org/wiki/SaveTableToFile
Licensed under the same terms as Lua itself.
]]--
do
-- declare local variables
--// exportstring( string )
--// returns a "Lua" portable version of the string
local function exportstring( s )
s = string.format( "%q",s )
-- to replace
s = string.gsub( s,"\\\n","\\n" )
s = string.gsub( s,"\r","\\r" )
s = string.gsub( s,string.char(26),"\"..string.char(26)..\"" )
return s
end
--// The Save Function
function table.save( tbl,filename )
local charS,charE = " ","\n"
local file,err
-- create a pseudo file that writes to a string and return the string
if not filename then
file = { write = function( self,newstr ) self.str =
self.str..newstr end, str = "" }
charS,charE = "",""
-- write table to tmpfile
elseif filename == true or filename == 1 then
charS,charE,file = "","",io.tmpfile()
-- write table to file
-- use io.open here rather than io.output, since in windows when
clicking on a file opened with io.output will create an error
else
file,err = io.open( filename, "w" )
if err then return _,err end
end
-- initiate variables for save procedure
local tables,lookup = { tbl },{ [tbl] = 1 }
file:write( "return {"..charE )
for idx,t in ipairs( tables ) do
if filename and filename ~= true and filename ~= 1 then
file:write( "-- Table: {"..idx.."}"..charE )
end
file:write( "{"..charE )
local thandled = {}
for i,v in ipairs( t ) do
thandled[i] = true
-- escape functions and userdata
if type( v ) ~= "userdata" then
-- only handle value
if type( v ) == "table" then
if not lookup[v] then
table.insert( tables, v )
lookup[v] = #tables
end
file:write( charS.."{"..lookup[v].."},"..charE )
elseif type( v ) == "function" then
file:write(
charS.."loadstring("..exportstring(string.dump( v )).."),"..charE )
else
local value = ( type( v ) == "string" and
exportstring( v ) ) or tostring( v )
file:write( charS..value..","..charE )
end
end
end
for i,v in pairs( t ) do
-- escape functions and userdata
if (not thandled[i]) and type( v ) ~= "userdata" then
-- handle index
if type( i ) == "table" then
if not lookup[i] then
table.insert( tables,i )
lookup[i] = #tables
end
file:write( charS.."[{"..lookup[i].."}]=" )
else
local index = ( type( i ) == "string" and
"["..exportstring( i ).."]" ) or string.format( "[%d]",i )
file:write( charS..index.."=" )
end
-- handle value
if type( v ) == "table" then
if not lookup[v] then
table.insert( tables,v )
lookup[v] = #tables
end
file:write( "{"..lookup[v].."},"..charE )
elseif type( v ) == "function" then
file:write( "loadstring("..exportstring(string.dump(
v )).."),"..charE )
else
local value = ( type( v ) == "string" and
exportstring( v ) ) or tostring( v )
file:write( value..","..charE )
end
end
end
file:write( "},"..charE )
end
file:write( "}" )
-- Return Values
-- return stringtable from string
if not filename then
-- set marker for stringtable
return file.str.."--|"
-- return stringttable from file
elseif filename == true or filename == 1 then
file:seek ( "set" )
-- no need to close file, it gets closed and removed automatically
-- set marker for stringtable
return file:read( "*a" ).."--|"
-- close file and return 1
else
file:close()
return 1
end
end
--// The Load Function
function table.load( sfile )
-- catch marker for stringtable
if string.sub( sfile,-3,-1 ) == "--|" then
tables,err = loadstring( sfile )
else
tables,err = loadfile( sfile )
end
if err then return _,err
end
tables = tables()
for idx = 1,#tables do
local tolinkv,tolinki = {},{}
for i,v in pairs( tables[idx] ) do
if type( v ) == "table" and tables[v[1]] then
table.insert( tolinkv,{ i,tables[v[1]] } )
end
if type( i ) == "table" and tables[i[1]] then
table.insert( tolinki,{ i,tables[i[1]] } )
end
end
-- link values, first due to possible changes of indices
for _,v in ipairs( tolinkv ) do
tables[idx][v[1]] = v[2]
end
-- link indices
for _,v in ipairs( tolinki ) do
tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil
end
end
return tables[1]
end
-- close do
end
-- my editor code starts here
iup.SetLanguage("ENGLISH")
lfs.chdir(exepath()..[[\scripts]])
current_file = lfs.currentdir()..[[\new.lua]]
file_tab = {}
function setdir()
local pos = 0
local current = 0
repeat
current = string.find(current_file, [[\]], pos)
if current ~= nil then pos = current + 1 end
until (current == nil)
current_dir = string.gsub (current_file, string.sub (current_file,
pos-1), [[]])
lfs.chdir(current_dir)
return current_dir
end
open_dlg = iup.filedlg{dialogtype = "OPEN", title = "Open Lua Script",
filter = "*.lua", filterinfo = "Lua Scripts",
directory = setdir()}
save_as_dlg = iup.filedlg{dialogtype = "SAVE", title = "Save Lua Script",
filter = "*.lua", filterinfo = "Lua Scripts",
directory = setdir()}
item_new = iup.item {title = "New", key = "N"}
item_open = iup.item {title = "Open", key = "O"}
item_save = iup.item {title = "Save", key = "S"}
item_save_as = iup.item {title = "Save As", key = "A"}
item_exit = iup.item {title = "Exit", key = "x"}
function item_new:action()
edit_box.value = ""
current_file = nil
return iup.DEFAULT
end
function item_open:action()
open_dlg:popup (iup.CENTER, iup.CENTER)
if open_dlg.status == "0" and open_dlg.fileexist == "YES" then
current_file = open_dlg.value
c_file_name = string.gsub(current_file, ".+\\", "")
local file = io.open(open_dlg.value, "r")
local text = file:read("*a")
edit_box.value = text
file:close()
dlg.title = c_file_name
end
open_dlg.directory = setdir()
return iup.DEFAULT
end
function item_save:action()
if current_file:find("new.lua") or current_file == nil then
save_as_dlg:popup (iup.CENTER, iup.CENTER)
if save_as_dlg.status ~= "-1" then
current_file = save_as_dlg.value
setdir()
end
end
save_file(current_file, edit_box.value)
return iup.DEFAULT
end
function item_save_as:action()
save_as_dlg.file = current_file
save_as_dlg:popup (iup.CENTER, iup.CENTER)
if save_as_dlg.status ~= "-1" then
current_file = save_as_dlg.value
c_file_name = string.gsub(current_file, ".+\\", "")
dlg.title = c_file_name
save_file(current_file, edit_box.value)
setdir(current_file)
end
return iup.DEFAULT
end
function item_exit:action()
return iup.CLOSE
end
-- function to save files
function save_file(file_name, file_text)
local file = io.open(file_name, "w+")
file:write(file_text)
file:flush()
file:close()
end
item_run_fblua = iup.item {title = "with FB Lua", key = "F"}
item_run_luaplayer = iup.item {title = "with Lua Player", key = "L"}
--run with fblua menu item
function item_run_fblua:action()
save_file("luatemp.lua", edit_box.value)
msgs, errmsg = io.popen(exepath().."\\fblua luatemp.lua catch")
if msgs then
error_box.value = error_box.value.."\n\nFB Lua output:"
for Line in msgs:lines() do
error_box.value = error_box.value.."\n"..Line
end
msgs:close()
else
error_box.value = error_box.value.."\n"..errmsg
end
os.remove("luatemp.lua")
return iup.DEFAULT
end
--run with lua player menu item
function item_run_luaplayer:action()
save_file("luatemp.lua", edit_box.value)
msgs, errmsg =
io.popen(exepath().."\\luaplayerwindows\\luaplayer.exe luatemp.lua")
if msgs then
error_box.value = error_box.value.."\n\nLua Player output:"
for Line in msgs:lines() do
error_box.value = error_box.value.."\n"..Line
end
msgs:close()
else
error_box.value = error_box.value.."\n"..errmsg
end
os.remove("luatemp.lua")
return iup.DEFAULT
end
edit_box = iup.multiline{
size = "400x250",
value = "" ,
expand = "YES",
tabsize = "15",
font = "COURIER_NORMAL_12"
}
error_label = iup.label{title="Interpreter output:"}
error_box = iup.multiline{
size = "x50",
value = "" ,
expand = "YES",
tabsize = "15",
font = "COURIER_NORMAL_12",
readonly = "YES"
}
error_b = iup.sbox{iup.vbox{error_label,error_box}, direction = "NORTH"}
color_mat = iup.matrix{numcol=8, numlin=32, numcol_visible=8,
numlin_visible=8, widthdef=5, alignment = "ACENTER"}
function color_mat:action_cb() return iup.IGNORE end
function color_mat:click_cb(line, col, button)
if tonumber(button) == 3 then
r, g, b = iup.GetColor(iup.CENTER,iup.CENTER, 255, 255, 255)
if r ~= nil then
name = iup.Scanf("Name This Color:\nName:%15.15%s\n","")
self["BGCOLOR"..line..":"..col] = r.." "..g.." "..b
colors[line][col].name = name
colors[line][col].red = r
colors[line][col].green = g
colors[line][col].blue = b
end
end
self.redraw = "ALL"
edit_box.value = line..":"..col.." button = "..button.." color id =
"..colors[line][col].name
return iup.IGNORE
end
colors = {}
counter = 1
for i = 1, 32 do
colors[i] = {}
for j = 1, 8 do
colors[i][j] = {id = counter, name = "", red = 255, green = 255,
blue = 255}
color_mat["BGCOLOR".. i ..":".. j] = colors[i][j].red.."
"..colors[i][j].green.." "..colors[i][j].blue
counter = counter +1
end
end
color_save = iup.button{title = "Save Colors"}
save_colors = iup.filedlg{dialogtype = "SAVE", title = "Save Custom
Color file",
filter = "*.cf", filterinfo = "Color File",
file = exepath().."/apps/editor/colors.cf"
}
function color_save.action()
save_colors:popup (iup.CENTER, iup.CENTER)
if save_colors.status ~= "-1" then
------------------------------------------------
table.save(colors, save_colors.value) ----- this line is
where it crashes
------------------------------------------------
end
end
color_load = iup.button{title = "Load Colors"}
function color_load.action()
open_dlg:popup (iup.CENTER, iup.CENTER)
if open_dlg.status == "0" and open_dlg.fileexist == "YES" then
colors = nil
colors = table.load(open_dlg.value)
end
end
color_tab = iup.vbox{
color_mat,
color_save,
color_load,
expand = "NO",
tabtitle = "Colors"
}
-- assemble menu items
submenu_file = iup.submenu {iup.menu {item_new, item_open, item_save,
item_save_as, iup.separator{}, item_exit}; title = "File"}
submenu_run = iup.submenu {iup.menu {item_run_fblua,
item_run_luaplayer}; title = "Run"}
-- assemble dialog elements
menu = iup.menu {submenu_file, submenu_run}
func_panel = iup.sbox{iup.tabs{color_tab}, direction = "WEST"}
main_panel = iup.vbox{edit_box, error_b}
main_frame = iup.hbox{main_panel, func_panel}
dlg = iup.dialog{main_frame; title="FB Lua Script Editor", menu=menu,
error_box}
-- shows the editor window
dlg:showxy(iup.CENTER,iup.CENTER)
edit_box.size = "" -- removes initial size from the edit box, allowing
it to be resized
-- blocks the script while allowing the dialogs to remain interactive
iup.MainLoop()
dlg:destroy()
More information about the iup-users
mailing list