Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 17, 2008, 8:59:48 PM (15 years ago)
Author:
rgrieder
Message:

Merged revisions 1875-2278 of the buildsystem branch to buildsystem2.

Location:
code/branches/buildsystem2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/buildsystem2

  • code/branches/buildsystem2/src/tolua/lua/function.lua

    r2087 r2509  
    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
Note: See TracChangeset for help on using the changeset viewer.