Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 2710 for code/trunk/src/tolua


Ignore:
Timestamp:
Feb 28, 2009, 7:46:37 PM (16 years ago)
Author:
rgrieder
Message:

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

Location:
code/trunk
Files:
3 deleted
30 edited
6 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/tolua/CMakeLists.txt

    r1815 r2710  
    1 SET (TOLUALIB_SRC_FILES
     1 #
     2 #             ORXONOX - the hottest 3D action shooter ever to exist
     3 #                             > www.orxonox.net <
     4 #
     5 #        This program is free software; you can redistribute it and/or
     6 #         modify it under the terms of the GNU General Public License
     7 #        as published by the Free Software Foundation; either version 2
     8 #            of the License, or (at your option) any later version.
     9 #
     10 #       This program is distributed in the hope that it will be useful,
     11 #        but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 #                 GNU General Public License for more details.
     14 #
     15 #   You should have received a copy of the GNU General Public License along
     16 #      with this program; if not, write to the Free Software Foundation,
     17 #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     18 #
     19
     20################### Tolua++ library ###################
     21
     22SET(TOLUA++_FILES
     23  tolua_event.h
     24  tolua++.h
     25
    226  tolua_event.c
    327  tolua_is.c
     
    630  tolua_to.c
    731)
     32GENERATE_SOURCE_GROUPS(${TOLUA++_FILES})
    833
    9 ADD_LIBRARY (tolualib_orxonox SHARED ${TOLUALIB_SRC_FILES})
     34# No warnings needed from third party libraries
     35REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
     36ADD_COMPILER_FLAGS("-w")
    1037
    11 TARGET_LINK_LIBRARIES (tolualib_orxonox
    12   lua_orxonox
    13 )
     38ADD_LIBRARY(tolua++_orxonox SHARED ${TOLUA++_FILES})
     39SET_TARGET_PROPERTIES(tolua++_orxonox PROPERTIES DEFINE_SYMBOL "TOLUA_SHARED_BUILD")
     40TARGET_LINK_LIBRARIES(tolua++_orxonox ${LUA_LIBRARIES})
     41
     42SET_TARGET_PROPERTIES(tolua++_orxonox PROPERTIES VERSION 1.0.92)
     43
     44ORXONOX_INSTALL(tolua++_orxonox)
    1445
    1546
    16 SET (TOLUAGEN_SRC_FILES
    17   tolua.c
    18   toluabind.c
     47################## Tolua++ generator ##################
     48
     49ADD_EXECUTABLE(tolua++app_orxonox tolua.c)
     50TARGET_LINK_LIBRARIES(tolua++app_orxonox tolua++_orxonox ${LUA_LIBRARIES})
     51
     52OPTION(TOLUA_PARSER_RELEASE "Disable all debug messages from tolua bind files for Release and MinSizeRel build types." FALSE)
     53
     54# Set some variables to the cache in order to use them in the TOLUA macro
     55SET(TOLUA_PARSER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/all-${LUA_VERSION}.lua" CACHE INTERNAL "")
     56SET(TOLUA_PARSER_DEPENDENCIES
     57  tolua++app_orxonox
     58  ${CMAKE_CURRENT_SOURCE_DIR}/all-${LUA_VERSION}.lua
     59  ${CMAKE_CURRENT_SOURCE_DIR}/lua/compat-5.1.lua
     60  ${CMAKE_CURRENT_SOURCE_DIR}/lua/compat.lua
     61  ${CMAKE_CURRENT_SOURCE_DIR}/lua/basic.lua
     62  ${CMAKE_CURRENT_SOURCE_DIR}/lua/feature.lua
     63  ${CMAKE_CURRENT_SOURCE_DIR}/lua/verbatim.lua
     64  ${CMAKE_CURRENT_SOURCE_DIR}/lua/code.lua
     65  ${CMAKE_CURRENT_SOURCE_DIR}/lua/typedef.lua
     66  ${CMAKE_CURRENT_SOURCE_DIR}/lua/container.lua
     67  ${CMAKE_CURRENT_SOURCE_DIR}/lua/package.lua
     68  ${CMAKE_CURRENT_SOURCE_DIR}/lua/module.lua
     69  ${CMAKE_CURRENT_SOURCE_DIR}/lua/namespace.lua
     70  ${CMAKE_CURRENT_SOURCE_DIR}/lua/define.lua
     71  ${CMAKE_CURRENT_SOURCE_DIR}/lua/enumerate.lua
     72  ${CMAKE_CURRENT_SOURCE_DIR}/lua/declaration.lua
     73  ${CMAKE_CURRENT_SOURCE_DIR}/lua/variable.lua
     74  ${CMAKE_CURRENT_SOURCE_DIR}/lua/array.lua
     75  ${CMAKE_CURRENT_SOURCE_DIR}/lua/function.lua
     76  ${CMAKE_CURRENT_SOURCE_DIR}/lua/operator.lua
     77  ${CMAKE_CURRENT_SOURCE_DIR}/lua/class.lua
     78  ${CMAKE_CURRENT_SOURCE_DIR}/lua/clean.lua
     79  ${CMAKE_CURRENT_SOURCE_DIR}/lua/doit.lua
     80
     81  CACHE INTERNAL ""
    1982)
    20 
    21 ADD_EXECUTABLE (toluagen_orxonox ${TOLUAGEN_SRC_FILES})
    22 
    23 TARGET_LINK_LIBRARIES (toluagen_orxonox
    24   lua_orxonox
    25   tolualib_orxonox
    26   m
    27 )
    28 
    29 
    30 SET (TOLUA_PACKAGE "../../src/tolua/tolua-5.1.pkg")
    31 GET_TARGET_PROPERTY(TOLUAGEN_EXE toluagen_orxonox LOCATION)
    32 ADD_CUSTOM_COMMAND(
    33   OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/toluabind_orxonox.c
    34   COMMAND ${TOLUAGEN_EXE} -n tolua -o ../../src/tolua/toluabind_orxonox.c -H ../../src/tolua/toluabind_orxonox.h ${TOLUA_PACKAGE}
    35   DEPENDS
    36     toluagen_orxonox
    37     tolua-5.1.pkg
    38     lua/compat-5.1.lua
    39     lua/compat.lua
    40     lua/basic.lua
    41     lua/feature.lua
    42     lua/verbatim.lua
    43     lua/code.lua
    44     lua/typedef.lua
    45     lua/container.lua
    46     lua/package.lua
    47     lua/module.lua
    48     lua/namespace.lua
    49     lua/define.lua
    50     lua/enumerate.lua
    51     lua/declaration.lua
    52     lua/variable.lua
    53     lua/array.lua
    54     lua/function.lua
    55     lua/operator.lua
    56     lua/class.lua
    57     lua/clean.lua
    58     lua/doit.lua
    59   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/lib
    60 )
    61 
    62 SET (TOLUAEXE_SRC_FILES
    63   tolua.c
    64   toluabind_orxonox.c
    65 )
    66 
    67 ADD_EXECUTABLE (tolua_orxonox ${TOLUAEXE_SRC_FILES})
    68 
    69 TARGET_LINK_LIBRARIES (tolua_orxonox
    70   lua_orxonox
    71   tolualib_orxonox
    72   m
    73 )
  • code/trunk/src/tolua/lua/array.lua

    r2087 r2710  
    2121-- Print method
    2222function classArray:print (ident,close)
    23  print(ident.."Array{")
    24  print(ident.." mod  = '"..self.mod.."',")
    25  print(ident.." type = '"..self.type.."',")
    26  print(ident.." ptr  = '"..self.ptr.."',")
    27  print(ident.." name = '"..self.name.."',")
    28  print(ident.." def  = '"..self.def.."',")
    29  print(ident.." dim  = '"..self.dim.."',")
    30  print(ident.." ret  = '"..self.ret.."',")
    31  print(ident.."}"..close)
     23    print(ident.."Array{")
     24    print(ident.." mod  = '"..self.mod.."',")
     25    print(ident.." type = '"..self.type.."',")
     26    print(ident.." ptr  = '"..self.ptr.."',")
     27    print(ident.." name = '"..self.name.."',")
     28    print(ident.." def  = '"..self.def.."',")
     29    print(ident.." dim  = '"..self.dim.."',")
     30    print(ident.." ret  = '"..self.ret.."',")
     31    print(ident.."}"..close)
    3232end
    3333
    3434-- check if it is a variable
    3535function classArray:isvariable ()
    36  return true
     36    return true
    3737end
    3838
     
    4040-- get variable value
    4141function classArray:getvalue (class,static)
    42  if class and static then
    43   return class..'::'..self.name..'[tolua_index]'
    44  elseif class then
    45   return 'self->'..self.name..'[tolua_index]'
    46  else
    47   return self.name..'[tolua_index]'
    48  end
     42    if class and static then
     43        return class..'::'..self.name..'[tolua_index]'
     44    elseif class then
     45        return 'self->'..self.name..'[tolua_index]'
     46    else
     47        return self.name..'[tolua_index]'
     48    end
    4949end
    5050
    5151-- Write binding functions
    5252function classArray:supcode ()
    53  local class = self:inclass()
    54 
    55  -- get function ------------------------------------------------
    56  if class then
    57   output("/* get function:",self.name," of class ",class," */")
    58  else
    59   output("/* get function:",self.name," */")
    60  end
    61  self.cgetname = self:cfuncname("tolua_get")
    62  output("#ifndef TOLUA_DISABLE_"..self.cgetname)
    63  output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
    64  output("{")
    65  output(" int tolua_index;")
    66 
    67  -- declare self, if the case
    68  local _,_,static = strfind(self.mod,'^%s*(static)')
    69  if class and static==nil then
    70   output(' ',self.parent.type,'*','self;')
    71   output(' lua_pushstring(tolua_S,".self");')
    72   output(' lua_rawget(tolua_S,1);')
    73   output(' self = ')
    74   output('(',self.parent.type,'*) ')
    75   output('lua_touserdata(tolua_S,-1);')
    76  elseif static then
    77   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
    78  end
    79 
    80  -- check index
    81         output('#ifndef TOLUA_RELEASE\n')
    82         output(' {')
    83         output('  tolua_Error tolua_err;')
    84  output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
    85  output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
    86         output(' }')
    87         output('#endif\n')
    88         if flags['1'] then -- for compatibility with tolua5 ?
    89                 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
    90         else
    91                 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
    92         end
    93         output('#ifndef TOLUA_RELEASE\n')
    94         if self.dim and self.dim ~= '' then
    95           output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
    96         else
    97           output(' if (tolua_index<0)')
    98         end
    99  output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
    100         output('#endif\n')
    101 
    102  -- return value
    103  local t,ct = isbasic(self.type)
    104  if t then
    105   output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
    106  else
    107                 t = self.type
    108   if self.ptr == '&' or self.ptr == '' then
    109    output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
    110   else
    111    output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
    112   end
    113  end
    114  output(' return 1;')
    115  output('}')
    116  output('#endif //#ifndef TOLUA_DISABLE\n')
    117  output('\n')
    118 
    119  -- set function ------------------------------------------------
    120  if not strfind(self.type,'const') then
    121   if class then
    122    output("/* set function:",self.name," of class ",class," */")
    123   else
    124    output("/* set function:",self.name," */")
    125   end
    126   self.csetname = self:cfuncname("tolua_set")
    127   output("#ifndef TOLUA_DISABLE_"..self.csetname)
    128   output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
    129   output("{")
    130 
    131   -- declare index
    132   output(' int tolua_index;')
    133 
    134   -- declare self, if the case
    135   local _,_,static = strfind(self.mod,'^%s*(static)')
    136   if class and static==nil then
    137    output(' ',self.parent.type,'*','self;')
    138    output(' lua_pushstring(tolua_S,".self");')
    139    output(' lua_rawget(tolua_S,1);')
    140    output(' self = ')
    141    output('(',self.parent.type,'*) ')
    142    output('lua_touserdata(tolua_S,-1);')
    143   elseif static then
    144    _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
    145   end
    146 
    147   -- check index
    148          output('#ifndef TOLUA_RELEASE\n')
    149          output(' {')
    150          output('  tolua_Error tolua_err;')
    151   output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
    152   output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
    153                 output(' }')
    154                 output('#endif\n')
    155 
    156         if flags['1'] then -- for compatibility with tolua5 ?
    157                 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
    158         else
    159                 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
    160         end
    161 
    162          output('#ifndef TOLUA_RELEASE\n')
    163         if self.dim and self.dim ~= '' then
    164           output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
    165         else
    166           output(' if (tolua_index<0)')
    167         end
    168   output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
    169                 output('#endif\n')
    170 
    171   -- assign value
    172   local ptr = ''
    173   if self.ptr~='' then ptr = '*' end
    174   output(' ')
    175   if class and static then
    176    output(class..'::'..self.name..'[tolua_index]')
    177   elseif class then
    178    output('self->'..self.name..'[tolua_index]')
    179   else
    180    output(self.name..'[tolua_index]')
    181   end
    182   local t = isbasic(self.type)
    183   output(' = ')
    184   if not t and ptr=='' then output('*') end
    185   output('((',self.mod,self.type)
    186   if not t then
    187    output('*')
    188   end
    189   output(') ')
    190   local def = 0
    191   if self.def ~= '' then def = self.def end
    192   if t then
    193    output('tolua_to'..t,'(tolua_S,3,',def,'));')
    194   else
    195    output('tolua_tousertype(tolua_S,3,',def,'));')
    196   end
    197   output(' return 0;')
    198   output('}')
    199   output('#endif //#ifndef TOLUA_DISABLE\n')
    200   output('\n')
    201  end
    202 
     53    local class = self:inclass()
     54
     55    -- get function ------------------------------------------------
     56    if class then
     57        output("/* get function:",self.name," of class ",class," */")
     58    else
     59        output("/* get function:",self.name," */")
     60    end
     61    self.cgetname = self:cfuncname("tolua_get")
     62    output("#ifndef TOLUA_DISABLE_"..self.cgetname)
     63    output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
     64    output("{")
     65    output(" int tolua_index;")
     66
     67    -- declare self, if the case
     68    local _,_,static = strfind(self.mod,'^%s*(static)')
     69    if class and static==nil then
     70        output(' ',self.parent.type,'*','self;')
     71        output(' lua_pushstring(tolua_S,".self");')
     72        output(' lua_rawget(tolua_S,1);')
     73        output(' self = ')
     74        output('(',self.parent.type,'*) ')
     75        output('lua_touserdata(tolua_S,-1);')
     76    elseif static then
     77        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
     78    end
     79
     80    -- check index
     81    output('#ifndef TOLUA_RELEASE\n')
     82    output(' {')
     83    output('  tolua_Error tolua_err;')
     84    output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
     85    output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
     86    output(' }')
     87    output('#endif\n')
     88    if flags['1'] then -- for compatibility with tolua5 ?
     89        output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
     90    else
     91        output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
     92    end
     93    output('#ifndef TOLUA_RELEASE\n')
     94    if self.dim and self.dim ~= '' then
     95        output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
     96    else
     97        output(' if (tolua_index<0)')
     98    end
     99    output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
     100    output('#endif\n')
     101
     102    -- return value
     103    local t,ct = isbasic(self.type)
     104    if t then
     105        output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
     106    else
     107        t = self.type
     108        if self.ptr == '&' or self.ptr == '' then
     109            output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
     110        else
     111            output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
     112        end
     113    end
     114    output(' return 1;')
     115    output('}')
     116    output('#endif //#ifndef TOLUA_DISABLE\n')
     117    output('\n')
     118
     119    -- set function ------------------------------------------------
     120    if not strfind(self.type,'const') then
     121        if class then
     122            output("/* set function:",self.name," of class ",class," */")
     123        else
     124            output("/* set function:",self.name," */")
     125        end
     126        self.csetname = self:cfuncname("tolua_set")
     127        output("#ifndef TOLUA_DISABLE_"..self.csetname)
     128        output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
     129        output("{")
     130
     131        -- declare index
     132        output(' int tolua_index;')
     133
     134        -- declare self, if the case
     135        local _,_,static = strfind(self.mod,'^%s*(static)')
     136        if class and static==nil then
     137            output(' ',self.parent.type,'*','self;')
     138            output(' lua_pushstring(tolua_S,".self");')
     139            output(' lua_rawget(tolua_S,1);')
     140            output(' self = ')
     141            output('(',self.parent.type,'*) ')
     142            output('lua_touserdata(tolua_S,-1);')
     143        elseif static then
     144            _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
     145        end
     146
     147        -- check index
     148        output('#ifndef TOLUA_RELEASE\n')
     149        output(' {')
     150        output('  tolua_Error tolua_err;')
     151        output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
     152        output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
     153        output(' }')
     154        output('#endif\n')
     155
     156        if flags['1'] then -- for compatibility with tolua5 ?
     157            output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
     158        else
     159            output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
     160        end
     161
     162        output('#ifndef TOLUA_RELEASE\n')
     163        if self.dim and self.dim ~= '' then
     164            output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
     165        else
     166            output(' if (tolua_index<0)')
     167        end
     168        output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
     169        output('#endif\n')
     170
     171        -- assign value
     172        local ptr = ''
     173        if self.ptr~='' then ptr = '*' end
     174            output(' ')
     175        if class and static then
     176            output(class..'::'..self.name..'[tolua_index]')
     177        elseif class then
     178            output('self->'..self.name..'[tolua_index]')
     179        else
     180            output(self.name..'[tolua_index]')
     181        end
     182        local t = isbasic(self.type)
     183        output(' = ')
     184        if not t and ptr=='' then output('*') end
     185        output('((',self.mod,self.type)
     186        if not t then
     187            output('*')
     188        end
     189        output(') ')
     190        local def = 0
     191        if self.def ~= '' then def = self.def end
     192        if t then
     193            output('tolua_to'..t,'(tolua_S,3,',def,'));')
     194        else
     195            output('tolua_tousertype(tolua_S,3,',def,'));')
     196        end
     197        output(' return 0;')
     198        output('}')
     199        output('#endif //#ifndef TOLUA_DISABLE\n')
     200        output('\n')
     201    end
    203202end
    204203
    205204function classArray:register (pre)
    206  pre = pre or ''
    207  if self.csetname then
    208   output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
    209  else
    210   output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
    211  end
     205    pre = pre or ''
     206    if self.csetname then
     207        output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
     208    else
     209        output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
     210    end
    212211end
    213212
    214213-- Internal constructor
    215214function _Array (t)
    216  setmetatable(t,classArray)
    217  append(t)
    218  return t
     215    setmetatable(t,classArray)
     216    append(t)
     217    return t
    219218end
    220219
     
    222221-- Expects a string representing the variable declaration.
    223222function Array (s)
    224  return _Array (Declaration(s,'var'))
    225 end
    226 
    227 
     223    return _Array (Declaration(s,'var'))
     224end
     225
     226
  • code/trunk/src/tolua/lua/basic.lua

    r2087 r2710  
    1616-- and all occurrences of "void*" will be replaced by "_userdata"
    1717_basic = {
    18  ['void'] = '',
    19  ['char'] = 'number',
    20  ['int'] = 'number',
    21  ['short'] = 'number',
    22  ['long'] = 'number',
    23  ['unsigned'] = 'number',
    24  ['float'] = 'number',
    25  ['double'] = 'number',
    26  ['_cstring'] = 'string',
    27  ['_userdata'] = 'userdata',
    28  ['char*'] = 'string',
    29  ['void*'] = 'userdata',
    30  ['bool'] = 'boolean',
    31  ['lua_Object'] = 'value',
    32  ['LUA_VALUE'] = 'value',    -- for compatibility with tolua 4.0
    33  ['lua_State*'] = 'state',
    34  ['_lstate'] = 'state',
    35  ['lua_Function'] = 'value',
     18    ['void'] = '',
     19    ['char'] = 'number',
     20    ['int'] = 'number',
     21    ['short'] = 'number',
     22    ['long'] = 'number',
     23    ['unsigned'] = 'number',
     24    ['float'] = 'number',
     25    ['double'] = 'number',
     26    ['_cstring'] = 'string',
     27    ['_userdata'] = 'userdata',
     28    ['char*'] = 'string',
     29    ['void*'] = 'userdata',
     30    ['bool'] = 'boolean',
     31    ['lua_Object'] = 'value',
     32    ['LUA_VALUE'] = 'value',    -- for compatibility with tolua 4.0
     33    ['lua_State*'] = 'state',
     34    ['_lstate'] = 'state',
     35    ['lua_Function'] = 'value',
    3636}
    3737
    3838_basic_ctype = {
    39  number = "lua_Number",
    40  string = "const char*",
    41  userdata = "void*",
    42  boolean = "bool",
    43  value = "int",
    44  state = "lua_State*",
     39    number = "lua_Number",
     40    string = "const char*",
     41    userdata = "void*",
     42    boolean = "bool",
     43    value = "int",
     44    state = "lua_State*",
    4545}
    4646
     
    6868_renaming = {}
    6969function appendrenaming (s)
    70  local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$")
    71         if not b then
    72         error("#Invalid renaming syntax; it should be of the form: pattern@pattern")
    73         end
    74         tinsert(_renaming,{old=old, new=new})
     70    local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$")
     71    if not b then
     72        error("#Invalid renaming syntax; it should be of the form: pattern@pattern")
     73    end
     74    tinsert(_renaming,{old=old, new=new})
    7575end
    7676
    7777function applyrenaming (s)
    78         for i=1,getn(_renaming) do
    79         local m,n = gsub(s,_renaming[i].old,_renaming[i].new)
    80                 if n ~= 0 then
    81                 return m
    82                 end
    83         end
    84         return nil
     78    for i=1,getn(_renaming) do
     79        local m,n = gsub(s,_renaming[i].old,_renaming[i].new)
     80        if n ~= 0 then
     81            return m
     82        end
     83    end
     84    return nil
    8585end
    8686
    8787-- Error handler
    8888function tolua_error (s,f)
    89 if _curr_code then
    90         print("***curr code for error is "..tostring(_curr_code))
    91         print(debug.traceback())
    92 end
    93  local out = _OUTPUT
    94  _OUTPUT = _STDERR
    95  if strsub(s,1,1) == '#' then
    96   write("\n** tolua: "..strsub(s,2)..".\n\n")
    97   if _curr_code then
    98    local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line
    99    if s==nil then s = _curr_code end
    100    s = gsub(s,"_userdata","void*") -- return with 'void*'
    101    s = gsub(s,"_cstring","char*")  -- return with 'char*'
    102    s = gsub(s,"_lstate","lua_State*")  -- return with 'lua_State*'
    103    write("Code being processed:\n"..s.."\n")
    104   end
    105  else
    106  if not f then f = "(f is nil)" end
    107   print("\n** tolua internal error: "..f..s..".\n\n")
    108   return
    109  end
    110  _OUTPUT = out
     89    if _curr_code then
     90        print("***curr code for error is "..tostring(_curr_code))
     91        print(debug.traceback())
     92    end
     93    local out = _OUTPUT
     94    _OUTPUT = _STDERR
     95    if strsub(s,1,1) == '#' then
     96        write("\n** tolua: "..strsub(s,2)..".\n\n")
     97        if _curr_code then
     98            local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line
     99            if s==nil then s = _curr_code end
     100            s = gsub(s,"_userdata","void*") -- return with 'void*'
     101            s = gsub(s,"_cstring","char*")  -- return with 'char*'
     102            s = gsub(s,"_lstate","lua_State*")  -- return with 'lua_State*'
     103            write("Code being processed:\n"..s.."\n")
     104        end
     105    else
     106        if not f then f = "(f is nil)" end
     107        print("\n** tolua internal error: "..f..s..".\n\n")
     108        return
     109    end
     110    _OUTPUT = out
    111111end
    112112
    113113function warning (msg)
    114  local out = _OUTPUT
    115  _OUTPUT = _STDERR
    116  write("\n** tolua warning: "..msg..".\n\n")
    117  _OUTPUT = out
     114    local out = _OUTPUT
     115    _OUTPUT = _STDERR
     116    write("\n** tolua warning: "..msg..".\n\n")
     117    _OUTPUT = out
    118118end
    119119
    120120-- register an user defined type: returns full type
    121121function regtype (t)
    122         --if isbasic(t) then
    123         --      return t
    124         --end
    125         local ft = findtype(t)
    126 
    127         if not _usertype[ft] then
    128                 return appendusertype(t)
    129         end
    130         return ft
     122    --if isbasic(t) then
     123    --    return t
     124    --end
     125    local ft = findtype(t)
     126
     127    if not _usertype[ft] then
     128        return appendusertype(t)
     129    end
     130    return ft
    131131end
    132132
    133133-- return type name: returns full type
    134134function typevar(type)
    135         if type == '' or type == 'void' then
    136                 return type
    137         else
    138                 local ft = findtype(type)
    139                 if ft then
    140                         return ft
    141                 end
    142                 _usertype[type] = type
    143                 return type
    144         end
     135    if type == '' or type == 'void' then
     136        return type
     137    else
     138        local ft = findtype(type)
     139        if ft then
     140            return ft
     141        end
     142        _usertype[type] = type
     143        return type
     144    end
    145145end
    146146
    147147-- check if basic type
    148148function isbasic (type)
    149  local t = gsub(type,'const ','')
    150  local m,t = applytypedef('', t)
    151  local b = _basic[t]
    152  if b then
    153   return b,_basic_ctype[b]
    154  end
    155  return nil
     149    local t = gsub(type,'const ','')
     150    local m,t = applytypedef('', t)
     151    local b = _basic[t]
     152    if b then
     153        return b,_basic_ctype[b]
     154    end
     155    return nil
    156156end
    157157
    158158-- split string using a token
    159159function split (s,t)
    160  local l = {n=0}
    161  local f = function (s)
    162   l.n = l.n + 1
    163   l[l.n] = s
    164   return ""
    165  end
    166  local p = "%s*(.-)%s*"..t.."%s*"
    167  s = gsub(s,"^%s+","")
    168  s = gsub(s,"%s+$","")
    169  s = gsub(s,p,f)
    170  l.n = l.n + 1
    171  l[l.n] = gsub(s,"(%s%s*)$","")
    172  return l
     160    local l = {n=0}
     161    local f = function (s)
     162        l.n = l.n + 1
     163        l[l.n] = s
     164        return ""
     165    end
     166    local p = "%s*(.-)%s*"..t.."%s*"
     167    s = gsub(s,"^%s+","")
     168    s = gsub(s,"%s+$","")
     169    s = gsub(s,p,f)
     170    l.n = l.n + 1
     171    l[l.n] = gsub(s,"(%s%s*)$","")
     172    return l
    173173end
    174174
     
    178178function split_c_tokens(s, pat)
    179179
    180         s = string.gsub(s, "^%s*", "")
    181         s = string.gsub(s, "%s*$", "")
    182 
    183         local token_begin = 1
    184         local token_end = 1
    185         local ofs = 1
    186         local ret = {n=0}
    187 
    188         function add_token(ofs)
    189 
    190                 local t = string.sub(s, token_begin, ofs)
    191                 t = string.gsub(t, "^%s*", "")
    192                 t = string.gsub(t, "%s*$", "")
    193                 ret.n = ret.n + 1
    194                 ret[ret.n] = t
    195         end
    196 
    197         while ofs <= string.len(s) do
    198 
    199                 local sub = string.sub(s, ofs, -1)
    200                 local b,e = string.find(sub, "^"..pat)
    201                 if b then
    202                         add_token(ofs-1)
    203                         ofs = ofs+e
    204                         token_begin = ofs
    205                 else
    206                         local char = string.sub(s, ofs, ofs)
    207                         if char == "(" or char == "<" then
    208 
    209                                 local block
    210                                 if char == "(" then block = "^%b()" end
    211                                 if char == "<" then block = "^%b<>" end
    212 
    213                                 b,e = string.find(sub, block)
    214                                 if not b then
    215                                         -- unterminated block?
    216                                         ofs = ofs+1
    217                                 else
    218                                         ofs = ofs + e
    219                                 end
    220 
    221                         else
    222                                 ofs = ofs+1
    223                         end
    224                 end
    225 
    226         end
    227         add_token(ofs)
    228         --if ret.n == 0 then
    229 
    230         --      ret.n=1
    231         --      ret[1] = ""
    232         --end
    233 
    234         return ret
     180    s = string.gsub(s, "^%s*", "")
     181    s = string.gsub(s, "%s*$", "")
     182
     183    local token_begin = 1
     184    local token_end = 1
     185    local ofs = 1
     186    local ret = {n=0}
     187
     188    function add_token(ofs)
     189
     190        local t = string.sub(s, token_begin, ofs)
     191        t = string.gsub(t, "^%s*", "")
     192        t = string.gsub(t, "%s*$", "")
     193        ret.n = ret.n + 1
     194        ret[ret.n] = t
     195    end
     196
     197    while ofs <= string.len(s) do
     198
     199        local sub = string.sub(s, ofs, -1)
     200        local b,e = string.find(sub, "^"..pat)
     201        if b then
     202            add_token(ofs-1)
     203            ofs = ofs+e
     204            token_begin = ofs
     205        else
     206            local char = string.sub(s, ofs, ofs)
     207            if char == "(" or char == "<" then
     208
     209                local block
     210                if char == "(" then block = "^%b()" end
     211                if char == "<" then block = "^%b<>" end
     212
     213                b,e = string.find(sub, block)
     214                if not b then
     215                    -- unterminated block?
     216                    ofs = ofs+1
     217                else
     218                    ofs = ofs + e
     219                end
     220
     221            else
     222                ofs = ofs+1
     223            end
     224        end
     225
     226    end
     227    add_token(ofs)
     228    --if ret.n == 0 then
     229
     230    --    ret.n=1
     231    --    ret[1] = ""
     232    --end
     233
     234    return ret
    235235
    236236end
     
    238238-- concatenate strings of a table
    239239function concat (t,f,l,jstr)
    240         jstr = jstr or " "
    241  local s = ''
    242  local i=f
    243  while i<=l do
    244   s = s..t[i]
    245   i = i+1
    246   if i <= l then s = s..jstr end
    247  end
    248  return s
     240    jstr = jstr or " "
     241    local s = ''
     242    local i=f
     243    while i<=l do
     244        s = s..t[i]
     245        i = i+1
     246        if i <= l then s = s..jstr end
     247    end
     248    return s
    249249end
    250250
    251251-- concatenate all parameters, following output rules
    252252function concatparam (line, ...)
    253  local i=1
    254  while i<=arg.n do
    255   if _cont and not strfind(_cont,'[%(,"]') and
    256      strfind(arg[i],"^[%a_~]") then
    257             line = line .. ' '
    258   end
    259   line = line .. arg[i]
    260   if arg[i] ~= '' then
    261    _cont = strsub(arg[i],-1,-1)
    262   end
    263   i = i+1
    264  end
    265  if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
    266   _cont=nil line = line .. '\n'
    267  end
    268         return line
     253    local i=1
     254    while i<=arg.n do
     255        if _cont and not strfind(_cont,'[%(,"]') and
     256            strfind(arg[i],"^[%a_~]") then
     257            line = line .. ' '
     258        end
     259        line = line .. arg[i]
     260        if arg[i] ~= '' then
     261            _cont = strsub(arg[i],-1,-1)
     262        end
     263        i = i+1
     264    end
     265    if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
     266        _cont=nil line = line .. '\n'
     267    end
     268    return line
    269269end
    270270
    271271-- output line
    272272function output (...)
    273  local i=1
    274  while i<=arg.n do
    275   if _cont and not strfind(_cont,'[%(,"]') and
    276      strfind(arg[i],"^[%a_~]") then
    277             write(' ')
    278   end
    279   write(arg[i])
    280   if arg[i] ~= '' then
    281    _cont = strsub(arg[i],-1,-1)
    282   end
    283   i = i+1
    284  end
    285  if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
    286   _cont=nil write('\n')
    287  end
     273    local i=1
     274    while i<=arg.n do
     275        if _cont and not strfind(_cont,'[%(,"]') and
     276            strfind(arg[i],"^[%a_~]") then
     277            write(' ')
     278        end
     279        write(arg[i])
     280        if arg[i] ~= '' then
     281            _cont = strsub(arg[i],-1,-1)
     282        end
     283        i = i+1
     284    end
     285    if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
     286        _cont=nil write('\n')
     287    end
    288288end
    289289
    290290function get_property_methods(ptype, name)
    291291
    292         if get_property_methods_hook and get_property_methods_hook(ptype,name) then
    293                 return get_property_methods_hook(ptype, name)
    294         end
    295 
    296         if ptype == "default" then -- get_name, set_name
    297                 return "get_"..name, "set_"..name
    298         end
    299 
    300         if ptype == "qt" then -- name, setName
    301                 return name, "set"..string.upper(string.sub(name, 1, 1))..string.sub(name, 2, -1)
    302         end
    303 
    304         if ptype == "overload" then -- name, name
    305                 return name,name
    306         end
    307 
    308         return nil
     292    if get_property_methods_hook and get_property_methods_hook(ptype,name) then
     293        return get_property_methods_hook(ptype, name)
     294    end
     295
     296    if ptype == "default" then -- get_name, set_name
     297        return "get_"..name, "set_"..name
     298    end
     299
     300    if ptype == "qt" then -- name, setName
     301        return name, "set"..string.upper(string.sub(name, 1, 1))..string.sub(name, 2, -1)
     302    end
     303
     304    if ptype == "overload" then -- name, name
     305        return name,name
     306    end
     307
     308    return nil
    309309end
    310310
     
    315315-- takes the package object as the parameter
    316316function preprocess_hook(p)
    317         -- p.code has all the input code from the pkg
     317    -- p.code has all the input code from the pkg
    318318end
    319319
     
    351351function parser_hook(s)
    352352
    353         return nil
    354 end
    355 
    356 
     353    return nil
     354end
     355
     356
  • code/trunk/src/tolua/lua/class.lua

    r2087 r2710  
    1818--    {i}  = list of members
    1919classClass = {
    20  classtype = 'class',
    21  name = '',
    22  base = '',
    23  type = '',
    24  btype = '',
    25  ctype = '',
     20    classtype = 'class',
     21    name = '',
     22    base = '',
     23    type = '',
     24    btype = '',
     25    ctype = '',
    2626}
    2727classClass.__index = classClass
     
    3131-- register class
    3232function classClass:register (pre)
    33         if not self:check_public_access() then
    34                 return
    35         end
    36 
    37  pre = pre or ''
    38  push(self)
    39         if _collect[self.type] then
    40                 output(pre,'#ifdef __cplusplus\n')
    41   output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",'.._collect[self.type]..');')
    42                 output(pre,'#else\n')
    43   output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
    44                 output(pre,'#endif\n')
    45         else
    46   output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
    47         end
    48         if self.extra_bases then
    49                 for k,base in ipairs(self.extra_bases) do
    50                         -- not now
    51    --output(pre..' tolua_addbase(tolua_S, "'..self.type..'", "'..base..'");')
    52                 end
    53         end
    54  output(pre..'tolua_beginmodule(tolua_S,"'..self.lname..'");')
    55  local i=1
    56  while self[i] do
    57   self[i]:register(pre..' ')
    58   i = i+1
    59  end
    60  output(pre..'tolua_endmodule(tolua_S);')
    61         pop()
     33    if not self:check_public_access() then
     34        return
     35    end
     36
     37    pre = pre or ''
     38    push(self)
     39    if _collect[self.type] then
     40        output(pre,'#ifdef __cplusplus\n')
     41        output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",'.._collect[self.type]..');')
     42        output(pre,'#else\n')
     43        output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
     44        output(pre,'#endif\n')
     45    else
     46        output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
     47    end
     48    if self.extra_bases then
     49        for k,base in ipairs(self.extra_bases) do
     50            -- not now
     51            --output(pre..' tolua_addbase(tolua_S, "'..self.type..'", "'..base..'");')
     52        end
     53    end
     54    output(pre..'tolua_beginmodule(tolua_S,"'..self.lname..'");')
     55    local i=1
     56    while self[i] do
     57        self[i]:register(pre..' ')
     58        i = i+1
     59    end
     60    output(pre..'tolua_endmodule(tolua_S);')
     61    pop()
    6262end
    6363
    6464-- return collection requirement
    6565function classClass:requirecollection (t)
    66         if self.flags.protected_destructor then
    67                 return false
    68         end
    69  push(self)
    70         local r = false
    71  local i=1
    72  while self[i] do
    73   r = self[i]:requirecollection(t) or r
    74   i = i+1
    75  end
    76         pop()
    77         -- only class that exports destructor can be appropriately collected
    78         -- classes that export constructors need to have a collector (overrided by -D flag on command line)
    79         if self._delete or ((not flags['D']) and self._new) then
    80                 --t[self.type] = "tolua_collect_" .. gsub(self.type,"::","_")
    81                 t[self.type] = "tolua_collect_" .. clean_template(self.type)
    82                 r = true
    83         end
    84  return r
     66    if self.flags.protected_destructor then
     67        return false
     68    end
     69    push(self)
     70    local r = false
     71    local i=1
     72    while self[i] do
     73        r = self[i]:requirecollection(t) or r
     74        i = i+1
     75    end
     76    pop()
     77    -- only class that exports destructor can be appropriately collected
     78    -- classes that export constructors need to have a collector (overrided by -D flag on command line)
     79    if self._delete or ((not flags['D']) and self._new) then
     80        --t[self.type] = "tolua_collect_" .. gsub(self.type,"::","_")
     81        t[self.type] = "tolua_collect_" .. clean_template(self.type)
     82        r = true
     83    end
     84    return r
    8585end
    8686
    8787-- output tags
    8888function classClass:decltype ()
    89  push(self)
    90         self.type = regtype(self.original_name or self.name)
    91         self.btype = typevar(self.base)
    92         self.ctype = 'const '..self.type
    93         if self.extra_bases then
    94                 for i=1,table.getn(self.extra_bases) do
    95                         self.extra_bases[i] = typevar(self.extra_bases[i])
    96                 end
    97         end
    98  local i=1
    99  while self[i] do
    100   self[i]:decltype()
    101   i = i+1
    102  end
    103         pop()
     89    push(self)
     90    self.type = regtype(self.original_name or self.name)
     91    self.btype = typevar(self.base)
     92    self.ctype = 'const '..self.type
     93    if self.extra_bases then
     94        for i=1,table.getn(self.extra_bases) do
     95            self.extra_bases[i] = typevar(self.extra_bases[i])
     96        end
     97    end
     98    local i=1
     99    while self[i] do
     100        self[i]:decltype()
     101        i = i+1
     102    end
     103    pop()
    104104end
    105105
     
    107107-- Print method
    108108function classClass:print (ident,close)
    109  print(ident.."Class{")
    110  print(ident.." name = '"..self.name.."',")
    111  print(ident.." base = '"..self.base.."';")
    112  print(ident.." lname = '"..self.lname.."',")
    113  print(ident.." type = '"..self.type.."',")
    114  print(ident.." btype = '"..self.btype.."',")
    115  print(ident.." ctype = '"..self.ctype.."',")
    116  local i=1
    117  while self[i] do
    118   self[i]:print(ident.." ",",")
    119   i = i+1
    120  end
    121  print(ident.."}"..close)
     109    print(ident.."Class{")
     110    print(ident.." name = '"..self.name.."',")
     111    print(ident.." base = '"..self.base.."';")
     112    print(ident.." lname = '"..self.lname.."',")
     113    print(ident.." type = '"..self.type.."',")
     114    print(ident.." btype = '"..self.btype.."',")
     115    print(ident.." ctype = '"..self.ctype.."',")
     116    local i=1
     117    while self[i] do
     118        self[i]:print(ident.." ",",")
     119        i = i+1
     120    end
     121    print(ident.."}"..close)
    122122end
    123123
    124124function classClass:set_protected_destructor(p)
    125         self.flags.protected_destructor = self.flags.protected_destructor or p
     125self.flags.protected_destructor = self.flags.protected_destructor or p
    126126end
    127127
    128128-- Internal constructor
    129129function _Class (t)
    130  setmetatable(t,classClass)
    131  t:buildnames()
    132  append(t)
    133  return t
     130    setmetatable(t,classClass)
     131    t:buildnames()
     132    append(t)
     133    return t
    134134end
    135135
     
    138138function Class (n,p,b)
    139139
    140         if table.getn(p) > 1 then
    141                 b = string.sub(b, 1, -2)
    142                 for i=2,table.getn(p),1 do
    143                         b = b.."\n tolua_inherits "..p[i].." __"..p[i].."__;\n"
    144                 end
    145                 b = b.."\n}"
    146         end
    147 
    148         -- check for template
    149         b = string.gsub(b, "^{%s*TEMPLATE_BIND", "{\nTOLUA_TEMPLATE_BIND")
    150         local t,_,T,I = string.find(b, "^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+")
    151         if t then
    152 
    153                 -- remove quotes
    154                 I = string.gsub(I, "\"", "")
    155                 T = string.gsub(T, "\"", "")
    156                 -- get type list
    157                 local types = split_c_tokens(I, ",")
    158                 -- remove TEMPLATE_BIND line
    159                 local bs = string.gsub(b, "^{%s*TOLUA_TEMPLATE_BIND[^\n]*\n", "{\n")
    160 
    161                 -- replace
    162                 for i =1 , types.n do
    163 
    164                         local Tl = split(T, " ")
    165                         local Il = split_c_tokens(types[i], " ")
    166                         local bI = bs
    167                         local pI = {}
    168                         for j = 1,Tl.n do
    169                                 Tl[j] = findtype(Tl[j]) or Tl[j]
    170                                 bI = string.gsub(bI, "([^_%w])"..Tl[j].."([^_%w])", "%1"..Il[j].."%2")
    171                                 if p then
    172                                         for i=1,table.getn(p) do
    173                                                 pI[i] = string.gsub(p[i], "([^_%w]?)"..Tl[j].."([^_%w]?)", "%1"..Il[j].."%2")
    174                                         end
    175                                 end
    176                         end
    177                         --local append = "<"..string.gsub(types[i], "%s+", ",")..">"
    178                         local append = "<"..concat(Il, 1, table.getn(Il), ",")..">"
    179                         append = string.gsub(append, "%s*,%s*", ",")
    180                         append = string.gsub(append, ">>", "> >")
    181                         for i=1,table.getn(pI) do
    182                                 --pI[i] = string.gsub(pI[i], ">>", "> >")
    183                                 pI[i] = resolve_template_types(pI[i])
    184                         end
    185                         bI = string.gsub(bI, ">>", "> >")
    186                         Class(n..append, pI, bI)
    187                 end
    188                 return
    189         end
    190 
    191         local mbase
    192 
    193         if p then
    194                 mbase = table.remove(p, 1)
    195                 if not p[1] then p = nil end
    196         end
    197 
    198         mbase = mbase and resolve_template_types(mbase)
    199 
    200         local c
    201         local oname = string.gsub(n, "@.*$", "")
    202         oname = getnamespace(classContainer.curr)..oname
    203 
    204         if _global_classes[oname] then
    205                 c = _global_classes[oname]
    206                 if mbase and ((not c.base) or c.base == "") then
    207                         c.base = mbase
    208                 end
    209         else
    210                 c = _Class(_Container{name=n, base=mbase, extra_bases=p})
    211 
    212                 local ft = getnamespace(c.parent)..c.original_name
    213                 append_global_type(ft, c)
    214         end
    215 
    216         push(c)
    217         c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
    218         pop()
    219 end
    220 
     140    if table.getn(p) > 1 then
     141        b = string.sub(b, 1, -2)
     142        for i=2,table.getn(p),1 do
     143            b = b.."\n tolua_inherits "..p[i].." __"..p[i].."__;\n"
     144        end
     145        b = b.."\n}"
     146    end
     147
     148    -- check for template
     149    b = string.gsub(b, "^{%s*TEMPLATE_BIND", "{\nTOLUA_TEMPLATE_BIND")
     150    local t,_,T,I = string.find(b, "^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+")
     151    if t then
     152
     153        -- remove quotes
     154        I = string.gsub(I, "\"", "")
     155        T = string.gsub(T, "\"", "")
     156        -- get type list
     157        local types = split_c_tokens(I, ",")
     158        -- remove TEMPLATE_BIND line
     159        local bs = string.gsub(b, "^{%s*TOLUA_TEMPLATE_BIND[^\n]*\n", "{\n")
     160
     161        -- replace
     162        for i =1 , types.n do
     163
     164            local Tl = split(T, " ")
     165            local Il = split_c_tokens(types[i], " ")
     166            local bI = bs
     167            local pI = {}
     168            for j = 1,Tl.n do
     169                Tl[j] = findtype(Tl[j]) or Tl[j]
     170                bI = string.gsub(bI, "([^_%w])"..Tl[j].."([^_%w])", "%1"..Il[j].."%2")
     171                if p then
     172                    for i=1,table.getn(p) do
     173                        pI[i] = string.gsub(p[i], "([^_%w]?)"..Tl[j].."([^_%w]?)", "%1"..Il[j].."%2")
     174                    end
     175                end
     176            end
     177            --local append = "<"..string.gsub(types[i], "%s+", ",")..">"
     178            local append = "<"..concat(Il, 1, table.getn(Il), ",")..">"
     179            append = string.gsub(append, "%s*,%s*", ",")
     180            append = string.gsub(append, ">>", "> >")
     181            for i=1,table.getn(pI) do
     182                --pI[i] = string.gsub(pI[i], ">>", "> >")
     183                pI[i] = resolve_template_types(pI[i])
     184            end
     185            bI = string.gsub(bI, ">>", "> >")
     186            Class(n..append, pI, bI)
     187        end
     188        return
     189    end
     190
     191    local mbase
     192
     193    if p then
     194        mbase = table.remove(p, 1)
     195        if not p[1] then p = nil end
     196    end
     197
     198    mbase = mbase and resolve_template_types(mbase)
     199
     200    local c
     201    local oname = string.gsub(n, "@.*$", "")
     202    oname = getnamespace(classContainer.curr)..oname
     203
     204    if _global_classes[oname] then
     205        c = _global_classes[oname]
     206        if mbase and ((not c.base) or c.base == "") then
     207            c.base = mbase
     208        end
     209    else
     210        c = _Class(_Container{name=n, base=mbase, extra_bases=p})
     211
     212        local ft = getnamespace(c.parent)..c.original_name
     213        append_global_type(ft, c)
     214    end
     215
     216    push(c)
     217    c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
     218    pop()
     219end
     220
  • code/trunk/src/tolua/lua/clean.lua

    r2087 r2710  
    1010
    1111MASK = { -- the substitution order is important
    12  {ESC1, "\\'"},
    13  {ESC2, '\\"'},
    14  {STR1, "'"},
    15  {STR2, '"'},
    16  {STR3, "%[%["},
    17  {STR4, "%]%]"},
    18  {REM , "%-%-"},
     12    {ESC1, "\\'"},
     13    {ESC2, '\\"'},
     14    {STR1, "'"},
     15    {STR2, '"'},
     16    {STR3, "%[%["},
     17    {STR4, "%]%]"},
     18    {REM , "%-%-"},
    1919}
    2020
    2121function mask (s)
    22  for i = 1,getn(MASK)  do
    23   s = gsub(s,MASK[i][2],MASK[i][1])
    24  end
    25  return s
     22    for i = 1,getn(MASK)  do
     23        s = gsub(s,MASK[i][2],MASK[i][1])
     24    end
     25    return s
    2626end
    2727
    2828function unmask (s)
    29  for i = 1,getn(MASK)  do
    30   s = gsub(s,MASK[i][1],MASK[i][2])
    31  end
    32  return s
     29    for i = 1,getn(MASK)  do
     30        s = gsub(s,MASK[i][1],MASK[i][2])
     31    end
     32    return s
    3333end
    3434
    3535function clean (s)
    36  -- check for compilation error
    37  local code = "return function ()\n" .. s .. "\n end"
    38  if not dostring(code) then
    39   return nil
    40  end
     36    -- check for compilation error
     37    local code = "return function ()\n" .. s .. "\n end"
     38    if not dostring(code) then
     39        return nil
     40    end
    4141
    42  if flags['C'] then
    43         return s
    44  end
     42    if flags['C'] then
     43        return s
     44    end
    4545
    46  local S = "" -- saved string
     46    local S = "" -- saved string
    4747
    48  s = mask(s)
     48    s = mask(s)
    4949
    50  -- remove blanks and comments
    51  while 1 do
    52   local b,e,d = strfind(s,ANY)
    53   if b then
    54    S = S..strsub(s,1,b-1)
    55    s = strsub(s,b+1)
    56    if d==STR1 or d==STR2 then
    57     e = strfind(s,d)
    58     S = S ..d..strsub(s,1,e)
    59     s = strsub(s,e+1)
    60    elseif d==STR3 then
    61     e = strfind(s,STR4)
    62     S = S..d..strsub(s,1,e)
    63     s = strsub(s,e+1)
    64    elseif d==REM then
    65     s = gsub(s,"[^\n]*(\n?)","%1",1)
    66    end
    67   else
    68    S = S..s
    69    break
    70   end
    71  end
    72  -- eliminate unecessary spaces
    73  S = gsub(S,"[ \t]+"," ")
    74  S = gsub(S,"[ \t]*\n[ \t]*","\n")
    75         S = gsub(S,"\n+","\n")
    76  S = unmask(S)
    77  return S
     50    -- remove blanks and comments
     51    while 1 do
     52        local b,e,d = strfind(s,ANY)
     53        if b then
     54            S = S..strsub(s,1,b-1)
     55            s = strsub(s,b+1)
     56            if d==STR1 or d==STR2 then
     57                e = strfind(s,d)
     58                S = S ..d..strsub(s,1,e)
     59                s = strsub(s,e+1)
     60            elseif d==STR3 then
     61                e = strfind(s,STR4)
     62                S = S..d..strsub(s,1,e)
     63                s = strsub(s,e+1)
     64            elseif d==REM then
     65                s = gsub(s,"[^\n]*(\n?)","%1",1)
     66            end
     67        else
     68            S = S..s
     69            break
     70        end
     71    end
     72    -- eliminate unecessary spaces
     73    S = gsub(S,"[ \t]+"," ")
     74    S = gsub(S,"[ \t]*\n[ \t]*","\n")
     75    S = gsub(S,"\n+","\n")
     76    S = unmask(S)
     77    return S
    7878end
    7979
  • code/trunk/src/tolua/lua/code.lua

    r2087 r2710  
    1919--   text = text code
    2020classCode = {
    21  text = '',
     21    text = '',
    2222}
    2323classCode.__index = classCode
     
    2626-- register code
    2727function classCode:register (pre)
    28  pre = pre or ''
    29  -- clean Lua code
    30  local s = clean(self.text)
    31  if not s then
    32   --print(self.text)
    33   error("parser error in embedded code")
    34  end
     28    pre = pre or ''
     29    -- clean Lua code
     30    local s = clean(self.text)
     31    if not s then
     32        --print(self.text)
     33        error("parser error in embedded code")
     34    end
    3535
    36  -- get first line
    37  local _, _, first_line=string.find(self.text, "^([^\n\r]*)")
    38  if string.find(first_line, "^%s*%-%-") then
    39         if string.find(first_line, "^%-%-##") then
    40                 first_line = string.gsub(first_line, "^%-%-##", "")
    41                 if flags['C'] then
    42                         s = string.gsub(s, "^%-%-##[^\n\r]*\n", "")
    43                 end
    44         end
    45  else
    46         first_line = ""
    47  end
     36    -- get first line
     37    local _, _, first_line=string.find(self.text, "^([^\n\r]*)")
     38    if string.find(first_line, "^%s*%-%-") then
     39        if string.find(first_line, "^%-%-##") then
     40            first_line = string.gsub(first_line, "^%-%-##", "")
     41            if flags['C'] then
     42                s = string.gsub(s, "^%-%-##[^\n\r]*\n", "")
     43            end
     44        end
     45    else
     46        first_line = ""
     47    end
    4848
    49  -- convert to C
    50  output('\n'..pre..'{ /* begin embedded lua code */\n')
    51  output(pre..' int top = lua_gettop(tolua_S);')
    52  output(pre..' static unsigned char B[] = {\n   ')
    53  local t={n=0}
    54  local b = gsub(s,'(.)',function (c)
    55                          local e = ''
    56                          t.n=t.n+1 if t.n==15 then t.n=0 e='\n'..pre..'  ' end
    57                          return format('%3u,%s',strbyte(c),e)
    58                         end
    59                )
    60  output(b..strbyte(" "))
    61  output('\n'..pre..' };\n')
    62  if first_line and first_line ~= "" then
    63         output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: '..first_line..'");')
    64  else
    65         output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code '..code_n..'");')
    66  end
    67  output(pre..' lua_settop(tolua_S, top);')
    68  output(pre..'} /* end of embedded lua code */\n\n')
    69  code_n = code_n +1
     49    -- convert to C
     50    output('\n'..pre..'{ /* begin embedded lua code */\n')
     51    output(pre..' int top = lua_gettop(tolua_S);')
     52    output(pre..' static unsigned char B[] = {\n   ')
     53    local t={n=0}
     54    local b = gsub(s, '(.)',
     55        function (c)
     56            local e = ''
     57            t.n=t.n+1
     58            if t.n==15 then
     59             t.n=0 e='\n'..pre..'  '
     60            end
     61            return format('%3u,%s',strbyte(c),e)
     62        end
     63    )
     64    output(b..strbyte(" "))
     65    output('\n'..pre..' };\n')
     66    if first_line and first_line ~= "" then
     67        output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: '..first_line..'");')
     68    else
     69        output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code '..code_n..'");')
     70    end
     71    output(pre..' lua_settop(tolua_S, top);')
     72    output(pre..'} /* end of embedded lua code */\n\n')
     73    code_n = code_n +1
    7074end
    7175
     
    7377-- Print method
    7478function classCode:print (ident,close)
    75  print(ident.."Code{")
    76  print(ident.." text = [["..self.text.."]],")
    77  print(ident.."}"..close)
     79    print(ident.."Code{")
     80    print(ident.." text = [["..self.text.."]],")
     81    print(ident.."}"..close)
    7882end
    7983
     
    8185-- Internal constructor
    8286function _Code (t)
    83  setmetatable(t,classCode)
    84  append(t)
    85  return t
     87    setmetatable(t,classCode)
     88    append(t)
     89    return t
    8690end
    8791
     
    8993-- Expects a string representing the code text
    9094function Code (l)
    91  return _Code {
    92   text = l
    93  }
     95    return _Code {
     96        text = l
     97    }
    9498end
    9599
  • code/trunk/src/tolua/lua/compat-5.1.lua

    r2087 r2710  
    11if string.find(_VERSION, "5%.0") then
    2         return
     2    return
    33end
    44
    55-- "loadfile"
    66local function pp_dofile(path)
     7    local loaded = false
     8    local getfile = function()
    79
    8         local loaded = false
    9         local getfile = function()
     10        if loaded then
     11            return
     12        else
     13            local file,err = io.open(path)
     14            if not file then
     15                error("error loading file "..path..": "..err)
     16            end
     17            local ret = file:read("*a")
     18            file:close()
    1019
    11                 if loaded then
    12                         return
    13                 else
    14                         local file,err = io.open(path)
    15                         if not file then
    16                                 error("error loading file "..path..": "..err)
    17                         end
    18                         local ret = file:read("*a")
    19                         file:close()
     20            ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};")
    2021
    21                         ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};")
     22            loaded = true
     23            return ret
     24        end
     25    end
    2226
    23                         loaded = true
    24                         return ret
    25                 end
    26         end
    27 
    28         local f = load(getfile, path)
    29         return f()
     27    local f = load(getfile, path)
     28    return f()
    3029end
    3130
     
    3837local ogsub = string.gsub
    3938local function compgsub(a,b,c,d)
    40   if type(c) == "function" then
    41     local oc = c
    42     c = function (...) return oc(...) or '' end
    43   end
    44   return ogsub(a,b,c,d)
     39    if type(c) == "function" then
     40        local oc = c
     41        c = function (...) return oc(...) or '' end
     42    end
     43    return ogsub(a,b,c,d)
    4544end
    4645string.repl = ogsub
  • code/trunk/src/tolua/lua/compat.lua

    r2087 r2710  
    3434
    3535function do_ (f, err)
    36   if not f then print(err); return end
    37   local a,b = pcall(f)
    38   if not a then print(b); return nil
    39   else return b or true
    40   end
     36    if not f then print(err); return end
     37    local a,b = pcall(f)
     38    if not a then print(b); return nil
     39    else return b or true
     40    end
    4141end
    4242
     
    141141
    142142function flush (f)
    143   if f then f:flush()
    144   else _OUTPUT:flush()
    145   end
     143    if f then f:flush()
     144    else _OUTPUT:flush()
     145    end
    146146end
    147147
    148148function readfrom (name)
    149   if name == nil then
    150     local f, err, cod = io.close(_INPUT)
    151     _INPUT = io.stdin
    152     return f, err, cod
    153   else
    154     local f, err, cod = io.open(name, "r")
    155     _INPUT = f or _INPUT
    156     return f, err, cod
    157   end
     149    if name == nil then
     150        local f, err, cod = io.close(_INPUT)
     151        _INPUT = io.stdin
     152        return f, err, cod
     153    else
     154        local f, err, cod = io.open(name, "r")
     155        _INPUT = f or _INPUT
     156        return f, err, cod
     157    end
    158158end
    159159
    160160function writeto (name)
    161   if name == nil then
    162     local f, err, cod = io.close(_OUTPUT)
    163     _OUTPUT = io.stdout
    164     return f, err, cod
    165   else
    166     local f, err, cod = io.open(name, "w")
    167     _OUTPUT = f or _OUTPUT
    168     return f, err, cod
    169   end
     161    if name == nil then
     162        local f, err, cod = io.close(_OUTPUT)
     163        _OUTPUT = io.stdout
     164        return f, err, cod
     165    else
     166        local f, err, cod = io.open(name, "w")
     167        _OUTPUT = f or _OUTPUT
     168        return f, err, cod
     169    end
    170170end
    171171
    172172function appendto (name)
    173   local f, err, cod = io.open(name, "a")
    174   _OUTPUT = f or _OUTPUT
    175   return f, err, cod
     173    local f, err, cod = io.open(name, "a")
     174    _OUTPUT = f or _OUTPUT
     175    return f, err, cod
    176176end
    177177
    178178function read (...)
    179   local f = _INPUT
    180   if rawtype(arg[1]) == 'userdata' then
    181     f = tab.remove(arg, 1)
    182   end
    183   return f:read(unpack(arg))
     179    local f = _INPUT
     180    if rawtype(arg[1]) == 'userdata' then
     181        f = tab.remove(arg, 1)
     182    end
     183    return f:read(unpack(arg))
    184184end
    185185
    186186function write (...)
    187   local f = _OUTPUT
    188   if rawtype(arg[1]) == 'userdata' then
    189     f = tab.remove(arg, 1)
    190   end
    191   return f:write(unpack(arg))
     187    local f = _OUTPUT
     188    if rawtype(arg[1]) == 'userdata' then
     189        f = tab.remove(arg, 1)
     190    end
     191    return f:write(unpack(arg))
    192192end
    193193
  • code/trunk/src/tolua/lua/container.lua

    r2087 r2710  
    1919classContainer =
    2020{
    21  curr = nil,
     21    curr = nil,
    2222}
    2323classContainer.__index = classContainer
     
    2626-- output tags
    2727function classContainer:decltype ()
    28  push(self)
    29  local i=1
    30  while self[i] do
    31   self[i]:decltype()
    32   i = i+1
    33  end
    34  pop()
     28    push(self)
     29    local i=1
     30    while self[i] do
     31        self[i]:decltype()
     32        i = i+1
     33    end
     34    pop()
    3535end
    3636
     
    3939function classContainer:supcode ()
    4040
    41         if not self:check_public_access() then
    42                 return
    43         end
    44 
    45  push(self)
    46  local i=1
    47  while self[i] do
    48   if self[i]:check_public_access() then
    49         self[i]:supcode()
    50   end
    51   i = i+1
    52  end
    53  pop()
     41    if not self:check_public_access() then
     42        return
     43    end
     44
     45    push(self)
     46    local i=1
     47    while self[i] do
     48        if self[i]:check_public_access() then
     49            self[i]:supcode()
     50        end
     51        i = i+1
     52    end
     53    pop()
    5454end
    5555
    5656function classContainer:hasvar ()
    57  local i=1
    58  while self[i] do
    59   if self[i]:isvariable() then
    60                 return 1
    61                 end
    62   i = i+1
    63  end
    64         return 0
     57    local i=1
     58    while self[i] do
     59        if self[i]:isvariable() then
     60            return 1
     61        end
     62        i = i+1
     63    end
     64    return 0
    6565end
    6666
    6767-- Internal container constructor
    6868function _Container (self)
    69  setmetatable(self,classContainer)
    70  self.n = 0
    71  self.typedefs = {tolua_n=0}
    72  self.usertypes = {}
    73  self.enums = {tolua_n=0}
    74  self.lnames = {}
    75  return self
     69    setmetatable(self,classContainer)
     70    self.n = 0
     71    self.typedefs = {tolua_n=0}
     72    self.usertypes = {}
     73    self.enums = {tolua_n=0}
     74    self.lnames = {}
     75    return self
    7676end
    7777
    7878-- push container
    7979function push (t)
    80         t.prox = classContainer.curr
    81  classContainer.curr = t
     80    t.prox = classContainer.curr
     81    classContainer.curr = t
    8282end
    8383
    8484-- pop container
    8585function pop ()
    86 --print("name",classContainer.curr.name)
    87 --foreach(classContainer.curr.usertypes,print)
    88 --print("______________")
    89  classContainer.curr = classContainer.curr.prox
     86    --print("name",classContainer.curr.name)
     87    --foreach(classContainer.curr.usertypes,print)
     88    --print("______________")
     89    classContainer.curr = classContainer.curr.prox
    9090end
    9191
    9292-- get current namespace
    9393function getcurrnamespace ()
    94         return getnamespace(classContainer.curr)
     94    return getnamespace(classContainer.curr)
    9595end
    9696
    9797-- append to current container
    9898function append (t)
    99  return classContainer.curr:append(t)
     99    return classContainer.curr:append(t)
    100100end
    101101
    102102-- append typedef to current container
    103103function appendtypedef (t)
    104  return classContainer.curr:appendtypedef(t)
     104    return classContainer.curr:appendtypedef(t)
    105105end
    106106
    107107-- append usertype to current container
    108108function appendusertype (t)
    109  return classContainer.curr:appendusertype(t)
     109    return classContainer.curr:appendusertype(t)
    110110end
    111111
    112112-- append enum to current container
    113113function appendenum (t)
    114  return classContainer.curr:appendenum(t)
     114    return classContainer.curr:appendenum(t)
    115115end
    116116
    117117-- substitute typedef
    118118function applytypedef (mod,type)
    119  return classContainer.curr:applytypedef(mod,type)
     119    return classContainer.curr:applytypedef(mod,type)
    120120end
    121121
    122122-- check if is type
    123123function findtype (type)
    124  local t = classContainer.curr:findtype(type)
    125         return t
     124    local t = classContainer.curr:findtype(type)
     125    return t
    126126end
    127127
    128128-- check if is typedef
    129129function istypedef (type)
    130  return classContainer.curr:istypedef(type)
     130    return classContainer.curr:istypedef(type)
    131131end
    132132
    133133-- get fulltype (with namespace)
    134134function fulltype (t)
    135  local curr =  classContainer.curr
    136         while curr do
    137         if curr then
    138                 if curr.typedefs and curr.typedefs[t] then
    139                   return curr.typedefs[t]
    140                 elseif curr.usertypes and curr.usertypes[t] then
    141                   return curr.usertypes[t]
    142                         end
    143                 end
    144         curr = curr.prox
    145         end
    146         return t
     135    local curr =  classContainer.curr
     136    while curr do
     137        if curr then
     138            if curr.typedefs and curr.typedefs[t] then
     139                return curr.typedefs[t]
     140            elseif curr.usertypes and curr.usertypes[t] then
     141                return curr.usertypes[t]
     142            end
     143        end
     144        curr = curr.prox
     145    end
     146    return t
    147147end
    148148
    149149-- checks if it requires collection
    150150function classContainer:requirecollection (t)
    151  push(self)
    152  local i=1
    153         local r = false
    154  while self[i] do
    155   r = self[i]:requirecollection(t) or r
    156   i = i+1
    157  end
    158         pop()
    159         return r
     151    push(self)
     152    local i=1
     153    local r = false
     154    while self[i] do
     155        r = self[i]:requirecollection(t) or r
     156        i = i+1
     157    end
     158    pop()
     159    return r
    160160end
    161161
     
    163163-- get namesapce
    164164function getnamespace (curr)
    165         local namespace = ''
    166         while curr do
    167         if curr and
    168                    ( curr.classtype == 'class' or curr.classtype == 'namespace')
    169                 then
    170                 namespace = (curr.original_name or curr.name) .. '::' .. namespace
    171                 --namespace = curr.name .. '::' .. namespace
    172                 end
    173         curr = curr.prox
    174         end
    175         return namespace
     165    local namespace = ''
     166    while curr do
     167        if curr and
     168            ( curr.classtype == 'class' or curr.classtype == 'namespace')
     169        then
     170            namespace = (curr.original_name or curr.name) .. '::' .. namespace
     171            --namespace = curr.name .. '::' .. namespace
     172        end
     173        curr = curr.prox
     174    end
     175    return namespace
    176176end
    177177
    178178-- get namespace (only namespace)
    179179function getonlynamespace ()
    180  local curr = classContainer.curr
    181         local namespace = ''
    182         while curr do
    183                 if curr.classtype == 'class' then
    184                 return namespace
    185                 elseif curr.classtype == 'namespace' then
    186                 namespace = curr.name .. '::' .. namespace
    187                 end
    188         curr = curr.prox
    189         end
    190         return namespace
     180    local curr = classContainer.curr
     181    local namespace = ''
     182    while curr do
     183        if curr.classtype == 'class' then
     184            return namespace
     185        elseif curr.classtype == 'namespace' then
     186            namespace = curr.name .. '::' .. namespace
     187        end
     188        curr = curr.prox
     189    end
     190    return namespace
    191191end
    192192
    193193-- check if is enum
    194194function isenum (type)
    195  return classContainer.curr:isenum(type)
     195    return classContainer.curr:isenum(type)
    196196end
    197197
    198198-- append feature to container
    199199function classContainer:append (t)
    200  self.n = self.n + 1
    201  self[self.n] = t
    202  t.parent = self
     200    self.n = self.n + 1
     201    self[self.n] = t
     202    t.parent = self
    203203end
    204204
    205205-- append typedef
    206206function classContainer:appendtypedef (t)
    207  local namespace = getnamespace(classContainer.curr)
    208  self.typedefs.tolua_n = self.typedefs.tolua_n + 1
    209  self.typedefs[self.typedefs.tolua_n] = t
    210         self.typedefs[t.utype] = namespace .. t.utype
    211         global_typedefs[namespace..t.utype] = t
    212         t.ftype = findtype(t.type) or t.type
    213         --print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype)
    214         append_global_type(namespace..t.utype)
    215         if t.ftype and isenum(t.ftype) then
    216 
    217                 global_enums[namespace..t.utype] = true
    218         end
     207    local namespace = getnamespace(classContainer.curr)
     208    self.typedefs.tolua_n = self.typedefs.tolua_n + 1
     209    self.typedefs[self.typedefs.tolua_n] = t
     210    self.typedefs[t.utype] = namespace .. t.utype
     211    global_typedefs[namespace..t.utype] = t
     212    t.ftype = findtype(t.type) or t.type
     213    --print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype)
     214    append_global_type(namespace..t.utype)
     215    if t.ftype and isenum(t.ftype) then
     216        global_enums[namespace..t.utype] = true
     217    end
    219218end
    220219
    221220-- append usertype: return full type
    222221function classContainer:appendusertype (t)
    223         local container
    224         if t == (self.original_name or self.name) then
    225                 container = self.prox
    226         else
    227                 container = self
    228         end
    229         local ft = getnamespace(container) .. t
    230         container.usertypes[t] = ft
    231         _usertype[ft] = ft
    232         return ft
     222    local container
     223    if t == (self.original_name or self.name) then
     224        container = self.prox
     225    else
     226        container = self
     227    end
     228    local ft = getnamespace(container) .. t
     229    container.usertypes[t] = ft
     230    _usertype[ft] = ft
     231    return ft
    233232end
    234233
    235234-- append enum
    236235function classContainer:appendenum (t)
    237  local namespace = getnamespace(classContainer.curr)
    238  self.enums.tolua_n = self.enums.tolua_n + 1
    239  self.enums[self.enums.tolua_n] = t
    240         global_enums[namespace..t.name] = t
     236    local namespace = getnamespace(classContainer.curr)
     237    self.enums.tolua_n = self.enums.tolua_n + 1
     238    self.enums[self.enums.tolua_n] = t
     239    global_enums[namespace..t.name] = t
    241240end
    242241
    243242-- determine lua function name overload
    244243function classContainer:overload (lname)
    245  if not self.lnames[lname] then
    246   self.lnames[lname] = 0
    247  else
    248   self.lnames[lname] = self.lnames[lname] + 1
    249  end
    250  return format("%02d",self.lnames[lname])
     244    if not self.lnames[lname] then
     245        self.lnames[lname] = 0
     246    else
     247        self.lnames[lname] = self.lnames[lname] + 1
     248    end
     249    return format("%02d",self.lnames[lname])
    251250end
    252251
    253252-- applies typedef: returns the 'the facto' modifier and type
    254253function classContainer:applytypedef (mod,type)
    255         if global_typedefs[type] then
    256                 --print("found typedef "..global_typedefs[type].type)
    257                 local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
    258                 local mod2, type2 = applytypedef(mod.." "..mod1, type1)
    259                 --return mod2 .. ' ' .. mod1, type2
    260                 return mod2, type2
    261         end
    262         do return mod,type end
     254    if global_typedefs[type] then
     255        --print("found typedef "..global_typedefs[type].type)
     256        local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
     257        local mod2, type2 = applytypedef(mod.." "..mod1, type1)
     258        --return mod2 .. ' ' .. mod1, type2
     259        return mod2, type2
     260    end
     261    do return mod,type end
    263262end
    264263
    265264-- check if it is a typedef
    266265function classContainer:istypedef (type)
    267  local env = self
    268  while env do
    269   if env.typedefs then
    270    local i=1
    271    while env.typedefs[i] do
    272     if env.typedefs[i].utype == type then
    273          return type
    274         end
    275         i = i+1
    276    end
    277   end
    278   env = env.parent
    279  end
    280  return nil
     266    local env = self
     267    while env do
     268        if env.typedefs then
     269            local i=1
     270            while env.typedefs[i] do
     271                if env.typedefs[i].utype == type then
     272                    return type
     273                end
     274                i = i+1
     275            end
     276        end
     277        env = env.parent
     278    end
     279    return nil
    281280end
    282281
    283282function find_enum_var(var)
    284283
    285         if tonumber(var) then return var end
    286 
    287         local c = classContainer.curr
    288         while c do
    289                 local ns = getnamespace(c)
    290                 for k,v in pairs(_global_enums) do
    291                         if match_type(var, v, ns) then
    292                                 return v
    293                         end
    294                 end
    295                 if c.base and c.base ~= '' then
    296                         c = _global_classes[c:findtype(c.base)]
    297                 else
    298                         c = nil
    299                 end
    300         end
    301 
    302         return var
     284    if tonumber(var) then return var end
     285
     286    local c = classContainer.curr
     287    while c do
     288        local ns = getnamespace(c)
     289        for k,v in pairs(_global_enums) do
     290            if match_type(var, v, ns) then
     291                return v
     292            end
     293        end
     294        if c.base and c.base ~= '' then
     295            c = _global_classes[c:findtype(c.base)]
     296        else
     297            c = nil
     298        end
     299    end
     300
     301    return var
    303302end
    304303
     
    306305function classContainer:findtype (t)
    307306
    308         t = string.gsub(t, "=.*", "")
    309         if _basic[t] then
    310         return t
    311         end
    312 
    313         local _,_,em = string.find(t, "([&%*])%s*$")
    314         t = string.gsub(t, "%s*([&%*])%s*$", "")
    315         p = self
    316         while p and type(p)=='table' do
    317                 local st = getnamespace(p)
    318 
    319                 for i=_global_types.n,1,-1 do -- in reverse order
    320 
    321                         if match_type(t, _global_types[i], st) then
    322                                 return _global_types[i]..(em or "")
    323                         end
    324                 end
    325                 if p.base and p.base ~= '' and p.base ~= t then
    326                         --print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
    327                         p = _global_classes[p:findtype(p.base)]
    328                 else
    329                         p = nil
    330                 end
    331         end
    332 
    333         return nil
     307    t = string.gsub(t, "=.*", "")
     308    if _basic[t] then
     309    return t
     310    end
     311
     312    local _,_,em = string.find(t, "([&%*])%s*$")
     313    t = string.gsub(t, "%s*([&%*])%s*$", "")
     314    p = self
     315    while p and type(p)=='table' do
     316        local st = getnamespace(p)
     317
     318        for i=_global_types.n,1,-1 do -- in reverse order
     319
     320            if match_type(t, _global_types[i], st) then
     321                return _global_types[i]..(em or "")
     322            end
     323        end
     324        if p.base and p.base ~= '' and p.base ~= t then
     325            --print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
     326            p = _global_classes[p:findtype(p.base)]
     327        else
     328            p = nil
     329        end
     330    end
     331
     332    return nil
    334333end
    335334
    336335function append_global_type(t, class)
    337         _global_types.n = _global_types.n +1
    338         _global_types[_global_types.n] = t
    339         _global_types_hash[t] = 1
    340         if class then append_class_type(t, class) end
     336    _global_types.n = _global_types.n +1
     337    _global_types[_global_types.n] = t
     338    _global_types_hash[t] = 1
     339    if class then append_class_type(t, class) end
    341340end
    342341
    343342function append_class_type(t,class)
    344         if _global_classes[t] then
    345                 class.flags = _global_classes[t].flags
    346                 class.lnames = _global_classes[t].lnames
    347                 if _global_classes[t].base and (_global_classes[t].base ~= '') then
    348                         class.base = _global_classes[t].base or class.base
    349                 end
    350         end
    351         _global_classes[t] = class
    352         class.flags = class.flags or {}
     343    if _global_classes[t] then
     344        class.flags = _global_classes[t].flags
     345        class.lnames = _global_classes[t].lnames
     346        if _global_classes[t].base and (_global_classes[t].base ~= '') then
     347            class.base = _global_classes[t].base or class.base
     348        end
     349    end
     350    _global_classes[t] = class
     351    class.flags = class.flags or {}
    353352end
    354353
    355354function match_type(childtype, regtype, st)
    356355--print("findtype "..childtype..", "..regtype..", "..st)
    357         local b,e = string.find(regtype, childtype, -string.len(childtype), true)
    358         if b then
    359 
    360                 if e == string.len(regtype) and
    361                                 (b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
    362                                 string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
    363                         return true
    364                 end
    365         end
    366 
    367         return false
     356    local b,e = string.find(regtype, childtype, -string.len(childtype), true)
     357    if b then
     358
     359        if e == string.len(regtype) and
     360                (b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
     361                string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
     362            return true
     363        end
     364    end
     365
     366    return false
    368367end
    369368
    370369function findtype_on_childs(self, t)
    371370
    372         local tchild
    373         if self.classtype == 'class' or self.classtype == 'namespace' then
    374                 for k,v in ipairs(self) do
    375                         if v.classtype == 'class' or v.classtype == 'namespace' then
    376                                 if v.typedefs and v.typedefs[t] then
    377                                 return v.typedefs[t]
    378                                 elseif v.usertypes and v.usertypes[t] then
    379                                 return v.usertypes[t]
    380                                 end
    381                                 tchild = findtype_on_childs(v, t)
    382                                 if tchild then return tchild end
    383                         end
    384                 end
    385         end
    386         return nil
     371    local tchild
     372    if self.classtype == 'class' or self.classtype == 'namespace' then
     373        for k,v in ipairs(self) do
     374            if v.classtype == 'class' or v.classtype == 'namespace' then
     375                if v.typedefs and v.typedefs[t] then
     376                return v.typedefs[t]
     377                elseif v.usertypes and v.usertypes[t] then
     378                return v.usertypes[t]
     379                end
     380                tchild = findtype_on_childs(v, t)
     381                if tchild then return tchild end
     382            end
     383        end
     384    end
     385    return nil
    387386
    388387end
    389388
    390389function classContainer:isenum (type)
    391  if global_enums[type] then
    392         return type
    393  else
    394         return false
    395  end
    396 
    397  local basetype = gsub(type,"^.*::","")
    398  local env = self
    399  while env do
    400   if env.enums then
    401    local i=1
    402    while env.enums[i] do
    403     if env.enums[i].name == basetype then
    404          return true
    405         end
    406         i = i+1
    407    end
    408   end
    409   env = env.parent
    410  end
    411  return false
     390    if global_enums[type] then
     391        return type
     392    else
     393        return false
     394    end
     395
     396    local basetype = gsub(type,"^.*::","")
     397    local env = self
     398    while env do
     399        if env.enums then
     400            local i=1
     401            while env.enums[i] do
     402                if env.enums[i].name == basetype then
     403                    return true
     404                end
     405                i = i+1
     406            end
     407        end
     408        env = env.parent
     409    end
     410    return false
    412411end
    413412
     
    416415-- parse chunk
    417416function classContainer:doparse (s)
    418 --print ("parse "..s)
    419 
    420  -- try the parser hook
    421  do
    422         local sub = parser_hook(s)
    423         if sub then
    424                 return sub
    425         end
    426  end
    427 
    428  -- try the null statement
    429  do
    430         local b,e,code = string.find(s, "^%s*;")
    431         if b then
    432                 return strsub(s,e+1)
    433         end
    434  end
    435 
    436  -- try empty verbatim line
    437  do
    438         local b,e,code = string.find(s, "^%s*$\n")
    439         if b then
    440                 return strsub(s,e+1)
    441         end
    442  end
    443 
    444  -- try Lua code
    445  do
    446   local b,e,code = strfind(s,"^%s*(%b\1\2)")
    447   if b then
    448    Code(strsub(code,2,-2))
    449    return strsub(s,e+1)
    450   end
    451  end
    452 
    453  -- try C code
    454  do
    455   local b,e,code = strfind(s,"^%s*(%b\3\4)")
    456   if b then
    457         code = '{'..strsub(code,2,-2)..'\n}\n'
    458         Verbatim(code,'r')        -- verbatim code for 'r'egister fragment
    459         return strsub(s,e+1)
    460   end
    461  end
    462 
    463  -- try C code for preamble section
    464  do
    465         local b,e,code = string.find(s, "^%s*(%b\5\6)")
    466         if b then
    467                 code = string.sub(code, 2, -2).."\n"
    468                 Verbatim(code, '')
    469                 return string.sub(s, e+1)
    470         end
    471  end
    472 
    473  -- try default_property directive
    474  do
    475         local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?")
    476         if b then
    477                 if not ptype or ptype == "" then
    478                         ptype = "default"
    479                 end
    480                 self:set_property_type(ptype)
    481                 return strsub(s, e+1)
    482         end
    483  end
    484 
    485  -- try protected_destructor directive
    486  do
    487         local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?")
    488         if b then
    489                 if self.set_protected_destructor then
    490                         self:set_protected_destructor(true)
    491                 end
    492                 return strsub(s, e+1)
    493         end
    494  end
    495 
    496  -- try 'extern' keyword
    497  do
    498         local b,e = string.find(s, "^%s*extern%s+")
    499         if b then
    500                 -- do nothing
    501                 return strsub(s, e+1)
    502         end
    503  end
    504        
    505  -- try 'virtual' keyworkd
    506  do
    507         local b,e = string.find(s, "^%s*virtual%s+")
    508         if b then
    509                 methodisvirtual = true
    510                 return strsub(s, e+1)
    511         end
    512  end
    513 
    514  -- try labels (public, private, etc)
    515  do
    516         local b,e = string.find(s, "^%s*%w*%s*:[^:]")
    517         if b then
    518                 return strsub(s, e) -- preserve the [^:]
    519         end
    520  end
    521 
    522  -- try module
    523  do
    524   local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
    525   if b then
    526    _curr_code = strsub(s,b,e)
    527    Module(name,body)
    528    return strsub(s,e+1)
    529   end
    530  end
    531 
    532  -- try namesapce
    533  do
    534   local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")
    535   if b then
    536    _curr_code = strsub(s,b,e)
    537    Namespace(name,body)
    538    return strsub(s,e+1)
    539   end
    540  end
    541 
    542  -- try define
    543  do
    544   local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
    545   if b then
    546    _curr_code = strsub(s,b,e)
    547    Define(name)
    548    return strsub(s,e+1)
    549   end
    550  end
    551 
    552  -- try enumerates
    553 
    554  do
    555   local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")
    556   if b then
    557    --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')")
    558    _curr_code = strsub(s,b,e)
    559    Enumerate(name,body,varname)
    560    return strsub(s,e+1)
    561   end
    562  end
    563 
    564 -- do
    565 --  local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")
    566 --  if b then
    567 --   _curr_code = strsub(s,b,e)
    568 --   Enumerate(name,body)
    569 --  return strsub(s,e+1)
    570 --  end
    571 -- end
    572 
    573  do
    574   local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
    575   if b then
    576    _curr_code = strsub(s,b,e)
    577    Enumerate(name,body)
    578    return strsub(s,e+1)
    579   end
    580  end
    581 
    582  -- try operator
    583  do
    584   local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
    585   if not b then
    586                 -- try inline
    587    b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)[%s\n]*%b{}%s*;?%s*")
    588   end
    589   if not b then
    590         -- try cast operator
    591         b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)");
    592         if b then
    593                 local _,ie = string.find(s, "^%s*%b{}", e+1)
    594                 if ie then
    595                         e = ie
    596                 end
    597         end
    598   end
    599   if b then
    600    _curr_code = strsub(s,b,e)
    601    Operator(decl,kind,arg,const)
    602    return strsub(s,e+1)
    603   end
    604  end
    605 
    606  -- try function
    607  do
    608   --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
    609   local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*")
    610   if not b then
    611         -- try function with template
    612         b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w]%b<>)%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
    613   end
    614   if not b then
    615    -- try a single letter function name
    616    b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
    617   end
    618   if b then
    619         if virt and string.find(virt, "[=0]") then
    620                 if self.flags then
    621                         self.flags.pure_virtual = true
    622                 end
    623         end
    624    _curr_code = strsub(s,b,e)
    625    Function(decl,arg,const)
    626    return strsub(s,e+1)
    627   end
    628  end
    629 
    630  -- try inline function
    631  do
    632   local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*")
    633   --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*")
    634   if not b then
    635    -- try a single letter function name
    636    b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")
    637   end
    638   if b then
    639    _curr_code = strsub(s,b,e)
    640    Function(decl,arg,const)
    641    return strsub(s,e+1)
    642   end
    643  end
    644 
    645  -- try class
    646  do
    647         local b,e,name,base,body
    648                 base = '' body = ''
    649                 b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
    650                 if not b then
    651                         b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
    652                         if not b then
    653                                 b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
    654                                 if not b then
    655                                         b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
    656                                         if not b then
    657                                                 b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
    658                                                 if not b then
    659                                                         base = ''
    660                                                         b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
    661                                                 end
    662                                         end
    663                                 end
    664                         end
    665                 end
    666                 if b then
    667                         if base ~= '' then
    668                                 base = string.gsub(base, "^%s*:%s*", "")
    669                                 base = string.gsub(base, "%s*public%s*", "")
    670                                 base = split(base, ",")
    671                                 --local b,e
    672                                 --b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$")
    673                         else
    674                                 base = {}
    675                         end
    676                         _curr_code = strsub(s,b,e)
    677                         Class(name,base,body)
    678                         return strsub(s,e+1)
    679                 end
    680         end
    681 
    682  -- try typedef
    683  do
    684   local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
    685   if b then
    686    _curr_code = strsub(s,b,e)
    687    Typedef(types)
    688    return strsub(s,e+1)
    689   end
    690  end
    691 
    692  -- try variable
    693  do
    694   local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")
    695   if b then
    696    _curr_code = strsub(s,b,e)
    697 
    698         local list = split_c_tokens(decl, ",")
    699         Variable(list[1])
    700         if list.n > 1 then
    701                 local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$");
    702 
    703                 local i =2;
    704                 while list[i] do
    705                         Variable(type.." "..list[i])
    706                         i=i+1
    707                 end
    708         end
    709    --Variable(decl)
    710    return strsub(s,e+1)
    711   end
    712  end
    713 
    714         -- try string
    715  do
    716   local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")
    717   if b then
    718    _curr_code = strsub(s,b,e)
    719    Variable(decl)
    720    return strsub(s,e+1)
    721   end
    722  end
    723 
    724  -- try array
    725  do
    726   local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
    727   if b then
    728    _curr_code = strsub(s,b,e)
    729    Array(decl)
    730    return strsub(s,e+1)
    731   end
    732  end
    733 
    734  -- no matching
    735  if gsub(s,"%s%s*","") ~= "" then
    736   _curr_code = s
    737   error("#parse error")
    738  else
    739   return ""
    740  end
     417    --print ("parse "..s)
     418
     419    -- try the parser hook
     420    do
     421        local sub = parser_hook(s)
     422        if sub then
     423            return sub
     424        end
     425    end
     426
     427    -- try the null statement
     428    do
     429        local b,e,code = string.find(s, "^%s*;")
     430        if b then
     431            return strsub(s,e+1)
     432        end
     433    end
     434
     435    -- try empty verbatim line
     436    do
     437        local b,e,code = string.find(s, "^%s*$\n")
     438        if b then
     439            return strsub(s,e+1)
     440        end
     441    end
     442
     443    -- try Lua code
     444    do
     445        local b,e,code = strfind(s,"^%s*(%b\1\2)")
     446        if b then
     447            Code(strsub(code,2,-2))
     448            return strsub(s,e+1)
     449        end
     450    end
     451
     452    -- try C code
     453    do
     454        local b,e,code = strfind(s,"^%s*(%b\3\4)")
     455        if b then
     456            code = '{'..strsub(code,2,-2)..'\n}\n'
     457            Verbatim(code,'r')        -- verbatim code for 'r'egister fragment
     458            return strsub(s,e+1)
     459        end
     460    end
     461
     462    -- try C code for preamble section
     463    do
     464        local b,e,code = string.find(s, "^%s*(%b\5\6)")
     465        if b then
     466            code = string.sub(code, 2, -2).."\n"
     467            Verbatim(code, '')
     468            return string.sub(s, e+1)
     469        end
     470    end
     471
     472    -- try default_property directive
     473    do
     474        local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?")
     475        if b then
     476            if not ptype or ptype == "" then
     477                ptype = "default"
     478            end
     479            self:set_property_type(ptype)
     480            return strsub(s, e+1)
     481        end
     482    end
     483
     484    -- try protected_destructor directive
     485    do
     486        local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?")
     487        if b then
     488            if self.set_protected_destructor then
     489                self:set_protected_destructor(true)
     490            end
     491            return strsub(s, e+1)
     492        end
     493    end
     494
     495    -- try 'extern' keyword
     496    do
     497        local b,e = string.find(s, "^%s*extern%s+")
     498        if b then
     499            -- do nothing
     500            return strsub(s, e+1)
     501        end
     502    end
     503
     504    -- try 'virtual' keyworkd
     505    do
     506        local b,e = string.find(s, "^%s*virtual%s+")
     507        if b then
     508            methodisvirtual = true
     509            return strsub(s, e+1)
     510        end
     511    end
     512
     513    -- try labels (public, private, etc)
     514    do
     515        local b,e = string.find(s, "^%s*%w*%s*:[^:]")
     516        if b then
     517            return strsub(s, e) -- preserve the [^:]
     518        end
     519    end
     520
     521    -- try module
     522    do
     523        local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
     524        if b then
     525            _curr_code = strsub(s,b,e)
     526            Module(name,body)
     527            return strsub(s,e+1)
     528        end
     529    end
     530
     531    -- try namesapce
     532    do
     533        local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")
     534        if b then
     535            _curr_code = strsub(s,b,e)
     536            Namespace(name,body)
     537            return strsub(s,e+1)
     538        end
     539    end
     540
     541    -- try define
     542    do
     543        local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
     544        if b then
     545            _curr_code = strsub(s,b,e)
     546            Define(name)
     547            return strsub(s,e+1)
     548        end
     549    end
     550
     551    -- try enumerates
     552
     553    do
     554        local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")
     555        if b then
     556            --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')")
     557            _curr_code = strsub(s,b,e)
     558            Enumerate(name,body,varname)
     559            return strsub(s,e+1)
     560        end
     561    end
     562
     563    -- do
     564    --    local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")
     565    --    if b then
     566    --        _curr_code = strsub(s,b,e)
     567    --        Enumerate(name,body)
     568    --        return strsub(s,e+1)
     569    --    end
     570    -- end
     571
     572    do
     573        local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
     574        if b then
     575        _curr_code = strsub(s,b,e)
     576        Enumerate(name,body)
     577        return strsub(s,e+1)
     578        end
     579    end
     580
     581    -- try operator
     582    do
     583        local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
     584        if not b then
     585            -- try inline
     586            b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)[%s\n]*%b{}%s*;?%s*")
     587        end
     588        if not b then
     589            -- try cast operator
     590            b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)");
     591            if b then
     592                local _,ie = string.find(s, "^%s*%b{}", e+1)
     593                if ie then
     594                    e = ie
     595                end
     596            end
     597        end
     598        if b then
     599            _curr_code = strsub(s,b,e)
     600            Operator(decl,kind,arg,const)
     601            return strsub(s,e+1)
     602        end
     603    end
     604
     605    -- try function
     606    do
     607        --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
     608        local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*")
     609        if not b then
     610            -- try function with template
     611            b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w]%b<>)%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
     612        end
     613        if not b then
     614            -- try a single letter function name
     615            b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
     616        end
     617        if b then
     618            if virt and string.find(virt, "[=0]") then
     619                if self.flags then
     620                    self.flags.pure_virtual = true
     621                end
     622            end
     623            _curr_code = strsub(s,b,e)
     624            Function(decl,arg,const)
     625            return strsub(s,e+1)
     626        end
     627    end
     628
     629    -- try inline function
     630    do
     631        local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*")
     632        --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*")
     633        if not b then
     634            -- try a single letter function name
     635            b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")
     636        end
     637        if b then
     638            _curr_code = strsub(s,b,e)
     639            Function(decl,arg,const)
     640            return strsub(s,e+1)
     641        end
     642    end
     643
     644    -- try class
     645    do
     646        local b,e,name,base,body
     647        base = '' body = ''
     648        b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
     649        if not b then
     650            b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
     651            if not b then
     652                b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
     653                if not b then
     654                    b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
     655                    if not b then
     656                        b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
     657                        if not b then
     658                            base = ''
     659                            b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
     660                        end
     661                    end
     662                end
     663            end
     664        end
     665        if b then
     666            if base ~= '' then
     667                base = string.gsub(base, "^%s*:%s*", "")
     668                base = string.gsub(base, "%s*public%s*", "")
     669                base = split(base, ",")
     670                --local b,e
     671                --b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$")
     672            else
     673                base = {}
     674            end
     675            _curr_code = strsub(s,b,e)
     676            Class(name,base,body)
     677            return strsub(s,e+1)
     678        end
     679    end
     680
     681    -- try typedef
     682    do
     683        local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
     684        if b then
     685            _curr_code = strsub(s,b,e)
     686            Typedef(types)
     687            return strsub(s,e+1)
     688        end
     689    end
     690
     691    -- try variable
     692    do
     693        local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")
     694        if b then
     695            _curr_code = strsub(s,b,e)
     696
     697            local list = split_c_tokens(decl, ",")
     698            Variable(list[1])
     699            if list.n > 1 then
     700                local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$");
     701
     702                local i =2;
     703                while list[i] do
     704                    Variable(type.." "..list[i])
     705                    i=i+1
     706                end
     707            end
     708            --Variable(decl)
     709            return strsub(s,e+1)
     710        end
     711    end
     712
     713    -- try string
     714    do
     715        local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")
     716        if b then
     717            _curr_code = strsub(s,b,e)
     718            Variable(decl)
     719            return strsub(s,e+1)
     720        end
     721    end
     722
     723    -- try array
     724    do
     725        local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
     726        if b then
     727            _curr_code = strsub(s,b,e)
     728            Array(decl)
     729            return strsub(s,e+1)
     730        end
     731    end
     732
     733    -- no matching
     734    if gsub(s,"%s%s*","") ~= "" then
     735        _curr_code = s
     736        error("#parse error")
     737    else
     738        return ""
     739    end
    741740
    742741end
     
    744743function classContainer:parse (s)
    745744
    746         self.curr_member_access = nil
    747 
    748  while s ~= '' do
    749   s = self:doparse(s)
    750   methodisvirtual = false
    751  end
     745    self.curr_member_access = nil
     746
     747    while s ~= '' do
     748        s = self:doparse(s)
     749        methodisvirtual = false
     750    end
    752751end
    753752
     
    757756function get_property_type()
    758757
    759         return classContainer.curr:get_property_type()
     758    return classContainer.curr:get_property_type()
    760759end
    761760
    762761function classContainer:set_property_type(ptype)
    763         ptype = string.gsub(ptype, "^%s*", "")
    764         ptype = string.gsub(ptype, "%s*$", "")
    765 
    766         self.property_type = ptype
     762    ptype = string.gsub(ptype, "^%s*", "")
     763    ptype = string.gsub(ptype, "%s*$", "")
     764
     765    self.property_type = ptype
    767766end
    768767
    769768function classContainer:get_property_type()
    770         return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
    771 end
     769    return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
     770end
  • code/trunk/src/tolua/lua/custom.lua

    r2087 r2710  
    11
    22function extract_code(fn,s)
    3         local code = ""
    4         if fn then
    5                 code = '\n$#include "'..fn..'"\n'
    6         end
    7         s= "\n" .. s .. "\n" -- add blank lines as sentinels
    8         local _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n")
    9         while e do
    10                 t = strlower(t)
    11                 if t == "bind_begin" then
    12                         _,e,c = strfind(s,"(.-)\n[^\n]*SCRIPT_BIND_END[^\n]*\n",e)
    13                         if not e then
    14                         tolua_error("Unbalanced 'SCRIPT_BIND_BEGIN' directive in header file")
    15                         end
    16                 end
    17                 if t == "bind_class" or t == "bind_block" then
    18                         local b
    19                         _,e,c,b = string.find(s, "([^{]-)(%b{})", e)
    20                         c = c..'{\n'..extract_code(nil, b)..'\n};\n'
    21                 end
    22                 code = code .. c .. "\n"
    23         _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n",e)
    24         end
    25         return code
     3    local code = ""
     4    if fn then
     5        code = '\n$#include "'..fn..'"\n'
     6    end
     7    s= "\n" .. s .. "\n" -- add blank lines as sentinels
     8    local _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n")
     9    while e do
     10        t = strlower(t)
     11        if t == "bind_begin" then
     12            _,e,c = strfind(s,"(.-)\n[^\n]*SCRIPT_BIND_END[^\n]*\n",e)
     13            if not e then
     14            tolua_error("Unbalanced 'SCRIPT_BIND_BEGIN' directive in header file")
     15            end
     16        end
     17        if t == "bind_class" or t == "bind_block" then
     18            local b
     19            _,e,c,b = string.find(s, "([^{]-)(%b{})", e)
     20            c = c..'{\n'..extract_code(nil, b)..'\n};\n'
     21        end
     22        code = code .. c .. "\n"
     23    _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n",e)
     24    end
     25    return code
    2626end
    2727
     
    3333
    3434function include_file_hook(p, filename)
    35         do return end
     35    do return end
    3636--print("FILENAME is "..filename)
    37         p.code = string.gsub(p.code, "\n%s*SigC::Signal", "\n\ttolua_readonly SigC::Signal")
    38         p.code = string.gsub(p.code, "#ifdef __cplusplus\nextern \"C\" {\n#endif", "")
    39         p.code = string.gsub(p.code, "#ifdef __cplusplus\n};?\n#endif", "")
    40         p.code = string.gsub(p.code, "DECLSPEC", "")
    41         p.code = string.gsub(p.code, "SDLCALL", "")
    42         p.code = string.gsub(p.code, "DLLINTERFACE", "")
    43         p.code = string.gsub(p.code, "#define[^\n]*_[hH]_?%s*\n", "\n")
     37    p.code = string.gsub(p.code, "\n%s*SigC::Signal", "\n\ttolua_readonly SigC::Signal")
     38    p.code = string.gsub(p.code, "#ifdef __cplusplus\nextern \"C\" {\n#endif", "")
     39    p.code = string.gsub(p.code, "#ifdef __cplusplus\n};?\n#endif", "")
     40    p.code = string.gsub(p.code, "DECLSPEC", "")
     41    p.code = string.gsub(p.code, "SDLCALL", "")
     42    p.code = string.gsub(p.code, "DLLINTERFACE", "")
     43    p.code = string.gsub(p.code, "#define[^\n]*_[hH]_?%s*\n", "\n")
    4444--print("code is "..p.code)
    4545end
  • code/trunk/src/tolua/lua/custom_hide.lua

    r2087 r2710  
    11-- extract code with tolua_hide, and also
    22function extract_code(fn,s)
    3         local code = '\n$#include "'..fn..'"\n'
    4         s= "\n" .. s .. "\n" -- add blank lines as sentinels
    5         local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
    6         while e do
    7                 t = strlower(t)
    8                 if t == "begin" then
    9                         _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e)
    10                         if not e then
    11                         tolua_error("Unbalanced 'tolua_begin' directive in header file")
    12                         end
    13                 end
    14                 c = c.."\n"
    15                 c = string.gsub(c, "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[hH][iI][Dd][eE][^\n]*\n", "\n");
    16                 c = string.gsub(c, "#define[^%(\n]*%(.-\n", "\n")
    17                 code = code .. c
    18         _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e)
    19         end
    20         return code
     3    local code = '\n$#include "'..fn..'"\n'
     4    s= "\n" .. s .. "\n" -- add blank lines as sentinels
     5    local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
     6    while e do
     7        t = strlower(t)
     8        if t == "begin" then
     9            _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e)
     10            if not e then
     11            tolua_error("Unbalanced 'tolua_begin' directive in header file")
     12            end
     13        end
     14        c = c.."\n"
     15        c = string.gsub(c, "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[hH][iI][Dd][eE][^\n]*\n", "\n");
     16        c = string.gsub(c, "#define[^%(\n]*%(.-\n", "\n")
     17        code = code .. c
     18    _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e)
     19    end
     20    return code
    2121end
  • code/trunk/src/tolua/lua/declaration.lua

    r2087 r2710  
    2222--  ret  = "*" or "&", if value is to be returned (only for arguments)
    2323classDeclaration = {
    24  mod = '',
    25  type = '',
    26  ptr = '',
    27  name = '',
    28  dim = '',
    29  ret = '',
    30  def = ''
     24    mod = '',
     25    type = '',
     26    ptr = '',
     27    name = '',
     28    dim = '',
     29    ret = '',
     30    def = ''
    3131}
    3232classDeclaration.__index = classDeclaration
     
    3535-- Create an unique variable name
    3636function create_varname ()
    37  if not _varnumber then _varnumber = 0 end
    38  _varnumber = _varnumber + 1
    39  return "tolua_var_".._varnumber
     37    if not _varnumber then _varnumber = 0 end
     38    _varnumber = _varnumber + 1
     39    return "tolua_var_".._varnumber
    4040end
    4141
     
    4444function classDeclaration:checkname ()
    4545
    46  if strsub(self.name,1,1) == '[' and not findtype(self.type) then
    47   self.name = self.type..self.name
    48   local m = split(self.mod,'%s%s*')
    49   self.type = m[m.n]
    50   self.mod = concat(m,1,m.n-1)
    51  end
    52 
    53  local t = split(self.name,'=')
    54  if t.n==2 then
    55   self.name = t[1]
    56   self.def = find_enum_var(t[t.n])
    57  end
    58 
    59  local b,e,d = strfind(self.name,"%[(.-)%]")
    60  if b then
    61   self.name = strsub(self.name,1,b-1)
    62   self.dim = find_enum_var(d)
    63  end
    64 
    65 
    66  if self.type ~= '' and self.type ~= 'void' and self.name == '' then
    67   self.name = create_varname()
    68  elseif self.kind=='var' then
    69   if self.type=='' and self.name~='' then
    70    self.type = self.type..self.name
    71    self.name = create_varname()
    72   elseif findtype(self.name) then
    73    if self.type=='' then self.type = self.name
    74    else self.type = self.type..' '..self.name end
    75    self.name = create_varname()
    76   end
    77  end
    78 
    79  -- adjust type of string
    80  if self.type == 'char' and self.dim ~= '' then
    81         self.type = 'char*'
    82  end
    83 
    84         if self.kind and self.kind == 'var' then
    85                 self.name = string.gsub(self.name, ":.*$", "") -- ???
    86         end
     46    if strsub(self.name,1,1) == '[' and not findtype(self.type) then
     47        self.name = self.type..self.name
     48        local m = split(self.mod,'%s%s*')
     49        self.type = m[m.n]
     50        self.mod = concat(m,1,m.n-1)
     51    end
     52
     53    local t = split(self.name,'=')
     54    if t.n==2 then
     55        self.name = t[1]
     56        self.def = find_enum_var(t[t.n])
     57    end
     58
     59    local b,e,d = strfind(self.name,"%[(.-)%]")
     60    if b then
     61        self.name = strsub(self.name,1,b-1)
     62        self.dim = find_enum_var(d)
     63    end
     64
     65
     66    if self.type ~= '' and self.type ~= 'void' and self.name == '' then
     67        self.name = create_varname()
     68    elseif self.kind=='var' then
     69        if self.type=='' and self.name~='' then
     70            self.type = self.type..self.name
     71            self.name = create_varname()
     72        elseif findtype(self.name) then
     73            if self.type=='' then self.type = self.name
     74            else self.type = self.type..' '..self.name end
     75            self.name = create_varname()
     76        end
     77    end
     78
     79    -- adjust type of string
     80    if self.type == 'char' and self.dim ~= '' then
     81        self.type = 'char*'
     82    end
     83
     84    if self.kind and self.kind == 'var' then
     85        self.name = string.gsub(self.name, ":.*$", "") -- ???
     86    end
    8787end
    8888
     
    9191function classDeclaration:checktype ()
    9292
    93  -- check if there is a pointer to basic type
    94  local basic = isbasic(self.type)
    95  if self.kind == 'func' and basic=='number' and string.find(self.ptr, "%*") then
    96         self.type = '_userdata'
    97         self.ptr = ""
    98  end
    99  if basic and self.ptr~='' then
    100   self.ret = self.ptr
    101   self.ptr = nil
    102   if isbasic(self.type) == 'number' then
    103         self.return_userdata = true
    104   end
    105  end
    106 
    107  -- check if there is array to be returned
    108  if self.dim~='' and self.ret~='' then
    109    error('#invalid parameter: cannot return an array of values')
    110  end
    111  -- restore 'void*' and 'string*'
    112  if self.type == '_userdata' then self.type = 'void*'
    113  elseif self.type == '_cstring' then self.type = 'char*'
    114  elseif self.type == '_lstate' then self.type = 'lua_State*'
    115  end
    116 
    117  -- resolve types inside the templates
    118  if self.type then
    119         self.type = resolve_template_types(self.type)
    120  end
    121 
    122 --
    123 -- -- if returning value, automatically set default value
    124 -- if self.ret ~= '' and self.def == '' then
    125 --  self.def = '0'
    126 -- end
    127 --
     93    -- check if there is a pointer to basic type
     94    local basic = isbasic(self.type)
     95    if self.kind == 'func' and basic=='number' and string.find(self.ptr, "%*") then
     96        self.type = '_userdata'
     97        self.ptr = ""
     98    end
     99    if basic and self.ptr~='' then
     100        self.ret = self.ptr
     101        self.ptr = nil
     102        if isbasic(self.type) == 'number' then
     103            self.return_userdata = true
     104        end
     105    end
     106
     107    -- check if there is array to be returned
     108    if self.dim~='' and self.ret~='' then
     109        error('#invalid parameter: cannot return an array of values')
     110    end
     111    -- restore 'void*' and 'string*'
     112    if self.type == '_userdata' then self.type = 'void*'
     113    elseif self.type == '_cstring' then self.type = 'char*'
     114    elseif self.type == '_lstate' then self.type = 'lua_State*'
     115    end
     116
     117    -- resolve types inside the templates
     118    if self.type then
     119        self.type = resolve_template_types(self.type)
     120    end
     121
     122    --
     123    -- -- if returning value, automatically set default value
     124    -- if self.ret ~= '' and self.def == '' then
     125    --  self.def = '0'
     126    -- end
     127    --
    128128
    129129end
     
    131131function resolve_template_types(type)
    132132
    133         if isbasic(type) then
    134                 return type
    135         end
    136         local b,_,m = string.find(type, "(%b<>)")
    137         if b then
    138 
    139                 m = split_c_tokens(string.sub(m, 2, -2), ",")
    140                 for i=1, table.getn(m) do
    141                         m[i] = string.gsub(m[i],"%s*([%*&])", "%1")
    142                         m[i] = findtype(m[i]) or m[i]
    143                         m[i] = resolve_template_types(m[i])
    144                 end
    145 
    146                 local b,i
    147                 type,b,i = break_template(type)
    148                 local template_part = "<"..string.gsub(concat(m, 1, m.n), " ", ",")..">"
    149                 type = rebuild_template(type, b, template_part)
    150                 type = string.gsub(type, ">>", "> >")
    151         end
    152         return type
     133    if isbasic(type) then
     134        return type
     135    end
     136    local b,_,m = string.find(type, "(%b<>)")
     137    if b then
     138
     139        m = split_c_tokens(string.sub(m, 2, -2), ",")
     140        for i=1, table.getn(m) do
     141            m[i] = string.gsub(m[i],"%s*([%*&])", "%1")
     142            m[i] = findtype(m[i]) or m[i]
     143            m[i] = resolve_template_types(m[i])
     144        end
     145
     146        local b,i
     147        type,b,i = break_template(type)
     148        local template_part = "<"..string.gsub(concat(m, 1, m.n), " ", ",")..">"
     149        type = rebuild_template(type, b, template_part)
     150        type = string.gsub(type, ">>", "> >")
     151    end
     152    return type
    153153end
    154154
    155155function break_template(s)
    156         local b,e,timpl = string.find(s, "(%b<>)")
    157         if timpl then
    158                 s = string.gsub(s, "%b<>", "")
    159                 return s, b, timpl
    160         else
    161                 return s, 0, nil
    162         end
     156    local b,e,timpl = string.find(s, "(%b<>)")
     157    if timpl then
     158        s = string.gsub(s, "%b<>", "")
     159        return s, b, timpl
     160    else
     161        return s, 0, nil
     162    end
    163163end
    164164
    165165function rebuild_template(s, b, timpl)
    166166
    167         if b == 0 then
    168                 return s
    169         end
    170 
    171         return string.sub(s, 1, b-1)..timpl..string.sub(s, b, -1)
     167    if b == 0 then
     168        return s
     169    end
     170
     171    return string.sub(s, 1, b-1)..timpl..string.sub(s, b, -1)
    172172end
    173173
    174174-- Print method
    175175function classDeclaration:print (ident,close)
    176  print(ident.."Declaration{")
    177  print(ident.." mod  = '"..self.mod.."',")
    178  print(ident.." type = '"..self.type.."',")
    179  print(ident.." ptr  = '"..self.ptr.."',")
    180  print(ident.." name = '"..self.name.."',")
    181  print(ident.." dim  = '"..self.dim.."',")
    182  print(ident.." def  = '"..self.def.."',")
    183  print(ident.." ret  = '"..self.ret.."',")
    184  print(ident.."}"..close)
     176    print(ident.."Declaration{")
     177    print(ident.." mod  = '"..self.mod.."',")
     178    print(ident.." type = '"..self.type.."',")
     179    print(ident.." ptr  = '"..self.ptr.."',")
     180    print(ident.." name = '"..self.name.."',")
     181    print(ident.." dim  = '"..self.dim.."',")
     182    print(ident.." def  = '"..self.def.."',")
     183    print(ident.." ret  = '"..self.ret.."',")
     184    print(ident.."}"..close)
    185185end
    186186
     
    188188function classDeclaration:requirecollection (t)
    189189 if self.mod ~= 'const' and
    190             self.dim and self.dim ~= '' and
    191                                 not isbasic(self.type) and
    192                                 self.ptr == '' then
    193                 local type = gsub(self.type,"%s*const%s+","")
    194                 t[type] = "tolua_collect_" .. clean_template(type)
    195                 return true
    196         end
    197         return false
     190        self.dim and self.dim ~= '' and
     191                not isbasic(self.type) and
     192                self.ptr == '' then
     193        local type = gsub(self.type,"%s*const%s+","")
     194        t[type] = "tolua_collect_" .. clean_template(type)
     195        return true
     196    end
     197    return false
    198198end
    199199
     
    201201function classDeclaration:decltype ()
    202202
    203         self.type = typevar(self.type)
    204         if strfind(self.mod,'const') then
    205                 self.type = 'const '..self.type
    206                 self.mod = gsub(self.mod,'const%s*','')
    207         end
     203    self.type = typevar(self.type)
     204    if strfind(self.mod,'const') then
     205        self.type = 'const '..self.type
     206        self.mod = gsub(self.mod,'const%s*','')
     207    end
    208208end
    209209
     
    211211-- output type checking
    212212function classDeclaration:outchecktype (narg)
    213  local def
    214  local t = isbasic(self.type)
    215  if self.def~='' then
    216   def = 1
    217  else
    218   def = 0
    219  end
    220  if self.dim ~= '' then
    221         --if t=='string' then
    222         --      return 'tolua_isstringarray(tolua_S,'..narg..','..def..',&tolua_err)'
    223         --else
    224         return 'tolua_istable(tolua_S,'..narg..',0,&tolua_err)'
    225         --end
    226  elseif t then
    227         return 'tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)'
    228  else
    229   return 'tolua_isusertype(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)'
    230  end
     213    local def
     214    local t = isbasic(self.type)
     215    if self.def~='' then
     216        def = 1
     217    else
     218        def = 0
     219    end
     220    if self.dim ~= '' then
     221        --if t=='string' then
     222        --    return 'tolua_isstringarray(tolua_S,'..narg..','..def..',&tolua_err)'
     223        --else
     224        return 'tolua_istable(tolua_S,'..narg..',0,&tolua_err)'
     225        --end
     226    elseif t then
     227        return 'tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)'
     228    else
     229        return 'tolua_isusertype(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)'
     230    end
    231231end
    232232
    233233function classDeclaration:builddeclaration (narg, cplusplus)
    234  local array = self.dim ~= '' and tonumber(self.dim)==nil
    235         local line = ""
    236  local ptr = ''
    237         local mod
    238         local type = self.type
    239  if self.dim ~= '' then
    240         type = gsub(self.type,'const%s+','')  -- eliminates const modifier for arrays
    241  end
    242  if self.ptr~='' and not isbasic(type) then ptr = '*' end
    243  line = concatparam(line," ",self.mod,type,ptr)
    244  if array then
    245   line = concatparam(line,'*')
    246  end
    247  line = concatparam(line,self.name)
    248  if self.dim ~= '' then
    249   if tonumber(self.dim)~=nil then
    250    line = concatparam(line,'[',self.dim,'];')
    251   else
    252         if cplusplus then
    253                 line = concatparam(line,' = new',type,ptr,'['..self.dim..'];')
    254         else
    255                 line = concatparam(line,' = (',type,ptr,'*)',
    256                 'malloc((',self.dim,')*sizeof(',type,ptr,'));')
    257         end
    258   end
    259  else
    260   local t = isbasic(type)
    261   line = concatparam(line,' = ')
    262   if t == 'state' then
    263         line = concatparam(line, 'tolua_S;')
    264   else
    265         --print("t is "..tostring(t)..", ptr is "..tostring(self.ptr))
    266         if t == 'number' and string.find(self.ptr, "%*") then
    267                 t = 'userdata'
    268         end
    269         if not t and ptr=='' then line = concatparam(line,'*') end
    270         line = concatparam(line,'((',self.mod,type)
    271         if not t then
    272                 line = concatparam(line,'*')
    273         end
    274         line = concatparam(line,') ')
    275                         if isenum(type) then
    276                         line = concatparam(line,'(int) ')
    277                         end
    278         local def = 0
    279         if self.def ~= '' then
    280                 def = self.def
    281                 if (ptr == '' or self.ptr == '&') and not t then
    282                         def = "(void*)&(const "..type..")"..def
    283                 end
    284         end
    285         if t then
    286         line = concatparam(line,'tolua_to'..t,'(tolua_S,',narg,',',def,'));')
    287         else
    288         line = concatparam(line,'tolua_tousertype(tolua_S,',narg,',',def,'));')
    289         end
    290   end
    291  end
    292         return line
     234    local array = self.dim ~= '' and tonumber(self.dim)==nil
     235    local line = ""
     236    local ptr = ''
     237    local mod
     238    local type = self.type
     239    if self.dim ~= '' then
     240        type = gsub(self.type,'const%s+','')  -- eliminates const modifier for arrays
     241    end
     242    if self.ptr~='' and not isbasic(type) then ptr = '*' end
     243    line = concatparam(line," ",self.mod,type,ptr)
     244    if array then
     245        line = concatparam(line,'*')
     246    end
     247    line = concatparam(line,self.name)
     248    if self.dim ~= '' then
     249        if tonumber(self.dim)~=nil then
     250            line = concatparam(line,'[',self.dim,'];')
     251        else
     252            if cplusplus then
     253                line = concatparam(line,' = new',type,ptr,'['..self.dim..'];')
     254            else
     255                line = concatparam(line,' = (',type,ptr,'*)',
     256                'malloc((',self.dim,')*sizeof(',type,ptr,'));')
     257            end
     258        end
     259    else
     260    local t = isbasic(type)
     261    line = concatparam(line,' = ')
     262    if t == 'state' then
     263        line = concatparam(line, 'tolua_S;')
     264    else
     265        --print("t is "..tostring(t)..", ptr is "..tostring(self.ptr))
     266        if t == 'number' and string.find(self.ptr, "%*") then
     267            t = 'userdata'
     268        end
     269        if not t and ptr=='' then line = concatparam(line,'*') end
     270            line = concatparam(line,'((',self.mod,type)
     271            if not t then
     272                line = concatparam(line,'*')
     273            end
     274            line = concatparam(line,') ')
     275            if isenum(type) then
     276                line = concatparam(line,'(int) ')
     277            end
     278            local def = 0
     279            if self.def ~= '' then
     280                def = self.def
     281                if (ptr == '' or self.ptr == '&') and not t then
     282                    def = "(void*)&(const "..type..")"..def
     283                end
     284            end
     285            if t then
     286                line = concatparam(line,'tolua_to'..t,'(tolua_S,',narg,',',def,'));')
     287            else
     288                line = concatparam(line,'tolua_tousertype(tolua_S,',narg,',',def,'));')
     289            end
     290        end
     291    end
     292    return line
    293293end
    294294
    295295-- Declare variable
    296296function classDeclaration:declare (narg)
    297  if self.dim ~= '' and tonumber(self.dim)==nil then
    298         output('#ifdef __cplusplus\n')
    299                 output(self:builddeclaration(narg,true))
    300                 output('#else\n')
    301                 output(self:builddeclaration(narg,false))
    302         output('#endif\n')
    303         else
    304                 output(self:builddeclaration(narg,false))
    305         end
     297    if self.dim ~= '' and tonumber(self.dim)==nil then
     298        output('#ifdef __cplusplus\n')
     299        output(self:builddeclaration(narg,true))
     300        output('#else\n')
     301        output(self:builddeclaration(narg,false))
     302        output('#endif\n')
     303    else
     304        output(self:builddeclaration(narg,false))
     305    end
    306306end
    307307
    308308-- Get parameter value
    309309function classDeclaration:getarray (narg)
    310  if self.dim ~= '' then
    311         local type = gsub(self.type,'const ','')
    312   output('  {')
    313         output('#ifndef TOLUA_RELEASE\n')
    314   local def; if self.def~='' then def=1 else def=0 end
    315                 local t = isbasic(type)
    316                 if (t) then
    317    output('   if (!tolua_is'..t..'array(tolua_S,',narg,',',self.dim,',',def,',&tolua_err))')
    318                 else
    319    output('   if (!tolua_isusertypearray(tolua_S,',narg,',"',type,'",',self.dim,',',def,',&tolua_err))')
    320                 end
    321   output('    goto tolua_lerror;')
    322   output('   else\n')
    323         output('#endif\n')
    324   output('   {')
    325   output('    int i;')
    326   output('    for(i=0; i<'..self.dim..';i++)')
    327   local t = isbasic(type)
    328   local ptr = ''
    329   if self.ptr~='' then ptr = '*' end
    330   output('   ',self.name..'[i] = ')
    331   if not t and ptr=='' then output('*') end
    332   output('((',type)
    333   if not t then
    334    output('*')
    335   end
    336   output(') ')
    337   local def = 0
    338   if self.def ~= '' then def = self.def end
    339   if t then
    340    output('tolua_tofield'..t..'(tolua_S,',narg,',i+1,',def,'));')
    341   else
    342    output('tolua_tofieldusertype(tolua_S,',narg,',i+1,',def,'));')
    343   end
    344   output('   }')
    345   output('  }')
    346  end
     310    if self.dim ~= '' then
     311        local type = gsub(self.type,'const ','')
     312        output('  {')
     313        output('#ifndef TOLUA_RELEASE\n')
     314        local def; if self.def~='' then def=1 else def=0 end
     315        local t = isbasic(type)
     316        if (t) then
     317            output('   if (!tolua_is'..t..'array(tolua_S,',narg,',',self.dim,',',def,',&tolua_err))')
     318        else
     319            output('   if (!tolua_isusertypearray(tolua_S,',narg,',"',type,'",',self.dim,',',def,',&tolua_err))')
     320        end
     321        output('    goto tolua_lerror;')
     322        output('   else\n')
     323        output('#endif\n')
     324        output('   {')
     325        output('    int i;')
     326        output('    for(i=0; i<'..self.dim..';i++)')
     327        local t = isbasic(type)
     328        local ptr = ''
     329        if self.ptr~='' then ptr = '*' end
     330        output('   ',self.name..'[i] = ')
     331        if not t and ptr=='' then output('*') end
     332        output('((',type)
     333        if not t then
     334            output('*')
     335        end
     336        output(') ')
     337        local def = 0
     338        if self.def ~= '' then def = self.def end
     339        if t then
     340            output('tolua_tofield'..t..'(tolua_S,',narg,',i+1,',def,'));')
     341        else
     342            output('tolua_tofieldusertype(tolua_S,',narg,',i+1,',def,'));')
     343        end
     344        output('   }')
     345        output('  }')
     346    end
    347347end
    348348
    349349-- Get parameter value
    350350function classDeclaration:setarray (narg)
    351  if not strfind(self.type,'const%s+') and self.dim ~= '' then
    352         local type = gsub(self.type,'const ','')
    353   output('  {')
    354   output('   int i;')
    355   output('   for(i=0; i<'..self.dim..';i++)')
    356   local t,ct = isbasic(type)
    357   if t then
    358    output('    tolua_pushfield'..t..'(tolua_S,',narg,',i+1,(',ct,')',self.name,'[i]);')
    359   else
    360    if self.ptr == '' then
    361      output('   {')
    362      output('#ifdef __cplusplus\n')
    363      output('    void* tolua_obj = new',type,'(',self.name,'[i]);')
    364      output('    tolua_pushfieldusertype_and_takeownership(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
    365      output('#else\n')
    366      output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&',self.name,'[i],sizeof(',type,'));')
    367      output('    tolua_pushfieldusertype(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
    368      output('#endif\n')
    369      output('   }')
    370    else
    371     output('   tolua_pushfieldusertype(tolua_S,',narg,',i+1,(void*)',self.name,'[i],"',type,'");')
    372    end
    373   end
    374   output('  }')
    375  end
     351    if not strfind(self.type,'const%s+') and self.dim ~= '' then
     352        local type = gsub(self.type,'const ','')
     353        output('  {')
     354        output('   int i;')
     355        output('   for(i=0; i<'..self.dim..';i++)')
     356        local t,ct = isbasic(type)
     357        if t then
     358            output('    tolua_pushfield'..t..'(tolua_S,',narg,',i+1,(',ct,')',self.name,'[i]);')
     359        else
     360            if self.ptr == '' then
     361                output('   {')
     362                output('#ifdef __cplusplus\n')
     363                output('    void* tolua_obj = new',type,'(',self.name,'[i]);')
     364                output('    tolua_pushfieldusertype_and_takeownership(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
     365                output('#else\n')
     366                output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&',self.name,'[i],sizeof(',type,'));')
     367                output('    tolua_pushfieldusertype(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
     368                output('#endif\n')
     369                output('   }')
     370            else
     371                output('   tolua_pushfieldusertype(tolua_S,',narg,',i+1,(void*)',self.name,'[i],"',type,'");')
     372            end
     373        end
     374        output('  }')
     375    end
    376376end
    377377
    378378-- Free dynamically allocated array
    379379function classDeclaration:freearray ()
    380  if self.dim ~= '' and tonumber(self.dim)==nil then
    381         output('#ifdef __cplusplus\n')
    382                 output('  delete []',self.name,';')
    383         output('#else\n')
    384   output('  free(',self.name,');')
    385         output('#endif\n')
    386  end
     380    if self.dim ~= '' and tonumber(self.dim)==nil then
     381        output('#ifdef __cplusplus\n')
     382        output('  delete []',self.name,';')
     383        output('#else\n')
     384        output('  free(',self.name,');')
     385        output('#endif\n')
     386    end
    387387end
    388388
    389389-- Pass parameter
    390390function classDeclaration:passpar ()
    391  if self.ptr=='&' and not isbasic(self.type) then
    392   output('*'..self.name)
    393  elseif self.ret=='*' then
    394   output('&'..self.name)
    395  else
    396   output(self.name)
    397  end
     391    if self.ptr=='&' and not isbasic(self.type) then
     392        output('*'..self.name)
     393    elseif self.ret=='*' then
     394        output('&'..self.name)
     395    else
     396        output(self.name)
     397    end
    398398end
    399399
    400400-- Return parameter value
    401401function classDeclaration:retvalue ()
    402  if self.ret ~= '' then
    403   local t,ct = isbasic(self.type)
    404   if t and t~='' then
    405    output('   tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');')
    406   else
    407    output('   tolua_pushusertype(tolua_S,(void*)'..self.name..',"',self.type,'");')
    408   end
    409   return 1
    410  end
    411  return 0
     402    if self.ret ~= '' then
     403        local t,ct = isbasic(self.type)
     404        if t and t~='' then
     405            output('   tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');')
     406        else
     407            output('   tolua_pushusertype(tolua_S,(void*)'..self.name..',"',self.type,'");')
     408        end
     409        return 1
     410    end
     411    return 0
    412412end
    413413
     
    415415function _Declaration (t)
    416416
    417  setmetatable(t,classDeclaration)
    418  t:buildnames()
    419  t:checkname()
    420  t:checktype()
    421  local ft = findtype(t.type) or t.type
    422  if not isenum(ft) then
    423         t.mod, t.type = applytypedef(t.mod, ft)
    424  end
    425 
    426  if t.kind=="var" and (string.find(t.mod, "tolua_property%s") or string.find(t.mod, "tolua_property$")) then
    427         t.mod = string.gsub(t.mod, "tolua_property", "tolua_property__"..get_property_type())
    428  end
    429 
    430  return t
     417    setmetatable(t,classDeclaration)
     418    t:buildnames()
     419    t:checkname()
     420    t:checktype()
     421    local ft = findtype(t.type) or t.type
     422    if not isenum(ft) then
     423        t.mod, t.type = applytypedef(t.mod, ft)
     424    end
     425
     426    if t.kind=="var" and (string.find(t.mod, "tolua_property%s") or string.find(t.mod, "tolua_property$")) then
     427        t.mod = string.gsub(t.mod, "tolua_property", "tolua_property__"..get_property_type())
     428    end
     429
     430    return t
    431431end
    432432
     
    436436function Declaration (s,kind,is_parameter)
    437437
    438  -- eliminate spaces if default value is provided
    439  s = gsub(s,"%s*=%s*","=")
    440  s = gsub(s, "%s*<", "<")
    441 
    442  local defb,tmpdef
    443  defb,_,tmpdef = string.find(s, "(=.*)$")
    444  if defb then
    445         s = string.gsub(s, "=.*$", "")
    446  else
    447         tmpdef = ''
    448  end
    449  if kind == "var" then
    450   -- check the form: void
    451   if s == '' or s == 'void' then
    452    return _Declaration{type = 'void', kind = kind, is_parameter = is_parameter}
    453   end
    454  end
    455 
    456  -- check the form: mod type*& name
    457  local t = split_c_tokens(s,'%*%s*&')
    458  if t.n == 2 then
    459   if kind == 'func' then
    460    error("#invalid function return type: "..s)
    461   end
    462   --local m = split(t[1],'%s%s*')
    463   local m = split_c_tokens(t[1],'%s+')
    464   return _Declaration{
    465    name = t[2]..tmpdef,
    466    ptr = '*',
    467    ret = '&',
    468    --type = rebuild_template(m[m.n], tb, timpl),
    469    type = m[m.n],
    470    mod = concat(m,1,m.n-1),
    471    is_parameter = is_parameter,
    472    kind = kind
    473   }
    474  end
    475 
    476  -- check the form: mod type** name
    477  t = split_c_tokens(s,'%*%s*%*')
    478  if t.n == 2 then
    479   if kind == 'func' then
    480    error("#invalid function return type: "..s)
    481   end
    482   --local m = split(t[1],'%s%s*')
    483   local m = split_c_tokens(t[1],'%s+')
    484   return _Declaration{
    485    name = t[2]..tmpdef,
    486    ptr = '*',
    487    ret = '*',
    488    --type = rebuild_template(m[m.n], tb, timpl),
    489    type = m[m.n],
    490    mod = concat(m,1,m.n-1),
    491    is_parameter = is_parameter,
    492    kind = kind
    493   }
    494  end
    495 
    496  -- check the form: mod type& name
    497  t = split_c_tokens(s,'&')
    498  if t.n == 2 then
    499   --local m = split(t[1],'%s%s*')
    500   local m = split_c_tokens(t[1],'%s+')
    501   return _Declaration{
    502    name = t[2]..tmpdef,
    503    ptr = '&',
    504    --type = rebuild_template(m[m.n], tb, timpl),
    505    type = m[m.n],
    506    mod = concat(m,1,m.n-1),
    507    is_parameter = is_parameter,
    508    kind = kind
    509   }
    510  end
    511 
    512  -- check the form: mod type* name
    513  local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)
    514  t = split_c_tokens(s1,'%*')
    515  if t.n == 2 then
    516   t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression
    517   --local m = split(t[1],'%s%s*')
    518   local m = split_c_tokens(t[1],'%s+')
    519   return _Declaration{
    520    name = t[2]..tmpdef,
    521    ptr = '*',
    522    type = m[m.n],
    523    --type = rebuild_template(m[m.n], tb, timpl),
    524    mod = concat(m,1,m.n-1)   ,
    525    is_parameter = is_parameter,
    526    kind = kind
    527   }
    528  end
    529 
    530  if kind == 'var' then
    531   -- check the form: mod type name
    532   --t = split(s,'%s%s*')
    533   t = split_c_tokens(s,'%s+')
    534   local v
    535   if findtype(t[t.n]) then v = create_varname() else v = t[t.n]; t.n = t.n-1 end
    536   return _Declaration{
    537    name = v..tmpdef,
    538    --type = rebuild_template(t[t.n], tb, timpl),
    539    type = t[t.n],
    540    mod = concat(t,1,t.n-1),
    541    is_parameter = is_parameter,
    542    kind = kind
    543   }
    544 
    545  else -- kind == "func"
    546 
    547   -- check the form: mod type name
    548   --t = split(s,'%s%s*')
    549   t = split_c_tokens(s,'%s+')
    550   local v = t[t.n]  -- last word is the function name
    551   local tp,md
    552   if t.n>1 then
    553    tp = t[t.n-1]
    554    md = concat(t,1,t.n-2)
    555   end
    556   --if tp then tp = rebuild_template(tp, tb, timpl) end
    557   return _Declaration{
    558    name = v,
    559    type = tp,
    560    mod = md,
    561    is_parameter = is_parameter,
    562    kind = kind
    563   }
    564  end
    565 
    566 end
    567 
     438    -- eliminate spaces if default value is provided
     439    s = gsub(s,"%s*=%s*","=")
     440    s = gsub(s, "%s*<", "<")
     441
     442    local defb,tmpdef
     443    defb,_,tmpdef = string.find(s, "(=.*)$")
     444    if defb then
     445        s = string.gsub(s, "=.*$", "")
     446    else
     447        tmpdef = ''
     448    end
     449    if kind == "var" then
     450        -- check the form: void
     451        if s == '' or s == 'void' then
     452            return _Declaration{type = 'void', kind = kind, is_parameter = is_parameter}
     453        end
     454    end
     455
     456    -- check the form: mod type*& name
     457    local t = split_c_tokens(s,'%*%s*&')
     458    if t.n == 2 then
     459        if kind == 'func' then
     460            error("#invalid function return type: "..s)
     461        end
     462        --local m = split(t[1],'%s%s*')
     463        local m = split_c_tokens(t[1],'%s+')
     464        return _Declaration {
     465            name = t[2]..tmpdef,
     466            ptr = '*',
     467            ret = '&',
     468            --type = rebuild_template(m[m.n], tb, timpl),
     469            type = m[m.n],
     470            mod = concat(m,1,m.n-1),
     471            is_parameter = is_parameter,
     472            kind = kind
     473        }
     474    end
     475
     476    -- check the form: mod type** name
     477    t = split_c_tokens(s,'%*%s*%*')
     478    if t.n == 2 then
     479        if kind == 'func' then
     480            error("#invalid function return type: "..s)
     481        end
     482        --local m = split(t[1],'%s%s*')
     483        local m = split_c_tokens(t[1],'%s+')
     484        return _Declaration {
     485            name = t[2]..tmpdef,
     486            ptr = '*',
     487            ret = '*',
     488            --type = rebuild_template(m[m.n], tb, timpl),
     489            type = m[m.n],
     490            mod = concat(m,1,m.n-1),
     491            is_parameter = is_parameter,
     492            kind = kind
     493        }
     494    end
     495
     496    -- check the form: mod type& name
     497    t = split_c_tokens(s,'&')
     498    if t.n == 2 then
     499        --local m = split(t[1],'%s%s*')
     500        local m = split_c_tokens(t[1],'%s+')
     501        return _Declaration {
     502            name = t[2]..tmpdef,
     503            ptr = '&',
     504            --type = rebuild_template(m[m.n], tb, timpl),
     505            type = m[m.n],
     506            mod = concat(m,1,m.n-1),
     507            is_parameter = is_parameter,
     508            kind = kind
     509        }
     510    end
     511
     512    -- check the form: mod type* name
     513    local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)
     514    t = split_c_tokens(s1,'%*')
     515    if t.n == 2 then
     516        t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression
     517        --local m = split(t[1],'%s%s*')
     518        local m = split_c_tokens(t[1],'%s+')
     519        return _Declaration {
     520            name = t[2]..tmpdef,
     521            ptr = '*',
     522            type = m[m.n],
     523            --type = rebuild_template(m[m.n], tb, timpl),
     524            mod = concat(m,1,m.n-1)   ,
     525            is_parameter = is_parameter,
     526            kind = kind
     527        }
     528    end
     529
     530    if kind == 'var' then
     531        -- check the form: mod type name
     532        --t = split(s,'%s%s*')
     533        t = split_c_tokens(s,'%s+')
     534        local v
     535        if findtype(t[t.n]) then v = create_varname() else v = t[t.n]; t.n = t.n-1 end
     536        return _Declaration {
     537            name = v..tmpdef,
     538            --type = rebuild_template(t[t.n], tb, timpl),
     539            type = t[t.n],
     540            mod = concat(t,1,t.n-1),
     541            is_parameter = is_parameter,
     542            kind = kind
     543        }
     544
     545    else -- kind == "func"
     546
     547        -- check the form: mod type name
     548        --t = split(s,'%s%s*')
     549        t = split_c_tokens(s,'%s+')
     550        local v = t[t.n]  -- last word is the function name
     551        local tp,md
     552        if t.n>1 then
     553            tp = t[t.n-1]
     554            md = concat(t,1,t.n-2)
     555        end
     556        --if tp then tp = rebuild_template(tp, tb, timpl) end
     557        return _Declaration {
     558            name = v,
     559            type = tp,
     560            mod = md,
     561            is_parameter = is_parameter,
     562            kind = kind
     563        }
     564    end
     565
     566end
     567
  • code/trunk/src/tolua/lua/define.lua

    r2087 r2710  
    1616--   name = constant name
    1717classDefine = {
    18  name = '',
     18    name = '',
    1919}
    2020classDefine.__index = classDefine
     
    2323-- register define
    2424function classDefine:register (pre)
    25         if not self:check_public_access() then
    26                 return
    27         end
     25    if not self:check_public_access() then
     26        return
     27    end
    2828
    29  pre = pre or ''
    30  output(pre..'tolua_constant(tolua_S,"'..self.lname..'",'..self.name..');')
     29    pre = pre or ''
     30    output(pre..'tolua_constant(tolua_S,"'..self.lname..'",'..self.name..');')
    3131end
    3232
    3333-- Print method
    3434function classDefine:print (ident,close)
    35  print(ident.."Define{")
    36  print(ident.." name = '"..self.name.."',")
    37  print(ident.." lname = '"..self.lname.."',")
    38  print(ident.."}"..close)
     35    print(ident.."Define{")
     36    print(ident.." name = '"..self.name.."',")
     37    print(ident.." lname = '"..self.lname.."',")
     38    print(ident.."}"..close)
    3939end
    4040
     
    4242-- Internal constructor
    4343function _Define (t)
    44  setmetatable(t,classDefine)
    45  t:buildnames()
     44    setmetatable(t,classDefine)
     45    t:buildnames()
    4646
    47  if t.name == '' then
    48   error("#invalid define")
    49  end
     47    if t.name == '' then
     48        error("#invalid define")
     49    end
    5050
    51  append(t)
    52  return t
     51    append(t)
     52    return t
    5353end
    5454
     
    5656-- Expects a string representing the constant name
    5757function Define (n)
    58  return _Define{
    59   name = n
    60  }
     58    return _Define {
     59        name = n
     60    }
    6161end
    6262
  • code/trunk/src/tolua/lua/doit.lua

    r2087 r2710  
    1414function parse_extra()
    1515
    16         for k,v in ipairs(_extra_parameters or {}) do
    17                
    18                 local b,e,name,value = string.find(v, "^([^=])=(.*)$")
    19                 if b then
    20                         _extra_parameters[name] = value
    21                 else
    22                         _extra_parameters[v] = true
    23                 end
    24         end
     16    for k,v in ipairs(_extra_parameters or {}) do
     17       
     18        local b,e,name,value = string.find(v, "^([^=])=(.*)$")
     19        if b then
     20            _extra_parameters[name] = value
     21        else
     22            _extra_parameters[v] = true
     23        end
     24    end
    2525end
    2626
    2727function doit ()
    28         -- define package name, if not provided
    29         if not flags.n then
    30                 if flags.f then
    31                         flags.n = gsub(flags.f,"%..*$","")
    32                         _,_,flags.n = string.find(flags.n, "([^/\\]*)$")
    33                 else
    34                         error("#no package name nor input file provided")
    35                 end
    36         end
     28    -- define package name, if not provided
     29    if not flags.n then
     30        if flags.f then
     31            flags.n = gsub(flags.f,"%..*$","")
     32            _,_,flags.n = string.find(flags.n, "([^/\\]*)$")
     33        else
     34            error("#no package name nor input file provided")
     35        end
     36    end
    3737
    38         -- parse table with extra paramters
    39         parse_extra()
     38    -- parse table with extra paramters
     39    parse_extra()
    4040
    41         -- do this after setting the package name
    42         if flags['L'] then
    43                 dofile(flags['L'])
    44         end
     41    -- get potential working directory
     42    if not flags.w then
     43        flags.w = ''
     44    end
    4545
    46         -- add cppstring
    47         if not flags['S'] then
    48                 _basic['string'] = 'cppstring'
    49                 _basic['std::string'] = 'cppstring'
    50                 _basic_ctype.cppstring = 'const char*'
    51         end
     46    -- do this after setting the package name
     47    if flags.L then
     48        if string.sub(flags.L, 1, 1) == '/' or string.sub(flags.L, 1, 1) == '\\' or (string.len(flags.L) > 1 and string.sub(flags.L, 2, 2) == ':') then
     49            dofile(flags.L)
     50        else
     51            dofile(flags.w..'/'..flags.L)
     52        end
     53    end
    5254
    53         -- proccess package
    54         local p  = Package(flags.n,flags.f)
     55    -- add cppstring
     56    if not flags.S then
     57        _basic['string'] = 'cppstring'
     58        _basic['std::string'] = 'cppstring'
     59        _basic_ctype.cppstring = 'const char*'
     60    end
    5561
    56         if flags.p then
    57                 return        -- only parse
    58         end
     62    -- proccess package
     63    local file
     64    if flags.f then
     65        if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then
     66            file = flags.f
     67        else
     68            file = flags.w..'/'..flags.f
     69        end
     70    else
     71        file = flags.f
     72    end
     73    local p  = Package(flags.n, file)
    5974
    60         if flags.o then
    61                 local st,msg = writeto(flags.o)
    62                 if not st then
    63                         error('#'..msg)
    64                 end
    65         end
     75    if flags.p then
     76        return        -- only parse
     77    end
    6678
    67         p:decltype()
    68         if flags.P then
    69                 p:print()
    70         else
    71                 p:preamble()
    72                 p:supcode()
    73                 p:register()
    74                 push(p)
    75                 post_output_hook(p)
    76                 pop()
    77         end
     79    if flags.o then
     80        local file
     81        if string.sub(flags.o, 1, 1) == '/' or string.sub(flags.o, 1, 1) == '\\' or (string.len(flags.o) > 1 and string.sub(flags.o, 2, 2) == ':') then
     82            file = flags.o
     83        else
     84            file = flags.w..'/'..flags.o
     85        end
     86        local st,msg = writeto(file)
     87        if not st then
     88            error('#'..msg)
     89        end
     90    end
    7891
    79         if flags.o then
    80                 writeto()
    81         end
     92    p:decltype()
     93    if flags.P then
     94        p:print()
     95    else
     96        p:preamble()
     97        p:supcode()
     98        p:register()
     99        push(p)
     100        post_output_hook(p)
     101        pop()
     102    end
    82103
    83         -- write header file
    84         if not flags.P then
    85                 if flags.H then
    86                         local st,msg = writeto(flags.H)
    87                         if not st then
    88                                 error('#'..msg)
    89                         end
    90                         p:header()
    91                         writeto()
    92                 end
    93         end
     104    if flags.o then
     105        writeto()
     106    end
     107
     108    -- write header file
     109    if not flags.P then
     110        if flags.H then
     111            local file
     112            if string.sub(flags.H, 1, 1) == '/' or string.sub(flags.H, 1, 1) == '\\' or (string.len(flags.H) > 1 and string.sub(flags.H, 2, 2) == ':') then
     113                file = flags.H
     114            else
     115                file = flags.w..'/'..flags.H
     116            end
     117            local st,msg = writeto(file)
     118            if not st then
     119                error('#'..msg)
     120            end
     121            p:header()
     122            writeto()
     123        end
     124    end
    94125end
    95126
  • code/trunk/src/tolua/lua/enumerate.lua

    r2087 r2710  
    2222-- register enumeration
    2323function classEnumerate:register (pre)
    24  pre = pre or ''
    25  local nspace = getnamespace(classContainer.curr)
    26  local i=1
    27  while self[i] do
    28   output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');')
    29   i = i+1
    30  end
     24    pre = pre or ''
     25    local nspace = getnamespace(classContainer.curr)
     26    local i=1
     27    while self[i] do
     28        output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');')
     29        i = i+1
     30    end
    3131end
    3232
    3333-- Print method
    3434function classEnumerate:print (ident,close)
    35  print(ident.."Enumerate{")
    36  print(ident.." name = "..self.name)
    37  local i=1
    38  while self[i] do
    39   print(ident.." '"..self[i].."'("..self.lnames[i].."),")
    40   i = i+1
    41  end
    42  print(ident.."}"..close)
     35    print(ident.."Enumerate{")
     36    print(ident.." name = "..self.name)
     37    local i=1
     38    while self[i] do
     39        print(ident.." '"..self[i].."'("..self.lnames[i].."),")
     40        i = i+1
     41    end
     42    print(ident.."}"..close)
    4343end
    4444
    4545-- Internal constructor
    4646function _Enumerate (t,varname)
    47  setmetatable(t,classEnumerate)
    48  append(t)
    49  appendenum(t)
    50         if varname and varname ~= "" then
    51                 if t.name ~= "" then
    52                         Variable(t.name.." "..varname)
    53                 else
    54                         local ns = getcurrnamespace()
    55                         warning("Variable "..ns..varname.." of type <anonymous enum> is declared as read-only")
    56                         Variable("tolua_readonly int "..varname)
    57                 end
    58         end
    59 return t
     47    setmetatable(t,classEnumerate)
     48    append(t)
     49    appendenum(t)
     50    if varname and varname ~= "" then
     51        if t.name ~= "" then
     52            Variable(t.name.." "..varname)
     53        else
     54            local ns = getcurrnamespace()
     55            warning("Variable "..ns..varname.." of type <anonymous enum> is declared as read-only")
     56            Variable("tolua_readonly int "..varname)
     57        end
     58    end
     59    return t
    6060end
    6161
     
    6363-- Expects a string representing the enumerate body
    6464function Enumerate (n,b,varname)
    65         b = string.gsub(b, ",[%s\n]*}", "\n}") -- eliminate last ','
    66  local t = split(strsub(b,2,-2),',') -- eliminate braces
    67  local i = 1
    68  local e = {n=0}
    69  while t[i] do
    70   local tt = split(t[i],'=')  -- discard initial value
    71   e.n = e.n + 1
    72   e[e.n] = tt[1]
    73   i = i+1
    74  end
    75  -- set lua names
    76  i  = 1
    77  e.lnames = {}
    78  local ns = getcurrnamespace()
    79  while e[i] do
    80   local t = split(e[i],'@')
    81   e[i] = t[1]
    82                 if not t[2] then
    83                 t[2] = applyrenaming(t[1])
    84                 end
    85   e.lnames[i] = t[2] or t[1]
    86   _global_enums[ ns..e[i] ] = (ns..e[i])
    87   i = i+1
    88  end
    89         e.name = n
    90         if n ~= "" then
    91                 Typedef("int "..n)
    92         end
    93  return _Enumerate(e, varname)
     65    b = string.gsub(b, ",[%s\n]*}", "\n}") -- eliminate last ','
     66    local t = split(strsub(b,2,-2),',') -- eliminate braces
     67    local i = 1
     68    local e = {n=0}
     69    while t[i] do
     70        local tt = split(t[i],'=')  -- discard initial value
     71        e.n = e.n + 1
     72        e[e.n] = tt[1]
     73        i = i+1
     74    end
     75    -- set lua names
     76    i  = 1
     77    e.lnames = {}
     78    local ns = getcurrnamespace()
     79    while e[i] do
     80        local t = split(e[i],'@')
     81        e[i] = t[1]
     82        if not t[2] then
     83            t[2] = applyrenaming(t[1])
     84        end
     85        e.lnames[i] = t[2] or t[1]
     86        _global_enums[ ns..e[i] ] = (ns..e[i])
     87        i = i+1
     88    end
     89    e.name = n
     90    if n ~= "" then
     91        Typedef("int "..n)
     92    end
     93    return _Enumerate(e, varname)
    9494end
    9595
  • code/trunk/src/tolua/lua/feature.lua

    r2087 r2710  
    4040-- check if it requires collection
    4141function classFeature:requirecollection (t)
    42  return false
     42    return false
    4343end
    4444
    4545-- build names
    4646function classFeature:buildnames ()
    47  if self.name and self.name~='' then
    48   local n = split(self.name,'@')
    49   self.name = n[1]
    50   if not n[2] then
    51    n[2] = applyrenaming(n[1])
    52   end
    53   self.lname = n[2] or gsub(n[1],"%[.-%]","")
    54   self.original_name = self.name
    55   self.lname = clean_template(self.lname)
    56  end
    57  if not self.is_parameter then
    58         self.name = getonlynamespace() .. self.name
    59  end
     47    if self.name and self.name~='' then
     48        local n = split(self.name,'@')
     49        self.name = n[1]
     50        if not n[2] then
     51            n[2] = applyrenaming(n[1])
     52        end
     53        self.lname = n[2] or gsub(n[1],"%[.-%]","")
     54        self.original_name = self.name
     55        self.lname = clean_template(self.lname)
     56    end
     57    if not self.is_parameter then
     58        self.name = getonlynamespace() .. self.name
     59    end
    6060
    61  local parent = classContainer.curr
    62  if parent then
    63         self.access = parent.curr_member_access
    64  else
    65  end
     61    local parent = classContainer.curr
     62    if parent then
     63        self.access = parent.curr_member_access
     64    else
     65    end
    6666end
    6767
    6868function classFeature:check_public_access()
    6969
    70         if self.access and self.access ~= 0 then
    71                 return false
    72         end
     70    if self.access and self.access ~= 0 then
     71        return false
     72    end
    7373
    74         local parent = classContainer.curr
    75         while parent do
    76                 if parent.access and parent.access ~= 0 then
    77                         return false
    78                 end
    79                 parent = parent.prox
    80         end
    81         return true
     74    local parent = classContainer.curr
     75    while parent do
     76        if parent.access and parent.access ~= 0 then
     77            return false
     78        end
     79        parent = parent.prox
     80    end
     81    return true
    8282end
    8383
    8484function clean_template(t)
    8585
    86         return string.gsub(t, "[<>:, %*]", "_")
     86    return string.gsub(t, "[<>:, %*]", "_")
    8787end
    8888
     
    9090-- it returns the container class name or nil.
    9191function classFeature:incontainer (which)
    92  if self.parent then
    93   local parent = self.parent
    94   while parent do
    95    if parent.classtype == which then
    96     return parent.name
    97    end
    98    parent = parent.parent
    99   end
    100  end
    101  return nil
     92    if self.parent then
     93        local parent = self.parent
     94        while parent do
     95            if parent.classtype == which then
     96                return parent.name
     97            end
     98            parent = parent.parent
     99        end
     100    end
     101    return nil
    102102end
    103103
    104104function classFeature:inclass ()
    105  return self:incontainer('class')
     105    return self:incontainer('class')
    106106end
    107107
    108108function classFeature:inmodule ()
    109  return self:incontainer('module')
     109    return self:incontainer('module')
    110110end
    111111
    112112function classFeature:innamespace ()
    113  return self:incontainer('namespace')
     113    return self:incontainer('namespace')
    114114end
    115115
     
    118118function classFeature:cfuncname (n)
    119119
    120  if self.parent then
    121   n = self.parent:cfuncname(n)
    122  end
     120    if self.parent then
     121        n = self.parent:cfuncname(n)
     122    end
    123123
    124   n = string.gsub(n..'_'.. (self.lname or self.name), "[<>:, \.%*&]", "_")
     124    n = string.gsub(n..'_'.. (self.lname or self.name), "[<>:, \.%*&]", "_")
    125125
    126   return n
     126    return n
    127127end
    128128
  • code/trunk/src/tolua/lua/function.lua

    r2087 r2710  
    5252    if e.ret == "nil" then
    5353        output("catch(",nameToEcho," CEGUIDeadException(",exceptionDefs[e.name].var,"))\n{\n")
    54         else
    55         output("catch(",nameToEcho,exceptionDefs[e.name].var,")\n{\n")
    56         end
     54    else
     55        output("catch(",nameToEcho,exceptionDefs[e.name].var,")\n{\n")
     56    end
    5757
    5858    -- if just a nil
     
    141141--  const = if it is a method receiving a const "this".
    142142classFunction = {
    143  mod = '',
    144  type = '',
    145  ptr = '',
    146  name = '',
    147  args = {n=0},
    148  const = '',
     143    mod = '',
     144    type = '',
     145    ptr = '',
     146    name = '',
     147    args = {n=0},
     148    const = '',
    149149}
    150150classFunction.__index = classFunction
     
    153153-- declare tags
    154154function classFunction:decltype ()
    155  self.type = typevar(self.type)
    156  if strfind(self.mod,'const') then
    157         self.type = 'const '..self.type
    158                 self.mod = gsub(self.mod,'const','')
    159         end
    160  local i=1
    161  while self.args[i] do
    162   self.args[i]:decltype()
    163   i = i+1
    164  end
     155    self.type = typevar(self.type)
     156    if strfind(self.mod,'const') then
     157        self.type = 'const '..self.type
     158        self.mod = gsub(self.mod,'const','')
     159    end
     160    local i=1
     161    while self.args[i] do
     162        self.args[i]:decltype()
     163        i = i+1
     164    end
    165165end
    166166
     
    170170function classFunction:supcode (local_constructor)
    171171
    172  local overload = strsub(self.cname,-2,-1) - 1  -- indicate overloaded func
    173  local nret = 0      -- number of returned values
    174  local class = self:inclass()
    175  local _,_,static = strfind(self.mod,'^%s*(static)')
    176  if class then
    177 
    178         if self.name == 'new' and self.parent.flags.pure_virtual then
    179                 -- no constructor for classes with pure virtual methods
    180                 return
    181         end
    182 
    183         if local_constructor then
    184                 output("/* method: new_local of class ",class," */")
    185         else
    186                 output("/* method:",self.name," of class ",class," */")
    187         end
    188  else
    189   output("/* function:",self.name," */")
    190  end
    191 
    192  if local_constructor then
    193   output("#ifndef TOLUA_DISABLE_"..self.cname.."_local")
    194   output("\nstatic int",self.cname.."_local","(lua_State* tolua_S)")
    195  else
    196   output("#ifndef TOLUA_DISABLE_"..self.cname)
    197   output("\nstatic int",self.cname,"(lua_State* tolua_S)")
    198  end
    199  output("{")
    200 
    201  -- check types
    202         if overload < 0 then
    203         output('#ifndef TOLUA_RELEASE\n')
    204         end
    205         output(' tolua_Error tolua_err;')
    206  output(' if (\n')
    207  -- check self
    208  local narg
    209  if class then narg=2 else narg=1 end
    210  if class then
    211                 local func = 'tolua_isusertype'
    212                 local type = self.parent.type
    213                 if self.name=='new' or static~=nil then
    214                         func = 'tolua_isusertable'
    215                         type = self.parent.type
    216                 end
    217                 if self.const ~= '' then
    218                         type = "const "..type
    219                 end
    220                 output('     !'..func..'(tolua_S,1,"'..type..'",0,&tolua_err) ||\n')
    221  end
    222  -- check args
    223  if self.args[1].type ~= 'void' then
    224   local i=1
    225   while self.args[i] do
    226    local btype = isbasic(self.args[i].type)
    227    if btype ~= 'value' and btype ~= 'state' then
    228     output('     !'..self.args[i]:outchecktype(narg)..' ||\n')
    229    end
    230    if btype ~= 'state' then
    231            narg = narg+1
    232    end
    233    i = i+1
    234   end
    235  end
    236  -- check end of list
    237  output('     !tolua_isnoobj(tolua_S,'..narg..',&tolua_err)\n )')
    238         output('  goto tolua_lerror;')
    239 
    240  output(' else\n')
    241         if overload < 0 then
    242         output('#endif\n')
    243         end
    244         output(' {')
    245 
    246  -- declare self, if the case
    247  local narg
    248  if class then narg=2 else narg=1 end
    249  if class and self.name~='new' and static==nil then
    250   output(' ',self.const,self.parent.type,'*','self = ')
    251   output('(',self.const,self.parent.type,'*) ')
    252   output('tolua_tousertype(tolua_S,1,0);')
    253  elseif static then
    254   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
    255  end
    256  -- declare parameters
    257  if self.args[1].type ~= 'void' then
    258   local i=1
    259   while self.args[i] do
    260    self.args[i]:declare(narg)
    261    if isbasic(self.args[i].type) ~= "state" then
    262            narg = narg+1
    263    end
    264    i = i+1
    265   end
    266  end
    267 
    268  -- check self
    269  if class and self.name~='new' and static==nil then
    270         output('#ifndef TOLUA_RELEASE\n')
    271   output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
    272         output('#endif\n')
    273  end
    274 
    275  -- get array element values
    276  if class then narg=2 else narg=1 end
    277  if self.args[1].type ~= 'void' then
    278   local i=1
    279   while self.args[i] do
    280    self.args[i]:getarray(narg)
    281    narg = narg+1
    282    i = i+1
    283   end
    284  end
    285 
    286  --------------------------------------------------
    287  -- CEGUILua mod
    288  -- init exception handling
    289  local throws = false
    290  do
    291   local pattern = "tolua_throws|.*|"
    292   local i,j = string.find(self.mod, pattern)
    293   if i then
    294    throws = {}
    295    -- ensure table is empty.  Used to be: table.setn(throws,0)
    296    for x in pairs(throws) do
    297      throws[x] = nil
    298    end
    299    local excepts = string.sub(self.mod, i+12,j)
    300    local epattern = "|.-|"
    301    local i,j = string.find(excepts, epattern)
    302    while i do
    303     local e = string.sub(excepts,i+1,j-1)
    304     local _,_,name,rest = string.find(e, "([%w:_]+),?(.*)")
    305     table.insert(throws,{name=name, ret=rest})
    306     i,j = string.find(excepts, epattern, j)
    307    end
    308    self.mod = string.gsub(self.mod, pattern, "")
    309   end
    310  end
    311  local exRaiseError = false
    312  --------------------------------------------------
    313 
    314  local out = string.find(self.mod, "tolua_outside")
    315 
    316  ---------------
    317  -- CEGUILua mod
    318  -- remove "tolua_outside" from self.mod
    319  if out then
    320     self.mod = string.gsub(self.mod, "tolua_outside", "")
    321  end
    322 
    323  -- call function
    324  if class and self.name=='delete' then
    325   output('  delete self;')
    326  elseif class and self.name == 'operator&[]' then
    327   if flags['1'] then -- for compatibility with tolua5 ?
    328         output('  self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';')
    329   else
    330     output('  self->operator[](',self.args[1].name,') = ',self.args[2].name,';')
    331   end
    332  else
    333   -- CEGUILua mod begin- throws
    334   if throws then
    335     for i=1,table.getn(throws) do
    336         if string.find(throws[i].ret, "error") then
    337             output("char errorBuffer["..exceptionMessageBufferSize.."];\n")
    338             output("bool errorDoIt = false;\n")
    339             exRaiseError = true
    340             break
    341         end
    342     end
    343     output("try\n")
    344   end
    345   -- CEGUILua mod end - throws
    346   output('  {')
    347   if self.type ~= '' and self.type ~= 'void' then
    348    output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
    349    output('(',self.mod,self.type,self.ptr,') ')
    350   else
    351    output('  ')
    352   end
    353   if class and self.name=='new' then
    354    output('new',self.type,'(')
    355   elseif class and static then
    356         if out then
    357                 output(self.name,'(')
    358         else
    359                 output(class..'::'..self.name,'(')
    360         end
    361   elseif class then
    362         if out then
    363                 output(self.name,'(')
    364         else
    365           if self.cast_operator then
    366                 output('static_cast<',self.mod,self.type,self.ptr,'>(*self')
    367           else
    368                 output('self->'..self.name,'(')
    369           end
    370         end
    371   else
    372    output(self.name,'(')
    373   end
    374 
    375   if out and not static then
    376         output('self')
    377         if self.args[1] and self.args[1].name ~= '' then
    378                 output(',')
    379         end
    380   end
    381   -- write parameters
    382   local i=1
    383   while self.args[i] do
    384    self.args[i]:passpar()
    385    i = i+1
    386    if self.args[i] then
    387     output(',')
    388    end
    389   end
    390 
    391   if class and self.name == 'operator[]' and flags['1'] then
    392         output('-1);')
    393   else
    394         output(');')
    395   end
    396 
    397   -- return values
    398   if self.type ~= '' and self.type ~= 'void' then
    399    nret = nret + 1
    400    local t,ct = isbasic(self.type)
    401    if t then
    402         if self.cast_operator and _basic_raw_push[t] then
    403                 output('   ',_basic_raw_push[t],'(tolua_S,(',ct,')tolua_ret);')
    404         else
    405             output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
    406         end
    407    else
    408                         t = self.type
    409                         new_t = string.gsub(t, "const%s+", "")
    410     if self.ptr == '' then
    411      output('   {')
    412      output('#ifdef __cplusplus\n')
    413      output('    void* tolua_obj = new',new_t,'(tolua_ret);')
    414      output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
    415      output('#else\n')
    416      output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
    417      output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
    418      output('#endif\n')
    419      output('   }')
    420     elseif self.ptr == '&' then
    421      output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
    422     else
    423         if local_constructor then
    424           output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
    425         else
    426                      output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
    427             end
    428     end
    429    end
    430   end
    431   local i=1
    432   while self.args[i] do
    433    nret = nret + self.args[i]:retvalue()
    434    i = i+1
    435   end
    436   output('  }')
    437 
    438   ------------------------------------------
    439   -- CEGUILua mod
    440   -- finish exception handling
    441   -- catch
    442   if throws then
    443    outputExceptionCatchBlocks(self.name, throws, exRaiseError)
    444   end
    445   ------------------------------------------
    446 
    447   -- set array element values
    448   if class then narg=2 else narg=1 end
    449   if self.args[1].type ~= 'void' then
    450    local i=1
    451    while self.args[i] do
    452     self.args[i]:setarray(narg)
    453     narg = narg+1
    454     i = i+1
    455    end
    456   end
    457 
    458   -- free dynamically allocated array
    459   if self.args[1].type ~= 'void' then
    460    local i=1
    461    while self.args[i] do
    462     self.args[i]:freearray()
    463     i = i+1
    464    end
    465   end
    466  end
    467 
    468  output(' }')
    469  output(' return '..nret..';')
    470 
    471  -- call overloaded function or generate error
    472         if overload < 0 then
    473 
    474                 output('#ifndef TOLUA_RELEASE\n')
    475                 output('tolua_lerror:\n')
    476                 output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
    477                 output(' return 0;')
    478                 output('#endif\n')
    479         else
    480                 local _local = ""
    481                 if local_constructor then
    482                         _local = "_local"
    483                 end
    484                 output('tolua_lerror:\n')
    485                 output(' return '..strsub(self.cname,1,-3)..format("%02d",overload).._local..'(tolua_S);')
    486         end
    487  output('}')
    488  output('#endif //#ifndef TOLUA_DISABLE\n')
    489  output('\n')
    490 
    491         -- recursive call to write local constructor
    492         if class and self.name=='new' and not local_constructor then
    493 
    494                 self:supcode(1)
    495         end
     172    local overload = strsub(self.cname,-2,-1) - 1  -- indicate overloaded func
     173    local nret = 0      -- number of returned values
     174    local class = self:inclass()
     175    local _,_,static = strfind(self.mod,'^%s*(static)')
     176    if class then
     177
     178        if self.name == 'new' and self.parent.flags.pure_virtual then
     179            -- no constructor for classes with pure virtual methods
     180            return
     181        end
     182
     183        if local_constructor then
     184           output("/* method: new_local of class ",class," */")
     185       else
     186           output("/* method:",self.name," of class ",class," */")
     187       end
     188    else
     189        output("/* function:",self.name," */")
     190    end
     191
     192    if local_constructor then
     193        output("#ifndef TOLUA_DISABLE_"..self.cname.."_local")
     194        output("\nstatic int",self.cname.."_local","(lua_State* tolua_S)")
     195    else
     196        output("#ifndef TOLUA_DISABLE_"..self.cname)
     197        output("\nstatic int",self.cname,"(lua_State* tolua_S)")
     198    end
     199    output("{")
     200
     201    -- check types
     202    if overload < 0 then
     203        output('#ifndef TOLUA_RELEASE\n')
     204    end
     205    output(' tolua_Error tolua_err;')
     206    output(' if (\n')
     207    -- check self
     208    local narg
     209    if class then narg=2 else narg=1 end
     210    if class then
     211        local func = 'tolua_isusertype'
     212        local type = self.parent.type
     213        if self.name=='new' or static~=nil then
     214            func = 'tolua_isusertable'
     215            type = self.parent.type
     216        end
     217        if self.const ~= '' then
     218            type = "const "..type
     219        end
     220        output('     !'..func..'(tolua_S,1,"'..type..'",0,&tolua_err) ||\n')
     221    end
     222    -- check args
     223    if self.args[1].type ~= 'void' then
     224        local i=1
     225        while self.args[i] do
     226            local btype = isbasic(self.args[i].type)
     227            if btype ~= 'value' and btype ~= 'state' then
     228                output('     !'..self.args[i]:outchecktype(narg)..' ||\n')
     229            end
     230            if btype ~= 'state' then
     231                narg = narg+1
     232            end
     233            i = i+1
     234        end
     235    end
     236    -- check end of list
     237    output('     !tolua_isnoobj(tolua_S,'..narg..',&tolua_err)\n )')
     238    output('  goto tolua_lerror;')
     239
     240    output(' else\n')
     241    if overload < 0 then
     242        output('#endif\n')
     243    end
     244    output(' {')
     245
     246    -- declare self, if the case
     247    local narg
     248    if class then narg=2 else narg=1 end
     249    if class and self.name~='new' and static==nil then
     250        output(' ',self.const,self.parent.type,'*','self = ')
     251        output('(',self.const,self.parent.type,'*) ')
     252        output('tolua_tousertype(tolua_S,1,0);')
     253    elseif static then
     254        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
     255    end
     256    -- declare parameters
     257    if self.args[1].type ~= 'void' then
     258        local i=1
     259        while self.args[i] do
     260            self.args[i]:declare(narg)
     261            if isbasic(self.args[i].type) ~= "state" then
     262                narg = narg+1
     263            end
     264            i = i+1
     265        end
     266    end
     267
     268    -- check self
     269    if class and self.name~='new' and static==nil then
     270        output('#ifndef TOLUA_RELEASE\n')
     271        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
     272        output('#endif\n')
     273    end
     274
     275    -- get array element values
     276    if class then narg=2 else narg=1 end
     277    if self.args[1].type ~= 'void' then
     278        local i=1
     279        while self.args[i] do
     280            self.args[i]:getarray(narg)
     281            narg = narg+1
     282            i = i+1
     283        end
     284    end
     285
     286    --------------------------------------------------
     287    -- CEGUILua mod
     288    -- init exception handling
     289    local throws = false
     290    do
     291        local pattern = "tolua_throws|.*|"
     292        local i,j = string.find(self.mod, pattern)
     293        if i then
     294            throws = {}
     295            -- ensure table is empty.  Used to be: table.setn(throws,0)
     296            for x in pairs(throws) do
     297                throws[x] = nil
     298            end
     299            local excepts = string.sub(self.mod, i+12,j)
     300            local epattern = "|.-|"
     301            local i,j = string.find(excepts, epattern)
     302            while i do
     303                local e = string.sub(excepts,i+1,j-1)
     304                local _,_,name,rest = string.find(e, "([%w:_]+),?(.*)")
     305                table.insert(throws,{name=name, ret=rest})
     306                i,j = string.find(excepts, epattern, j)
     307            end
     308            self.mod = string.gsub(self.mod, pattern, "")
     309        end
     310    end
     311    local exRaiseError = false
     312    --------------------------------------------------
     313
     314    local out = string.find(self.mod, "tolua_outside")
     315
     316    ---------------
     317    -- CEGUILua mod
     318    -- remove "tolua_outside" from self.mod
     319    if out then
     320        self.mod = string.gsub(self.mod, "tolua_outside", "")
     321    end
     322
     323    -- call function
     324    if class and self.name=='delete' then
     325        output('  delete self;')
     326    elseif class and self.name == 'operator&[]' then
     327        if flags['1'] then -- for compatibility with tolua5 ?
     328            output('  self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';')
     329        else
     330            output('  self->operator[](',self.args[1].name,') = ',self.args[2].name,';')
     331        end
     332    else
     333    -- CEGUILua mod begin- throws
     334    if throws then
     335        for i=1,table.getn(throws) do
     336            if string.find(throws[i].ret, "error") then
     337                output("char errorBuffer["..exceptionMessageBufferSize.."];\n")
     338                output("bool errorDoIt = false;\n")
     339                exRaiseError = true
     340                break
     341            end
     342        end
     343        output("try\n")
     344    end
     345    -- CEGUILua mod end - throws
     346    output('  {')
     347    if self.type ~= '' and self.type ~= 'void' then
     348        output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
     349        output('(',self.mod,self.type,self.ptr,') ')
     350    else
     351        output('  ')
     352    end
     353    if class and self.name=='new' then
     354        output('new',self.type,'(')
     355    elseif class and static then
     356        if out then
     357            output(self.name,'(')
     358        else
     359            output(class..'::'..self.name,'(')
     360        end
     361    elseif class then
     362        if out then
     363            output(self.name,'(')
     364        else
     365            if self.cast_operator then
     366                output('static_cast<',self.mod,self.type,self.ptr,'>(*self')
     367            else
     368                output('self->'..self.name,'(')
     369            end
     370        end
     371    else
     372        output(self.name,'(')
     373    end
     374
     375    if out and not static then
     376        output('self')
     377        if self.args[1] and self.args[1].name ~= '' then
     378            output(',')
     379        end
     380    end
     381    -- write parameters
     382    local i=1
     383    while self.args[i] do
     384        self.args[i]:passpar()
     385        i = i+1
     386        if self.args[i] then
     387            output(',')
     388        end
     389    end
     390
     391    if class and self.name == 'operator[]' and flags['1'] then
     392        output('-1);')
     393    else
     394        output(');')
     395    end
     396
     397    -- return values
     398    if self.type ~= '' and self.type ~= 'void' then
     399        nret = nret + 1
     400        local t,ct = isbasic(self.type)
     401        if t then
     402            if self.cast_operator and _basic_raw_push[t] then
     403                output('   ',_basic_raw_push[t],'(tolua_S,(',ct,')tolua_ret);')
     404            else
     405                output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
     406            end
     407            else
     408                t = self.type
     409                new_t = string.gsub(t, "const%s+", "")
     410                if self.ptr == '' then
     411                    output('   {')
     412                    output('#ifdef __cplusplus\n')
     413                    output('    void* tolua_obj = new',new_t,'(tolua_ret);')
     414                    output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
     415                    output('#else\n')
     416                    output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
     417                    output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
     418                    output('#endif\n')
     419                    output('   }')
     420                elseif self.ptr == '&' then
     421                    output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
     422                else
     423                    if local_constructor then
     424                        output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
     425                    else
     426                        output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
     427                    end
     428                end
     429            end
     430        end
     431        local i=1
     432        while self.args[i] do
     433            nret = nret + self.args[i]:retvalue()
     434            i = i+1
     435        end
     436        output('  }')
     437
     438        ------------------------------------------
     439        -- CEGUILua mod
     440        -- finish exception handling
     441        -- catch
     442        if throws then
     443            outputExceptionCatchBlocks(self.name, throws, exRaiseError)
     444        end
     445        ------------------------------------------
     446
     447        -- set array element values
     448        if class then narg=2 else narg=1 end
     449        if self.args[1].type ~= 'void' then
     450            local i=1
     451            while self.args[i] do
     452                self.args[i]:setarray(narg)
     453                narg = narg+1
     454                i = i+1
     455            end
     456        end
     457
     458        -- free dynamically allocated array
     459        if self.args[1].type ~= 'void' then
     460            local i=1
     461            while self.args[i] do
     462                self.args[i]:freearray()
     463                i = i+1
     464            end
     465        end
     466    end
     467
     468    output(' }')
     469    output(' return '..nret..';')
     470
     471    -- call overloaded function or generate error
     472    if overload < 0 then
     473
     474        output('#ifndef TOLUA_RELEASE\n')
     475        output('tolua_lerror:\n')
     476        output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
     477        output(' return 0;')
     478        output('#endif\n')
     479    else
     480        local _local = ""
     481        if local_constructor then
     482            _local = "_local"
     483        end
     484        output('tolua_lerror:\n')
     485        output(' return '..strsub(self.cname,1,-3)..format("%02d",overload).._local..'(tolua_S);')
     486    end
     487    output('}')
     488    output('#endif //#ifndef TOLUA_DISABLE\n')
     489    output('\n')
     490
     491    -- recursive call to write local constructor
     492    if class and self.name=='new' and not local_constructor then
     493
     494        self:supcode(1)
     495    end
    496496
    497497end
     
    501501function classFunction:register (pre)
    502502
    503         if not self:check_public_access() then
    504                 return
    505         end
    506 
    507         if self.name == 'new' and self.parent.flags.pure_virtual then
    508                 -- no constructor for classes with pure virtual methods
    509                 return
    510         end
    511 
    512  output(pre..'tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');')
    513   if self.name == 'new' then
    514           output(pre..'tolua_function(tolua_S,"new_local",'..self.cname..'_local);')
    515           output(pre..'tolua_function(tolua_S,".call",'..self.cname..'_local);')
    516           --output(' tolua_set_call_event(tolua_S,'..self.cname..'_local, "'..self.parent.type..'");')
    517   end
     503    if not self:check_public_access() then
     504        return
     505    end
     506
     507    if self.name == 'new' and self.parent.flags.pure_virtual then
     508        -- no constructor for classes with pure virtual methods
     509        return
     510    end
     511
     512    output(pre..'tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');')
     513    if self.name == 'new' then
     514        output(pre..'tolua_function(tolua_S,"new_local",'..self.cname..'_local);')
     515        output(pre..'tolua_function(tolua_S,".call",'..self.cname..'_local);')
     516        --output(' tolua_set_call_event(tolua_S,'..self.cname..'_local, "'..self.parent.type..'");')
     517    end
    518518end
    519519
    520520-- Print method
    521521function classFunction:print (ident,close)
    522  print(ident.."Function{")
    523  print(ident.." mod  = '"..self.mod.."',")
    524  print(ident.." type = '"..self.type.."',")
    525  print(ident.." ptr  = '"..self.ptr.."',")
    526  print(ident.." name = '"..self.name.."',")
    527  print(ident.." lname = '"..self.lname.."',")
    528  print(ident.." const = '"..self.const.."',")
    529  print(ident.." cname = '"..self.cname.."',")
    530  print(ident.." lname = '"..self.lname.."',")
    531  print(ident.." args = {")
    532  local i=1
    533  while self.args[i] do
    534   self.args[i]:print(ident.."  ",",")
    535   i = i+1
    536  end
    537  print(ident.." }")
    538  print(ident.."}"..close)
     522    print(ident.."Function{")
     523    print(ident.." mod  = '"..self.mod.."',")
     524    print(ident.." type = '"..self.type.."',")
     525    print(ident.." ptr  = '"..self.ptr.."',")
     526    print(ident.." name = '"..self.name.."',")
     527    print(ident.." lname = '"..self.lname.."',")
     528    print(ident.." const = '"..self.const.."',")
     529    print(ident.." cname = '"..self.cname.."',")
     530    print(ident.." lname = '"..self.lname.."',")
     531    print(ident.." args = {")
     532    local i=1
     533    while self.args[i] do
     534        self.args[i]:print(ident.."  ",",")
     535        i = i+1
     536    end
     537    print(ident.." }")
     538    print(ident.."}"..close)
    539539end
    540540
    541541-- check if it returns an object by value
    542542function classFunction:requirecollection (t)
    543         local r = false
    544         if self.type ~= '' and not isbasic(self.type) and self.ptr=='' then
    545                 local type = gsub(self.type,"%s*const%s+","")
    546         t[type] = "tolua_collect_" .. clean_template(type)
    547         r = true
    548         end
    549         local i=1
    550         while self.args[i] do
    551                 r = self.args[i]:requirecollection(t) or r
    552                 i = i+1
    553         end
    554         return r
     543    local r = false
     544    if self.type ~= '' and not isbasic(self.type) and self.ptr=='' then
     545        local type = gsub(self.type,"%s*const%s+","")
     546        t[type] = "tolua_collect_" .. clean_template(type)
     547        r = true
     548    end
     549    local i=1
     550    while self.args[i] do
     551        r = self.args[i]:requirecollection(t) or r
     552        i = i+1
     553    end
     554    return r
    555555end
    556556
    557557-- determine lua function name overload
    558558function classFunction:overload ()
    559  return self.parent:overload(self.lname)
     559    return self.parent:overload(self.lname)
    560560end
    561561
     
    563563function param_object(par) -- returns true if the parameter has an object as its default value
    564564
    565         if not string.find(par, '=') then return false end -- it has no default value
    566 
    567         local _,_,def = string.find(par, "=(.*)$")
    568 
    569         if string.find(par, "|") then -- a list of flags
    570 
    571                 return true
    572         end
    573 
    574         if string.find(par, "%*") then -- it's a pointer with a default value
    575 
    576                 if string.find(par, '=%s*new') then -- it's a pointer with an instance as default parameter.. is that valid?
    577                         return true
    578                 end
    579                 return false -- default value is 'NULL' or something
    580         end
    581 
    582 
    583         if string.find(par, "[%(&]") then
    584                 return true
    585         end -- default value is a constructor call (most likely for a const reference)
    586 
    587         --if string.find(par, "&") then
    588 
    589         --      if string.find(def, ":") or string.find(def, "^%s*new%s+") then
    590 
    591         --              -- it's a reference with default to something like Class::member, or 'new Class'
    592         --              return true
    593         --      end
    594         --end
    595 
    596         return false -- ?
     565    if not string.find(par, '=') then return false end -- it has no default value
     566
     567    local _,_,def = string.find(par, "=(.*)$")
     568
     569    if string.find(par, "|") then -- a list of flags
     570
     571        return true
     572    end
     573
     574    if string.find(par, "%*") then -- it's a pointer with a default value
     575
     576        if string.find(par, '=%s*new') then -- it's a pointer with an instance as default parameter.. is that valid?
     577            return true
     578        end
     579        return false -- default value is 'NULL' or something
     580    end
     581
     582
     583    if string.find(par, "[%(&]") then
     584        return true
     585    end -- default value is a constructor call (most likely for a const reference)
     586
     587    --if string.find(par, "&") then
     588
     589    --    if string.find(def, ":") or string.find(def, "^%s*new%s+") then
     590
     591    --        -- it's a reference with default to something like Class::member, or 'new Class'
     592    --        return true
     593    --    end
     594    --end
     595
     596    return false -- ?
    597597end
    598598
    599599function strip_last_arg(all_args, last_arg) -- strips the default value from the last argument
    600600
    601         local _,_,s_arg = string.find(last_arg, "^([^=]+)")
    602         last_arg = string.gsub(last_arg, "([%%%(%)])", "%%%1");
    603         all_args = string.gsub(all_args, "%s*,%s*"..last_arg.."%s*%)%s*$", ")")
    604         return all_args, s_arg
     601    local _,_,s_arg = string.find(last_arg, "^([^=]+)")
     602    last_arg = string.gsub(last_arg, "([%%%(%)])", "%%%1");
     603    all_args = string.gsub(all_args, "%s*,%s*"..last_arg.."%s*%)%s*$", ")")
     604    return all_args, s_arg
    605605end
    606606
     
    609609-- Internal constructor
    610610function _Function (t)
    611  setmetatable(t,classFunction)
    612 
    613  if t.const ~= 'const' and t.const ~= '' then
    614   error("#invalid 'const' specification")
    615  end
    616 
    617  append(t)
    618  if t:inclass() then
    619  --print ('t.name is '..t.name..', parent.name is '..t.parent.name)
    620   if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
    621    t.name = 'new'
    622    t.lname = 'new'
    623    t.parent._new = true
    624    t.type = t.parent.name
    625    t.ptr = '*'
    626   elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
    627    t.name = 'delete'
    628    t.lname = 'delete'
    629    t.parent._delete = true
    630   end
    631  end
    632  t.cname = t:cfuncname("tolua")..t:overload(t)
    633  return t
     611    setmetatable(t,classFunction)
     612
     613    if t.const ~= 'const' and t.const ~= '' then
     614        error("#invalid 'const' specification")
     615    end
     616
     617    append(t)
     618    if t:inclass() then
     619        --print ('t.name is '..t.name..', parent.name is '..t.parent.name)
     620        if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
     621            t.name = 'new'
     622            t.lname = 'new'
     623            t.parent._new = true
     624            t.type = t.parent.name
     625            t.ptr = '*'
     626        elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
     627            t.name = 'delete'
     628            t.lname = 'delete'
     629            t.parent._delete = true
     630        end
     631    end
     632    t.cname = t:cfuncname("tolua")..t:overload(t)
     633    return t
    634634end
    635635
     
    639639-- the "const" or empty string.
    640640function Function (d,a,c)
    641  --local t = split(strsub(a,2,-2),',') -- eliminate braces
    642  --local t = split_params(strsub(a,2,-2))
    643 
    644         if not flags['W'] and string.find(a, "%.%.%.%s*%)") then
    645 
    646                 warning("Functions with variable arguments (`...') are not supported. Ignoring "..d..a..c)
    647                 return nil
    648         end
    649 
    650 
    651  local i=1
    652  local l = {n=0}
    653 
    654         a = string.gsub(a, "%s*([%(%)])%s*", "%1")
    655         local t,strip,last = strip_pars(strsub(a,2,-2));
    656         if strip then
    657                 --local ns = string.sub(strsub(a,1,-2), 1, -(string.len(last)+1))
    658                 local ns = join(t, ",", 1, last-1)
    659 
    660                 ns = "("..string.gsub(ns, "%s*,%s*$", "")..')'
    661                 --ns = strip_defaults(ns)
    662 
    663                 Function(d, ns, c)
    664                 for i=1,last do
    665                         t[i] = string.gsub(t[i], "=.*$", "")
    666                 end
    667         end
    668 
    669  while t[i] do
    670   l.n = l.n+1
    671   l[l.n] = Declaration(t[i],'var',true)
    672   i = i+1
    673  end
    674  local f = Declaration(d,'func')
    675  f.args = l
    676  f.const = c
    677  return _Function(f)
     641    --local t = split(strsub(a,2,-2),',') -- eliminate braces
     642    --local t = split_params(strsub(a,2,-2))
     643
     644    if not flags['W'] and string.find(a, "%.%.%.%s*%)") then
     645
     646        warning("Functions with variable arguments (`...') are not supported. Ignoring "..d..a..c)
     647        return nil
     648    end
     649
     650
     651    local i=1
     652    local l = {n=0}
     653
     654    a = string.gsub(a, "%s*([%(%)])%s*", "%1")
     655    local t,strip,last = strip_pars(strsub(a,2,-2));
     656    if strip then
     657        --local ns = string.sub(strsub(a,1,-2), 1, -(string.len(last)+1))
     658        local ns = join(t, ",", 1, last-1)
     659
     660        ns = "("..string.gsub(ns, "%s*,%s*$", "")..')'
     661        --ns = strip_defaults(ns)
     662
     663        Function(d, ns, c)
     664        for i=1,last do
     665            t[i] = string.gsub(t[i], "=.*$", "")
     666        end
     667    end
     668
     669    while t[i] do
     670        l.n = l.n+1
     671        l[l.n] = Declaration(t[i],'var',true)
     672        i = i+1
     673    end
     674    local f = Declaration(d,'func')
     675    f.args = l
     676    f.const = c
     677    return _Function(f)
    678678end
    679679
    680680function join(t, sep, first, last)
    681681
    682         first = first or 1
    683         last = last or table.getn(t)
    684         local lsep = ""
    685         local ret = ""
    686         local loop = false
    687         for i = first,last do
    688 
    689                 ret = ret..lsep..t[i]
    690                 lsep = sep
    691                 loop = true
    692         end
    693         if not loop then
    694                 return ""
    695         end
    696 
    697         return ret
     682    first = first or 1
     683    last = last or table.getn(t)
     684    local lsep = ""
     685    local ret = ""
     686    local loop = false
     687    for i = first,last do
     688
     689        ret = ret..lsep..t[i]
     690        lsep = sep
     691        loop = true
     692    end
     693    if not loop then
     694        return ""
     695    end
     696
     697    return ret
    698698end
    699699
    700700function strip_pars(s)
    701701
    702         local t = split_c_tokens(s, ',')
    703         local strip = false
    704         local last
    705 
    706         for i=t.n,1,-1 do
    707 
    708                 if not strip and param_object(t[i]) then
    709                         last = i
    710                         strip = true
    711                 end
    712                 --if strip then
    713                 --      t[i] = string.gsub(t[i], "=.*$", "")
    714                 --end
    715         end
    716 
    717         return t,strip,last
     702    local t = split_c_tokens(s, ',')
     703    local strip = false
     704    local last
     705
     706    for i=t.n,1,-1 do
     707
     708        if not strip and param_object(t[i]) then
     709            last = i
     710            strip = true
     711        end
     712        --if strip then
     713        --    t[i] = string.gsub(t[i], "=.*$", "")
     714        --end
     715    end
     716
     717    return t,strip,last
    718718
    719719end
     
    721721function strip_defaults(s)
    722722
    723         s = string.gsub(s, "^%(", "")
    724         s = string.gsub(s, "%)$", "")
    725 
    726         local t = split_c_tokens(s, ",")
    727         local sep, ret = "",""
    728         for i=1,t.n do
    729                 t[i] = string.gsub(t[i], "=.*$", "")
    730                 ret = ret..sep..t[i]
    731                 sep = ","
    732         end
    733 
    734         return "("..ret..")"
    735 end
    736 
    737 
     723    s = string.gsub(s, "^%(", "")
     724    s = string.gsub(s, "%)$", "")
     725
     726    local t = split_c_tokens(s, ",")
     727    local sep, ret = "",""
     728    for i=1,t.n do
     729        t[i] = string.gsub(t[i], "=.*$", "")
     730        ret = ret..sep..t[i]
     731        sep = ","
     732    end
     733
     734    return "("..ret..")"
     735end
     736
     737
  • code/trunk/src/tolua/lua/module.lua

    r2087 r2710  
    1717--    {i} = list of objects in the module.
    1818classModule = {
    19  classtype = 'module'
     19    classtype = 'module'
    2020}
    2121classModule.__index = classModule
     
    2424-- register module
    2525function classModule:register (pre)
    26  pre = pre or ''
    27  push(self)
    28  output(pre..'tolua_module(tolua_S,"'..self.name..'",',self:hasvar(),');')
    29  output(pre..'tolua_beginmodule(tolua_S,"'..self.name..'");')
    30  local i=1
    31  while self[i] do
    32   self[i]:register(pre..' ')
    33   i = i+1
    34  end
    35  output(pre..'tolua_endmodule(tolua_S);')
    36         pop()
     26    pre = pre or ''
     27    push(self)
     28    output(pre..'tolua_module(tolua_S,"'..self.name..'",',self:hasvar(),');')
     29    output(pre..'tolua_beginmodule(tolua_S,"'..self.name..'");')
     30    local i=1
     31    while self[i] do
     32        self[i]:register(pre..' ')
     33        i = i+1
     34    end
     35    output(pre..'tolua_endmodule(tolua_S);')
     36    pop()
    3737end
    3838
    3939-- Print method
    4040function classModule:print (ident,close)
    41  print(ident.."Module{")
    42  print(ident.." name = '"..self.name.."';")
    43  local i=1
    44  while self[i] do
    45   self[i]:print(ident.." ",",")
    46   i = i+1
    47  end
    48  print(ident.."}"..close)
     41    print(ident.."Module{")
     42    print(ident.." name = '"..self.name.."';")
     43    local i=1
     44    while self[i] do
     45        self[i]:print(ident.." ",",")
     46        i = i+1
     47    end
     48    print(ident.."}"..close)
    4949end
    5050
    5151-- Internal constructor
    5252function _Module (t)
    53  setmetatable(t,classModule)
    54  append(t)
    55  return t
     53    setmetatable(t,classModule)
     54    append(t)
     55    return t
    5656end
    5757
     
    5959-- Expects two string representing the module name and body.
    6060function Module (n,b)
    61  local t = _Module(_Container{name=n})
    62  push(t)
    63  t:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
    64  pop()
    65  return t
     61    local t = _Module(_Container{name=n})
     62    push(t)
     63    t:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
     64    pop()
     65    return t
    6666end
    6767
  • code/trunk/src/tolua/lua/namespace.lua

    r2087 r2710  
    1717--    {i}  = list of members
    1818classNamespace = {
    19  classtype = 'namespace',
    20  name = '',
     19    classtype = 'namespace',
     20    name = '',
    2121}
    2222classNamespace.__index = classNamespace
     
    2525-- Print method
    2626function classNamespace:print (ident,close)
    27  print(ident.."Namespace{")
    28  print(ident.." name = '"..self.name.."',")
    29  local i=1
    30  while self[i] do
    31   self[i]:print(ident.." ",",")
    32   i = i+1
    33  end
    34  print(ident.."}"..close)
     27    print(ident.."Namespace{")
     28    print(ident.." name = '"..self.name.."',")
     29    local i=1
     30    while self[i] do
     31        self[i]:print(ident.." ",",")
     32        i = i+1
     33    end
     34    print(ident.."}"..close)
    3535end
    3636
    3737-- Internal constructor
    3838function _Namespace (t)
    39  setmetatable(t,classNamespace)
    40  append(t)
    41  return t
     39    setmetatable(t,classNamespace)
     40    append(t)
     41    return t
    4242end
    4343
     
    4545-- Expects the name and the body of the namespace.
    4646function Namespace (n,b)
    47  local c = _Namespace(_Container{name=n})
    48  push(c)
    49  c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
    50  pop()
     47    local c = _Namespace(_Container{name=n})
     48    push(c)
     49    c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
     50    pop()
    5151end
    5252
  • code/trunk/src/tolua/lua/operator.lua

    r2087 r2710  
    1616--  kind = set of character representing the operator (as it appers in C++ code)
    1717classOperator = {
    18  kind = '',
     18    kind = '',
    1919}
    2020classOperator.__index = classOperator
     
    2222
    2323-- table to transform operator kind into the appropriate tag method name
    24 _TM = {['+'] = 'add',
    25        ['-'] = 'sub',
    26        ['*'] = 'mul',
    27        ['/'] = 'div',
    28        ['<'] = 'lt',
    29        ['<='] = 'le',
    30        ['=='] = 'eq',
    31        ['[]'] = 'geti',
    32        ['&[]'] = 'seti',
    33        --['->'] = 'flechita',
    34       }
     24_TM = {
     25    ['+'] = 'add',
     26    ['-'] = 'sub',
     27    ['*'] = 'mul',
     28    ['/'] = 'div',
     29    ['<'] = 'lt',
     30    ['<='] = 'le',
     31    ['=='] = 'eq',
     32    ['[]'] = 'geti',
     33    ['&[]'] = 'seti',
     34    --['->'] = 'flechita',
     35}
    3536
    3637
    3738-- Print method
    3839function classOperator:print (ident,close)
    39  print(ident.."Operator{")
    40  print(ident.." kind  = '"..self.kind.."',")
    41  print(ident.." mod  = '"..self.mod.."',")
    42  print(ident.." type = '"..self.type.."',")
    43  print(ident.." ptr  = '"..self.ptr.."',")
    44  print(ident.." name = '"..self.name.."',")
    45  print(ident.." const = '"..self.const.."',")
    46  print(ident.." cname = '"..self.cname.."',")
    47  print(ident.." lname = '"..self.lname.."',")
    48  print(ident.." args = {")
    49  local i=1
    50  while self.args[i] do
    51   self.args[i]:print(ident.."  ",",")
    52   i = i+1
    53  end
    54  print(ident.." }")
    55  print(ident.."}"..close)
     40    print(ident.."Operator{")
     41    print(ident.." kind  = '"..self.kind.."',")
     42    print(ident.." mod  = '"..self.mod.."',")
     43    print(ident.." type = '"..self.type.."',")
     44    print(ident.." ptr  = '"..self.ptr.."',")
     45    print(ident.." name = '"..self.name.."',")
     46    print(ident.." const = '"..self.const.."',")
     47    print(ident.." cname = '"..self.cname.."',")
     48    print(ident.." lname = '"..self.lname.."',")
     49    print(ident.." args = {")
     50    local i=1
     51    while self.args[i] do
     52        self.args[i]:print(ident.."  ",",")
     53        i = i+1
     54    end
     55    print(ident.." }")
     56    print(ident.."}"..close)
    5657end
    5758
    5859function classOperator:supcode_tmp()
    5960
    60         if not _TM[self.kind] then
    61                 return classFunction.supcode(self)
    62         end
    63 
    64         -- no overload, no parameters, always inclass
    65         output("/* method:",self.name," of class ",self:inclass()," */")
    66 
    67         output("#ifndef TOLUA_DISABLE_"..self.cname)
    68         output("\nstatic int",self.cname,"(lua_State* tolua_S)")
    69 
    70         if overload < 0 then
    71         output('#ifndef TOLUA_RELEASE\n')
    72         end
    73         output(' tolua_Error tolua_err;')
    74         output(' if (\n')
    75         -- check self
    76         output('     !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
    77         output('     !tolua_isnoobj(tolua_S,2,&tolua_err)\n )')
    78         output('  goto tolua_lerror;')
    79 
    80         output(' else\n')
    81         output('#endif\n') -- tolua_release
    82         output(' {')
    83 
    84         -- declare self
    85         output(' ',self.const,self.parent.type,'*','self = ')
    86         output('(',self.const,self.parent.type,'*) ')
    87         output('tolua_tousertype(tolua_S,1,0);')
    88 
    89         -- check self
    90         output('#ifndef TOLUA_RELEASE\n')
    91         output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
    92         output('#endif\n')
    93 
    94         -- cast self
    95         output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
    96         output('(',self.mod,self.type,self.ptr,')(*self);')
    97 
    98         -- return value
    99         local t,ct = isbasic(self.type)
    100         if t then
    101                 output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
    102         else
    103                 t = self.type
    104                 new_t = string.gsub(t, "const%s+", "")
    105                 if self.ptr == '' then
    106                         output('   {')
    107                         output('#ifdef __cplusplus\n')
    108                         output('    void* tolua_obj = new',new_t,'(tolua_ret);')
    109                         output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
    110                         output('#else\n')
    111                         output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
    112                         output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
    113                         output('#endif\n')
    114                         output('   }')
    115                 elseif self.ptr == '&' then
    116                         output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
    117                 else
    118                         if local_constructor then
    119                                 output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
    120                         else
    121                                 output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
    122                         end
    123                 end
    124         end
    125 
    126         output('  }')
    127         output(' return 1;')
    128 
    129         output('#ifndef TOLUA_RELEASE\n')
    130         output('tolua_lerror:\n')
    131         output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
    132         output(' return 0;')
    133         output('#endif\n')
    134 
    135 
    136         output('}')
    137         output('#endif //#ifndef TOLUA_DISABLE\n')
    138         output('\n')
     61    if not _TM[self.kind] then
     62        return classFunction.supcode(self)
     63    end
     64
     65    -- no overload, no parameters, always inclass
     66    output("/* method:",self.name," of class ",self:inclass()," */")
     67
     68    output("#ifndef TOLUA_DISABLE_"..self.cname)
     69    output("\nstatic int",self.cname,"(lua_State* tolua_S)")
     70
     71    if overload < 0 then
     72        output('#ifndef TOLUA_RELEASE\n')
     73    end
     74    output(' tolua_Error tolua_err;')
     75    output(' if (\n')
     76    -- check self
     77    output('     !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
     78    output('     !tolua_isnoobj(tolua_S,2,&tolua_err)\n )')
     79    output('  goto tolua_lerror;')
     80
     81    output(' else\n')
     82    output('#endif\n') -- tolua_release
     83    output(' {')
     84
     85    -- declare self
     86    output(' ',self.const,self.parent.type,'*','self = ')
     87    output('(',self.const,self.parent.type,'*) ')
     88    output('tolua_tousertype(tolua_S,1,0);')
     89
     90    -- check self
     91    output('#ifndef TOLUA_RELEASE\n')
     92    output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
     93    output('#endif\n')
     94
     95    -- cast self
     96    output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
     97    output('(',self.mod,self.type,self.ptr,')(*self);')
     98
     99    -- return value
     100    local t,ct = isbasic(self.type)
     101    if t then
     102        output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
     103    else
     104        t = self.type
     105        new_t = string.gsub(t, "const%s+", "")
     106        if self.ptr == '' then
     107            output('   {')
     108            output('#ifdef __cplusplus\n')
     109            output('    void* tolua_obj = new',new_t,'(tolua_ret);')
     110            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
     111            output('#else\n')
     112            output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
     113            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
     114            output('#endif\n')
     115            output('   }')
     116        elseif self.ptr == '&' then
     117            output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
     118        else
     119            if local_constructor then
     120                output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
     121            else
     122                output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
     123            end
     124        end
     125    end
     126
     127    output('  }')
     128    output(' return 1;')
     129
     130    output('#ifndef TOLUA_RELEASE\n')
     131    output('tolua_lerror:\n')
     132    output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
     133    output(' return 0;')
     134    output('#endif\n')
     135
     136
     137    output('}')
     138    output('#endif //#ifndef TOLUA_DISABLE\n')
     139    output('\n')
    139140end
    140141
    141142-- Internal constructor
    142143function _Operator (t)
    143  setmetatable(t,classOperator)
    144 
    145  if t.const ~= 'const' and t.const ~= '' then
    146   error("#invalid 'const' specification")
    147  end
    148 
    149  append(t)
    150  if not t:inclass() then
    151   error("#operator can only be defined as class member")
    152  end
    153 
    154  --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind)
    155  t.cname = t:cfuncname("tolua")..t:overload(t)
    156  t.name = "operator" .. t.kind  -- set appropriate calling name
    157  return t
     144    setmetatable(t,classOperator)
     145
     146    if t.const ~= 'const' and t.const ~= '' then
     147        error("#invalid 'const' specification")
     148    end
     149
     150    append(t)
     151    if not t:inclass() then
     152        error("#operator can only be defined as class member")
     153    end
     154
     155    --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind)
     156    t.cname = t:cfuncname("tolua")..t:overload(t)
     157    t.name = "operator" .. t.kind  -- set appropriate calling name
     158    return t
    158159end
    159160
     
    161162function Operator (d,k,a,c)
    162163
    163         local op_k = string.gsub(k, "^%s*", "")
    164         op_k = string.gsub(k, "%s*$", "")
    165         --if string.find(k, "^[%w_:%d<>%*%&]+$") then
    166         if d == "operator" and k ~= '' then
    167 
    168                 d = k.." operator"
    169         elseif not _TM[op_k] then
    170 
    171                 if flags['W'] then
    172                         error("tolua: no support for operator" .. f.kind)
    173                 else
    174                         warning("No support for operator "..op_k..", ignoring")
    175                         return nil
    176                 end
    177         end
    178 
    179         local ref = ''
    180  local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces
    181  local i=1
    182  local l = {n=0}
    183  while t[i] do
    184   l.n = l.n+1
    185   l[l.n] = Declaration(t[i],'var')
    186   i = i+1
    187  end
    188  if k == '[]' then
    189         local _
    190         _, _, ref = strfind(d,'(&)')
    191   d = gsub(d,'&','')
    192  elseif k=='&[]' then
    193   l.n = l.n+1
    194   l[l.n] = Declaration(d,'var')
    195   l[l.n].name = 'tolua_value'
    196  end
    197  local f = Declaration(d,'func')
    198  if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then
    199   error('operator[] can only be defined for numeric index.')
    200  end
    201  f.args = l
    202  f.const = c
    203  f.kind = op_k
    204  f.lname = "."..(_TM[f.kind] or f.kind)
    205  if not _TM[f.kind] then
    206         f.cast_operator = true
    207  end
    208  if f.kind == '[]' and ref=='&' and f.const~='const' then
    209   Operator(d,'&'..k,a,c)        -- create correspoding set operator
    210  end
    211  return _Operator(f)
    212 end
    213 
    214 
     164    local op_k = string.gsub(k, "^%s*", "")
     165    op_k = string.gsub(k, "%s*$", "")
     166    --if string.find(k, "^[%w_:%d<>%*%&]+$") then
     167    if d == "operator" and k ~= '' then
     168
     169        d = k.." operator"
     170    elseif not _TM[op_k] then
     171
     172        if flags['W'] then
     173            error("tolua: no support for operator" .. f.kind)
     174        else
     175            warning("No support for operator "..op_k..", ignoring")
     176            return nil
     177        end
     178    end
     179
     180    local ref = ''
     181    local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces
     182    local i=1
     183    local l = {n=0}
     184    while t[i] do
     185        l.n = l.n+1
     186        l[l.n] = Declaration(t[i],'var')
     187        i = i+1
     188    end
     189    if k == '[]' then
     190        local _
     191        _, _, ref = strfind(d,'(&)')
     192        d = gsub(d,'&','')
     193    elseif k=='&[]' then
     194        l.n = l.n+1
     195        l[l.n] = Declaration(d,'var')
     196        l[l.n].name = 'tolua_value'
     197    end
     198    local f = Declaration(d,'func')
     199    if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then
     200        error('operator[] can only be defined for numeric index.')
     201    end
     202    f.args = l
     203    f.const = c
     204    f.kind = op_k
     205    f.lname = "."..(_TM[f.kind] or f.kind)
     206    if not _TM[f.kind] then
     207        f.cast_operator = true
     208    end
     209    if f.kind == '[]' and ref=='&' and f.const~='const' then
     210        Operator(d,'&'..k,a,c)     -- create correspoding set operator
     211    end
     212    return _Operator(f)
     213end
     214
     215
  • code/trunk/src/tolua/lua/package.lua

    r2087 r2710  
    1717--    {i} = list of objects in the package.
    1818classPackage = {
    19  classtype = 'package'
     19    classtype = 'package'
    2020}
    2121classPackage.__index = classPackage
     
    2424-- Print method
    2525function classPackage:print ()
    26  print("Package: "..self.name)
    27  local i=1
    28  while self[i] do
    29   self[i]:print("","")
    30   i = i+1
    31  end
     26    print("Package: "..self.name)
     27    local i=1
     28    while self[i] do
     29        self[i]:print("","")
     30        i = i+1
     31    end
    3232end
    3333
    3434function classPackage:preprocess ()
    3535
    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)
     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)
    4141                                               tinsert(L,c)
    4242                                               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)
    4950                                               tinsert(C,c)
    5051                                               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)
    5658                                               tinsert(C,c)
    5759                                               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    )
    105113end
    106114
    107115-- translate verbatim
    108116function 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         output('#ifndef __cplusplus\n')
    115         output('#include "stdlib.h"\n')
    116         output('#endif\n')
    117         output('#include "string.h"\n\n')
    118  output('#include "tolua/tolua++.h"\n\n')
    119 
    120  if not flags.h then
    121 --  local temp = string.reverse(flags.H)
    122 --  local start1, end1 = string.find(temp, '/')
    123 --  local start2, end2 = string.find(temp, '\\')
    124 --  local res
    125 --  if not start1 == nil then
    126 --   if not start2 == nil then
    127 --    if start1 > start2 then
    128 --     res = string.sub(temp, 1, start2)
    129 --    else
    130 --     res = string.sub(temp, 1, start1)
    131 --    end
    132 --   else
    133 --    res = string.sub(temp, 1, start1)
    134 --   end
    135 --  elseif not start2 == nil then
    136 --   res = string.sub(temp, 1, start2)
    137 --  end
    138 --  res = string.reverse(res)
    139   output('#include "tolua_bind.h"')
    140   output('\n')
    141  end
    142 
    143  local i=1
    144  while self[i] do
    145   self[i]:preamble()
    146   i = i+1
    147  end
    148 
    149         if self:requirecollection(_collect) then
    150                 output('\n')
    151                 output('/* function to release collected object via destructor */')
    152                 output('#ifdef __cplusplus\n')
    153                 for i,v in pairs(_collect) do
    154                  output('\nstatic int '..v..' (lua_State* tolua_S)')
    155                         output('{')
    156                         output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
    157                         output('        delete self;')
    158                         output('        return 0;')
    159                         output('}')
    160                 end
    161                 output('#endif\n\n')
    162         end
    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         if flags.t then
    170                 output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n")
    171                 foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end)
    172         end
    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 flags.H then
     129        local header = gsub(flags.H, '^.-([%w_]*%.[%w_]*)$', '%1')
     130        local package_lower = string.lower(self.name)
     131        output('#include "'..header..'"\n')
     132    end
     133
     134    local i=1
     135    while self[i] do
     136        self[i]:preamble()
     137        i = i+1
     138    end
     139
     140    if self:requirecollection(_collect) then
     141        output('\n')
     142        output('/* function to release collected object via destructor */')
     143        output('#ifdef __cplusplus\n')
     144        for i,v in pairs(_collect) do
     145            output('\nstatic int '..v..' (lua_State* tolua_S)')
     146            output('{')
     147            output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
     148            output('    delete self;')
     149            output('    return 0;')
     150            output('}')
     151        end
     152        output('#endif\n\n')
     153    end
     154
     155    output('\n')
     156    output('/* function to register type */')
     157    output('static void tolua_reg_types (lua_State* tolua_S)')
     158    output('{')
     159    foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)
     160    if flags.t then
     161        output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n")
     162        foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end)
     163    end
     164    output('}')
     165    output('\n')
    175166end
    176167
     
    178169-- write package open function
    179170function 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=1
    190  while self[i] do
    191   self[i]:register(pre.."  ")
    192   i = i+1
    193  end
    194  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         pop()
     171    pre = pre or ''
     172    push(self)
     173    output(pre.."/* Open function */")
     174    output(pre.."int tolua_"..self.name.."_open (lua_State* tolua_S)")
     175    output(pre.."{")
     176    output(pre.." tolua_open(tolua_S);")
     177    output(pre.." tolua_reg_types(tolua_S);")
     178    output(pre.." tolua_module(tolua_S,NULL,",self:hasvar(),");")
     179    output(pre.." tolua_beginmodule(tolua_S,NULL);")
     180    local i=1
     181    while self[i] do
     182        self[i]:register(pre.."  ")
     183        i = i+1
     184    end
     185    output(pre.." tolua_endmodule(tolua_S);")
     186    output(pre.." return 1;")
     187    output(pre.."}")
     188
     189    output("\n\n")
     190    output("#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501\n");
     191    output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {")
     192    output(pre.." return tolua_"..self.name.."_open(tolua_S);")
     193    output(pre.."};")
     194    output("#endif\n\n")
     195
     196    pop()
    206197end
    207198
    208199-- write header file
    209200function 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 then
    215   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  end
     201    output('/*\n') output('** Lua binding: '..self.name..'\n')
     202    output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n')
     203    output('*/\n\n')
     204
     205    if flags.H then
     206        local package_lower = string.lower(self.name)
     207        output('#include "'..package_lower..'/'..self.name..'Prereqs.h"\n')
     208        output('/* Exported function */')
     209        output('_'..self.name..'Export')
     210        output('int  tolua_'..self.name..'_open (lua_State* tolua_S);')
     211        output('\n')
     212    end
    220213end
    221214
    222215-- Internal constructor
    223216function _Package (self)
    224  setmetatable(self,classPackage)
    225  return self
     217    setmetatable(self,classPackage)
     218    return self
    226219end
    227220
     
    229222-- *** Thanks to Ariel Manzur for fixing bugs in nested directives ***
    230223function extract_code(fn,s)
    231         local code = '\n$#include "'..fn..'"\n'
    232         s= "\n" .. s .. "\n" -- add blank lines as sentinels
    233         local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
    234         while e do
    235                 t = strlower(t)
    236                 if t == "begin" then
    237                         _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e)
    238                         if not e then
    239                          tolua_error("Unbalanced 'tolua_begin' directive in header file")
    240                         end
    241                 end
    242                 code = code .. c .. "\n"
    243          _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e)
    244         end
    245         return code
     224    local code = '\n$#include "'..string.lower(flags.n)..'/'..fn..'"\n'
     225    s= "\n" .. s .. "\n" -- add blank lines as sentinels
     226
     227    -- eliminate export macro problems in class declarations
     228    s = gsub(s, ' _%w*Export ', ' ')
     229
     230    local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
     231    while e do
     232        t = strlower(t)
     233        if t == "begin" then
     234            _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e)
     235            if not e then
     236             tolua_error("Unbalanced 'tolua_begin' directive in header file")
     237            end
     238        end
     239        code = code .. c .. "\n"
     240        _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e)
     241    end
     242    return code
    246243end
    247244
     
    249246-- Expects the package name, the file extension, and the file text.
    250247function 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 
     248    local ext = "pkg"
     249
     250    -- open input file, if any
     251    if fn then
     252        local file
     253        if flags.f then
     254            if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then
     255                file = flags.f
     256            else
     257                file = flags.w..'/'..flags.f
     258            end
     259        else
     260            file = flags.f
     261        end
     262        local st, msg = readfrom(file)
     263        if not st then
     264            error('#'..msg..' path: '..flags.f)
     265        end
     266        local _; _, _, ext = strfind(fn,".*%.(.*)$")
     267    end
     268    local code = "\n" .. read('*a')
     269    if ext == 'h' or ext == 'hpp' then
     270        code = extract_code(fn,code)
     271    end
     272
     273    -- close file
     274    if fn then
     275        readfrom()
     276    end
     277
     278    -- prepare working directory
     279    local current_path
     280    if not flags.w and flags.f then
     281        current_path = gsub(flags.f, '(/)[^/]*%.?[^/]*$', '%1')
     282    elseif flags.w then
     283        if not (string.sub(flags.w, string.len(flags.w)) == '/') then
     284            current_path = flags.w..'/'
     285        else
     286            current_path = flags.w
     287        end
     288    else
     289        current_path = ''
     290    end
     291
     292    -- deal with include directive
     293    local nsubst
     294    repeat
     295        code,nsubst = gsub(code,'\n%s*%$(.)file%s*"(.-)"([^\n]*)\n',
     296            function (kind,fn,extra)
     297                local _, _, ext = strfind(fn,".*%.(.*)$")
     298                local fp,msg = openfile(current_path..fn,'r')
     299                if not fp then
     300                    error('#'..msg..': '..fn)
     301                end
     302                local s = read(fp,'*a')
     303                closefile(fp)
     304                if kind == 'c' or kind == 'h' then
     305                    return extract_code(fn,s)
     306                elseif kind == 'p' then
     307                    return "\n\n" .. s
     308                elseif kind == 'l' then
     309                    return "\n$[--##"..fn.."\n" .. s .. "\n$]\n"
     310                elseif kind == 'i' then
     311                    local t = {code=s}
     312                    extra = string.gsub(extra, "^%s*,%s*", "")
     313                    local pars = split_c_tokens(extra, ",")
     314                    include_file_hook(t, fn, unpack(pars))
     315                    return "\n\n" .. t.code
     316                else
     317                    error('#Invalid include directive (use $cfile, $pfile, $lfile or $ifile)')
     318                end
     319            end
     320        )
     321    until nsubst==0
     322
     323    -- deal with renaming directive
     324    repeat -- I don't know why this is necesary
     325        code,nsubst = gsub(code,'\n%s*%$renaming%s*(.-)%s*\n', function (r) appendrenaming(r) return "\n" end)
     326    until nsubst == 0
     327
     328    local t = _Package(_Container{name=name, code=code})
     329    push(t)
     330    preprocess_hook(t)
     331    t:preprocess()
     332    preparse_hook(t)
     333    t:parse(t.code)
     334    pop()
     335    return t
     336end
     337
     338
  • code/trunk/src/tolua/lua/typedef.lua

    r2087 r2710  
    2121--   mod = modifiers to the 'de facto' type
    2222classTypedef = {
    23  utype = '',
    24  mod = '',
    25  type = ''
     23    utype = '',
     24    mod = '',
     25    type = ''
    2626}
    2727classTypedef.__index = classTypedef
     
    2929-- Print method
    3030function classTypedef:print (ident,close)
    31  print(ident.."Typedef{")
    32  print(ident.." utype = '"..self.utype.."',")
    33  print(ident.." mod = '"..self.mod.."',")
    34  print(ident.." type = '"..self.type.."',")
    35  print(ident.."}"..close)
     31    print(ident.."Typedef{")
     32    print(ident.." utype = '"..self.utype.."',")
     33    print(ident.." mod = '"..self.mod.."',")
     34    print(ident.." type = '"..self.type.."',")
     35    print(ident.."}"..close)
    3636end
    3737
    3838-- Return it's not a variable
    3939function classTypedef:isvariable ()
    40  return false
     40    return false
    4141end
    4242
    4343-- Internal constructor
    4444function _Typedef (t)
    45  setmetatable(t,classTypedef)
    46  t.type = resolve_template_types(t.type)
    47  appendtypedef(t)
    48  return t
     45    setmetatable(t,classTypedef)
     46    t.type = resolve_template_types(t.type)
     47    appendtypedef(t)
     48    return t
    4949end
    5050
     
    5252-- Expects one string representing the type definition.
    5353function Typedef (s)
    54  if strfind(string.gsub(s, '%b<>', ''),'[%*&]') then
    55   tolua_error("#invalid typedef: pointers (and references) are not supported")
    56  end
    57  local o = {mod = ''}
    58  if string.find(s, "[<>]") then
    59         _,_,o.type,o.utype = string.find(s, "^%s*([^<>]+%b<>[^%s]*)%s+(.-)$")
    60  else
    61         local t = split(gsub(s,"%s%s*"," ")," ")
    62         o = {
    63           utype = t[t.n],
    64           type = t[t.n-1],
    65           mod = concat(t,1,t.n-2),
    66         }
    67  end
    68  return _Typedef(o)
     54    if strfind(string.gsub(s, '%b<>', ''),'[%*&]') then
     55        tolua_error("#invalid typedef: pointers (and references) are not supported")
     56    end
     57    local o = {mod = ''}
     58    if string.find(s, "[<>]") then
     59        _,_,o.type,o.utype = string.find(s, "^%s*([^<>]+%b<>[^%s]*)%s+(.-)$")
     60    else
     61        local t = split(gsub(s,"%s%s*"," ")," ")
     62        o = {
     63            utype = t[t.n],
     64            type = t[t.n-1],
     65            mod = concat(t,1,t.n-2),
     66        }
     67    end
     68    return _Typedef(o)
    6969end
    7070
  • code/trunk/src/tolua/lua/variable.lua

    r2087 r2710  
    1515-- Stores all fields present in a declaration.
    1616classVariable = {
    17  _get = {},   -- mapped get functions
    18  _set = {},   -- mapped set functions
     17    _get = {},   -- mapped get functions
     18    _set = {},   -- mapped set functions
    1919}
    2020classVariable.__index = classVariable
     
    2323-- Print method
    2424function classVariable:print (ident,close)
    25  print(ident.."Variable{")
    26  print(ident.." mod  = '"..self.mod.."',")
    27  print(ident.." type = '"..self.type.."',")
    28  print(ident.." ptr  = '"..self.ptr.."',")
    29  print(ident.." name = '"..self.name.."',")
    30  if self.dim then print(ident.." dim = '"..self.dim.."',") end
    31  print(ident.." def  = '"..self.def.."',")
    32  print(ident.." ret  = '"..self.ret.."',")
    33  print(ident.."}"..close)
     25    print(ident.."Variable{")
     26    print(ident.." mod  = '"..self.mod.."',")
     27    print(ident.." type = '"..self.type.."',")
     28    print(ident.." ptr  = '"..self.ptr.."',")
     29    print(ident.." name = '"..self.name.."',")
     30    if self.dim then print(ident.." dim = '"..self.dim.."',") end
     31    print(ident.." def  = '"..self.def.."',")
     32    print(ident.." ret  = '"..self.ret.."',")
     33    print(ident.."}"..close)
    3434end
    3535
    3636-- Generates C function name
    3737function classVariable:cfuncname (prefix)
    38  local parent = ""
    39  local unsigned = ""
    40  local ptr = ""
    41 
    42  local p = self:inmodule() or self:innamespace() or self:inclass()
    43 
    44  if p then
    45         if self.parent.classtype == 'class' then
    46                 parent = "_" .. self.parent.type
    47         else
    48           parent = "_" .. p
    49         end
    50  end
    51 
    52  if strfind(self.mod,"(unsigned)") then
    53   unsigned = "_unsigned"
    54  end
    55 
    56  if self.ptr == "*" then ptr = "_ptr"
    57  elseif self.ptr == "&" then ptr = "_ref"
    58  end
    59 
    60  local name =  prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr
    61 
    62         name = clean_template(name)
    63  return name
     38    local parent = ""
     39    local unsigned = ""
     40    local ptr = ""
     41
     42    local p = self:inmodule() or self:innamespace() or self:inclass()
     43
     44    if p then
     45        if self.parent.classtype == 'class' then
     46            parent = "_" .. self.parent.type
     47        else
     48            parent = "_" .. p
     49        end
     50    end
     51
     52    if strfind(self.mod,"(unsigned)") then
     53        unsigned = "_unsigned"
     54    end
     55
     56    if self.ptr == "*" then ptr = "_ptr"
     57    elseif self.ptr == "&" then ptr = "_ref"
     58    end
     59
     60    local name =  prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr
     61
     62    name = clean_template(name)
     63    return name
    6464
    6565end
     
    6767-- check if it is a variable
    6868function classVariable:isvariable ()
    69  return true
     69    return true
    7070end
    7171
     
    7373function classVariable:getvalue (class,static, prop_get)
    7474
    75         local name
    76         if prop_get then
    77 
    78                 name = prop_get.."()"
    79         else
    80                 name = self.name
    81         end
    82 
    83         if class and static then
    84         return self.parent.type..'::'..name
    85         elseif class then
    86         return 'self->'..name
    87         else
    88         return name
    89         end
     75    local name
     76    if prop_get then
     77
     78        name = prop_get.."()"
     79    else
     80        name = self.name
     81    end
     82
     83    if class and static then
     84        return self.parent.type..'::'..name
     85    elseif class then
     86        return 'self->'..name
     87    else
     88        return name
     89    end
    9090end
    9191
    9292-- get variable pointer value
    9393function classVariable:getpointervalue (class,static)
    94  if class and static then
    95   return class..'::p'
    96  elseif class then
    97   return 'self->p'
    98  else
    99   return 'p'
    100  end
     94    if class and static then
     95        return class..'::p'
     96    elseif class then
     97        return 'self->p'
     98    else
     99        return 'p'
     100    end
    101101end
    102102
     
    106106 local class = self:inclass()
    107107
    108         local prop_get,prop_set
    109         if string.find(self.mod, 'tolua_property') then
    110 
    111                 _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
    112                 type = type or "default"
    113                 prop_get,prop_set = get_property_methods(type, self.name)
    114                 self.mod = string.gsub(self.mod, "tolua_property[^%s]*", "")
    115         end
    116 
    117  -- get function ------------------------------------------------
    118  if class then
    119   output("/* get function:",self.name," of class ",class," */")
    120  else
    121   output("/* get function:",self.name," */")
    122  end
    123  self.cgetname = self:cfuncname("tolua_get")
    124  output("#ifndef TOLUA_DISABLE_"..self.cgetname)
    125  output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
    126  output("{")
    127 
    128  -- declare self, if the case
    129  local _,_,static = strfind(self.mod,'^%s*(static)')
    130  if class and static==nil then
    131   output(' ',self.parent.type,'*','self = ')
    132   output('(',self.parent.type,'*) ')
    133   output('tolua_tousertype(tolua_S,1,0);')
    134  elseif static then
    135   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
    136  end
    137 
    138 
    139  -- check self value
    140  if class and static==nil then
    141         output('#ifndef TOLUA_RELEASE\n')
    142   output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
    143                 output('#endif\n')
    144  end
    145 
    146  -- return value
    147  if string.find(self.mod, 'tolua_inherits') then
    148         output('#ifdef __cplusplus\n')
    149         output('  tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
    150         output('#else\n')
    151         output('  tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
    152         output('#endif\n')
    153  else
    154         local t,ct = isbasic(self.type)
    155         if t then
    156                 output('  tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static,prop_get)..');')
    157         else
    158                 t = self.type
    159                 if self.ptr == '&' or self.ptr == '' then
    160                         output('  tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");')
    161                 else
    162                         output('  tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");')
    163                 end
    164         end
    165  end
    166  output(' return 1;')
    167  output('}')
    168  output('#endif //#ifndef TOLUA_DISABLE\n')
    169  output('\n')
    170 
    171  -- set function ------------------------------------------------
    172  if not (strfind(self.type,'const%s+') or string.find(self.mod, 'tolua_readonly') or string.find(self.mod, 'tolua_inherits'))  then
    173   if class then
    174    output("/* set function:",self.name," of class ",class," */")
    175   else
    176    output("/* set function:",self.name," */")
    177   end
    178   self.csetname = self:cfuncname("tolua_set")
    179   output("#ifndef TOLUA_DISABLE_"..self.csetname)
    180   output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
    181   output("{")
    182 
    183   -- declare self, if the case
    184   if class and static==nil then
    185    output(' ',self.parent.type,'*','self = ')
    186    output('(',self.parent.type,'*) ')
    187    output('tolua_tousertype(tolua_S,1,0);')
    188    -- check self value
    189                 end
    190   -- check types
    191                 output('#ifndef TOLUA_RELEASE\n')
    192                 output('  tolua_Error tolua_err;')
    193   if class and static==nil then
    194    output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
    195   elseif static then
    196    _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
    197   end
    198 
    199   -- check variable type
    200   output('  if (!'..self:outchecktype(2)..')')
    201   output('   tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')
    202                 output('#endif\n')
    203 
    204   -- assign value
    205                 local def = 0
    206                 if self.def ~= '' then def = self.def end
    207                 if self.type == 'char*' and self.dim ~= '' then -- is string
    208                 output(' strncpy(')
    209                         if class and static then
    210                                 output(self.parent.type..'::'..self.name)
    211                         elseif class then
    212                                 output('self->'..self.name)
    213                         else
    214                                 output(self.name)
    215                         end
    216                         output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
    217                 else
    218                         local ptr = ''
    219                         if self.ptr~='' then ptr = '*' end
    220                         output(' ')
    221                         local name = prop_set or self.name
    222                         if class and static then
    223                                 output(self.parent.type..'::'..name)
    224                         elseif class then
    225                                 output('self->'..name)
    226                         else
    227                                 output(name)
    228                         end
    229                         local t = isbasic(self.type)
    230                         if prop_set then
    231                                 output('(')
    232                         else
    233                                 output(' = ')
    234                         end
    235                         if not t and ptr=='' then output('*') end
    236                         output('((',self.mod,self.type)
    237                         if not t then
    238                                 output('*')
    239                         end
    240                         output(') ')
    241                         if t then
    242                                 if isenum(self.type) then
    243                                         output('(int) ')
    244                                 end
    245                                 output('tolua_to'..t,'(tolua_S,2,',def,'))')
    246                         else
    247                                 output('tolua_tousertype(tolua_S,2,',def,'))')
    248                         end
    249                         if prop_set then
    250                                 output(")")
    251                         end
    252                         output(";")
    253                 end
    254   output(' return 0;')
    255   output('}')
    256   output('#endif //#ifndef TOLUA_DISABLE\n')
    257   output('\n')
    258  end
     108    local prop_get,prop_set
     109    if string.find(self.mod, 'tolua_property') then
     110
     111        _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
     112        type = type or "default"
     113        prop_get,prop_set = get_property_methods(type, self.name)
     114        self.mod = string.gsub(self.mod, "tolua_property[^%s]*", "")
     115    end
     116
     117    -- get function ------------------------------------------------
     118    if class then
     119        output("/* get function:",self.name," of class ",class," */")
     120    else
     121        output("/* get function:",self.name," */")
     122    end
     123    self.cgetname = self:cfuncname("tolua_get")
     124    output("#ifndef TOLUA_DISABLE_"..self.cgetname)
     125    output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
     126    output("{")
     127
     128    -- declare self, if the case
     129    local _,_,static = strfind(self.mod,'^%s*(static)')
     130    if class and static==nil then
     131        output(' ',self.parent.type,'*','self = ')
     132        output('(',self.parent.type,'*) ')
     133        output('tolua_tousertype(tolua_S,1,0);')
     134    elseif static then
     135        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
     136    end
     137
     138
     139    -- check self value
     140    if class and static==nil then
     141        output('#ifndef TOLUA_RELEASE\n')
     142        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
     143        output('#endif\n')
     144    end
     145
     146    -- return value
     147    if string.find(self.mod, 'tolua_inherits') then
     148        output('#ifdef __cplusplus\n')
     149        output('  tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
     150        output('#else\n')
     151        output('  tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
     152        output('#endif\n')
     153    else
     154        local t,ct = isbasic(self.type)
     155        if t then
     156            output('  tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static,prop_get)..');')
     157        else
     158            t = self.type
     159            if self.ptr == '&' or self.ptr == '' then
     160                output('  tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");')
     161            else
     162                output('  tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");')
     163            end
     164        end
     165    end
     166    output(' return 1;')
     167    output('}')
     168    output('#endif //#ifndef TOLUA_DISABLE\n')
     169    output('\n')
     170
     171    -- set function ------------------------------------------------
     172    if not (strfind(self.type,'const%s+') or string.find(self.mod, 'tolua_readonly') or string.find(self.mod, 'tolua_inherits'))  then
     173    if class then
     174        output("/* set function:",self.name," of class ",class," */")
     175    else
     176        output("/* set function:",self.name," */")
     177    end
     178    self.csetname = self:cfuncname("tolua_set")
     179    output("#ifndef TOLUA_DISABLE_"..self.csetname)
     180    output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
     181    output("{")
     182
     183    -- declare self, if the case
     184    if class and static==nil then
     185        output(' ',self.parent.type,'*','self = ')
     186        output('(',self.parent.type,'*) ')
     187        output('tolua_tousertype(tolua_S,1,0);')
     188        -- check self value
     189    end
     190    -- check types
     191    output('#ifndef TOLUA_RELEASE\n')
     192    output('  tolua_Error tolua_err;')
     193    if class and static==nil then
     194        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
     195    elseif static then
     196        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
     197    end
     198
     199    -- check variable type
     200    output('  if (!'..self:outchecktype(2)..')')
     201    output('   tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')
     202    output('#endif\n')
     203
     204    -- assign value
     205    local def = 0
     206    if self.def ~= '' then def = self.def end
     207    if self.type == 'char*' and self.dim ~= '' then -- is string
     208        output(' strncpy(')
     209        if class and static then
     210            output(self.parent.type..'::'..self.name)
     211            elseif class then
     212                output('self->'..self.name)
     213            else
     214                output(self.name)
     215            end
     216            output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
     217        else
     218            local ptr = ''
     219            if self.ptr~='' then ptr = '*' end
     220            output(' ')
     221            local name = prop_set or self.name
     222            if class and static then
     223                output(self.parent.type..'::'..name)
     224            elseif class then
     225                output('self->'..name)
     226            else
     227                output(name)
     228            end
     229            local t = isbasic(self.type)
     230            if prop_set then
     231                output('(')
     232            else
     233                output(' = ')
     234            end
     235            if not t and ptr=='' then output('*') end
     236            output('((',self.mod,self.type)
     237            if not t then
     238                output('*')
     239            end
     240            output(') ')
     241            if t then
     242                if isenum(self.type) then
     243                    output('(int) ')
     244                end
     245                output('tolua_to'..t,'(tolua_S,2,',def,'))')
     246            else
     247                output('tolua_tousertype(tolua_S,2,',def,'))')
     248            end
     249            if prop_set then
     250                output(")")
     251            end
     252            output(";")
     253        end
     254        output(' return 0;')
     255        output('}')
     256        output('#endif //#ifndef TOLUA_DISABLE\n')
     257        output('\n')
     258    end
    259259
    260260end
     
    262262function classVariable:register (pre)
    263263
    264         if not self:check_public_access() then
    265                 return
    266         end
    267  pre = pre or ''
    268  local parent = self:inmodule() or self:innamespace() or self:inclass()
    269  if not parent then
    270   if classVariable._warning==nil then
    271    warning("Mapping variable to global may degrade performance")
    272    classVariable._warning = 1
    273   end
    274  end
    275  if self.csetname then
    276   output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
    277  else
    278   output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
    279  end
     264    if not self:check_public_access() then
     265        return
     266    end
     267    pre = pre or ''
     268    local parent = self:inmodule() or self:innamespace() or self:inclass()
     269    if not parent then
     270        if classVariable._warning==nil then
     271            warning("Mapping variable to global may degrade performance")
     272            classVariable._warning = 1
     273        end
     274    end
     275    if self.csetname then
     276        output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
     277    else
     278        output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
     279    end
    280280end
    281281
    282282-- Internal constructor
    283283function _Variable (t)
    284  setmetatable(t,classVariable)
    285  append(t)
    286  return t
     284    setmetatable(t,classVariable)
     285    append(t)
     286    return t
    287287end
    288288
     
    290290-- Expects a string representing the variable declaration.
    291291function Variable (s)
    292  return _Variable (Declaration(s,'var'))
    293 end
    294 
    295 
     292    return _Variable (Declaration(s,'var'))
     293end
     294
     295
  • code/trunk/src/tolua/lua/verbatim.lua

    r2087 r2710  
    1717--   line = line text
    1818classVerbatim = {
    19  line = '',
    20         cond = nil,    -- condition: where to generate the code (s=suport, r=register)
     19    line = '',
     20    cond = nil,    -- condition: where to generate the code (s=suport, r=register)
    2121}
    2222classVerbatim.__index = classVerbatim
     
    2525-- preamble verbatim
    2626function classVerbatim:preamble ()
    27  if self.cond == '' then
    28   write(self.line)
    29  end
     27    if self.cond == '' then
     28        write(self.line)
     29    end
    3030end
    3131
    3232-- support code
    3333function classVerbatim:supcode ()
    34  if strfind(self.cond,'s') then
    35   write(self.line)
    36   write('\n')
    37  end
     34    if strfind(self.cond,'s') then
     35        write(self.line)
     36        write('\n')
     37    end
    3838end
    3939
    4040-- register code
    4141function classVerbatim:register (pre)
    42  if strfind(self.cond,'r') then
    43   write(self.line)
    44  end
     42    if strfind(self.cond,'r') then
     43        write(self.line)
     44    end
    4545end
    4646
     
    4848-- Print method
    4949function classVerbatim:print (ident,close)
    50  print(ident.."Verbatim{")
    51  print(ident.." line = '"..self.line.."',")
    52  print(ident.."}"..close)
    53 end
     50    print(ident.."Verbatim{")
     51    print(ident.." line = '"..self.line.."',")
     52    print(ident.."}"..close)
     53    end
    5454
    5555
    5656-- Internal constructor
    5757function _Verbatim (t)
    58  setmetatable(t,classVerbatim)
    59  append(t)
    60  return t
     58    setmetatable(t,classVerbatim)
     59    append(t)
     60    return t
    6161end
    6262
     
    6464-- Expects a string representing the text line
    6565function Verbatim (l,cond)
    66  if strsub(l,1,1) == "'" then
    67   l = strsub(l,2)
    68  elseif strsub(l,1,1) == '$' then
    69   cond = 'sr'       -- generates in both suport and register fragments
    70   l = strsub(l,2)
    71  end
    72  return _Verbatim {
    73   line = l,
    74   cond = cond or '',
    75  }
     66    if strsub(l,1,1) == "'" then
     67        l = strsub(l,2)
     68    elseif strsub(l,1,1) == '$' then
     69        cond = 'sr'       -- generates in both suport and register fragments
     70        l = strsub(l,2)
     71    end
     72    return _Verbatim {
     73        line = l,
     74        cond = cond or '',
     75    }
    7676end
    7777
  • code/trunk/src/tolua/tolua++.h

    r1810 r2710  
    6565typedef int lua_Object;
    6666
    67 #include "lua/lua.h"
    68 #include "lua/lauxlib.h"
     67#include "lua.h"
     68#include "lauxlib.h"
    6969
    7070struct tolua_Error
  • code/trunk/src/tolua/tolua.c

    r1810 r2710  
    55** Aug 2003
    66** $Id:$
     7** Extension by Orxonox (Reto Grieder) to support working directory
     8** and direct usage of lua files. (2008)
    79*/
    810
     
    1517#include "tolua++.h"
    1618
    17 #include "lua/lua.h"
    18 #include "lua/lualib.h"
    19 #include "lua/lauxlib.h"
     19#include "lua.h"
     20#include "lualib.h"
     21#include "lauxlib.h"
    2022
    2123#include <stdio.h>
     
    3436         "  -H  file : create include file.\n"
    3537         "  -n  name : set package name; default is input file root name.\n"
     38         "  -w  directory : set working directory; default is location of package file.\n"
     39         "  -s  file : specify source lua code for the parser; all.lua is default.\n"
    3640         "  -p       : parse only.\n"
    3741         "  -P       : parse and print structure information (for debug).\n"
     
    6569
    6670static void add_extra (lua_State* L, char* value) {
    67         int len;
    68         lua_getglobal(L, "_extra_parameters");
    69         len = luaL_getn(L, -1);
    70         lua_pushstring(L, value);
    71         lua_rawseti(L, -2, len+1);
    72         lua_pop(L, 1);
     71 int len;
     72 lua_getglobal(L, "_extra_parameters");
     73 len = luaL_getn(L, -1);
     74 lua_pushstring(L, value);
     75 lua_rawseti(L, -2, len+1);
     76 lua_pop(L, 1);
    7377};
    7478
     
    8286int main (int argc, char* argv[])
    8387{
     88 char* working_directory = "";
     89 char* lua_source = "";
     90
    8491 #ifdef LUA_VERSION_NUM /* lua 5.1 */
    8592 lua_State* L = luaL_newstate();
     
    97104 lua_pushstring(L,TOLUA_VERSION); lua_setglobal(L,"TOLUA_VERSION");
    98105 lua_pushstring(L,LUA_VERSION); lua_setglobal(L,"TOLUA_LUA_VERSION");
     106
    99107
    100108 if (argc==1)
     
    125133     case 'n': setfield(L,t,"n",argv[++i]); break;
    126134     case 'H': setfield(L,t,"H",argv[++i]); break;
     135     case 'w':
     136      working_directory = argv[++i];
     137      setfield(L,t,"w",argv[i]);
     138      break;
     139     case 's':
     140      lua_source = argv[++i];
     141      setfield(L,t,"s",argv[i]);
     142      break;
    127143     case 'S': setfield(L,t,"S",""); break;
    128144     case '1': setfield(L,t,"1",""); break;
     
    144160  lua_pop(L,1);
    145161 }
    146 /* #define TOLUA_SCRIPT_RUN */
    147 #ifndef TOLUA_SCRIPT_RUN
     162
    148163 {
    149   int tolua_tolua_open (lua_State* L);
    150   tolua_tolua_open(L);
     164  char path[BUFSIZ];
     165  char file[BUFSIZ];
     166  path[0] = '\0';
     167  file[0] = '\0';
     168
     169  if (strlen(lua_source) > 0 &&
     170      lua_source[0] != '/' &&
     171      lua_source[0] != '\\' &&
     172      strlen(lua_source) > 1 &&
     173      lua_source[1] != ':')
     174  {
     175   /* Relative path, prefix working directory */
     176   strcpy(path, working_directory);
     177   /* Make sure there is '\\' or '/' at the end of the path */
     178   if (strlen(path) > 0)
     179   {
     180    char last = path[strlen(path) - 1];
     181    if (last != '\\' && last != '/')
     182     strcat(path, "/");
     183   }
     184  }
     185
     186  strcat(path, lua_source);
     187
     188  /* Extract the full path */
     189  {
     190   char* p;
     191   p = strrchr(path, '/');
     192   if (p == NULL)
     193    p = strrchr(path, '\\');
     194   p = (p == NULL) ? path : p + 1;
     195   strcpy(file, p);
     196   *p = '\0';
     197  }
     198  if (strlen(file) == 0)
     199   strcpy(file, "all.lua");
     200
     201  lua_pushstring(L, path);
     202  lua_setglobal(L, "path");
     203  strcat(path, file);
     204#ifdef LUA_VERSION_NUM /* lua 5.1 */
     205  luaL_dofile(L, path);
     206#else
     207  lua_dofile(L, path);
     208#endif
    151209 }
    152 #else
    153  {
    154   char* p;
    155   char  path[BUFSIZ];
    156   strcpy(path,argv[0]);
    157   p = strrchr(path,'/');
    158   if (p==NULL) p = strrchr(path,'\\');
    159   p = (p==NULL) ? path : p+1;
    160   sprintf(p,"%s","../src/bin/lua/");
    161   lua_pushstring(L,path); lua_setglobal(L,"path");
    162                 strcat(path,"all.lua");
    163   lua_dofile(L,path);
    164  }
    165 #endif
    166210 return 0;
    167211}
  • code/trunk/src/tolua/tolua_is.c

    r1810 r2710  
    1414
    1515#include "tolua++.h"
    16 #include "lua/lauxlib.h"
     16#include "lauxlib.h"
    1717
    1818#include <stdlib.h>
  • code/trunk/src/tolua/tolua_map.c

    r1810 r2710  
    1515#include "tolua++.h"
    1616#include "tolua_event.h"
    17 #include "lua/lauxlib.h"
     17#include "lauxlib.h"
    1818
    1919#include <string.h>
  • code/trunk/src/tolua/tolua_push.c

    r1810 r2710  
    1414
    1515#include "tolua++.h"
    16 #include "lua/lauxlib.h"
     16#include "lauxlib.h"
    1717
    1818#include <stdlib.h>
Note: See TracChangeset for help on using the changeset viewer.