Index: code/branches/buildsystem2/src/tolua/lua/container.lua
===================================================================
--- code/branches/buildsystem2/src/tolua/lua/container.lua	(revision 2507)
+++ code/branches/buildsystem2/src/tolua/lua/container.lua	(revision 2509)
@@ -19,5 +19,5 @@
 classContainer =
 {
- curr = nil,
+    curr = nil,
 }
 classContainer.__index = classContainer
@@ -26,11 +26,11 @@
 -- output tags
 function classContainer:decltype ()
- push(self)
- local i=1
- while self[i] do
-  self[i]:decltype()
-  i = i+1
- end
- pop()
+    push(self)
+    local i=1
+    while self[i] do
+        self[i]:decltype()
+        i = i+1
+    end
+    pop()
 end
 
@@ -39,123 +39,123 @@
 function classContainer:supcode ()
 
-	if not self:check_public_access() then
-		return
-	end
-
- push(self)
- local i=1
- while self[i] do
-  if self[i]:check_public_access() then
-  	self[i]:supcode()
-  end
-  i = i+1
- end
- pop()
+    if not self:check_public_access() then
+        return
+    end
+
+    push(self)
+    local i=1
+    while self[i] do
+        if self[i]:check_public_access() then
+            self[i]:supcode()
+        end
+        i = i+1
+    end
+    pop()
 end
 
 function classContainer:hasvar ()
- local i=1
- while self[i] do
-  if self[i]:isvariable() then
-		 return 1
-		end
-  i = i+1
- end
-	return 0
+    local i=1
+    while self[i] do
+        if self[i]:isvariable() then
+            return 1
+        end
+        i = i+1
+    end
+    return 0
 end
 
 -- Internal container constructor
 function _Container (self)
- setmetatable(self,classContainer)
- self.n = 0
- self.typedefs = {tolua_n=0}
- self.usertypes = {}
- self.enums = {tolua_n=0}
- self.lnames = {}
- return self
+    setmetatable(self,classContainer)
+    self.n = 0
+    self.typedefs = {tolua_n=0}
+    self.usertypes = {}
+    self.enums = {tolua_n=0}
+    self.lnames = {}
+    return self
 end
 
 -- push container
 function push (t)
-	t.prox = classContainer.curr
- classContainer.curr = t
+    t.prox = classContainer.curr
+    classContainer.curr = t
 end
 
 -- pop container
 function pop ()
---print("name",classContainer.curr.name)
---foreach(classContainer.curr.usertypes,print)
---print("______________")
- classContainer.curr = classContainer.curr.prox
+    --print("name",classContainer.curr.name)
+    --foreach(classContainer.curr.usertypes,print)
+    --print("______________")
+    classContainer.curr = classContainer.curr.prox
 end
 
 -- get current namespace
 function getcurrnamespace ()
-	return getnamespace(classContainer.curr)
+    return getnamespace(classContainer.curr)
 end
 
 -- append to current container
 function append (t)
- return classContainer.curr:append(t)
+    return classContainer.curr:append(t)
 end
 
 -- append typedef to current container
 function appendtypedef (t)
- return classContainer.curr:appendtypedef(t)
+    return classContainer.curr:appendtypedef(t)
 end
 
 -- append usertype to current container
 function appendusertype (t)
- return classContainer.curr:appendusertype(t)
+    return classContainer.curr:appendusertype(t)
 end
 
 -- append enum to current container
 function appendenum (t)
- return classContainer.curr:appendenum(t)
+    return classContainer.curr:appendenum(t)
 end
 
 -- substitute typedef
 function applytypedef (mod,type)
- return classContainer.curr:applytypedef(mod,type)
+    return classContainer.curr:applytypedef(mod,type)
 end
 
 -- check if is type
 function findtype (type)
- local t = classContainer.curr:findtype(type)
-	return t
+    local t = classContainer.curr:findtype(type)
+    return t
 end
 
 -- check if is typedef
 function istypedef (type)
- return classContainer.curr:istypedef(type)
+    return classContainer.curr:istypedef(type)
 end
 
 -- get fulltype (with namespace)
 function fulltype (t)
