function dofile(f) pcall(loadfile(f)) end function pairsSorted(t, f) local i, tt = 0, {} for k in pairs(t) do table.insert(tt, k) end table.sort(tt, f) return function () i = i + 1 if not tt[i] then return nil end return tt[i], t[tt[i]] end end -- compatibility functions (with iuplua.lua) iup = {} function iup.SetClass(ctrl, name) element = ctrl end -- dummy functions iupDoNothing = function() end iupSetMethod = iupDoNothing iup.RegisterWidget = iupDoNothing -- TODO: This is different from iupClassRegisterCallback, -- should be changed to use the same standard c_types = { c = "unsigned char ", n = "int", f = "float", d = "double", s = "char *", i = "Ihandle *", v = "Ihandle **", o = "void*", } -- Adjust the callbacks table function adjustcallbacktable(c) d = {} for i,j in pairsSorted(c) do if type(j) == "string" then d[i] = { j, "IUP_".. string.upper(i)} elseif type(j) == "table" then d[i] = j else print("ERROR IN CALLBACK TABLE FORMAT") end end return d end function header(o,i) io.write [[ /****************************************************************************** * Automatically generated file. Please don't change anything. * *****************************************************************************/ #include #include #include #include "iup.h" #include "iuplua.h" ]] if i then io.write('#include "',i,'"\n') end io.write('#include "il.h"\n\n\n') end function firstupper(name) return string.upper(string.sub(name,1,1)) .. string.sub(name,2,-1) end function write_creation(o, t) local aux = {n = 1} local u = firstupper(o) local v = t.creation local c = t.callback if t.funcname then u = t.funcname end io.write ("static int ",u,"(lua_State *L)\n") io.write ("{\n") if t.rettype == nil then io.write(" Ihandle *ih = Iup",u,"(") elseif t.rettype == "n" then io.write(" int n = (Iup",u,"(") elseif t.rettype == "s" then io.write(" char *s = (Iup",u,"(") end local max = string.len(v) string.gsub(v, "(.)", function(p) if p == "n" then io.write("luaL_checkinteger(L, ",aux.n,")") elseif p == "N" then io.write("luaL_optinteger(L, ",aux.n,", 0)") elseif p == "d" then io.write("luaL_number(L, ",aux.n,")") elseif p == "s" then io.write("(char *)luaL_checkstring(L, ",aux.n,")") elseif p == "S" then io.write("(char *)luaL_optstring(L, ",aux.n,", NULL)") elseif p == "i" then io.write("iuplua_checkihandle(L, ",aux.n,")") elseif p == "I" then io.write("iuplua_checkihandleornil(L, ",aux.n,")") elseif p == "-" then io.write("NULL") elseif p == "a" then io.write("iuplua_checkstring_array(L, ",aux.n,", -1)") elseif p == "t" then io.write("iuplua_checkint_array(L, ",aux.n,", -1)") elseif p == "v" then io.write("iuplua_checkihandle_array(L, ",aux.n,", -1)") else io.write("FORMAT '", p, "' NOT SUPPORTED\n") end if aux.n < max then io.write(", ") end aux.n = aux.n + 1 end) io.write(");\n") io.write(" iuplua_plugstate(L, ih);\n") io.write(" iuplua_pushihandle_raw(L, ih);\n") io.write(" return 1;\n") io.write("}\n\n") end function write_callbacks(o, c) local aux = { } for i,v in pairsSorted(c) do local s = v[1] local max = string.len(s) aux.n = 0 io.write("static ") if v.ret then if v.ret == "s" then io.write("char * ") end if v.ret == "d" then io.write("double ") end else io.write("int ") end io.write(o, "_", i, "(Ihandle *self") if max > 0 then io.write(", ") end string.gsub(s, "(.)", function(p) io.write(c_types[p], " p", aux.n) aux.n = aux.n + 1 if aux.n < max then io.write(", ") end end) io.write(")\n{\n") io.write(' lua_State *L = iuplua_call_start(self, "', i, '");') aux.n = 0 string.gsub(s, "(.)", function(p) if p == "n" or p == "c" then io.write("\n lua_pushinteger(L, p"..aux.n..");") elseif p == "f" or p == "d" then io.write("\n lua_pushnumber(L, p"..aux.n..");") elseif p == "s" then io.write("\n lua_pushstring(L, p"..aux.n..");") elseif p == "i" then io.write("\n iuplua_pushihandle(L, p"..aux.n..");") elseif p == "o" then io.write("\n lua_pushlightuserdata(L, p"..aux.n..");") else io.write("\n ERROR !! ") end aux.n = aux.n + 1 end) if v.ret and v.ret == "s" then io.write("\n return iuplua_call_ret_s(L, " .. max .. ");") elseif v.ret and v.ret == "d" then io.write("\n return iuplua_call_ret_d(L, " .. max .. ");") else io.write("\n return iuplua_call(L, " .. max .. ");") end io.write("\n}\n\n") end end function write_initialization(o,t) local aux= {n=1} local c = t.callback local u = firstupper(o) if t.extrafuncs then io.write('void iuplua_', o,'funcs_open(lua_State *L);\n\n') end if t.openfuncname then io.write("int iup", t.openfuncname, "lua_open(lua_State * L)\n") else io.write("int iup", o, "lua_open(lua_State * L)\n") end io.write("{\n") io.write(" iuplua_register(L, ") if t.funcname then u = t.funcname end io.write(u, ', "', u,'");\n\n') for i,v in pairsSorted(c) do local type = "NULL" -- Handle callbacks that have same names but different parameters if i == "action" or -- canvas, button, item, list, text, toggle, etc i == "action_cb" or -- matrix and timer i == "flat_action" or -- flatbutton, flatlist, dropbutton, flattoggle i == "mousemove_cb" then -- matrix and val type = '"'..string.lower(o)..'"' end io.write(' iuplua_register_cb(L, "',string.upper(i),'", (lua_CFunction)',o,'_',i,', ',type,');\n') first = 0 end io.write('\n') if t.extrafuncs then io.write(' iuplua_', o,'funcs_open(L);\n\n') end io.write('#ifdef IUPLUA_USELOH\n') io.write('#include "', o,'.loh"\n') io.write('#else\n') io.write('#ifdef IUPLUA_USELH\n') io.write('#include "', o,'.lh"\n') io.write('#else\n') io.write(' iuplua_dofile(L, "', o,'.lua");\n') io.write('#endif\n') io.write('#endif\n\n') io.write(' return 0;\n') io.write("}\n\n") end dofile(arg[1]) element.callback = adjustcallbacktable(element.callback) filename = "il_"..element.nick..".c" if (element.subdir) then filename = element.subdir.."/"..filename end io.output(filename) header(element.nick, element.include) write_callbacks(element.nick, element.callback) if element.createfunc == nil then write_creation(element.nick, element) else io.write(element.createfunc) end write_initialization(element.nick, element) if element.extracode then io.write(element.extracode) end