Changeset 2229 for code/branches/buildsystem/src/tolua/lua/package.lua
- Timestamp:
- Nov 19, 2008, 4:40:43 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/buildsystem/src/tolua/lua/package.lua
r1882 r2229 17 17 -- {i} = list of objects in the package. 18 18 classPackage = { 19 classtype = 'package'19 classtype = 'package' 20 20 } 21 21 classPackage.__index = classPackage … … 24 24 -- Print method 25 25 function classPackage:print () 26 print("Package: "..self.name)27 local i=128 while self[i] do29 self[i]:print("","")30 i = i+131 end26 print("Package: "..self.name) 27 local i=1 28 while self[i] do 29 self[i]:print("","") 30 i = i+1 31 end 32 32 end 33 33 34 34 function classPackage:preprocess () 35 35 36 -- avoid preprocessing embedded Lua code37 local L = {}38 self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded lua code39 self.code = gsub(self.code,"\n%s*%$%]","\2")40 self.code = gsub(self.code,"(%b\1\2)",function (c)36 -- avoid preprocessing embedded Lua code 37 local L = {} 38 self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded lua code 39 self.code = gsub(self.code,"\n%s*%$%]","\2") 40 self.code = gsub(self.code,"(%b\1\2)", function (c) 41 41 tinsert(L,c) 42 42 return "\n#["..getn(L).."]#" 43 end) 44 -- avoid preprocessing embedded C code 45 local C = {} 46 self.code = gsub(self.code,"\n%s*%$%<","\3") -- deal with embedded C code 47 self.code = gsub(self.code,"\n%s*%$%>","\4") 48 self.code = gsub(self.code,"(%b\3\4)", function (c) 43 end 44 ) 45 -- avoid preprocessing embedded C code 46 local C = {} 47 self.code = gsub(self.code,"\n%s*%$%<","\3") -- deal with embedded C code 48 self.code = gsub(self.code,"\n%s*%$%>","\4") 49 self.code = gsub(self.code,"(%b\3\4)", function (c) 49 50 tinsert(C,c) 50 51 return "\n#<"..getn(C)..">#" 51 end) 52 -- avoid preprocessing embedded C code 53 self.code = gsub(self.code,"\n%s*%$%{","\5") -- deal with embedded C code 54 self.code = gsub(self.code,"\n%s*%$%}","\6") 55 self.code = gsub(self.code,"(%b\5\6)", function (c) 52 end 53 ) 54 -- avoid preprocessing embedded C code 55 self.code = gsub(self.code,"\n%s*%$%{","\5") -- deal with embedded C code 56 self.code = gsub(self.code,"\n%s*%$%}","\6") 57 self.code = gsub(self.code,"(%b\5\6)", function (c) 56 58 tinsert(C,c) 57 59 return "\n#<"..getn(C)..">#" 58 end) 59 60 --self.code = gsub(self.code,"\n%s*#[^d][^\n]*\n", "\n\n") -- eliminate preprocessor directives that don't start with 'd' 61 self.code = gsub(self.code,"\n[ \t]*#[ \t]*[^d%<%[]", "\n//") -- eliminate preprocessor directives that don't start with 'd' 62 63 -- avoid preprocessing verbatim lines 64 local V = {} 65 self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)",function (v) 66 tinsert(V,v) 67 return "\n#"..getn(V).."#" 68 end) 69 70 -- perform global substitution 71 72 self.code = gsub(self.code,"(//[^\n]*)","") -- eliminate C++ comments 73 self.code = gsub(self.code,"/%*","\1") 74 self.code = gsub(self.code,"%*/","\2") 75 self.code = gsub(self.code,"%b\1\2","") 76 self.code = gsub(self.code,"\1","/%*") 77 self.code = gsub(self.code,"\2","%*/") 78 self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @ 79 self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword 80 --self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword 81 --self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword 82 --self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword 83 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 84 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 85 self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*' 86 self.code = gsub(self.code,"([^%w_])lua_State%s*%*","%1_lstate ") -- substitute 'lua_State*' 87 88 -- restore embedded Lua code 89 self.code = gsub(self.code,"%#%[(%d+)%]%#",function (n) 90 return L[tonumber(n)] 91 end) 92 -- restore embedded C code 93 self.code = gsub(self.code,"%#%<(%d+)%>%#",function (n) 94 return C[tonumber(n)] 95 end) 96 -- restore verbatim lines 97 self.code = gsub(self.code,"%#(%d+)%#",function (n) 98 return V[tonumber(n)] 99 end) 100 101 self.code = string.gsub(self.code, "\n%s*%$([^\n]+)", function (l) 102 Verbatim(l.."\n") 103 return "\n" 104 end) 60 end 61 ) 62 63 --self.code = gsub(self.code,"\n%s*#[^d][^\n]*\n", "\n\n") -- eliminate preprocessor directives that don't start with 'd' 64 self.code = gsub(self.code,"\n[ \t]*#[ \t]*[^d%<%[]", "\n//") -- eliminate preprocessor directives that don't start with 'd' 65 66 -- avoid preprocessing verbatim lines 67 local V = {} 68 self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)", function (v) 69 tinsert(V,v) 70 return "\n#"..getn(V).."#" 71 end 72 ) 73 74 -- perform global substitution 75 76 self.code = gsub(self.code,"(//[^\n]*)","") -- eliminate C++ comments 77 self.code = gsub(self.code,"/%*","\1") 78 self.code = gsub(self.code,"%*/","\2") 79 self.code = gsub(self.code,"%b\1\2","") 80 self.code = gsub(self.code,"\1","/%*") 81 self.code = gsub(self.code,"\2","%*/") 82 self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @ 83 self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword 84 --self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword 85 --self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword 86 --self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword 87 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 88 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 89 self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*' 90 self.code = gsub(self.code,"([^%w_])lua_State%s*%*","%1_lstate ") -- substitute 'lua_State*' 91 92 -- restore embedded Lua code 93 self.code = gsub(self.code,"%#%[(%d+)%]%#", function (n) 94 return L[tonumber(n)] 95 end 96 ) 97 -- restore embedded C code 98 self.code = gsub(self.code,"%#%<(%d+)%>%#", function (n) 99 return C[tonumber(n)] 100 end 101 ) 102 -- restore verbatim lines 103 self.code = gsub(self.code,"%#(%d+)%#", function (n) 104 return V[tonumber(n)] 105 end 106 ) 107 108 self.code = string.gsub(self.code, "\n%s*%$([^\n]+)", function (l) 109 Verbatim(l.."\n") 110 return "\n" 111 end 112 ) 105 113 end 106 114 107 115 -- translate verbatim 108 116 function classPackage:preamble () 109 output('/*\n')110 output('** Lua binding: '..self.name..'\n')111 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n')112 output('*/\n\n')113 114 115 116 117 118 output('#include "tolua/tolua++.h"\n\n')119 120 if not flags.h then121 -- local temp = string.reverse(flags.H)122 -- local start1, end1 = string.find(temp, '/')123 -- local start2, end2 = string.find(temp, '\\')124 -- local res125 -- if not start1 == nil then126 -- if not start2 == nil then127 -- if start1 > start2 then128 -- res = string.sub(temp, 1, start2)129 -- else130 -- res = string.sub(temp, 1, start1)131 -- end132 -- else133 -- res = string.sub(temp, 1, start1)134 -- end135 -- elseif not start2 == nil then136 -- res = string.sub(temp, 1, start2)137 -- end138 -- res = string.reverse(res)139 output('#include "tolua_bind.h"')140 output('\n')141 end142 143 local i=1144 while self[i] do145 self[i]:preamble()146 i = i+1147 end148 149 150 151 152 153 154 155 156 157 output('delete self;')158 output('return 0;')159 160 161 162 163 164 output('\n')165 output('/* function to register type */')166 output('static void tolua_reg_types (lua_State* tolua_S)')167 output('{')168 foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)169 170 171 172 173 output('}')174 output('\n')117 output('/*\n') 118 output('** Lua binding: '..self.name..'\n') 119 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n') 120 output('*/\n\n') 121 122 output('#ifndef __cplusplus\n') 123 output('#include "stdlib.h"\n') 124 output('#endif\n') 125 output('#include "string.h"\n\n') 126 output('#include "tolua/tolua++.h"\n\n') 127 128 if not flags.h then 129 -- local temp = string.reverse(flags.H) 130 -- local start1, end1 = string.find(temp, '/') 131 -- local start2, end2 = string.find(temp, '\\') 132 -- local res 133 -- if not start1 == nil then 134 -- if not start2 == nil then 135 -- if start1 > start2 then 136 -- res = string.sub(temp, 1, start2) 137 -- else 138 -- res = string.sub(temp, 1, start1) 139 -- end 140 -- else 141 -- res = string.sub(temp, 1, start1) 142 -- end 143 -- elseif not start2 == nil then 144 -- res = string.sub(temp, 1, start2) 145 -- end 146 -- res = string.reverse(res) 147 output('#include "tolua_bind.h"') 148 output('\n') 149 end 150 151 local i=1 152 while self[i] do 153 self[i]:preamble() 154 i = i+1 155 end 156 157 if self:requirecollection(_collect) then 158 output('\n') 159 output('/* function to release collected object via destructor */') 160 output('#ifdef __cplusplus\n') 161 for i,v in pairs(_collect) do 162 output('\nstatic int '..v..' (lua_State* tolua_S)') 163 output('{') 164 output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);') 165 output(' delete self;') 166 output(' return 0;') 167 output('}') 168 end 169 output('#endif\n\n') 170 end 171 172 output('\n') 173 output('/* function to register type */') 174 output('static void tolua_reg_types (lua_State* tolua_S)') 175 output('{') 176 foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end) 177 if flags.t then 178 output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n") 179 foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end) 180 end 181 output('}') 182 output('\n') 175 183 end 176 184 … … 178 186 -- write package open function 179 187 function classPackage:register (pre) 180 pre = pre or ''181 push(self)182 output(pre.."/* Open function */")183 output(pre.."int tolua_"..self.name.."_open (lua_State* tolua_S)")184 output(pre.."{")185 output(pre.." tolua_open(tolua_S);")186 output(pre.." tolua_reg_types(tolua_S);")187 output(pre.." tolua_module(tolua_S,NULL,",self:hasvar(),");")188 output(pre.." tolua_beginmodule(tolua_S,NULL);")189 local i=1190 while self[i] do191 self[i]:register(pre.." ")192 i = i+1193 end194 output(pre.." tolua_endmodule(tolua_S);")195 output(pre.." return 1;")196 output(pre.."}")197 198 output("\n\n")199 output("#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501\n");200 output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {")201 output(pre.." return tolua_"..self.name.."_open(tolua_S);")202 output(pre.."};")203 output("#endif\n\n")204 205 188 pre = pre or '' 189 push(self) 190 output(pre.."/* Open function */") 191 output(pre.."int tolua_"..self.name.."_open (lua_State* tolua_S)") 192 output(pre.."{") 193 output(pre.." tolua_open(tolua_S);") 194 output(pre.." tolua_reg_types(tolua_S);") 195 output(pre.." tolua_module(tolua_S,NULL,",self:hasvar(),");") 196 output(pre.." tolua_beginmodule(tolua_S,NULL);") 197 local i=1 198 while self[i] do 199 self[i]:register(pre.." ") 200 i = i+1 201 end 202 output(pre.." tolua_endmodule(tolua_S);") 203 output(pre.." return 1;") 204 output(pre.."}") 205 206 output("\n\n") 207 output("#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501\n"); 208 output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {") 209 output(pre.." return tolua_"..self.name.."_open(tolua_S);") 210 output(pre.."};") 211 output("#endif\n\n") 212 213 pop() 206 214 end 207 215 208 216 -- write header file 209 217 function classPackage:header () 210 output('/*\n') output('** Lua binding: '..self.name..'\n')211 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n')212 output('*/\n\n')213 214 if not flags.h then215 output('#include "'..self.name..'Prereqs.h"\n')216 output('/* Exported function */')217 output('_'..self.name..'Export int tolua_'..self.name..'_open (lua_State* tolua_S);')218 output('\n')219 end218 output('/*\n') output('** Lua binding: '..self.name..'\n') 219 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n') 220 output('*/\n\n') 221 222 if not flags.h then 223 output('#include "'..self.name..'Prereqs.h"\n') 224 output('/* Exported function */') 225 output('_'..self.name..'Export int tolua_'..self.name..'_open (lua_State* tolua_S);') 226 output('\n') 227 end 220 228 end 221 229 222 230 -- Internal constructor 223 231 function _Package (self) 224 setmetatable(self,classPackage)225 return self232 setmetatable(self,classPackage) 233 return self 226 234 end 227 235 … … 229 237 -- *** Thanks to Ariel Manzur for fixing bugs in nested directives *** 230 238 function extract_code(fn,s) 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 239 local code = '\n$#include "'..fn..'"\n' 240 s= "\n" .. s .. "\n" -- add blank lines as sentinels 241 local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n") 242 while e do 243 t = strlower(t) 244 if t == "begin" then 245 _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e) 246 if not e then 247 tolua_error("Unbalanced 'tolua_begin' directive in header file") 248 end 249 end 250 code = code .. c .. "\n" 251 _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e) 252 end 253 return code 246 254 end 247 255 … … 249 257 -- Expects the package name, the file extension, and the file text. 250 258 function Package (name,fn) 251 local ext = "pkg" 252 253 -- open input file, if any 254 if fn then 255 local st, msg = readfrom(flags.f) 256 if not st then 257 error('#'..msg) 258 end 259 local _; _, _, ext = strfind(fn,".*%.(.*)$") 260 end 261 local code = "\n" .. read('*a') 262 if ext == 'h' or ext == 'hpp' then 263 code = extract_code(fn,code) 264 end 265 266 -- close file 267 if fn then 268 readfrom() 269 end 270 271 -- deal with include directive 272 local nsubst 273 repeat 274 code,nsubst = gsub(code,'\n%s*%$(.)file%s*"(.-)"([^\n]*)\n', 275 function (kind,fn,extra) 276 local _, _, ext = strfind(fn,".*%.(.*)$") 277 local fp,msg = openfile(fn,'r') 278 if not fp then 279 error('#'..msg..': '..fn) 280 end 281 local s = read(fp,'*a') 282 closefile(fp) 283 if kind == 'c' or kind == 'h' then 284 return extract_code(fn,s) 285 elseif kind == 'p' then 286 return "\n\n" .. s 287 elseif kind == 'l' then 288 return "\n$[--##"..fn.."\n" .. s .. "\n$]\n" 289 elseif kind == 'i' then 290 local t = {code=s} 291 extra = string.gsub(extra, "^%s*,%s*", "") 292 local pars = split_c_tokens(extra, ",") 293 include_file_hook(t, fn, unpack(pars)) 294 return "\n\n" .. t.code 295 else 296 error('#Invalid include directive (use $cfile, $pfile, $lfile or $ifile)') 297 end 298 end) 299 until nsubst==0 300 301 -- deal with renaming directive 302 repeat -- I don't know why this is necesary 303 code,nsubst = gsub(code,'\n%s*%$renaming%s*(.-)%s*\n', function (r) appendrenaming(r) return "\n" end) 304 until nsubst == 0 305 306 local t = _Package(_Container{name=name, code=code}) 307 push(t) 308 preprocess_hook(t) 309 t:preprocess() 310 preparse_hook(t) 311 t:parse(t.code) 312 pop() 313 return t 314 end 315 316 259 local ext = "pkg" 260 261 -- open input file, if any 262 if fn then 263 local st, msg = readfrom(flags.f) 264 if not st then 265 error('#'..msg) 266 end 267 local _; _, _, ext = strfind(fn,".*%.(.*)$") 268 end 269 local code = "\n" .. read('*a') 270 if ext == 'h' or ext == 'hpp' then 271 code = extract_code(fn,code) 272 end 273 274 -- close file 275 if fn then 276 readfrom() 277 end 278 279 -- deal with include directive 280 local nsubst 281 repeat 282 code,nsubst = gsub(code,'\n%s*%$(.)file%s*"(.-)"([^\n]*)\n', 283 function (kind,fn,extra) 284 local _, _, ext = strfind(fn,".*%.(.*)$") 285 local fp,msg = openfile(fn,'r') 286 if not fp then 287 error('#'..msg..': '..fn) 288 end 289 local s = read(fp,'*a') 290 closefile(fp) 291 if kind == 'c' or kind == 'h' then 292 return extract_code(fn,s) 293 elseif kind == 'p' then 294 return "\n\n" .. s 295 elseif kind == 'l' then 296 return "\n$[--##"..fn.."\n" .. s .. "\n$]\n" 297 elseif kind == 'i' then 298 local t = {code=s} 299 extra = string.gsub(extra, "^%s*,%s*", "") 300 local pars = split_c_tokens(extra, ",") 301 include_file_hook(t, fn, unpack(pars)) 302 return "\n\n" .. t.code 303 else 304 error('#Invalid include directive (use $cfile, $pfile, $lfile or $ifile)') 305 end 306 end 307 ) 308 until nsubst==0 309 310 -- deal with renaming directive 311 repeat -- I don't know why this is necesary 312 code,nsubst = gsub(code,'\n%s*%$renaming%s*(.-)%s*\n', function (r) appendrenaming(r) return "\n" end) 313 until nsubst == 0 314 315 local t = _Package(_Container{name=name, code=code}) 316 push(t) 317 preprocess_hook(t) 318 t:preprocess() 319 preparse_hook(t) 320 t:parse(t.code) 321 pop() 322 return t 323 end 324 325
Note: See TracChangeset
for help on using the changeset viewer.