- local curr =  classContainer.curr
-	while curr do
-	 if curr then
-		 if curr.typedefs and curr.typedefs[t] then
-		  return curr.typedefs[t]
-		 elseif curr.usertypes and curr.usertypes[t] then
-		  return curr.usertypes[t]
-			end
-		end
-	 curr = curr.prox
-	end
-	return t
+    local curr =  classContainer.curr
+    while curr do
+        if curr then
+            if curr.typedefs and curr.typedefs[t] then
+                return curr.typedefs[t]
+            elseif curr.usertypes and curr.usertypes[t] then
+                return curr.usertypes[t]
+            end
+        end
+        curr = curr.prox
+    end
+    return t
 end
 
 -- checks if it requires collection
 function classContainer:requirecollection (t)
- push(self)
- local i=1
-	local r = false
- while self[i] do
-  r = self[i]:requirecollection(t) or r
-  i = i+1
- end
-	pop()
-	return r
+    push(self)
+    local i=1
+    local r = false
+    while self[i] do
+        r = self[i]:requirecollection(t) or r
+        i = i+1
+    end
+    pop()
+    return r
 end
 
@@ -163,142 +163,141 @@
 -- get namesapce
 function getnamespace (curr)
-	local namespace = ''
-	while curr do
-	 if curr and
-		   ( curr.classtype == 'class' or curr.classtype == 'namespace')
-		then
-		 namespace = (curr.original_name or curr.name) .. '::' .. namespace
-		 --namespace = curr.name .. '::' .. namespace
-		end
-	 curr = curr.prox
-	end
-	return namespace
+    local namespace = ''
+    while curr do
+        if curr and
+            ( curr.classtype == 'class' or curr.classtype == 'namespace')
+        then
+            namespace = (curr.original_name or curr.name) .. '::' .. namespace
+            --namespace = curr.name .. '::' .. namespace
+        end
+        curr = curr.prox
+    end
+    return namespace
 end
 
 -- get namespace (only namespace)
 function getonlynamespace ()
- local curr = classContainer.curr
-	local namespace = ''
-	while curr do
-		if curr.classtype == 'class' then
-		 return namespace
-		elseif curr.classtype == 'namespace' then
-		 namespace = curr.name .. '::' .. namespace
-		end
-	 curr = curr.prox
-	end
-	return namespace
+    local curr = classContainer.curr
+    local namespace = ''
+    while curr do
+        if curr.classtype == 'class' then
+            return namespace
+        elseif curr.classtype == 'namespace' then
+            namespace = curr.name .. '::' .. namespace
+        end
+        curr = curr.prox
+    end
+    return namespace
 end
 
 -- check if is enum
 function isenum (type)
- return classContainer.curr:isenum(type)
+    return classContainer.curr:isenum(type)
 end
 
 -- append feature to container
 function classContainer:append (t)
- self.n = self.n + 1
- self[self.n] = t
- t.parent = self
+    self.n = self.n + 1
+    self[self.n] = t
+    t.parent = self
 end
 
 -- append typedef
 function classContainer:appendtypedef (t)
- local namespace = getnamespace(classContainer.curr)
- self.typedefs.tolua_n = self.typedefs.tolua_n + 1
- self.typedefs[self.typedefs.tolua_n] = t
-	self.typedefs[t.utype] = namespace .. t.utype
-	global_typedefs[namespace..t.utype] = t
-	t.ftype = findtype(t.type) or t.type
-	--print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype)
-	append_global_type(namespace..t.utype)
-	if t.ftype and isenum(t.ftype) then
-
-		global_enums[namespace..t.utype] = true
-	end
+    local namespace = getnamespace(classContainer.curr)
+    self.typedefs.tolua_n = self.typedefs.tolua_n + 1
+    self.typedefs[self.typedefs.tolua_n] = t
+    self.typedefs[t.utype] = namespace .. t.utype
+    global_typedefs[namespace..t.utype] = t
+    t.ftype = findtype(t.type) or t.type
+    --print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype)
+    append_global_type(namespace..t.utype)
+    if t.ftype and isenum(t.ftype) then
+        global_enums[namespace..t.utype] = true
+    end
 end
 
 -- append usertype: return full type
 function classContainer:appendusertype (t)
