-- --------------------------------------------------------------------------- -- Name: genwxbind.lua -- Purpose: This script generates wrapper files from the table interface_fileTable (see below) -- Author: Ray Gilbert, J Winwood, John Labenski -- Created: 19/05/2004 -- Copyright: Ray Gilbert -- Licence: wxWidgets licence -- --------------------------------------------------------------------------- -- This generator creates -- * separate cpp files for each interface file -- * each wrapper file uses c-preprocessor defines, and leaves it -- up to the compiler to add correct wrapper functions. This also has -- the advantage of being able to distribute pre-generated wrapper interface files -- --------------------------------------------------------------------------- -- --------------------------------------------------------------------------- -- Globals -- --------------------------------------------------------------------------- WXLUA_BINDING_VERSION = 23 -- Used to verify that the bindings are updated -- This must match modules/wxlua/include/wxldefs.h -- otherwise a compile time error will be generated. bindingKeywordTable = {} -- Binding keywords used by the generator %XXX skipBindingKeywordTable = {} -- Binding keywords to skip and not handle (for testing?) bindingOperatorTable = {} -- Binding %operator keywords preprocConditionTable = {} -- Preprocessor conditions for #ifing the output code -- table["binding code condition"] = "C preproc code suitable for #if statement" preprocOperatorTable = {} -- Preprocessor operators, e.g. table["&"] == "&&" typedefTable = {} -- all %typedefs read from the interface files dataTypeTable = {} -- all datatypes; int, double, class names, see AllocDataType dataTypeAttribTable = {} -- attributes for data types; unsigned, const functionAttribTable = {} -- attributes for functions; static, virtual enumBindingTable = {} -- table[i] = { Map, Condition, ... } defineBindingTable = {} -- table[i] = { Map, Condition, ... } stringBindingTable = {} -- table[i] = { Map, Condition, ... } objectBindingTable = {} -- table[i] = { Map, Condition, ... } pointerBindingTable = {} -- table[i] = { Map, Condition, ... } eventBindingTable = {} -- table[i] = { Map, Condition, ... } functionBindingTable = {} -- table[i] = { Map, Condition, Method, ... } classBindingTable = {} enumClassBindingTable = {} -- table[classname][i] = { Map, Condition, ... } classTypeBindingTable = {} classIncludeBindingTable = {} encapsulationBindingTable = {} overrideTable = {} -- binding code from override file as a table indexed by C function name overrideTableUsed = {} -- table set to true if override was used, indexed by C function name -- ---------------------------------------------------------------------------- -- Helpers for SplitString to make it faster -- ---------------------------------------------------------------------------- -- Table of delimiters in the binding text that separate different elements. -- Used in SplitString when reading the binding files. bindingDelimiters = { "[]", "==", ">=", "<=", "&&", "||", "//", "/*", "*/", "*", "&", "|", "(", ")", "[", "]", ",", "=", "{", "}", "!", ";", "\t", "\r", "\n", " " } bindingDelimsToKeep = { "[]", "==", ">=", "<=", "&&", "||", "//", "/*", "*/", "*", "&", "|", "(", ")", "[", "]", ",", "=", "{", "!" } bindingDelimiters_hash = {} for i = 1, #bindingDelimiters do bindingDelimiters_hash[bindingDelimiters[i]] = true end -- make these string.XXX functions local so there's no table lookup local string_sub = string.sub local string_len = string.len local string_byte = string.byte local char_BACKSLASH = string.byte("\\") local char_DOUBLEQUOTE = string.byte("\"") -- --------------------------------------------------------------------------- -- CheckRules - check the settings in the rules file for common errors -- --------------------------------------------------------------------------- function CheckRules() assert(type(interface_filepath) == "string", "Rules file ERROR: 'interface_filepath' is not a string") assert(type(output_cpp_filepath) == "string", "Rules file ERROR: 'output_cpp_filepath' is not a string") assert(type(output_cpp_header_filepath) == "string", "Rules file ERROR: 'output_cpp_header_filepath' is not a string") assert(type(output_cpp_impexpsymbol) == "string", "Rules file ERROR: 'output_cpp_impexpsymbol' is not a string") assert(type(output_cpp_impexpdatasymbol) == "string", "Rules file ERROR: 'output_cpp_impexpdatasymbol' is not a string") assert(type(hook_lua_namespace) == "string", "Rules file ERROR: 'hook_lua_namespace' is not a string") assert(type(hook_cpp_namespace) == "string", "Rules file ERROR: 'hook_cpp_namespace' is not a string") assert(wxLuaBinding_PreRegister == nil, "Rules file ERROR: 'wxLuaBinding_PreRegister' is deprecated") assert(wxLuaBinding_PostRegister == nil, "Rules file ERROR: 'wxLuaBinding_PreRegister' is deprecated") end -- --------------------------------------------------------------------------- -- Replacement for pairs(table) that sorts them alphabetically, returns iterator -- Code from "Programming in Lua" by Roberto Ierusalimschy -- the input is a Lua table and optional comp function (see table.sort) -- --------------------------------------------------------------------------- function pairs_sort(atable, comp_func) local a = {} for n in pairs(atable) do table.insert(a, n) end table.sort(a, comp_func) local i = 0 -- iterator variable local iter = function () -- iterator function i = i + 1 if a[i] == nil then return nil else return a[i], atable[a[i]] end end return iter end -- --------------------------------------------------------------------------- -- Sort the table and return it as an numerically indexed table array -- --------------------------------------------------------------------------- function TableSort(atable, comp_func) local a = {} for k, v in pairs(atable) do table.insert(a, k) end table.sort(a, comp_func) local b = {} for n = 1, #a do table.insert(b, atable[a[n]]) end return b end -- --------------------------------------------------------------------------- -- Completely dump the contents of a table -- atable is the input table to dump the contents of -- prefix is a string prefix for debugging purposes -- tablelevel is tracker for recursive calls to TableDump (do not use initially) -- --------------------------------------------------------------------------- function TableDump(atable, prefix, tablelevel) if prefix == nil then prefix = "" end if tablelevel == nil then tablelevel = "" end print(prefix.."-Dumping Table "..tablelevel, atable) prefix = prefix.." " local n = 0 for k, v in pairs_sort(atable) do n = n + 1 print(prefix..n, tablelevel.."["..k.."]", v) if type(v) == "table" then TableDump(v, prefix.." ", tablelevel.."["..k.."]") end end end -- --------------------------------------------------------------------------- -- Make a deep copy of a table, including all sub tables -- --------------------------------------------------------------------------- function TableCopy(atable) local newtable = {} for k, v in pairs(atable) do if type(v) == "table" then newtable[k] = TableCopy(v) else newtable[k] = v end end return newtable end -- --------------------------------------------------------------------------- -- Add a value to the table at any number of keys into it -- TableAdd(value, atable, "b", 2, 5) = atable["b"][2][5] = value -- --------------------------------------------------------------------------- function TableAdd(value, atable, ...) local t = atable for n = 1, #arg-1 do if not t[arg[n]] then t[arg[n]] = {} end t = t[arg[n]] end t[arg[#arg]] = value end -- --------------------------------------------------------------------------- -- A simple function to implement "cond ? A : B", eg "result = iff(cond, A, B)" -- --------------------------------------------------------------------------- function iff(cond, A, B) if cond then return A else return B end end -- --------------------------------------------------------------------------- -- Append text to a table if "comment_cpp_binding_code", else do nothing -- --------------------------------------------------------------------------- function CommentBindingTable(atable, str) if comment_cpp_binding_code then table.insert(atable, str) end end -- --------------------------------------------------------------------------- -- Allocate a data type description table (int, double, class...) to dataTypeTable -- --------------------------------------------------------------------------- function AllocDataType(name, value_type, is_number, abstract) dataTypeTable[name] = { Name = name, -- typename, eg. void, bool, wxInt32 ValueType = value_type, -- "number", "enum", "class", "special" (special handling) -- determines how to handle the data type BaseClass = nil, -- the BaseClass of this, if this is a class IsNumber = is_number, -- can this data type be stored as a double (Lua's number type) Abstract = abstract, Condition = nil, -- conditions for this data type, eg. wxLUA_USE_xxx ["%encapsulate"] = nil, -- Non wxObject derived class } end -- --------------------------------------------------------------------------- -- Initialize the data types with standard ones and wxWidget's types -- --------------------------------------------------------------------------- function InitDataTypes() -- Standard C data types AllocDataType("bool", "number", true) AllocDataType("BOOL", "number", true) AllocDataType("double", "number", true) AllocDataType("int", "number", true) AllocDataType("char", "number", true) AllocDataType("float", "number", true) AllocDataType("long", "number", true) AllocDataType("short", "number", true) AllocDataType("size_t", "number", true) AllocDataType("time_t", "number", true) AllocDataType("unsigned char", "number", true) AllocDataType("unsigned int", "number", true) AllocDataType("unsigned long", "number", true) AllocDataType("unsigned short", "number", true) AllocDataType("uchar", "number", true) AllocDataType("uint", "number", true) AllocDataType("ulong", "number", true) AllocDataType("ushort", "number", true) AllocDataType("void", "number", true) AllocDataType("wchar_t", "number", true) -- wxWidgets defined data types --AllocDataType("wxString", "special", true) -- treat as wxString AllocDataType("wxByte", "number", true) AllocDataType("wxChar", "number", true) AllocDataType("wxWord", "number", true) AllocDataType("wxInt8", "number", true) AllocDataType("wxUint8", "number", true) AllocDataType("wxInt16", "number", true) AllocDataType("wxUint16", "number", true) AllocDataType("wxInt32", "number", true) AllocDataType("wxUint32", "number", true) AllocDataType("wxInt64", "number", true) AllocDataType("wxUint64", "number", true) AllocDataType("wxFloat32", "number", true) AllocDataType("wxFloat64", "number", true) AllocDataType("wxDouble", "number", true) AllocDataType("wxCoord", "number", true) AllocDataType("wxTextCoord", "number", true) AllocDataType("wxMemorySize", "number", true) AllocDataType("WXTYPE", "number", true) AllocDataType("wxWindowID", "number", true) AllocDataType("wxEventType", "number", true) AllocDataType("wxFileOffset", "number", true) --AllocDataType("wxStructStat", "number", true) -- Lua data types AllocDataType("lua_State", "number", false) -- win32 data types AllocDataType("HANDLE", "number", false) AllocDataType("DWORD64", "number", true) AllocDataType("DWORD", "number", true) AllocDataType("PVOID", "number", true) AllocDataType("LPCVOID", "number", true) AllocDataType("LPVOID", "number", true) AllocDataType("LPDWORD", "number", true) -- "fake" data types that we handle in some more complicated way AllocDataType("LuaFunction", "special", true) AllocDataType("LuaTable", "special", true) AllocDataType("wxString", "special", true) --AllocDataType("wxArrayString", "special", true) -- special, but we only convert input, not output --AllocDataType("wxSortedArrayString", "special", true) -- special, but we only convert input, not output --AllocDataType("wxArrayInt", "special", true) -- special, but we only convert input, not output AllocDataType("IntArray_FromLuaTable", "special", true) AllocDataType("voidptr_long", "special", true) -- attributes that can precede a data type (must set equal to true) dataTypeAttribTable["unsigned"] = true dataTypeAttribTable["const"] = true dataTypeAttribTable["%gc"] = true -- this object will be gc by Lua dataTypeAttribTable["%ungc"] = true -- this object won't be gc by Lua -- attributes that can precede a function (must set equal to true) functionAttribTable["static"] = true functionAttribTable["virtual"] = true functionAttribTable["inline"] = true end -- --------------------------------------------------------------------------- -- Decode Declaration of a data type, see DecodeDataType -- For "const wxDateTime &" returns {"const"}, "wxDateTime", {"&"} -- --------------------------------------------------------------------------- function DecodeDecl(decl) local attribs = {} local data_type = nil local ptrs = {} local cast = 0 local typeData = SplitString(decl, { "[]", " ", "&", "*", "(", ")" }, { "[]", "&", "*", "(", ")" }) for i = 1, #typeData do if cast < 0 then print("ERROR: Mismatched () in casting data type: '"..decl.."'") end local type_n = typeData[i] if type_n == "(" then cast = cast + 1 elseif type_n == ")" then cast = cast - 1 elseif cast == 0 then if dataTypeAttribTable[type_n] then table.insert(attribs, type_n) elseif (type_n == "[]") or (type_n == "*") or (type_n == "&") then table.insert(ptrs, type_n) elseif dataTypeTable[type_n] then data_type = type_n elseif typedefTable[type_n] then data_type = type_n end end end if not data_type then print("ERROR: Cannot find data type: '"..decl.."'") end return attribs, data_type, ptrs end -- --------------------------------------------------------------------------- -- Decode DataType, also handles typedefs, see TranslateDataType -- For "const wxDateTime &" returns {"const"}, "wxDateTime", {"&"} -- --------------------------------------------------------------------------- function DecodeDataType(decl) local attribs, data_type, ptrs = DecodeDecl(decl) -- merge typeDef declaration if typedefTable[data_type] then -- build new datatype using typeDef local datatype = nil if #attribs > 0 then datatype = table.concat(attribs, " ") end datatype = SpaceSeparateStrings(datatype, typedefTable[data_type]) datatype = datatype..table.concat(ptrs) attribs, data_type, ptrs = DecodeDataType(datatype) end return attribs, data_type, ptrs end -- --------------------------------------------------------------------------- -- Translate the data type from a typedef -- --------------------------------------------------------------------------- function TranslateDataType(param) -- build datatype local datatype = param.DataTypeWithAttrib.." "..table.concat(param.DataTypePointer) local attribs, data_type, ptrs = DecodeDataType(datatype) -- build new datatype local tlstype = nil if #attribs > 0 then tlstype = table.concat(attribs, " ") end tlstype = SpaceSeparateStrings(tlstype, data_type) param.TypedDataType = data_type param.TypedDataTypeWithAttrib = tlstype param.TypedDataTypePointer = ptrs end -- --------------------------------------------------------------------------- -- Is the input to this a data type? Generate a error if typedef not complete -- --------------------------------------------------------------------------- function IsDataType(datatype) if dataTypeTable[datatype] then return true elseif typedefTable[datatype] then if not dataTypeTable[typedefTable[datatype]] then print("ERROR: Supposed datatype: '"..tostring(datatype).."' has typedef = '"..typedefTable[datatype].."' which is not a data type either") end return true end return false end -- --------------------------------------------------------------------------- -- Get base type for a data type that is a typedef -- --------------------------------------------------------------------------- function GetTypeDef(datatype) -- if typedef is found, replace type with replacement typedef return typedefTable[datatype] or datatype end -- --------------------------------------------------------------------------- -- Get the dataTypeTable[typedefinition] from a string after removing delimiters -- --------------------------------------------------------------------------- function GetDataTypeOnly(typedefinition) local typeData = SplitString(typedefinition, { " ", "&", "*" }) for i = 1, #typeData do if dataTypeTable[typeData[i]] then return typeData[i] end end return nil end -- --------------------------------------------------------------------------- -- Get the base dataTypeTable[typedefinition] by translating typedefs -- --------------------------------------------------------------------------- function GetDataTypeBase(datatype) if dataTypeTable[datatype] then return dataTypeTable[datatype] end -- try for underlying TypeDef DataType if typedefTable[datatype] then local base_type = GetDataTypeOnly(typedefTable[datatype]) if base_type and dataTypeTable[base_type] then return dataTypeTable[base_type] end end print("ERROR: Missing data type '"..tostring(datatype).."' in GetDataTypeBase.") return nil end -- --------------------------------------------------------------------------- -- Get any conditions for this data type -- --------------------------------------------------------------------------- function GetDataTypeCondition(datatype) local dtype = GetDataTypeBase(datatype) if dtype then return dtype.Condition else print("ERROR: Missing data type '"..datatype.."' in GetDataTypeCondition.") end return nil end -- --------------------------------------------------------------------------- -- Is this data type intrinisic, eg is it basically a number -- --------------------------------------------------------------------------- function IsDataTypeNumeric(datatype) local dtype = GetDataTypeBase(datatype) if dtype then return dtype.IsNumber else print("ERROR: Missing data type '"..tostring(datatype).."' in IsDataTypeNumeric.") end return false end -- --------------------------------------------------------------------------- -- Is this data type an enum -- --------------------------------------------------------------------------- function IsDataTypeEnum(datatype) local dtype = GetDataTypeBase(datatype) if dtype then return (dtype.ValueType == "enum") else print("ERROR: Missing data type '"..tostring(datatype).."' in IsDataTypeEnum.") end return false end -- --------------------------------------------------------------------------- -- Is the input in the 'bindingDelimiters' table? -- --------------------------------------------------------------------------- function IsDelimiter(delim) return bindingDelimiters_hash[delim] or false end -- --------------------------------------------------------------------------- -- FileExists - return true if file exists and is readable -- --------------------------------------------------------------------------- function FileExists(path) local file_handle = io.open(path) if not file_handle then return false end io.close(file_handle) return true end -- --------------------------------------------------------------------------- -- Do the contents of the file match the strings in the fileData table? -- the table may contain any number of \n per index -- returns true for a match or false if not -- --------------------------------------------------------------------------- function FileDataIsStringData(filename, strData) local file_handle = io.open(filename) if not file_handle then return false end -- ok if it doesn't exist local f = file_handle:read("*a") local is_same = (f == strData) io.close(file_handle) return is_same end -- --------------------------------------------------------------------------- -- Write the contents of the table fileData (indexes 1.. are line numbers) -- to the filename, but only write to the file if FileDataIsStringData returns -- false. If overwrite_always is true then always overwrite the file. -- returns true if the file was overwritten -- --------------------------------------------------------------------------- function WriteTableToFile(filename, fileData, overwrite_always) assert(filename and fileData, "Invalid filename or fileData in WriteTableToFile") local strData = table.concat(fileData) if (not overwrite_always) and FileDataIsStringData(filename, strData) then print("No changes to file : '"..filename.."'") return false end print("Updating file : '"..filename.."'") local outfile = io.open(filename, "w+") if not outfile then print("Unable to open file for writing '"..filename.."'.") return end outfile:write(strData) outfile:flush() outfile:close() return true end -- --------------------------------------------------------------------------- -- Find and return an already set condition or for a special set of conditions -- create a new one and add it to the condition table, else return nil -- --------------------------------------------------------------------------- function FindOrCreateCondition(condition) local result = nil if preprocConditionTable[condition] then result = preprocConditionTable[condition] elseif string.find(condition, "%wxchkver_", 1, 1) then -- check for conditions like %wxchkver_1_2_3 = wxCHECK_VERSION(1,2,3) local ver = { 0, 0, 0 } local n = 1 for v in string.gmatch(condition, "%d+") do ver[n] = tonumber(v); n = n + 1 end assert(#ver == 3, "%wxchkver_x_y_z conditions has too many version numbers. '"..condition.."'") result = string.format("wxCHECK_VERSION(%d,%d,%d)", ver[1], ver[2], ver[3]) preprocConditionTable[condition] = result -- cache result elseif string.find(condition, "wxchkver_", 1, 1) then print("WARNING: found wxchkver_XXX, did you forget the leading '%'? '"..condition.."'") elseif string.find(condition, "%wxcompat_", 1, 1) then -- check for conditions like %wxcompat_1_2 = WXWIN_COMPATIBILITY_1_2 -- just copy everything after wxcompat_ local p1, p2 = string.find(condition, "%wxcompat_", 1, 1) result = "WXWIN_COMPATIBILITY"..string.sub(condition, p2) result = "(defined("..result..") && "..result..")" preprocConditionTable[condition] = result -- cache result elseif string.find(condition, "wxcompat_", 1, 1) then print("WARNING: found wxcompat_XXX, did you forget the leading '%'? '"..condition.."'") elseif string.find(condition, "wxLUA_USE_", 1, 1) then print("WARNING: unknown wxLUA_USE_XXX condition? '"..condition.."'") elseif string.find(condition, "wxUSE_", 1, 1) then print("WARNING: unknown wxUSE_XXX condition? '"..condition.."'") elseif string.find(condition, "%wxchkver2", 1, 1) then assert(false, "ERROR: %wxchkverXYZ has been replaced by %wxchkver_X_Y_Z, please update your bindings.") elseif string.find(condition, "%wxcompat2", 1, 1) then assert(false, "ERROR: %wxcompatXY has been replaced by %wxcompat_X_Y, please update your bindings.") end return result end -- --------------------------------------------------------------------------- -- Is this condition really a condition? "1" is a placeholder for none -- --------------------------------------------------------------------------- function HasCondition(condition) return (condition ~= nil) and (condition ~= "1") and (condition ~= "") end -- --------------------------------------------------------------------------- -- Fix the condition to be uniform, "1" means none -- --------------------------------------------------------------------------- function FixCondition(condition) if not HasCondition(condition) then return "1" end return condition end -- --------------------------------------------------------------------------- -- Build condition string using condition stack (number indexed Lua table) -- --------------------------------------------------------------------------- function BuildCondition(conditionStack) local condition = nil if HasCondition(conditionStack[1]) then if not HasCondition(conditionStack[2]) then -- only one item condition = conditionStack[1] else condition = "("..conditionStack[1]..")" for i = 2, #conditionStack do if HasCondition(conditionStack[i]) then condition = condition.." && ("..conditionStack[i]..")" end end end end return condition end -- --------------------------------------------------------------------------- -- Add conditions with &&, either input condition may be nil -- --------------------------------------------------------------------------- function AddCondition(condition1, condition2) local condition = nil if HasCondition(condition1) and HasCondition(condition2) then condition = "("..condition1..") && ("..condition2..")" elseif HasCondition(condition1) then condition = condition1 elseif HasCondition(condition2) then condition = condition2 end return condition end -- --------------------------------------------------------------------------- -- Init all the bindingKeywordTable used for parsing -- --------------------------------------------------------------------------- function InitKeywords() preprocConditionTable["WXWIN_COMPATIBILITY_2"] = "(defined(WXWIN_COMPATIBILITY_2) && WXWIN_COMPATIBILITY_2)" preprocConditionTable["WXWIN_COMPATIBILITY_2_2"] = "(defined(WXWIN_COMPATIBILITY_2_2) && WXWIN_COMPATIBILITY_2_2)" preprocConditionTable["WXWIN_COMPATIBILITY_2_4"] = "(defined(WXWIN_COMPATIBILITY_2_4) && WXWIN_COMPATIBILITY_2_4)" preprocConditionTable["WXWIN_COMPATIBILITY_2_6"] = "(defined(WXWIN_COMPATIBILITY_2_6) && WXWIN_COMPATIBILITY_2_6)" preprocConditionTable["WXWIN_COMPATIBILITY_2_8"] = "(defined(WXWIN_COMPATIBILITY_2_8) && WXWIN_COMPATIBILITY_2_8)" -- wxWidgets platform checks preprocConditionTable["%win"] = "defined(__WXMSW__)" preprocConditionTable["%msw"] = "defined(__WXMSW__)" preprocConditionTable["%gtk"] = "defined(__WXGTK__)" preprocConditionTable["%mac"] = "defined(__WXMAC__)" preprocConditionTable["%mgl"] = "defined(__WXMGL__)" preprocConditionTable["%motif"] = "defined(__WXMOTIF__)" preprocConditionTable["%univ"] = "defined(__WXUNIVERSAL__)" preprocConditionTable["%x11"] = "defined(__WXX11__)" preprocConditionTable["%cocoa"] = "defined(__WXCOCOA__)" preprocConditionTable["%os2"] = "defined(__WXPM__)" preprocConditionTable["%palm"] = "defined(__WXPALMOS__)" preprocConditionTable["%wince"] = "defined(__WXWINCE__)" preprocConditionTable["%__WINDOWS__"] = "defined(__WINDOWS__)" preprocConditionTable["%__WIN16__"] = "defined(__WIN16__)" preprocConditionTable["%__WIN32__"] = "defined(__WIN32__)" preprocConditionTable["%__WIN95__"] = "defined(__WIN95__)" preprocConditionTable["%__WXBASE__"] = "defined(__WXBASE__)" preprocConditionTable["%__WXCOCOA__"] = "defined(__WXCOCOA__)" preprocConditionTable["%__WXWINCE__"] = "defined(__WXWINCE__)" preprocConditionTable["%__WXGTK__"] = "defined(__WXGTK__)" preprocConditionTable["%__WXGTK12__"] = "defined(__WXGTK12__)" preprocConditionTable["%__WXGTK20__"] = "defined(__WXGTK20__)" preprocConditionTable["%__WXMOTIF__"] = "defined(__WXMOTIF__)" preprocConditionTable["%__WXMOTIF20__"] = "defined(__WXMOTIF20__)" preprocConditionTable["%__WXMAC__"] = "defined(__WXMAC__)" preprocConditionTable["%__WXMAC_CLASSIC__"] = "defined(__WXMAC_CLASSIC__)" preprocConditionTable["%__WXMAC_CARBON__"] = "defined(__WXMAC_CARBON__)" preprocConditionTable["%__WXMAC_OSX__"] = "defined(__WXMAC_OSX__)" preprocConditionTable["%__WXMGL__"] = "defined(__WXMGL__)" preprocConditionTable["%__WXMSW__"] = "defined(__WXMSW__)" preprocConditionTable["%__WXOS2__"] = "defined(__WXOS2__)" preprocConditionTable["%__WXOSX__"] = "defined(__WXOSX__)" preprocConditionTable["%__WXPALMOS__"] = "defined(__WXPALMOS__)" preprocConditionTable["%__WXPM__"] = "defined(__WXPM__)" preprocConditionTable["%__WXSTUBS__"] = "defined(__WXSTUBS__)" preprocConditionTable["%__WXXT__"] = "defined(__WXXT__)" preprocConditionTable["%__WXX11__"] = "defined(__WXX11__)" preprocConditionTable["%__WXWINE__"] = "defined(__WXWINE__)" preprocConditionTable["%__WXUNIVERSAL__"] = "defined(__WXUNIVERSAL__)" preprocConditionTable["%__X__"] = "defined(__X__)" preprocConditionTable["%__WXWINCE__"] = "defined(__WXWINCE__)" preprocConditionTable["wxHAS_POWER_EVENTS"] = "defined(wxHAS_POWER_EVENTS)" preprocConditionTable["%wxHAS_NATIVE_RENDERER"] = "defined(wxHAS_NATIVE_RENDERER)" -- wxUSE_ conditions preprocConditionTable["wxUSE_ABOUTDLG"] = "wxUSE_ABOUTDLG" preprocConditionTable["wxUSE_ACCEL"] = "wxUSE_ACCEL" preprocConditionTable["wxUSE_ACCESSIBILITY"] = "wxUSE_ACCESSIBILITY" preprocConditionTable["wxUSE_AFM_FOR_POSTSCRIPT"] = "wxUSE_AFM_FOR_POSTSCRIPT" preprocConditionTable["wxUSE_ANIMATIONCTRL"] = "wxUSE_ANIMATIONCTRL" preprocConditionTable["wxUSE_APPLE_IEEE"] = "wxUSE_APPLE_IEEE" preprocConditionTable["wxUSE_AUI"] = "wxUSE_AUI" preprocConditionTable["wxUSE_BITMAPCOMBOBOX"] = "wxUSE_BITMAPCOMBOBOX" preprocConditionTable["wxUSE_BMPBUTTON"] = "wxUSE_BMPBUTTON" preprocConditionTable["wxUSE_BOOKCTRL"] = "wxUSE_BOOKCTRL" preprocConditionTable["wxUSE_BUILTIN_IODBC"] = "wxUSE_BUILTIN_IODBC" preprocConditionTable["wxUSE_BUSYINFO"] = "wxUSE_BUSYINFO" preprocConditionTable["wxUSE_BUTTON"] = "wxUSE_BUTTON" preprocConditionTable["wxUSE_CALENDARCTRL"] = "wxUSE_CALENDARCTRL" preprocConditionTable["wxUSE_CARET"] = "wxUSE_CARET" preprocConditionTable["wxUSE_CHECKBOX"] = "wxUSE_CHECKBOX" preprocConditionTable["wxUSE_CHECKLISTBOX"] = "wxUSE_CHECKLISTBOX" preprocConditionTable["wxUSE_CHOICE"] = "wxUSE_CHOICE" preprocConditionTable["wxUSE_CHOICEBOOK"] = "wxUSE_CHOICEBOOK" preprocConditionTable["wxUSE_CHOICEDLG"] = "wxUSE_CHOICEDLG" preprocConditionTable["wxUSE_CLIPBOARD"] = "wxUSE_CLIPBOARD" preprocConditionTable["wxUSE_CMDLINE_PARSER"] = "wxUSE_CMDLINE_PARSER" preprocConditionTable["wxUSE_COLLPANE"] = "wxUSE_COLLPANE" preprocConditionTable["wxUSE_COLOURDLG"] = "wxUSE_COLOURDLG" preprocConditionTable["wxUSE_COLOURPICKERCTRL"] = "wxUSE_COLOURPICKERCTRL" preprocConditionTable["wxUSE_COMBOBOX"] = "wxUSE_COMBOBOX" preprocConditionTable["wxUSE_CONFIG"] = "wxUSE_CONFIG" preprocConditionTable["wxUSE_CONSTRAINTS"] = "wxUSE_CONSTRAINTS" preprocConditionTable["wxUSE_CONTROLS"] = "wxUSE_CONTROLS" preprocConditionTable["wxUSE_DATAOBJ"] = "wxUSE_DATAOBJ" preprocConditionTable["wxUSE_DATEPICKCTRL"] = "wxUSE_DATEPICKCTRL" preprocConditionTable["wxUSE_DATETIME"] = "wxUSE_DATETIME" preprocConditionTable["wxUSE_DEBUG_CONTEXT"] = "wxUSE_DEBUG_CONTEXT" preprocConditionTable["wxUSE_DEBUG_NEW_ALWAYS"] = "wxUSE_DEBUG_NEW_ALWAYS" preprocConditionTable["wxUSE_DIALUP_MANAGER"] = "wxUSE_DIALUP_MANAGER" preprocConditionTable["wxUSE_DIRDLG"] = "wxUSE_DIRDLG" preprocConditionTable["wxUSE_DIRPICKERCTRL"] = "wxUSE_DIRPICKERCTRL" preprocConditionTable["wxUSE_DISPLAY"] = "wxUSE_DISPLAY" preprocConditionTable["wxUSE_DOC_VIEW_ARCHITECTURE"] = "wxUSE_DOC_VIEW_ARCHITECTURE" preprocConditionTable["wxUSE_DRAGIMAGE"] = "wxUSE_DRAGIMAGE" preprocConditionTable["wxUSE_DRAG_AND_DROP"] = "wxUSE_DRAG_AND_DROP" preprocConditionTable["wxUSE_DYNAMIC_CLASSES"] = "wxUSE_DYNAMIC_CLASSES" preprocConditionTable["wxUSE_DYNAMIC_LOADER"] = "wxUSE_DYNAMIC_LOADER" preprocConditionTable["wxUSE_DYNLIB_CLASS"] = "wxUSE_DYNLIB_CLASS" preprocConditionTable["wxUSE_ENH_METAFILE"] = "wxUSE_ENH_METAFILE" preprocConditionTable["wxUSE_EXCEPTIONS"] = "wxUSE_EXCEPTIONS" preprocConditionTable["wxUSE_EXPERIMENTAL_PRINTF"] = "wxUSE_EXPERIMENTAL_PRINTF" preprocConditionTable["wxUSE_FFILE"] = "wxUSE_FFILE" preprocConditionTable["wxUSE_FILE"] = "wxUSE_FILE" preprocConditionTable["wxUSE_FILEDLG"] = "wxUSE_FILEDLG" preprocConditionTable["wxUSE_FILEPICKERCTRL"] = "wxUSE_FILEPICKERCTRL" preprocConditionTable["wxUSE_FILESYSTEM"] = "wxUSE_FILESYSTEM" preprocConditionTable["wxUSE_FINDREPLDLG"] = "wxUSE_FINDREPLDLG" preprocConditionTable["wxUSE_FONTDLG"] = "wxUSE_FONTDLG" preprocConditionTable["wxUSE_FONTMAP"] = "wxUSE_FONTMAP" preprocConditionTable["wxUSE_FONTPICKERCTRL"] = "wxUSE_FONTPICKERCTRL" preprocConditionTable["wxUSE_FREETYPE"] = "wxUSE_FREETYPE" preprocConditionTable["wxUSE_FSVOLUME"] = "wxUSE_FSVOLUME" preprocConditionTable["wxUSE_FS_INET"] = "wxUSE_FS_INET" preprocConditionTable["wxUSE_FS_ZIP"] = "wxUSE_FS_ZIP" preprocConditionTable["wxUSE_GAUGE"] = "wxUSE_GAUGE" preprocConditionTable["wxUSE_GEOMETRY"] = "wxUSE_GEOMETRY" preprocConditionTable["wxUSE_GIF"] = "wxUSE_GIF" preprocConditionTable["wxUSE_GLCANVAS"] = "wxUSE_GLCANVAS" preprocConditionTable["wxUSE_GLOBAL_MEMORY_OPERATORS"] = "wxUSE_GLOBAL_MEMORY_OPERATORS" preprocConditionTable["wxUSE_GRID"] = "wxUSE_GRID" preprocConditionTable["wxUSE_GUI"] = "wxUSE_GUI" preprocConditionTable["wxUSE_HELP"] = "wxUSE_HELP" preprocConditionTable["wxUSE_HOTKEY"] = "wxUSE_HOTKEY" preprocConditionTable["wxUSE_HTML"] = "wxUSE_HTML" preprocConditionTable["wxUSE_HYPERLINKCTRL"] = "wxUSE_HYPERLINKCTRL" preprocConditionTable["wxUSE_ICO_CUR"] = "wxUSE_ICO_CUR" preprocConditionTable["wxUSE_IFF"] = "wxUSE_IFF" preprocConditionTable["wxUSE_IMAGE"] = "wxUSE_IMAGE" preprocConditionTable["wxUSE_IMAGLIST"] = "wxUSE_IMAGLIST" preprocConditionTable["wxUSE_INTL"] = "wxUSE_INTL" preprocConditionTable["wxUSE_IOSTREAMH"] = "wxUSE_IOSTREAMH" preprocConditionTable["wxUSE_IPC"] = "wxUSE_IPC" preprocConditionTable["wxUSE_JOYSTICK"] = "wxUSE_JOYSTICK" preprocConditionTable["wxUSE_LIBJPEG"] = "wxUSE_LIBJPEG" preprocConditionTable["wxUSE_LIBMSPACK"] = "wxUSE_LIBMSPACK" preprocConditionTable["wxUSE_LIBPNG"] = "wxUSE_LIBPNG" preprocConditionTable["wxUSE_LIBSDL"] = "wxUSE_LIBSDL" preprocConditionTable["wxUSE_LIBTIFF"] = "wxUSE_LIBTIFF" preprocConditionTable["wxUSE_LISTBOOK"] = "wxUSE_LISTBOOK" preprocConditionTable["wxUSE_LISTBOX"] = "wxUSE_LISTBOX" preprocConditionTable["wxUSE_LISTCTRL"] = "wxUSE_LISTCTRL" preprocConditionTable["wxUSE_LOG"] = "wxUSE_LOG" preprocConditionTable["wxUSE_LOGGUI"] = "wxUSE_LOGGUI" preprocConditionTable["wxUSE_LOGWINDOW"] = "wxUSE_LOGWINDOW" preprocConditionTable["wxUSE_LOG_DIALOG"] = "wxUSE_LOG_DIALOG" preprocConditionTable["wxUSE_LONGLONG"] = "wxUSE_LONGLONG" preprocConditionTable["wxUSE_MDI"] = "wxUSE_MDI" preprocConditionTable["wxUSE_MDI_ARCHITECTURE"] = "wxUSE_MDI_ARCHITECTURE" preprocConditionTable["wxUSE_MEDIACTRL"] = "wxUSE_MEDIACTRL" preprocConditionTable["wxUSE_MEMORY_TRACING"] = "wxUSE_MEMORY_TRACING" preprocConditionTable["wxUSE_MENUS"] = "wxUSE_MENUS" preprocConditionTable["wxUSE_METAFILE"] = "wxUSE_METAFILE" preprocConditionTable["wxUSE_MIMETYPE"] = "wxUSE_MIMETYPE" preprocConditionTable["wxUSE_MINIFRAME"] = "wxUSE_MINIFRAME" preprocConditionTable["wxUSE_MOUSEWHEEL"] = "wxUSE_MOUSEWHEEL" preprocConditionTable["wxUSE_MSGDLG"] = "wxUSE_MSGDLG" preprocConditionTable["wxUSE_MS_HTML_HELP"] = "wxUSE_MS_HTML_HELP" preprocConditionTable["wxUSE_NANOX"] = "wxUSE_NANOX" preprocConditionTable["wxUSE_NATIVE_STATUSBAR"] = "wxUSE_NATIVE_STATUSBAR" preprocConditionTable["wxUSE_NEW_GRID"] = "wxUSE_NEW_GRID" preprocConditionTable["wxUSE_NOGUI"] = "wxUSE_NOGUI" preprocConditionTable["wxUSE_NORMALIZED_PS_FONTS"] = "wxUSE_NORMALIZED_PS_FONTS" preprocConditionTable["wxUSE_NOTEBOOK"] = "wxUSE_NOTEBOOK" preprocConditionTable["wxUSE_NUMBERDLG"] = "wxUSE_NUMBERDLG" preprocConditionTable["wxUSE_ODBC"] = "wxUSE_ODBC" preprocConditionTable["wxUSE_OLE"] = "wxUSE_OLE" preprocConditionTable["wxUSE_ON_FATAL_EXCEPTION"] = "wxUSE_ON_FATAL_EXCEPTION" preprocConditionTable["wxUSE_OPENGL"] = "wxUSE_OPENGL" preprocConditionTable["wxUSE_OWNER_DRAWN"] = "wxUSE_OWNER_DRAWN" preprocConditionTable["wxUSE_PALETTE"] = "wxUSE_PALETTE" preprocConditionTable["wxUSE_PCX"] = "wxUSE_PCX" preprocConditionTable["wxUSE_PLUGINS"] = "wxUSE_PLUGINS" preprocConditionTable["wxUSE_PNM"] = "wxUSE_PNM" preprocConditionTable["wxUSE_POPUPWIN"] = "wxUSE_POPUPWIN" preprocConditionTable["wxUSE_POSTSCRIPT"] = "wxUSE_POSTSCRIPT" preprocConditionTable["wxUSE_PRINTING_ARCHITECTURE"] = "wxUSE_PRINTING_ARCHITECTURE" preprocConditionTable["wxUSE_PROGRESSDLG"] = "wxUSE_PROGRESSDLG" preprocConditionTable["wxUSE_PROLOGIO"] = "wxUSE_PROLOGIO" preprocConditionTable["wxUSE_PROPSHEET"] = "wxUSE_PROPSHEET" preprocConditionTable["wxUSE_PROTOCOL"] = "wxUSE_PROTOCOL" preprocConditionTable["wxUSE_PROTOCOL_FILE"] = "wxUSE_PROTOCOL_FILE" preprocConditionTable["wxUSE_PROTOCOL_FTP"] = "wxUSE_PROTOCOL_FTP" preprocConditionTable["wxUSE_PROTOCOL_HTTP"] = "wxUSE_PROTOCOL_HTTP" preprocConditionTable["wxUSE_RADIOBOX"] = "wxUSE_RADIOBOX" preprocConditionTable["wxUSE_RADIOBTN"] = "wxUSE_RADIOBTN" preprocConditionTable["wxUSE_REGEX"] = "wxUSE_REGEX" preprocConditionTable["wxUSE_RESOURCES"] = "wxUSE_RESOURCES" preprocConditionTable["wxUSE_RICHEDIT"] = "wxUSE_RICHEDIT" preprocConditionTable["wxUSE_RICHTEXT"] = "wxUSE_RICHTEXT" preprocConditionTable["wxUSE_SASH"] = "wxUSE_SASH" preprocConditionTable["wxUSE_SCROLLBAR"] = "wxUSE_SCROLLBAR" preprocConditionTable["wxUSE_SLIDER"] = "wxUSE_SLIDER" preprocConditionTable["wxUSE_SNGLINST_CHECKER"] = "wxUSE_SNGLINST_CHECKER" preprocConditionTable["wxUSE_SOCKETS"] = "wxUSE_SOCKETS" preprocConditionTable["wxUSE_SOUND"] = "wxUSE_SOUND" preprocConditionTable["wxUSE_SPINBTN"] = "wxUSE_SPINBTN" preprocConditionTable["wxUSE_SPINCTRL"] = "wxUSE_SPINCTRL" preprocConditionTable["wxUSE_SPLASH"] = "wxUSE_SPLASH" preprocConditionTable["wxUSE_SPLINES"] = "wxUSE_SPLINES" preprocConditionTable["wxUSE_SPLITTER"] = "wxUSE_SPLITTER" preprocConditionTable["wxUSE_STARTUP_TIPS"] = "wxUSE_STARTUP_TIPS" preprocConditionTable["wxUSE_STATBMP"] = "wxUSE_STATBMP" preprocConditionTable["wxUSE_STATBOX"] = "wxUSE_STATBOX" preprocConditionTable["wxUSE_STATLINE"] = "wxUSE_STATLINE" preprocConditionTable["wxUSE_STATTEXT"] = "wxUSE_STATTEXT" preprocConditionTable["wxUSE_STATUSBAR"] = "wxUSE_STATUSBAR" preprocConditionTable["wxUSE_STD_IOSTREAM"] = "wxUSE_STD_IOSTREAM" preprocConditionTable["wxUSE_STL"] = "wxUSE_STL" preprocConditionTable["wxUSE_STOPWATCH"] = "wxUSE_STOPWATCH" preprocConditionTable["wxUSE_STREAMS"] = "wxUSE_STREAMS" preprocConditionTable["wxUSE_SYSTEM_OPTIONS"] = "wxUSE_SYSTEM_OPTIONS" preprocConditionTable["wxUSE_TABDIALOG"] = "wxUSE_TABDIALOG" preprocConditionTable["wxUSE_TAB_DIALOG"] = "wxUSE_TAB_DIALOG" preprocConditionTable["wxUSE_TEXTBUFFER"] = "wxUSE_TEXTBUFFER" preprocConditionTable["wxUSE_TEXTCTRL"] = "wxUSE_TEXTCTRL" preprocConditionTable["wxUSE_TEXTDLG"] = "wxUSE_TEXTDLG" preprocConditionTable["wxUSE_TEXTFILE"] = "wxUSE_TEXTFILE" preprocConditionTable["wxUSE_TGA"] = "wxUSE_TGA" preprocConditionTable["wxUSE_THREADS"] = "wxUSE_THREADS" preprocConditionTable["wxUSE_TIMEDATE"] = "wxUSE_TIMEDATE" preprocConditionTable["wxUSE_TIMER"] = "wxUSE_TIMER" preprocConditionTable["wxUSE_TIPWINDOW"] = "wxUSE_TIPWINDOW" preprocConditionTable["wxUSE_TOGGLEBTN"] = "wxUSE_TOGGLEBTN" preprocConditionTable["wxUSE_TOOLBAR"] = "wxUSE_TOOLBAR" preprocConditionTable["wxUSE_TOOLBAR_NATIVE"] = "wxUSE_TOOLBAR_NATIVE" preprocConditionTable["wxUSE_TOOLBOOK"] = "wxUSE_TOOLBOOK" preprocConditionTable["wxUSE_TOOLTIPS"] = "wxUSE_TOOLTIPS" preprocConditionTable["wxUSE_TREEBOOK"] = "wxUSE_TREEBOOK" preprocConditionTable["wxUSE_TREECTRL"] = "wxUSE_TREECTRL" preprocConditionTable["wxUSE_TREELAYOUT"] = "wxUSE_TREELAYOUT" preprocConditionTable["wxUSE_UNICODE"] = "wxUSE_UNICODE" preprocConditionTable["wxUSE_UNICODE_MSLU"] = "wxUSE_UNICODE_MSLU" preprocConditionTable["wxUSE_UNIX"] = "wxUSE_UNIX" preprocConditionTable["wxUSE_URL"] = "wxUSE_URL" preprocConditionTable["wxUSE_UXTHEME"] = "wxUSE_UXTHEME" preprocConditionTable["wxUSE_UXTHEME_AUTO"] = "wxUSE_UXTHEME_AUTO" preprocConditionTable["wxUSE_VALIDATORS"] = "wxUSE_VALIDATORS" preprocConditionTable["wxUSE_WAVE"] = "wxUSE_WAVE" preprocConditionTable["wxUSE_WCHAR_T"] = "wxUSE_WCHAR_T" preprocConditionTable["wxUSE_WCSRTOMBS"] = "wxUSE_WCSRTOMBS" preprocConditionTable["wxUSE_WIZARDDLG"] = "wxUSE_WIZARDDLG" preprocConditionTable["wxUSE_WXHTML_HELP"] = "wxUSE_WXHTML_HELP" preprocConditionTable["wxUSE_WX_RESOURCES"] = "wxUSE_WX_RESOURCES" preprocConditionTable["wxUSE_XML"] = "wxUSE_XML" preprocConditionTable["wxUSE_XPM"] = "wxUSE_XPM" preprocConditionTable["wxUSE_XPM_IN_MSW"] = "wxUSE_XPM_IN_MSW" preprocConditionTable["wxUSE_XRC"] = "wxUSE_XRC" preprocConditionTable["wxUSE_X_RESOURCES"] = "wxUSE_X_RESOURCES" preprocConditionTable["wxUSE_ZIPSTREAM"] = "wxUSE_ZIPSTREAM" preprocConditionTable["wxUSE_ZLIB"] = "wxUSE_ZLIB" -- wxLUA_USE_xxx conditions preprocConditionTable["wxLUA_USE_FL"] = "wxLUA_USE_FL" preprocConditionTable["wxLUA_USE_Geometry"] = "wxLUA_USE_Geometry" preprocConditionTable["wxLUA_USE_MDI"] = "wxLUA_USE_MDI" preprocConditionTable["wxLUA_USE_wxAboutDialog"] = "wxLUA_USE_wxAboutDialog" preprocConditionTable["wxLUA_USE_wxAcceleratorTable"] = "wxLUA_USE_wxAcceleratorTable" preprocConditionTable["wxLUA_USE_wxAnimation"] = "wxLUA_USE_wxAnimation" preprocConditionTable["wxLUA_USE_wxApp"] = "wxLUA_USE_wxApp" preprocConditionTable["wxLUA_USE_wxArrayInt"] = "wxLUA_USE_wxArrayInt" preprocConditionTable["wxLUA_USE_wxArrayString"] = "wxLUA_USE_wxArrayString" preprocConditionTable["wxLUA_USE_wxArtProvider"] = "wxLUA_USE_wxArtProvider" preprocConditionTable["wxLUA_USE_wxAUI"] = "wxLUA_USE_wxAUI" preprocConditionTable["wxLUA_USE_wxBitmap"] = "wxLUA_USE_wxBitmap" preprocConditionTable["wxLUA_USE_wxBitmapComboBox"] = "wxLUA_USE_wxBitmapComboBox" preprocConditionTable["wxLUA_USE_wxBitmapButton"] = "wxLUA_USE_wxBitmapButton" preprocConditionTable["wxLUA_USE_wxBrushList"] = "wxLUA_USE_wxBrushList" preprocConditionTable["wxLUA_USE_wxBusyCursor"] = "wxLUA_USE_wxBusyCursor" preprocConditionTable["wxLUA_USE_wxBusyInfo"] = "wxLUA_USE_wxBusyInfo" preprocConditionTable["wxLUA_USE_wxButton"] = "wxLUA_USE_wxButton" preprocConditionTable["wxLUA_USE_wxCalendarCtrl"] = "wxLUA_USE_wxCalendarCtrl" preprocConditionTable["wxLUA_USE_wxCaret"] = "wxLUA_USE_wxCaret" preprocConditionTable["wxLUA_USE_wxCheckBox"] = "wxLUA_USE_wxCheckBox" preprocConditionTable["wxLUA_USE_wxCheckListBox"] = "wxLUA_USE_wxCheckListBox" preprocConditionTable["wxLUA_USE_wxChoice"] = "wxLUA_USE_wxChoice" preprocConditionTable["wxLUA_USE_wxClassInfo"] = "wxLUA_USE_wxClassInfo" preprocConditionTable["wxLUA_USE_wxClipboard"] = "wxLUA_USE_wxClipboard" preprocConditionTable["wxLUA_USE_wxCollapsiblePane"] = "wxLUA_USE_wxCollapsiblePane" preprocConditionTable["wxLUA_USE_wxColourDialog"] = "wxLUA_USE_wxColourDialog" preprocConditionTable["wxLUA_USE_wxColourPenBrush"] = "wxLUA_USE_wxColourPenBrush" preprocConditionTable["wxLUA_USE_wxColourPickerCtrl"] = "wxLUA_USE_wxColourPickerCtrl" preprocConditionTable["wxLUA_USE_wxComboBox"] = "wxLUA_USE_wxComboBox" preprocConditionTable["wxLUA_USE_wxCommandProcessor"] = "wxLUA_USE_wxCommandProcessor" preprocConditionTable["wxLUA_USE_wxConfig"] = "wxLUA_USE_wxConfig" preprocConditionTable["wxLUA_USE_wxCursor"] = "wxLUA_USE_wxCursor" preprocConditionTable["wxLUA_USE_wxCriticalSection"] = "wxLUA_USE_wxCriticalSection" preprocConditionTable["wxLUA_USE_wxCriticalSectionLocker"] = "wxLUA_USE_wxCriticalSectionLocker" preprocConditionTable["wxLUA_USE_wxDataObject"] = "wxLUA_USE_wxDataObject" preprocConditionTable["wxLUA_USE_wxDatePickerCtrl"] = "wxLUA_USE_wxDatePickerCtrl" preprocConditionTable["wxLUA_USE_wxDateSpan"] = "wxLUA_USE_wxDateSpan" preprocConditionTable["wxLUA_USE_wxDateTime"] = "wxLUA_USE_wxDateTime" preprocConditionTable["wxLUA_USE_wxDateTimeHolidayAuthority"] = "wxLUA_USE_wxDateTimeHolidayAuthority" preprocConditionTable["wxLUA_USE_wxDC"] = "wxLUA_USE_wxDC" preprocConditionTable["wxLUA_USE_wxDialog"] = "wxLUA_USE_wxDialog" preprocConditionTable["wxLUA_USE_wxDir"] = "wxLUA_USE_wxDir" preprocConditionTable["wxLUA_USE_wxDirDialog"] = "wxLUA_USE_wxDirDialog" preprocConditionTable["wxLUA_USE_wxDirPickerCtrl"] = "wxLUA_USE_wxDirPickerCtrl" preprocConditionTable["wxLUA_USE_wxDisplay"] = "wxLUA_USE_wxDisplay" preprocConditionTable["wxLUA_USE_wxDragDrop"] = "wxLUA_USE_wxDragDrop" preprocConditionTable["wxLUA_USE_wxDynamicLibrary"] = "wxLUA_USE_wxDynamicLibrary" preprocConditionTable["wxLUA_USE_wxFile"] = "wxLUA_USE_wxFile" preprocConditionTable["wxLUA_USE_wxFileDialog"] = "wxLUA_USE_wxFileDialog" preprocConditionTable["wxLUA_USE_wxFileHistory"] = "wxLUA_USE_wxFileHistory" preprocConditionTable["wxLUA_USE_wxFileName"] = "wxLUA_USE_wxFileName" preprocConditionTable["wxLUA_USE_wxFilePickerCtrl"] = "wxLUA_USE_wxFilePickerCtrl" preprocConditionTable["wxLUA_USE_wxFindReplaceDialog"] = "wxLUA_USE_wxFindReplaceDialog" preprocConditionTable["wxLUA_USE_wxFont"] = "wxLUA_USE_wxFont" preprocConditionTable["wxLUA_USE_wxFontDialog"] = "wxLUA_USE_wxFontDialog" preprocConditionTable["wxLUA_USE_wxFontEnumerator"] = "wxLUA_USE_wxFontEnumerator" preprocConditionTable["wxLUA_USE_wxFontList"] = "wxLUA_USE_wxFontList" preprocConditionTable["wxLUA_USE_wxFontMapper"] = "wxLUA_USE_wxFontMapper" preprocConditionTable["wxLUA_USE_wxFontPickerCtrl"] = "wxLUA_USE_wxFontPickerCtrl" preprocConditionTable["wxLUA_USE_wxFrame"] = "wxLUA_USE_wxFrame" preprocConditionTable["wxLUA_USE_wxGauge"] = "wxLUA_USE_wxGauge" preprocConditionTable["wxLUA_USE_wxGenericDirCtrl"] = "wxLUA_USE_wxGenericDirCtrl" preprocConditionTable["wxLUA_USE_wxGenericValidator"] = "wxLUA_USE_wxGenericValidator" preprocConditionTable["wxLUA_USE_wxGLCanvas"] = "wxLUA_USE_wxGLCanvas" preprocConditionTable["wxLUA_USE_wxGrid"] = "wxLUA_USE_wxGrid" preprocConditionTable["wxLUA_USE_wxHashTable"] = "wxLUA_USE_wxHashTable" preprocConditionTable["wxLUA_USE_wxHelpController"] = "wxLUA_USE_wxHelpController" preprocConditionTable["wxLUA_USE_wxHTML"] = "wxLUA_USE_wxHTML" preprocConditionTable["wxLUA_USE_wxHtmlHelpController"] = "wxLUA_USE_wxHtmlHelpController" preprocConditionTable["wxLUA_USE_wxHyperlinkCtrl"] = "wxLUA_USE_wxHyperlinkCtrl" preprocConditionTable["wxLUA_USE_wxIcon"] = "wxLUA_USE_wxIcon" preprocConditionTable["wxLUA_USE_wxID_XXX"] = "wxLUA_USE_wxID_XXX" preprocConditionTable["wxLUA_USE_wxImage"] = "wxLUA_USE_wxImage" preprocConditionTable["wxLUA_USE_wxImageList"] = "wxLUA_USE_wxImageList" preprocConditionTable["wxLUA_USE_wxJoystick"] = "wxLUA_USE_wxJoystick" preprocConditionTable["wxLUA_USE_wxLayoutConstraints"] = "wxLUA_USE_wxLayoutConstraints" preprocConditionTable["wxLUA_USE_wxList"] = "wxLUA_USE_wxList" preprocConditionTable["wxLUA_USE_wxListBox"] = "wxLUA_USE_wxListBox" preprocConditionTable["wxLUA_USE_wxListCtrl"] = "wxLUA_USE_wxListCtrl" preprocConditionTable["wxLUA_USE_wxLog"] = "wxLUA_USE_wxLog" preprocConditionTable["wxLUA_USE_wxLogWindow"] = "wxLUA_USE_wxLogWindow" preprocConditionTable["wxLUA_USE_wxLuaHtmlWindow"] = "wxLUA_USE_wxLuaHtmlWindow" preprocConditionTable["wxLUA_USE_wxLuaPrintout"] = "wxLUA_USE_wxLuaPrintout" preprocConditionTable["wxLUA_USE_wxMask"] = "wxLUA_USE_wxMask" preprocConditionTable["wxLUA_USE_wxMediaCtrl"] = "wxLUA_USE_wxMediaCtrl" preprocConditionTable["wxLUA_USE_wxMenu"] = "wxLUA_USE_wxMenu" preprocConditionTable["wxLUA_USE_wxMessageDialog"] = "wxLUA_USE_wxMessageDialog" preprocConditionTable["wxLUA_USE_wxMetafile"] = "wxLUA_USE_wxMetafile" preprocConditionTable["wxLUA_USE_wxMiniFrame"] = "wxLUA_USE_wxMiniFrame" preprocConditionTable["wxLUA_USE_wxMultiChoiceDialog"] = "wxLUA_USE_wxMultiChoiceDialog" preprocConditionTable["wxLUA_USE_wxNotebook"] = "wxLUA_USE_wxNotebook" preprocConditionTable["wxLUA_USE_wxObject"] = "wxLUA_USE_wxObject" preprocConditionTable["wxLUA_USE_wxPalette"] = "wxLUA_USE_wxPalette" preprocConditionTable["wxLUA_USE_wxPenList"] = "wxLUA_USE_wxPenList" preprocConditionTable["wxLUA_USE_wxPicker"] = "wxLUA_USE_wxPicker" preprocConditionTable["wxLUA_USE_wxPointSizeRect"] = "wxLUA_USE_wxPointSizeRect" preprocConditionTable["wxLUA_USE_wxPrint"] = "wxLUA_USE_wxPrint" preprocConditionTable["wxLUA_USE_wxProcess"] = "wxLUA_USE_wxProcess" preprocConditionTable["wxLUA_USE_wxProgressDialog"] = "wxLUA_USE_wxProgressDialog" preprocConditionTable["wxLUA_USE_wxRadioBox"] = "wxLUA_USE_wxRadioBox" preprocConditionTable["wxLUA_USE_wxRadioButton"] = "wxLUA_USE_wxRadioButton" preprocConditionTable["wxLUA_USE_wxRegEx"] = "wxLUA_USE_wxRegEx" preprocConditionTable["wxLUA_USE_wxRegion"] = "wxLUA_USE_wxRegion" preprocConditionTable["wxLUA_USE_wxRenderer"] = "wxLUA_USE_wxRenderer" preprocConditionTable["wxLUA_USE_wxRichText"] = "wxLUA_USE_wxRichText" preprocConditionTable["wxLUA_USE_wxSashWindow"] = "wxLUA_USE_wxSashWindow" preprocConditionTable["wxLUA_USE_wxScrollBar"] = "wxLUA_USE_wxScrollBar" preprocConditionTable["wxLUA_USE_wxScrolledWindow"] = "wxLUA_USE_wxScrolledWindow" preprocConditionTable["wxLUA_USE_wxSingleChoiceDialog"] = "wxLUA_USE_wxSingleChoiceDialog" preprocConditionTable["wxLUA_USE_wxSizer"] = "wxLUA_USE_wxSizer" preprocConditionTable["wxLUA_USE_wxSlider"] = "wxLUA_USE_wxSlider" preprocConditionTable["wxLUA_USE_wxSocket"] = "wxLUA_USE_wxSocket" preprocConditionTable["wxLUA_USE_wxSpinButton"] = "wxLUA_USE_wxSpinButton" preprocConditionTable["wxLUA_USE_wxSpinCtrl"] = "wxLUA_USE_wxSpinCtrl" preprocConditionTable["wxLUA_USE_wxSplashScreen"] = "wxLUA_USE_wxSplashScreen" preprocConditionTable["wxLUA_USE_wxSplitterWindow"] = "wxLUA_USE_wxSplitterWindow" preprocConditionTable["wxLUA_USE_wxStandardPaths"] = "wxLUA_USE_wxStandardPaths" preprocConditionTable["wxLUA_USE_wxStaticBitmap"] = "wxLUA_USE_wxStaticBitmap" preprocConditionTable["wxLUA_USE_wxStaticBox"] = "wxLUA_USE_wxStaticBox" preprocConditionTable["wxLUA_USE_wxStaticLine"] = "wxLUA_USE_wxStaticLine" preprocConditionTable["wxLUA_USE_wxStaticText"] = "wxLUA_USE_wxStaticText" preprocConditionTable["wxLUA_USE_wxStatusBar"] = "wxLUA_USE_wxStatusBar" preprocConditionTable["wxLUA_USE_wxStopWatch"] = "wxLUA_USE_wxStopWatch" preprocConditionTable["wxLUA_USE_wxStringList"] = "wxLUA_USE_wxStringList" preprocConditionTable["wxLUA_USE_wxSystemOptions"] = "wxLUA_USE_wxSystemOptions" preprocConditionTable["wxLUA_USE_wxSystemSettings"] = "wxLUA_USE_wxSystemSettings" preprocConditionTable["wxLUA_USE_wxTabCtrl"] = "wxLUA_USE_wxTabCtrl" preprocConditionTable["wxLUA_USE_wxTaskBarIcon"] = "wxLUA_USE_wxTaskBarIcon" preprocConditionTable["wxLUA_USE_wxTextCtrl"] = "wxLUA_USE_wxTextCtrl" preprocConditionTable["wxLUA_USE_wxTextEntryDialog"] = "wxLUA_USE_wxTextEntryDialog" preprocConditionTable["wxLUA_USE_wxTextValidator"] = "wxLUA_USE_wxTextValidator" preprocConditionTable["wxLUA_USE_wxTimer"] = "wxLUA_USE_wxTimer" preprocConditionTable["wxLUA_USE_wxTimeSpan"] = "wxLUA_USE_wxTimeSpan" preprocConditionTable["wxLUA_USE_wxToggleButton"] = "wxLUA_USE_wxToggleButton" preprocConditionTable["wxLUA_USE_wxToolbar"] = "wxLUA_USE_wxToolbar" preprocConditionTable["wxLUA_USE_wxToolbook"] = "wxLUA_USE_wxToolbook" preprocConditionTable["wxLUA_USE_wxTooltip"] = "wxLUA_USE_wxTooltip" preprocConditionTable["wxLUA_USE_wxTreebook"] = "wxLUA_USE_wxTreebook" preprocConditionTable["wxLUA_USE_wxTreeCtrl"] = "wxLUA_USE_wxTreeCtrl" preprocConditionTable["wxLUA_USE_wxValidator"] = "wxLUA_USE_wxValidator" preprocConditionTable["wxLUA_USE_wxWave"] = "wxLUA_USE_wxWave" preprocConditionTable["wxLUA_USE_wxWindowList"] = "wxLUA_USE_wxWindowList" preprocConditionTable["wxLUA_USE_wxWizard"] = "wxLUA_USE_wxWizard" preprocConditionTable["wxLUA_USE_wxXML"] = "wxLUA_USE_wxXML" preprocConditionTable["wxLUA_USE_wxXRC"] = "wxLUA_USE_wxXRC" -- condition operators for preprocessor #if statements preprocOperatorTable["|"] = "||" preprocOperatorTable["||"] = "||" preprocOperatorTable["&"] = "&&" preprocOperatorTable["&&"] = "&&" preprocOperatorTable["!"] = "!" preprocOperatorTable["("] = "(" preprocOperatorTable[")"] = ")" -- operators for %operator bindingOperatorTable["="] = "op_set" bindingOperatorTable["=="] = "op_eq" bindingOperatorTable["!="] = "op_ne" bindingOperatorTable["<"] = "op_lt" bindingOperatorTable[">"] = "op_gt" bindingOperatorTable["<="] = "op_le" bindingOperatorTable[">="] = "op_ge" bindingOperatorTable["|"] = "op_or" bindingOperatorTable["&"] = "op_and" bindingOperatorTable["||"] = "op_lor" bindingOperatorTable["&&"] = "op_land" bindingOperatorTable["!"] = "op_not" bindingOperatorTable["^"] = "op_xor" bindingOperatorTable["++"] = "op_inc" bindingOperatorTable["--"] = "op_dec" bindingOperatorTable["+"] = "op_add" bindingOperatorTable["-"] = "op_sub" -- also op_neg if unary - bindingOperatorTable["*"] = "op_mul" bindingOperatorTable["/"] = "op_div" bindingOperatorTable["+="] = "op_iadd" bindingOperatorTable["-="] = "op_isub" bindingOperatorTable["*="] = "op_imul" bindingOperatorTable["/="] = "op_idiv" bindingOperatorTable["%="] = "op_imod" bindingOperatorTable["&="] = "op_iand" bindingOperatorTable["|="] = "op_ior" bindingOperatorTable["^="] = "op_ixor" -- bindingKeywordTable bindingKeywordTable["%if"] = true bindingKeywordTable["%endif"] = true bindingKeywordTable["%rename"] = true bindingKeywordTable["%class"] = true -- keywords that come after %class tag bindingKeywordTable["%delete"] = true bindingKeywordTable["%noclassinfo"] = true bindingKeywordTable["%encapsulate"] = true -- keywords that can only be used within %class tag bindingKeywordTable["%constructor"] = true bindingKeywordTable["%member"] = true bindingKeywordTable["%member_func"] = true bindingKeywordTable["%operator"] = true bindingKeywordTable["%property"] = true bindingKeywordTable["%private"] = true bindingKeywordTable["%protected"] = true bindingKeywordTable["%endclass"] = true bindingKeywordTable["%abstract"] = true bindingKeywordTable["%struct"] = true bindingKeywordTable["%endstruct"] = true bindingKeywordTable["%enum"] = true bindingKeywordTable["%endenum"] = true bindingKeywordTable["%function"] = true bindingKeywordTable["%override"] = true bindingKeywordTable["%override_name"] = true bindingKeywordTable["%not_overload"] = true bindingKeywordTable["%typedef"] = true bindingKeywordTable["%include"] = true bindingKeywordTable["%includefile"] = true bindingKeywordTable["%gc_this"] = true bindingKeywordTable["%ungc_this"] = true bindingKeywordTable["%define"] = true bindingKeywordTable["%define_string"] = true bindingKeywordTable["%define_event"] = true bindingKeywordTable["%define_object"] = true bindingKeywordTable["%define_pointer"] = true bindingKeywordTable["//"] = true bindingKeywordTable["/*"] = true bindingKeywordTable["*/"] = true end -- --------------------------------------------------------------------------- -- SpaceSeparateStrings - add a space between strings, either can be nil -- returns either the sum of them or whichever is not nil -- --------------------------------------------------------------------------- function SpaceSeparateStrings(str1, str2) if str1 and str2 then return str1.." "..str2 end return str1 or str2 end -- --------------------------------------------------------------------------- -- SplitString - String tokenizing function -- -- str - input string to split -- delimTable - list of strings that delimit string tokens -- keepTable - list of delimiters that will be kept in return list -- stringliterals - bool - true to not tokenise string literals -- lineTable - table w/ .FileName name and .LineNumber for error messages -- --------------------------------------------------------------------------- function SplitString(str, delimTable, keepTable, stringliterals, lineTable) assert(str, "Error: input string is nil in SplitString "..LineTableErrString(lineTable)) local len = string_len(str) local tokens = {} if len == 0 then return tokens end local wordStart = nil local wordEnd = nil local inStringLiteral = false local escapedQuote = false -- Trim out unused delimiters using faster C find function local delimTable_start = {} -- starting char of the delimiters local delimTable_char = {} -- single char delims in this string local delimTable_str = {} -- multichar delimiters in this string local delimTable_len = {} -- lengths of the delimTable_str strings for n = 1, #delimTable do local delim = delimTable[n] if string.find(str, delim, 1, 1) then local delim_len = string_len(delim) local char = string_byte(delim) delimTable_start[char] = true if delim_len == 1 then delimTable_char[char] = delim else table.insert(delimTable_str, delim) table.insert(delimTable_len, delim_len) end end end -- create a hash table of the keepTable strings local keepTable_hash = {} if keepTable then for n = 1, #keepTable do keepTable_hash[keepTable[n]] = true end end local i = 1 while i <= len do local delim = nil local keepDelim = false local char = string_byte(str, i) if stringliterals then if inStringLiteral then if (char == char_BACKSLASH) and (string_byte(str, i+2) == char_DOUBLEQUOTE) then i = i + 1 -- skip \" char = char_DOUBLEQUOTE elseif (char == char_DOUBLEQUOTE) then inStringLiteral = false end elseif char == char_DOUBLEQUOTE then inStringLiteral = true end end if (not inStringLiteral) and delimTable_start[char] then -- check multichar delimiters for n = 1, #delimTable_str do --if string.find(str, delimTable_str[n], i, 1) == i then if string_sub(str, i, i+delimTable_len[n]-1) == delimTable_str[n] then delim = delimTable_str[n] break end end -- check single char delimiters if not delim and delimTable_char[char] then delim = delimTable_char[char] end -- keep delimiter in list if delim and keepTable and keepTable_hash[delim] then keepDelim = true end end if not delim then if not wordStart then wordStart = i end wordEnd = i i = i + 1 else if wordStart then table.insert(tokens, string_sub(str, wordStart, wordEnd)) end if keepDelim then table.insert(tokens, delim) end wordStart = nil i = i + string_len(delim) end end if wordStart then table.insert(tokens, string_sub(str, wordStart)) end if inStringLiteral then print("ERROR: Couldn't find closing quote for string literal. "..LineTableErrString(lineTable)) print(str) end return tokens; end -- --------------------------------------------------------------------------- -- Load Override Functions from the override file -- --------------------------------------------------------------------------- function ReadOverrideFile(override_file) local inOverride = false local inComment = false local filename = interface_filepath.."/"..override_file local linenumber = 0 local OverrideFunc = nil local delimiters = {" ", "\t"} if not FileExists(filename) then print("ERROR: Missing override file:'"..filename.."'") return end for line in io.lines(filename) do local lineData = SplitString(line, delimiters) local isOverride = false local isEnd = false linenumber = linenumber + 1 -- %override or %end for i = 1, #lineData do local tag = lineData[i] if (not inOverride) and (tag == "/*") then inComment = true elseif (not inOverride) and (tag == "*/") then inComment = false elseif tag == "//" then break elseif tag == "%override" then isOverride = true elseif tag == "%end" then isEnd = true elseif isOverride and (not inComment) then OverrideFunc = tag break end end if isOverride and (not inComment) then if inOverride then print("ERROR: Expected %end. File: "..filename.." (Line: "..linenumber..")") elseif not OverrideFunc then print("ERROR: Expected Override Function Name. File: "..filename.." (Line: "..linenumber..")") end elseif isEnd and (not inOverride) and (not inComment) then print("ERROR: Expected %override. File: "..filename.." (Line: "..linenumber..")") end if isOverride and (not inComment) then if not overrideTable[OverrideFunc] then overrideTable[OverrideFunc] = {} end if not overrideTableUsed[OverrideFunc] then overrideTableUsed[OverrideFunc] = false end inOverride = true table.insert(overrideTable[OverrideFunc], "// "..line.."\n") elseif isEnd and (not inComment) then table.insert(overrideTable[OverrideFunc], "\n") inOverride = false OverrideFunc = nil elseif inOverride and (not inComment) then table.insert(overrideTable[OverrideFunc], line.."\n") end end end -- --------------------------------------------------------------------------- -- Get the cpp filename to write the binding to by prepending the path -- --------------------------------------------------------------------------- function GetCPPFileName(filename) local splitpath = SplitString(filename, { "/", "\\" }) local name = SplitString(splitpath[#splitpath], { "." }) return output_cpp_filepath.."/"..name[1]..".cpp" end -- --------------------------------------------------------------------------- -- Get the cpp header filename to write the bindings to -- --------------------------------------------------------------------------- function GetCPPHeaderFileName(filename) local splitpath = SplitString(filename, { "/", "\\" }) local name = SplitString(splitpath[#splitpath], { "." }) if not output_cpp_header_filepath then output_cpp_header_filepath = output_cpp_filepath end return output_cpp_header_filepath.."/"..name[1]..".h" end -- --------------------------------------------------------------------------- -- Load an interface file creating a table {FileName, LineNumber, Tags, Line} -- --------------------------------------------------------------------------- function ReadInterfaceFile(filename) local fileData = {} local linenumber = 0 for line in io.lines(filename) do linenumber = linenumber + 1 local lineTable = { FileName = filename, LineNumber = linenumber, LineText = line, Tags = SplitString(line, bindingDelimiters, bindingDelimsToKeep, true, lineTable) } table.insert(fileData, lineTable) end return fileData end -- --------------------------------------------------------------------------- -- Return a nicely formatted string where an error occurred using the lineTable -- from ReadInterfaceFile -- --------------------------------------------------------------------------- function LineTableErrString(lineTable) if type(lineTable) == "table" then return "File: '"..lineTable.FileName.."':(line "..lineTable.LineNumber..")\n '"..lineTable.LineText.."'" else return "" end end -- --------------------------------------------------------------------------- -- Entry point to read the .i interface files and parse them into data -- --------------------------------------------------------------------------- function GenerateInterfaceData() local interfaceFileDataList = {} local interfaceList = {} local time1 = os.time() -- read all interface files and build DataType Table for i = 1, #interface_fileTable do local filename = interface_filepath.."/"..interface_fileTable[i] if FileExists(filename) then -- read the interface .i file into a table local interfaceFileData = ReadInterfaceFile(filename) -- find and add data types to the dataTypeTable table BuildDataTypeTable(interfaceFileData) table.insert(interfaceFileDataList, { FileName=filename, Data=interfaceFileData }) else print("ERROR: Interface file does not exist : '"..filename.."'") end end local time2 = os.time() print("Timing: BuildDataTypeTable "..os.difftime(time2, time1).." seconds.") time1 = time2 for i = 1, #interfaceFileDataList do -- Parse interface file data into a structured object list local objectList = ParseData(interfaceFileDataList[i].Data) if objectList then local interface = { CPPFileName = GetCPPFileName(interfaceFileDataList[i].FileName), includeBindingTable = {}, includeFiles = {}, objectData = objectList, lineData = interfaceFileDataList[i].Data } table.insert(interfaceList, interface) end end local time2 = os.time() print("Timing: ParseData "..os.difftime(time2, time1).." seconds.") return interfaceList end -- --------------------------------------------------------------------------- -- After generating the wrapper files, write them to disk -- --------------------------------------------------------------------------- function WriteWrapperFiles(interfaceList) local time1 = os.time() local monolithicFileData = {} local updated_files = 0 -- generatelanguage binding, binding is stored in objectList for i = 1, #interfaceList do local interface = interfaceList[i] -- theoretically you could write other language binding generators -- using parsed interface data GenerateLuaLanguageBinding(interface) -- create c/c++ file local fileData = {} local add_includes = true if output_single_cpp_binding_file then fileData = monolithicFileData add_includes = (i == 1) end fileData = GenerateBindingFileTable(interface, fileData, add_includes) if output_single_cpp_binding_file then monolithicFileData[#monolithicFileData+1] = "\n\n" else local written = WriteTableToFile(interface.CPPFileName, fileData, false) if written then updated_files = updated_files + 1 end end end local fileData = GenerateHookHeaderFileTable() local written = WriteTableToFile(GetCPPHeaderFileName(hook_cpp_header_filename), fileData, false) if written then updated_files = updated_files + 1 end local fileData = {} -- reset to empty table if output_single_cpp_binding_file then fileData = monolithicFileData end fileData = GenerateHookCppFileHeader(fileData, GetCPPFileName(hook_cpp_binding_filename), not output_single_cpp_binding_file) table.insert(fileData, (hook_cpp_binding_source_includes or "").."\n") fileData = GenerateHookEventFileTable(fileData) fileData = GenerateHookDefineFileTable(fileData) fileData = GenerateHookObjectFileTable(fileData) fileData = GenerateHookCFunctionFileTable(fileData) fileData = GenerateHookClassFileTable(fileData) written = WriteTableToFile(GetCPPFileName(hook_cpp_binding_filename), fileData, false) if written then updated_files = updated_files + 1 end local time2 = os.time() --print("Timing: GenerateLuaLanguageBinding and write files "..os.difftime(time2, time1).." seconds.") return updated_files end function AllocParseObject(obj_type) local parseObject = { Name = "<"..obj_type..">", ObjType = obj_type, TagDeclaration = nil, BindTable = {}, BaseClasses = {}, Members = {}, ["%delete"] = false, ["%noclassinfo"] = false, ["%encapsulate"] = false, Condition = nil, } return parseObject end function AllocMember(lineState, extraCondition) local member = { DefType = lineState.DefType, DataType = lineState.DataType, DataTypeWithAttrib = lineState.DataTypeWithAttrib, DataTypePointer = lineState.DataTypePointer, TypedDataType = lineState.DataType, TypedDataTypeWithAttrib = lineState.DataTypeWithAttrib, TypedDataTypePointer = lineState.DataTypePointer, Name = lineState.Name, ["%rename"] = lineState["%rename"], Value = lineState.Value, ["%function"] = lineState["%function"], IsConstructor = lineState.IsConstructor, ["%operator"] = lineState["%operator"], IsFunction = lineState.IsFunction, IsConstFunction = lineState.IsConstFunction, IsStaticFunction = lineState.IsStaticFunction, IsVirtualFunction = lineState.IsVirtualFunction, IsPureVirtualFunction = lineState.IsPureVirtualFunction, NotOverload = lineState.NotOverload, override_name = lineState.override_name, Condition = lineState.Condition, ExtraCondition = extraCondition, Params = lineState.Params, FileName = lineState.FileName, LineNumber = lineState.LineNumber, LineText = lineState.LineText, ["%gc_this"] = lineState["%gc_this"], ["%ungc_this"] = lineState["%ungc_this"], } return member end function AllocParam() local member = { DataType = nil, DataTypeWithAttrib = nil, DataTypePointer = {}, TypedDataType = nil, TypedDataTypeWithAttrib = nil, TypedDataTypePointer = {}, Name = nil, DefaultValue = nil, ParamObjectDeclared = nil, Binding = nil } return member end -- --------------------------------------------------------------------------- -- Build DataType Table by adding %classes (and their bases), %structs, and %enums -- --------------------------------------------------------------------------- function BuildDataTypeTable(interfaceData) local in_block_comment = 0 for l = 1, #interfaceData do local lineTable = interfaceData[l] local lineTags = lineTable.Tags local classname = nil -- current classname if any local action = nil -- what to look for next for t = 1, #lineTags do local tag = lineTags[t] if bindingKeywordTable[tag] then -- block comment (start) if tag == "/*" then in_block_comment = in_block_comment + 1 -- block comment (end) elseif tag == "*/" then in_block_comment = in_block_comment - 1 end -- ignore until end of block comment if in_block_comment == 0 then -- rest of line comment if tag == "//" then break elseif tag == "%class" then action = "find_classname" elseif tag == "%struct" then action = "find_structname" elseif tag == "%enum" then action = "find_enumname" end end elseif (in_block_comment == 0) and action and (not preprocOperatorTable[tag]) and (not FindOrCreateCondition(tag)) and (not skipBindingKeywordTable[tag]) then if action == "find_classname" then if not dataTypeTable[tag] then AllocDataType(tag, "class", false) end classname = tag action = "find_classcomma" elseif action == "find_classcomma" then if tag ~= "," then print("WARNING: Expected comma (',') after class name : '"..classname.."' in "..LineTableErrString(lineTable)) end action = "find_classbase" elseif action == "find_classbase" then if not dataTypeTable[tag] then AllocDataType(tag, "class", false) end -- set class's BaseClass if not dataTypeTable[classname].BaseClass then dataTypeTable[classname].BaseClass = tag end action = "find_classcomma" elseif action == "find_structname" then if not dataTypeTable[tag] then AllocDataType(tag, "struct", false) end action = nil elseif action == "find_enumname" then if not dataTypeTable[tag] then AllocDataType(tag, "enum", true) end action = nil end end end end end -- --------------------------------------------------------------------------- -- Parse the interface file tags -- This uses a stack of AllocParseObjects with the top most one the globals -- classes and enums are temporarily pushed onto it and removed at the end. -- --------------------------------------------------------------------------- function ParseData(interfaceData) local objectList = {} local parseState = { ObjectStack = {}, ConditionStack = {}, -- stack of conditions IsBlockComment = 0, -- /* then +1 else */ then -1, 0 == not in comment } local globals = AllocParseObject("objtype_globals") -- Global Objects globals.Name = "globals" table.insert(parseState.ObjectStack, 1, globals) local enumType = "" -- FIXME temp fix to remember named enums local l = 0 while interfaceData[l+1] do -- not for loop so we can adjust l l = l + 1 local lineTable = interfaceData[l] local lineTags = interfaceData[l].Tags local lineState = { Skip = false, -- skip rest of line InlineConditionIf = false, -- single line condition Action = nil, ActionAttributes = {}, ActionMandatory = false, PopParseObject = nil, ParamState = AllocParam(), BaseClasses = {}, RValue = nil, DefType = nil, -- below are copied by AllocMember DataType = nil, DataTypeWithAttrib = nil, DataTypePointer = {}, Name = nil, ["%rename"] = nil, Value = nil, ["%gc_this"] = nil, ["%ungc_this"] = nil, ["%function"] = nil, IsConstructor = nil, ["%operator"] = nil, IsFunction = nil, IsConstFunction = nil, IsStaticFunction = nil, IsVirtualFunction = nil, IsPureVirtualFunction = nil, override_name = nil, NotOverload = nil, Condition = nil, Params = {}, FileName = lineTable.FileName, LineNumber = lineTable.LineNumber, LineText = lineTable.LineText, } local t = 0 while lineTags[t+1] do t = t + 1 local tag = lineTags[t] if lineState.Skip then break end -- --------------------------------------------------------------- -- Is this tag a binding keyword, e.g. %XXX -- --------------------------------------------------------------- if bindingKeywordTable[tag] then -- block comment (start) if tag == "/*" then parseState.IsBlockComment = parseState.IsBlockComment + 1 -- block comment (end) elseif tag == "*/" then parseState.IsBlockComment = parseState.IsBlockComment - 1 -- ignore until end of block comment elseif parseState.IsBlockComment == 0 then -- warn if we're expecting something and it's not there if not lineState.ActionAttributes[tag] and lineState.ActionMandatory then print("ERROR: Expected Line Action '"..lineState.Action.."', got '"..tag.."'. "..LineTableErrString(lineTable)) end -- end inline conditionals since we should have handled it already if lineState.InlineConditionIf then lineState.InlineConditionIf = false end -- rest of line comment if tag == "//" then break -- %if wxLUA_USE_xxx ... %endif elseif tag == "%if" then lineState.DefType = "deftype_%if" elseif tag == "%endif" then table.remove(parseState.ConditionStack, #parseState.ConditionStack) -- pop last %if break -- we can stop processing line elseif tag == "%rename" then lineState.Action = "action_rename" lineState.ActionMandatory = true elseif tag == "%function" then lineState["%function"] = true elseif tag == "%gc_this" then lineState["%gc_this"] = true if parseState.ObjectStack[1].ObjType ~= "objtype_%class" then print("ERROR: %gc_this is not used for a %class member function. "..LineTableErrString(lineTable)) end elseif tag == "%ungc_this" then lineState["%ungc_this"] = true if parseState.ObjectStack[1].ObjType ~= "objtype_%class" then print("ERROR: %ungc_this is not used for a %class member function. "..LineTableErrString(lineTable)) end -- ------------------------------------------------------- elseif tag == "%class" then local parseObject = AllocParseObject("objtype_%class") table.insert(parseState.ObjectStack, 1, parseObject) lineState.ParseObjectDeclaration = true lineState.DefType = "deftype_%class" lineState.Action = "action_classname" lineState.ActionMandatory = true lineState.ActionAttributes["%delete"] = true lineState.ActionAttributes["%noclassinfo"] = true lineState.ActionAttributes["%abstract"] = true lineState.ActionAttributes["%encapsulate"] = true elseif tag == "%endclass" then if parseState.ObjectStack[1].ObjType ~= "objtype_%class" then print("ERROR: %endclass does not have matching %class. "..LineTableErrString(lineTable)) end table.insert(objectList, parseState.ObjectStack[1]) table.remove(parseState.ObjectStack, 1) if #parseState.ObjectStack == 0 then print("ERROR: parseState.ObjectStack is unexpectedly empty on %endclass. "..LineTableErrString(lineTable)) end lineState.Action = "action_keyword" lineState.ActionMandatory = true break -- we can stop processing line elseif tag == "%delete" then -- tag for %class parseState.ObjectStack[1]["%delete"] = true if (parseState.ObjectStack[1].ObjType ~= "objtype_%class") and (parseState.ObjectStack[1].ObjType ~= "objtype_%struct") then print("ERROR: %delete is not used for a %class. "..LineTableErrString(lineTable)) end elseif tag == "%noclassinfo" then -- tag for %class parseState.ObjectStack[1]["%noclassinfo"] = true if (parseState.ObjectStack[1].ObjType ~= "objtype_%class") and (parseState.ObjectStack[1].ObjType ~= "objtype_%struct") then print("ERROR: %noclassinfo is not used for a %class. "..LineTableErrString(lineTable)) end elseif tag == "%abstract" then -- tag for %class parseState.ObjectStack[1]["%abstract"] = true if parseState.ObjectStack[1].ObjType ~= "objtype_%class" then print("ERROR: %abstract is not used for a %class. "..LineTableErrString(lineTable)) end elseif tag == "%encapsulate" then -- tag for %class parseState.ObjectStack[1]["%encapsulate"] = true if (parseState.ObjectStack[1].ObjType ~= "objtype_%class") and (parseState.ObjectStack[1].ObjType ~= "objtype_%struct") then print("ERROR: %encapsulate is not used for a %class. "..LineTableErrString(lineTable)) end -- ------------------------------------------------------- elseif tag == "%protected" then -- skip %protected functions lineState.Skip = true break elseif tag == "%private" then -- skip %private functions lineState.Skip = true break elseif tag == "%property" then -- FIXME removed properties lineState.Skip = true print("WARNING: the %property tag is ignored and properties are generated at runtime.") break elseif tag == "%member" then lineState.DefType = "deftype_%member" lineState.Action = "action_member" lineState.ActionMandatory = true if (parseState.ObjectStack[1].ObjType ~= "objtype_%class") and (parseState.ObjectStack[1].ObjType ~= "objtype_%struct") then print("ERROR: %member is not used for a %class or %struct. "..LineTableErrString(lineTable)) end elseif tag == "%member_func" then lineState.DefType = "deftype_%member_func" lineState.Action = "action_member" lineState.ActionMandatory = true if (parseState.ObjectStack[1].ObjType ~= "objtype_%class") and (parseState.ObjectStack[1].ObjType ~= "objtype_%struct") then print("ERROR: %member_func is not used for a %class or %struct. "..LineTableErrString(lineTable)) end elseif tag == "%constructor" then lineState.IsConstructor = true if parseState.ObjectStack[1].ObjType ~= "objtype_%class" then print("ERROR: %constructor is not used for a %class. "..LineTableErrString(lineTable)) end elseif tag == "%operator" then lineState["%operator"] = true if parseState.ObjectStack[1].ObjType ~= "objtype_%class" then print("ERROR: %operator is not used for a %class. "..LineTableErrString(lineTable)) end -- ------------------------------------------------------- elseif tag == "%struct" then local parseObject = AllocParseObject("objtype_%struct") table.insert(parseState.ObjectStack, 1, parseObject) lineState.ParseObjectDeclaration = true parseState.ObjectStack[1]["%noclassinfo"] = true parseState.ObjectStack[1]["%encapsulate"] = true lineState.DefType = "deftype_%struct" lineState.Action = "action_structname" lineState.ActionMandatory = true lineState.ActionAttributes["%delete"] = true lineState.ActionAttributes["%noclassinfo"] = true lineState.ActionAttributes["%abstract"] = true lineState.ActionAttributes["%encapsulate"] = true elseif tag == "%endstruct" then if parseState.ObjectStack[1].ObjType ~= "objtype_%struct" then print("ERROR: %endstruct does not have matching %struct. "..LineTableErrString(lineTable)) end table.insert(objectList, parseState.ObjectStack[1]) table.remove(parseState.ObjectStack, 1) if #parseState.ObjectStack == 0 then print("ERROR: parseState.ObjectStack is unexpectedly empty on %endstruct. "..LineTableErrString(lineTable)) end break -- we can stop processing line -- ------------------------------------------------------- elseif tag == "%enum" then local parseObject = AllocParseObject("objtype_%enum") table.insert(parseState.ObjectStack, 1, parseObject) lineState.ParseObjectDeclaration = true lineState.DefType = "deftype_%enum" lineState.Action = "action_enumname" lineState.ActionMandatory = false -- not all enums have a name elseif tag == "%endenum" then if parseState.ObjectStack[1].ObjType ~= "objtype_%enum" then print("ERROR: %endenum does not have matching %enum. "..LineTableErrString(lineTable)) end enumType = "" table.insert(objectList, parseState.ObjectStack[1]) table.remove(parseState.ObjectStack, 1) if #parseState.ObjectStack == 0 then print("ERROR: parseState.ObjectStack is unexpectedly empty on %endenum. "..LineTableErrString(lineTable)) end break -- we can stop processing line -- ------------------------------------------------------- elseif tag == "%include" then local parseObject = AllocParseObject("objtype_%include") table.insert(parseState.ObjectStack, 1, parseObject) lineState.ParseObjectDeclaration = true lineState.PopParseObject = true -- pop parseObject off stack at end of line lineState.DefType = "deftype_%include" lineState.Action = "action_include" lineState.ActionMandatory = true elseif tag == "%includefile" then local parseObject = AllocParseObject("objtype_%includefile") table.insert(parseState.ObjectStack, 1, parseObject) lineState.ParseObjectDeclaration = true lineState.PopParseObject = true -- pop parseObject off stack at end of line lineState.DefType = "deftype_%includefile" lineState.Action = "action_includefile" lineState.ActionMandatory = true -- ------------------------------------------------------- elseif tag == "%typedef" then lineState.DefType = "deftype_%typedef" lineState.Action = "action_typedef" lineState.ActionMandatory = true elseif tag == "%override_name" then lineState.Action = "action_override_name" lineState.ActionMandatory = true elseif tag == "%not_overload" then lineState.NotOverload = true -- ------------------------------------------------------- elseif tag == "%define" then lineState.DefType = "deftype_%define" lineState.Action = "action_define" lineState.ActionMandatory = true elseif tag == "%define_string" then lineState.DefType = "deftype_%define_string" lineState.Action = "action_define" lineState.ActionMandatory = true elseif tag == "%define_event" then lineState.DefType = "deftype_%define_event" lineState.Action = "action_define" lineState.ActionMandatory = true elseif tag == "%define_object" then lineState.DefType = "deftype_%define_object" lineState.Action = "action_define" lineState.ActionMandatory = true elseif tag == "%define_pointer" then lineState.DefType = "deftype_%define_pointer" lineState.Action = "action_define" lineState.ActionMandatory = true else print("WARNING: Unhandled keyword '"..tag.."' in "..LineTableErrString(lineTable)) end end -- --------------------------------------------------------------- -- else !keyword[tag] -- --------------------------------------------------------------- elseif parseState.IsBlockComment == 0 then -- handle condition operators, note can have leading ! for not if (tag == "!") or (((lineState.DefType == "deftype_%if") or lineState.InlineConditionIf) and preprocOperatorTable[tag]) then if lineState.Condition or (preprocOperatorTable[tag] == "!") or (preprocOperatorTable[tag] == "(") then if not lineState.Condition then lineState.Condition = preprocOperatorTable[tag] else local c = string.sub(lineState.Condition, -1, -1) -- get last char if ((c ~= "(") and (preprocOperatorTable[tag] ~= ")")) or ((c ~= ")") and (preprocOperatorTable[tag] == ")")) then lineState.Condition = lineState.Condition.." " end -- add c operator lineState.Condition = lineState.Condition..preprocOperatorTable[tag] end else print("ERROR: Unexpected Conditional Operator "..tag..". "..LineTableErrString(lineTable)) end elseif FindOrCreateCondition(tag) then if (lineState.DefType ~= "deftype_%if") and not lineState.InlineConditionIf then lineState.InlineConditionIf = true end if not lineState.Condition then lineState.Condition = "" else local c = string.sub(lineState.Condition, -1, -1) -- get last char if (c ~= "(") and (c ~= "!") then -- eg. not start of condition if not preprocOperatorTable[c] then print("ERROR: Expected Conditional Operator "..tag..". "..LineTableErrString(lineTable)) end lineState.Condition = lineState.Condition.." " end end lineState.Condition = lineState.Condition..FindOrCreateCondition(tag) elseif not skipBindingKeywordTable[tag] then -- ------------------------------------------------------- -- Process Interface Data -- ------------------------------------------------------- if (lineState.Action == "action_keyword") and lineState.ActionMandatory then print("ERROR: Invalid Token '"..tag.."'. "..LineTableErrString(lineTable)) end -- ------------------------------------------------------- -- add block condition -- ------------------------------------------------------- if lineState.DefType == "deftype_%if" then if not lineState.Condition then lineState.Condition = "" else local c = string.sub(lineState.Condition, -1, -1) -- get last char if (c ~= "(") and (c ~= "!") then -- eg. not start of condition if not preprocOperatorTable[c] then print("ERROR: Expected Conditional Operator "..tag..". "..LineTableErrString(lineTable)) end lineState.Condition = lineState.Condition.." " end end lineState.Condition = lineState.Condition..tag -- ------------------------------------------------------- -- apply tag to lineState.Action -- ------------------------------------------------------- else -- end inline conditionals if lineState.InlineConditionIf then lineState.InlineConditionIf = false end if not lineState.Action then -- no actions specified -- ----------------------------------------------- -- enum parseObject if parseState.ObjectStack[1].ObjType == "objtype_%enum" then if IsDataType(tag) or dataTypeAttribTable[tag] or (tag == "*") or (tag == "&") or (tag == "[]") then print("ERROR: Invalid Enum Token '"..tag.."'. "..LineTableErrString(lineTable)) elseif tag ~= "," then -- ignore trailing commas lineState.DefType = "deftype_%enum" lineState.Name = tag lineState.DataType = enumType local member = AllocMember(lineState, BuildCondition(parseState.ConditionStack)) table.insert(parseState.ObjectStack[1].Members, member) end -- ----------------------------------------------- -- class or function parseObject elseif (parseState.ObjectStack[1].ObjType == "objtype_%class") or (parseState.ObjectStack[1].ObjType == "objtype_%struct") or (parseState.ObjectStack[1].ObjType == "objtype_globals") then if IsDataType(tag) then lineState.DataType = SpaceSeparateStrings(lineState.DataType, tag) lineState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.DataTypeWithAttrib, tag) lineState.DefType = "deftype_method" lineState.Action = "action_method" lineState.ActionMandatory = true elseif dataTypeAttribTable[tag] then lineState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.DataTypeWithAttrib, tag) lineState.DefType = "deftype_method" lineState.Action = "action_method" lineState.ActionMandatory = true elseif tag == "virtual" then lineState.IsVirtualFunction = true lineState.DefType = "deftype_method" lineState.Action = "action_method" lineState.ActionMandatory = true elseif tag == "static" then lineState.IsStaticFunction = true lineState.DefType = "deftype_method" lineState.Action = "action_method" lineState.ActionMandatory = true elseif tag == "inline" then lineState.DefType = "deftype_method" lineState.Action = "action_method" lineState.ActionMandatory = true elseif lineState.IsConstructor then lineState.Name = tag lineState.DataType = parseState.ObjectStack[1].Name lineState.DataTypeWithAttrib = lineState.DataType lineState.DefType = "deftype_method" lineState.Action = "action_method" else print("ERROR: Expected DataType, got '"..tag.."'. "..LineTableErrString(lineTable)) end else print("ERROR: Unexpected parseObject :"..parseState.ObjectStack[1].ObjType.." "..parseState.ObjectStack[1].Name..". "..LineTableErrString(lineTable)) end elseif lineState.Action == "action_classname" then parseState.ObjectStack[1].Name = tag lineState.Action = "action_classcomma" lineState.ActionMandatory = false elseif lineState.Action == "action_classcomma" then if tag ~= "," then print("ERROR: %class tag expected ','. "..LineTableErrString(lineTable)) end lineState.Action = "action_classbase" lineState.ActionMandatory = true elseif lineState.Action == "action_classbase" then table.insert(parseState.ObjectStack[1].BaseClasses, tag) lineState.Action = "action_classcomma" lineState.ActionMandatory = false elseif lineState.Action == "action_structname" then parseState.ObjectStack[1].Name = tag lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_enumname" then parseState.ObjectStack[1].Name = tag enumType = tag lineState.DataType = tag lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_include" then parseState.ObjectStack[1].Name = tag lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_includefile" then parseState.ObjectStack[1].Name = tag lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_override_name" then lineState.override_name = tag lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_typedef" then lineState.Name = tag lineState.Action = "action_typedefvalue" lineState.ActionMandatory = true elseif lineState.Action == "action_typedefvalue" then lineState.RValue = SpaceSeparateStrings(lineState.RValue, tag) lineState.Action = "action_typedefvalue" -- allow more than one word lineState.ActionMandatory = false elseif lineState.Action == "action_rename" then lineState["%rename"] = tag lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_define" then lineState.Name = tag -- if they specify a value after the tag use it, unless a keyword while (lineTags[t+1] ~= nil) and (bindingKeywordTable[lineTags[t+1]] == nil) do lineState.Value = (lineState.Value or "")..lineTags[t+1] t = t + 1 end lineState.Action = nil lineState.ActionMandatory = false elseif lineState.Action == "action_member" then if IsDataType(tag) then lineState.DataType = SpaceSeparateStrings(lineState.DataType, tag) lineState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.DataTypeWithAttrib, tag) lineState.Action = "action_member" lineState.ActionMandatory = true elseif dataTypeAttribTable[tag] then lineState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.DataTypeWithAttrib, tag) lineState.Action = "action_member" lineState.ActionMandatory = true elseif (tag == "*") or (tag == "&") or (tag == "[]") then table.insert(lineState.DataTypePointer, tag) lineState.Action = "action_member" lineState.ActionMandatory = true elseif tag == "static" then lineState.IsStaticFunction = true elseif IsDelimiter(tag) or functionAttribTable[tag] then print("ERROR: Expected Member Name, got Tag='"..tag.."'. "..LineTableErrString(lineTable)) else lineState.Name = tag if not lineState.DataType then print("ERROR: %member requires DataType to be assigned. Tag='"..tag.."'. "..LineTableErrString(lineTable)) end lineState.Action = nil lineState.ActionMandatory = false end elseif lineState.Action == "action_method" then if IsDataType(tag) then lineState.DataType = SpaceSeparateStrings(lineState.DataType, tag) lineState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.DataTypeWithAttrib, tag) lineState.Action = "action_method" lineState.ActionMandatory = true elseif dataTypeAttribTable[tag] then lineState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.DataTypeWithAttrib, tag) lineState.Action = "action_method" lineState.ActionMandatory = true elseif (tag == "*") or (tag == "&") or (tag == "[]") then table.insert(lineState.DataTypePointer, tag) lineState.Action = "action_method" lineState.ActionMandatory = true elseif tag == "virtual" then lineState.IsVirtualFunction = true elseif tag == "static" then lineState.IsStaticFunction = true elseif lineState["%operator"] and string.find(tag, "operator", 1, 1) then -- eat the rest of the "operator+=(...)" symbols which may be split before ( while lineTags[t+1] and (not string.find(lineTags[t+1], "(", 1, 1)) do tag = tag..lineTags[t+1] t = t + 1 end local a, b = string.find(tag, "operator", 1, 1) local op = string.sub(tag, b+1) lineState["%operator"] = op lineState.Action = "action_methodbracket" -- next char should be ( lineState.Name = bindingOperatorTable[op] elseif tag == "(" then if lineState.DataType == parseState.ObjectStack[1].Name then lineState.IsConstructor = true end if lineState.IsConstructor then if not lineState.Name then lineState.Name = lineState.DataType end lineState.DataType = parseState.ObjectStack[1].Name lineState.DataTypeWithAttrib = lineState.DataType if IsDataType(lineState.Name) and (lineState.Name ~= parseState.ObjectStack[1].Name) then if not IsDataTypeEnum(lineState.Name) then print("ERROR: Constructor Name ("..lineState.Name..") conflicts with datatype definition. "..LineTableErrString(lineTable)) else print("WARNING: Constructor Name ("..lineState.Name..") also used by enum definition. "..LineTableErrString(lineTable)) end end else print("ERROR: Expected Method Name, got Tag='"..tag.."'. "..LineTableErrString(lineTable)) end lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif IsDelimiter(tag) then print("ERROR: Expected Method Name, got delimiter Tag='"..tag.."'. "..LineTableErrString(lineTable)) else lineState.Name = tag if lineState.IsConstructor then lineState.DataType = parseState.ObjectStack[1].Name lineState.DataTypeWithAttrib = lineState.DataType end if not lineState.DataType then print("ERROR: Method requires DataType to be assigned. Tag='"..tag.."'. "..LineTableErrString(lineTable)) end lineState.Action = "action_methodbracket" lineState.ActionMandatory = true end elseif lineState.Action == "action_methodbracket" then if tag ~= '(' then local msg = "(Name="..tostring(lineState.Name).."; DataType="..tostring(lineState.DataType)..")" print("ERROR: Expected Method Tag '(', got Tag='"..tag.."'. "..msg.." "..LineTableErrString(lineTable)) end lineState.IsFunction = true lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif lineState.Action == "action_methodparam" then lineState.IsFunction = true if IsDataType(tag) then lineState.ParamState.DataType = SpaceSeparateStrings(lineState.ParamState.DataType, tag) lineState.ParamState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.ParamState.DataTypeWithAttrib, tag) lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif dataTypeAttribTable[tag] then lineState.ParamState.DataTypeWithAttrib = SpaceSeparateStrings(lineState.ParamState.DataTypeWithAttrib, tag) lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif (tag == "*") or (tag == "&") or (tag == "[]") then table.insert(lineState.ParamState.DataTypePointer, tag) lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif tag == "," then if not lineState.ParamState.DataType then print("ERROR: Method Parameter requires DataType to be assigned. "..LineTableErrString(lineTable)) end table.insert(lineState.Params, lineState.ParamState) lineState.ParamState = AllocParam() lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif tag == ")" then if lineState.ParamState.DataType then table.insert(lineState.Params, lineState.ParamState) lineState.ParamState = AllocParam() end lineState.Action = "action_method_body" lineState.ActionMandatory = false elseif tag == "=" then lineState.Action = "action_methodparam_defaultvalue" lineState.ActionMandatory = true elseif IsDelimiter(tag) or functionAttribTable[tag] then print("ERROR: Expected Method Param Name, got Tag='"..tag.."'. "..LineTableErrString(lineTable)) else lineState.ParamState.Name = tag lineState.Action = "action_methodparam_paramdelimiter" lineState.ActionMandatory = true end elseif lineState.Action == "action_methodparam_defaultvalue" then if tag == "," then if not lineState.ParamState.DefaultValue then print("ERROR: Method Parameter requires DefaultValue to be assigned. "..LineTableErrString(lineTable)) end if not lineState.ParamState.DataType then print("ERROR: Method Parameter requires DataType to be assigned. "..LineTableErrString(lineTable)) end table.insert(lineState.Params, lineState.ParamState) lineState.ParamState = AllocParam() lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif tag == ")" then if not lineState.ParamState.DefaultValue then print("ERROR: Method Parameter requires DefaultValue to be assigned. "..LineTableErrString(lineTable)) end if lineState.ParamState.DataType then table.insert(lineState.Params, lineState.ParamState) lineState.ParamState = AllocParam() end lineState.Action = "action_method_body" lineState.ActionMandatory = false elseif IsDataType(tag) or dataTypeAttribTable[tag] or functionAttribTable[tag] or (tag == "*") or (tag == "&") or (tag == "[]") or IsDelimiter(tag) and (tag ~= "|") and (tag ~= "&") then print("ERROR: Expected Parameter Default Value, got Tag='"..tag.."'. "..LineTableErrString(lineTable)) else lineState.ParamState.DefaultValue = SpaceSeparateStrings(lineState.ParamState.DefaultValue, tag) lineState.Action = "action_methodparam_defaultvalue" lineState.ActionMandatory = true end elseif lineState.Action == "action_methodparam_paramdelimiter" then if tag == "," then if not lineState.ParamState.DataType then print("ERROR: Method Parameter requires DataType to be assigned. "..LineTableErrString(lineTable)) end table.insert(lineState.Params, lineState.ParamState) lineState.ParamState = AllocParam() lineState.Action = "action_methodparam" lineState.ActionMandatory = true elseif tag == ")" then if lineState.ParamState.DataType then table.insert(lineState.Params, lineState.ParamState) lineState.ParamState = AllocParam() end lineState.Action = "action_method_body" lineState.ActionMandatory = false elseif tag == "=" then lineState.Action = "action_methodparam_defaultvalue" lineState.ActionMandatory = true elseif tag == "[]" then table.insert(lineState.ParamState.DataTypePointer, tag) lineState.Action = "action_methodparam_paramdelimiter" lineState.ActionMandatory = true else local msg = "(Name="..tostring(lineState.ParamState.Name).. "; DataType="..tostring(lineState.ParamState.DataType)..")" print("ERROR: Expected Parameter '=', ')', or ',' got Tag='"..tag.."'. "..msg.." "..LineTableErrString(lineTable)) end elseif lineState.Action == "action_method_body" then if tag == "const" then lineState.IsConstFunction = true lineState.Action = "action_method_body" lineState.ActionMandatory = false elseif tag == "=" then lineState.IsPureVirtualFunction = true parseState.ObjectStack[1]["%abstract"] = true -- junk rest of line lineState.Action = nil lineState.ActionMandatory = false lineState.Skip = true elseif (tag == "{") or (tag == ";") then -- junk rest of line lineState.Action = nil lineState.ActionMandatory = false lineState.Skip = true else print("ERROR: Expected Parameter 'const', '=', ';', or '{' got Tag='"..tag.."'. "..LineTableErrString(lineTable)) end end end end end end -- set line definition data if lineState.DefType == "deftype_%typedef" then -- line is a typedef typedefTable[lineState.Name] = lineState.RValue elseif lineState.DefType == "deftype_%if" then -- line is a block condition, push onto condition stack table.insert(parseState.ConditionStack, lineState.Condition) elseif (lineState.DefType == "deftype_%member") or (lineState.DefType == "deftype_%member_func") then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) elseif lineState.DefType == "deftype_%define" then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) elseif lineState.DefType == "deftype_%define_string" then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) elseif lineState.DefType == "deftype_%define_event" then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) elseif lineState.DefType == "deftype_%define_object" then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) elseif lineState.DefType == "deftype_%define_pointer" then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) elseif lineState.DefType == "deftype_method" then table.insert(parseState.ObjectStack[1].Members, AllocMember(lineState, BuildCondition(parseState.ConditionStack))) end -- line is an object declaration if lineState.ParseObjectDeclaration then -- push inline condition onto condition stack if not lineState.IsBlockCondition and lineState.Condition then table.insert(parseState.ConditionStack, 1, lineState.Condition) end -- Set Parse Object