-	local container
-	if t == (self.original_name or self.name) then
-		container = self.prox
-	else
-		container = self
-	end
-	local ft = getnamespace(container) .. t
-	container.usertypes[t] = ft
-	_usertype[ft] = ft
-	return ft
+    local container
+    if t == (self.original_name or self.name) then
+        container = self.prox
+    else
+        container = self
+    end
+    local ft = getnamespace(container) .. t
+    container.usertypes[t] = ft
+    _usertype[ft] = ft
+    return ft
 end
 
 -- append enum
 function classContainer:appendenum (t)
- local namespace = getnamespace(classContainer.curr)
- self.enums.tolua_n = self.enums.tolua_n + 1
- self.enums[self.enums.tolua_n] = t
-	global_enums[namespace..t.name] = t
+    local namespace = getnamespace(classContainer.curr)
+    self.enums.tolua_n = self.enums.tolua_n + 1
+    self.enums[self.enums.tolua_n] = t
+    global_enums[namespace..t.name] = t
 end
 
 -- determine lua function name overload
 function classContainer:overload (lname)
- if not self.lnames[lname] then
-  self.lnames[lname] = 0
- else
-  self.lnames[lname] = self.lnames[lname] + 1
- end
- return format("%02d",self.lnames[lname])
+    if not self.lnames[lname] then
+        self.lnames[lname] = 0
+    else
+        self.lnames[lname] = self.lnames[lname] + 1
+    end
+    return format("%02d",self.lnames[lname])
 end
 
 -- applies typedef: returns the 'the facto' modifier and type
 function classContainer:applytypedef (mod,type)
-	if global_typedefs[type] then
-		--print("found typedef "..global_typedefs[type].type)
-		local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
-		local mod2, type2 = applytypedef(mod.." "..mod1, type1)
-		--return mod2 .. ' ' .. mod1, type2
-		return mod2, type2
-	end
-	do return mod,type end
+    if global_typedefs[type] then
+        --print("found typedef "..global_typedefs[type].type)
+        local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
+        local mod2, type2 = applytypedef(mod.." "..mod1, type1)
+        --return mod2 .. ' ' .. mod1, type2
+        return mod2, type2
+    end
+    do return mod,type end
 end
 
 -- check if it is a typedef
 function classContainer:istypedef (type)
- local env = self
- while env do
-  if env.typedefs then
-   local i=1
-   while env.typedefs[i] do
-    if env.typedefs[i].utype == type then
-         return type
-        end
-        i = i+1
-   end
-  end
-  env = env.parent
- end
- return nil
+    local env = self
+    while env do
+        if env.typedefs then
+            local i=1
+            while env.typedefs[i] do
+                if env.typedefs[i].utype == type then
+                    return type
+                end
+                i = i+1
+            end
+        end
+        env = env.parent
+    end
+    return nil
 end
 
 function find_enum_var(var)
 
-	if tonumber(var) then return var end
-
-	local c = classContainer.curr
-	while c do
-		local ns = getnamespace(c)
-		for k,v in pairs(_global_enums) do
-			if match_type(var, v, ns) then
-				return v
-			end
-		end
-		if c.base and c.base ~= '' then
-			c = _global_classes[c:findtype(c.base)]
-		else
-			c = nil
-		end
-	end
-
-	return var
+    if tonumber(var) then return var end
+
+    local c = classContainer.curr
+    while c do
+        local ns = getnamespace(c)
+        for k,v in pairs(_global_enums) do
+            if match_type(var, v, ns) then
+                return v
+            end
+        end
+        if c.base and c.base ~= '' then
+            c = _global_classes[c:findtype(c.base)]
+        else
+            c = nil
+        end
+    end
+
+    return var
 end
 
@@ -306,108 +305,108 @@
 function classContainer:findtype (t)
 
-	t = string.gsub(t, "=.*", "")
-	if _basic[t] then
-	 return t
-	end
-
-	local _,_,em = string.find(t, "([&%*])%s*$")
-	t = string.gsub(t, "%s*([&%*])%s*$", "")
-	p = self
-	while p and type(p)=='table' do
-		local st = getnamespace(p)
-
-		for i=_global_types.n,1,-1 do -- in reverse order
-
-			if match_type(t, _global_types[i], st) then
-				return _global_types[i]..(em or "")
-			end
-		end
-		if p.base and p.base ~= '' and p.base ~= t then
-			--print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
-			p = _global_classes[p:findtype(p.base)]
-		else
-			p = nil
-		end
-	end
-
-	return nil
+    t = string.gsub(t, "=.*", "")
+    if _basic[t] then
+     return t
+    end
+
+    local _,_,em = string.find(t, "([&%*])%s*$")
+    t = string.gsub(t, "%s*([&%*])%s*$", "")
+    p = self
+    while p and type(p)=='table' do
+        local st = getnamespace(p)
+
+        for i=_global_types.n,1,-1 do -- in reverse order
+
+            if match_type(t, _global_types[i], st) then
+                return _global_types[i]..(em or "")
+            end
+        end
+        if p.base and p.base ~= '' and p.base ~= t then
+            --print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
+            p = _global_classes[p:findtype(p.base)]
+        else
+            p = nil
+        end
+    end
+
+    return nil
 end
 
 function append_global_type(t, class)
-	_global_types.n = _global_types.n +1
-	_global_types[_global_types.n] = t
-	_global_types_hash[t] = 1
-	if class then append_class_type(t, class) end
+    _global_types.n = _global_types.n +1
+    _global_types[_global_types.n] = t
+    _global_types_hash[t] = 1
+    if class then append_class_type(t, class) end
 end
 
 function append_class_type(t,class)
-	if _global_classes[t] then
-		class.flags = _global_classes[t].flags
-		class.lnames = _global_classes[t].lnames
-		if _global_classes[t].base and (_global_classes[t].base ~= '') then
-			class.base = _global_classes[t].base or class.base
-		end
-	end
-	_global_classes[t] = class
-	class.flags = class.flags or {}
+    if _global_classes[t] then
+        class.flags = _global_classes[t].flags
+        class.lnames = _global_classes[t].lnames
+        if _global_classes[t].base and (_global_classes[t].base ~= '') then
+            class.base = _global_classes[t].base or class.base
+        end
+    end
+    _global_classes[t] = class
+    class.flags = class.flags or {}
 end
 
 function match_type(childtype, regtype, st)
 --print("findtype "..childtype..", "..regtype..", "..st)
-	local b,e = string.find(regtype, childtype, -string.len(childtype), true)
-	if b then
-
-		if e == string.len(regtype) and
-				(b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
-				string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
-			return true
-		end
-	end
-
-	return false
+    local b,e = string.find(regtype, childtype, -string.len(childtype), true)
+    if b then
+
+        if e == string.len(regtype) and
+                (b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
+                string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
+            return true
+        end
+    end
+
+    return false
 end
 
 function findtype_on_childs(self, t)
 
-	local tchild
-	if self.classtype == 'class' or self.classtype == 'namespace' then
-		for k,v in ipairs(self) do
-			if v.classtype == 'class' or v.classtype == 'namespace' then
-				if v.typedefs and v.typedefs[t] then
-				 return v.typedefs[t]
-				elseif v.usertypes and v.usertypes[t] then
-				 return v.usertypes[t]
-				end
-				tchild = findtype_on_childs(v, t)
-				if tchild then return tchild end
-			end
-		end
-	end
-	return nil
+    local tchild
+    if self.classtype == 'class' or self.classtype == 'namespace' then
+        for k,v in ipairs(self) do
+            if v.classtype == 'class' or v.classtype == 'namespace' then
+                if v.typedefs and v.typedefs[t] then
+                 return v.typedefs[t]
+                elseif v.usertypes and v.usertypes[t] then
+                 return v.usertypes[t]
+                end
+                tchild = findtype_on_childs(v, t)
+                if tchild then return tchild end
+            end
+        end
+    end
+    return nil
 
 end
 
 function classContainer:isenum (type)
- if global_enums[type] then
-	return type
- else
- 	return false
- end
-
- local basetype = gsub(type,"^.*::","")
- local env = self
- while env do
-  if env.enums then
-   local i=1
-   while env.enums[i] do
-    if env.enums[i].name == basetype then
-         return true
-        end
-        i = i+1
-   end
-  end
-  env = env.parent
- end
- return false
+    if global_enums[type] then
+        return type
+    else
+        return false
+    end
+
+    local basetype = gsub(type,"^.*::","")
+    local env = self
+    while env do
+        if env.enums then
+            local i=1
+            while env.enums[i] do
+                if env.enums[i].name == basetype then
+                    return true
+                end
+                i = i+1
+            end
+        end
+        env = env.parent
+    end
+    return false
 end
 
@@ -416,327 +415,327 @@
 -- parse chunk
 function classContainer:doparse (s)
---print ("parse "..s)
-
- -- try the parser hook
- do
- 	local sub = parser_hook(s)
- 	if sub then
- 		return sub
- 	end
- end
-
- -- try the null statement
- do
- 	local b,e,code = string.find(s, "^%s*;")
- 	if b then
- 		return strsub(s,e+1)
- 	end
- end
-
- -- try empty verbatim line
- do
- 	local b,e,code = string.find(s, "^%s*$\n")
- 	if b then
- 		return strsub(s,e+1)
- 	end
- end
-
- -- try Lua code
- do
-  local b,e,code = strfind(s,"^%s*(%b\1\2)")
-  if b then
-   Code(strsub(code,2,-2))
-   return strsub(s,e+1)
-  end
- end
-
- -- try C code
- do
-  local b,e,code = strfind(s,"^%s*(%b\3\4)")
-  if b then
-	code = '{'..strsub(code,2,-2)..'\n}\n'
-	Verbatim(code,'r')        -- verbatim code for 'r'egister fragment
-	return strsub(s,e+1)
-  end
- end
-
- -- try C code for preamble section
- do
- 	local b,e,code = string.find(s, "^%s*(%b\5\6)")
- 	if b then
- 		code = string.sub(code, 2, -2).."\n"
-		Verbatim(code, '')
-		return string.sub(s, e+1)
- 	end
- end
-
- -- try default_property directive
- do
- 	local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?")
- 	if b then
- 		if not ptype or ptype == "" then
- 			ptype = "default"
- 		end
- 		self:set_property_type(ptype)
-	 	return strsub(s, e+1)
- 	end
- end
-
- -- try protected_destructor directive
- do
- 	local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?")
-	if b then
-		if self.set_protected_destructor then
-	 		self:set_protected_destructor(true)
-	 	end
- 		return strsub(s, e+1)
- 	end
- end
-
- -- try 'extern' keyword
- do
- 	local b,e = string.find(s, "^%s*extern%s+")
- 	if b then
-		-- do nothing
- 		return strsub(s, e+1)
- 	end
- end
-	
- -- try 'virtual' keyworkd
- do
- 	local b,e = string.find(s, "^%s*virtual%s+")
- 	if b then
- 		methodisvirtual = true
- 		return strsub(s, e+1)
- 	end
- end
-
- -- try labels (public, private, etc)
- do
- 	local b,e = string.find(s, "^%s*%w*%s*:[^:]")
- 	if b then
- 		return strsub(s, e) -- preserve the [^:]
- 	end
- end
-
- -- try module
- do
-  local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Module(name,body)
-   return strsub(s,e+1)
-  end
- end
-
- -- try namesapce
- do
-  local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Namespace(name,body)
-   return strsub(s,e+1)
-  end
- end
-
- -- try define
- do
-  local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Define(name)
-   return strsub(s,e+1)
-  end
- end
-
- -- try enumerates
-
- do
-  local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")
-  if b then
-   --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')")
-   _curr_code = strsub(s,b,e)
-   Enumerate(name,body,varname)
-   return strsub(s,e+1)
-  end
- end
-
--- do
---  local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")
---  if b then
---   _curr_code = strsub(s,b,e)
---   Enumerate(name,body)
---  return strsub(s,e+1)
---  end
--- end
-
- do
-  local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Enumerate(name,body)
-   return strsub(s,e+1)
-  end
- end
-
- -- try operator
- do
-  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*")
-  if not b then
-		 -- try inline
-   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*")
-  end
-  if not b then
-  	-- try cast operator
-  	b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)");
-  	if b then
-  		local _,ie = string.find(s, "^%s*%b{}", e+1)
-  		if ie then
-  			e = ie
-  		end
-  	end
-  end
-  if b then
-   _curr_code = strsub(s,b,e)
-   Operator(decl,kind,arg,const)
-   return strsub(s,e+1)
-  end
- end
-
- -- try function
- do
-  --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*")
-  local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*")
-  if not b then
-  	-- try function with template
-  	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*")
-  end
-  if not b then
-   -- try a single letter function name
-   b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
-  end
-  if b then
-  	if virt and string.find(virt, "[=0]") then
-  		if self.flags then
-  			self.flags.pure_virtual = true
-  		end
-  	end
-   _curr_code = strsub(s,b,e)
-   Function(decl,arg,const)
-   return strsub(s,e+1)
-  end
- end
-
- -- try inline function
- do
-  local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*")
-  --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*")
-  if not b then
-   -- try a single letter function name
-   b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")
-  end
-  if b then
-   _curr_code = strsub(s,b,e)
-   Function(decl,arg,const)
-   return strsub(s,e+1)
-  end
- end
-
- -- try class
- do
-	 local b,e,name,base,body
-		base = '' body = ''
-		b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
-		if not b then
-			b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
-			if not b then
-				b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
-				if not b then
-					b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
-					if not b then
-						b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
-						if not b then
-							base = ''
-							b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
-						end
-					end
-				end
-			end
-		end
-		if b then
-			if base ~= '' then
-				base = string.gsub(base, "^%s*:%s*", "")
-				base = string.gsub(base, "%s*public%s*", "")
-				base = split(base, ",")
-				--local b,e
-				--b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$")
-			else
-				base = {}
-			end
-			_curr_code = strsub(s,b,e)
-			Class(name,base,body)
-			return strsub(s,e+1)
-		end
-	end
-
- -- try typedef
- do
-  local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Typedef(types)
-   return strsub(s,e+1)
-  end
- end
-
- -- try variable
- do
-  local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-
-	local list = split_c_tokens(decl, ",")
-	Variable(list[1])
-	if list.n > 1 then
-		local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$");
-
-		local i =2;
-		while list[i] do
-			Variable(type.." "..list[i])
-			i=i+1
-		end
-	end
-   --Variable(decl)
-   return strsub(s,e+1)
-  end
- end
-
-	-- try string
- do
-  local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Variable(decl)
-   return strsub(s,e+1)
-  end
- end
-
- -- try array
- do
-  local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
-  if b then
-   _curr_code = strsub(s,b,e)
-   Array(decl)
-   return strsub(s,e+1)
-  end
- end
-
- -- no matching
- if gsub(s,"%s%s*","") ~= "" then
-  _curr_code = s
-  error("#parse error")
- else
-  return ""
- end
+    --print ("parse "..s)
+
+    -- try the parser hook
+    do
+        local sub = parser_hook(s)
+        if sub then
+            return sub
+        end
+    end
+
+    -- try the null statement
+    do
+        local b,e,code = string.find(s, "^%s*;")
+        if b then
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try empty verbatim line
+    do
+        local b,e,code = string.find(s, "^%s*$\n")
+        if b then
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try Lua code
+    do
+        local b,e,code = strfind(s,"^%s*(%b\1\2)")
+        if b then
+            Code(strsub(code,2,-2))
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try C code
+    do
+        local b,e,code = strfind(s,"^%s*(%b\3\4)")
+        if b then
+            code = '{'..strsub(code,2,-2)..'\n}\n'
+            Verbatim(code,'r')        -- verbatim code for 'r'egister fragment
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try C code for preamble section
+    do
+        local b,e,code = string.find(s, "^%s*(%b\5\6)")
+        if b then
+            code = string.sub(code, 2, -2).."\n"
+            Verbatim(code, '')
+            return string.sub(s, e+1)
+        end
+    end
+
+    -- try default_property directive
+    do
+        local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?")
+        if b then
+            if not ptype or ptype == "" then
+                ptype = "default"
+            end
+            self:set_property_type(ptype)
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try protected_destructor directive
+    do
+        local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?")
+        if b then
+            if self.set_protected_destructor then
+                self:set_protected_destructor(true)
+            end
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try 'extern' keyword
+    do
+        local b,e = string.find(s, "^%s*extern%s+")
+        if b then
+            -- do nothing
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try 'virtual' keyworkd
+    do
+        local b,e = string.find(s, "^%s*virtual%s+")
+        if b then
+            methodisvirtual = true
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try labels (public, private, etc)
+    do
+        local b,e = string.find(s, "^%s*%w*%s*:[^:]")
+        if b then
+            return strsub(s, e) -- preserve the [^:]
+        end
+    end
+
+    -- try module
+    do
+        local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Module(name,body)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try namesapce
+    do
+        local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Namespace(name,body)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try define
+    do
+        local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Define(name)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try enumerates
+
+    do
+        local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")
+        if b then
+            --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')")
+            _curr_code = strsub(s,b,e)
+            Enumerate(name,body,varname)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- do
+    --    local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")
+    --    if b then
+    --        _curr_code = strsub(s,b,e)
+    --        Enumerate(name,body)
+    --        return strsub(s,e+1)
+    --    end
+    -- end
+
+    do
+        local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
+        if b then
+        _curr_code = strsub(s,b,e)
+        Enumerate(name,body)
+        return strsub(s,e+1)
+        end
+    end
+
+    -- try operator
+    do
+        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*")
+        if not b then
+            -- try inline
+            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*")
+        end
+        if not b then
+            -- try cast operator
+            b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)");
+            if b then
+                local _,ie = string.find(s, "^%s*%b{}", e+1)
+                if ie then
+                    e = ie
+                end
+            end
+        end
+        if b then
+            _curr_code = strsub(s,b,e)
+            Operator(decl,kind,arg,const)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try function
+    do
+        --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*")
+        local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*")
+        if not b then
+            -- try function with template
+            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*")
+        end
+        if not b then
+            -- try a single letter function name
+            b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
+        end
+        if b then
+            if virt and string.find(virt, "[=0]") then
+                if self.flags then
+                    self.flags.pure_virtual = true
+                end
+            end
+            _curr_code = strsub(s,b,e)
+            Function(decl,arg,const)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try inline function
+    do
+        local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*")
+        --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*")
+        if not b then
+            -- try a single letter function name
+            b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")
+        end
+        if b then
+            _curr_code = strsub(s,b,e)
+            Function(decl,arg,const)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try class
+    do
+        local b,e,name,base,body
+        base = '' body = ''
+        b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
+        if not b then
+            b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
+            if not b then
+                b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                if not b then
+                    b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                    if not b then
+                        b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                        if not b then
+                            base = ''
+                            b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
+                        end
+                    end
+                end
+            end
+        end
+        if b then
+            if base ~= '' then
+                base = string.gsub(base, "^%s*:%s*", "")
+                base = string.gsub(base, "%s*public%s*", "")
+                base = split(base, ",")
+                --local b,e
+                --b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$")
+            else
+                base = {}
+            end
+            _curr_code = strsub(s,b,e)
+            Class(name,base,body)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try typedef
+    do
+        local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Typedef(types)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try variable
+    do
+        local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+
+            local list = split_c_tokens(decl, ",")
+            Variable(list[1])
+            if list.n > 1 then
+                local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$");
+
+                local i =2;
+                while list[i] do
+                    Variable(type.." "..list[i])
+                    i=i+1
+                end
+            end
+            --Variable(decl)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try string
+    do
+        local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Variable(decl)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try array
+    do
+        local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Array(decl)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- no matching
+    if gsub(s,"%s%s*","") ~= "" then
+        _curr_code = s
+        error("#parse error")
+    else
+        return ""
+    end
 
 end
@@ -744,10 +743,10 @@
 function classContainer:parse (s)
 
-	self.curr_member_access = nil
-
- while s ~= '' do
-  s = self:doparse(s)
-  methodisvirtual = false
- end
+    self.curr_member_access = nil
+
+    while s ~= '' do
+        s = self:doparse(s)
+        methodisvirtual = false
+    end
 end
 
@@ -757,15 +756,15 @@
 function get_property_type()
 
-	return classContainer.curr:get_property_type()
+    return classContainer.curr:get_property_type()
 end
 
 function classContainer:set_property_type(ptype)
-	ptype = string.gsub(ptype, "^%s*", "")
-	ptype = string.gsub(ptype, "%s*$", "")
-
-	self.property_type = ptype
+    ptype = string.gsub(ptype, "^%s*", "")
+    ptype = string.gsub(ptype, "%s*$", "")
+
+    self.property_type = ptype
 end
 
 function classContainer:get_property_type()
-	return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
-end
+    return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
+end
