Files
mir_server/Gateway/srvlib/3rd/tolua++/lua/basic.lua
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

436 lines
10 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- tolua: basic utility functions
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- Last update: Apr 2003
-- $Id: basic.lua 1004 2006-02-27 13:03:20Z lindquist $
-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications.
-- Basic C types and their corresponding Lua types
-- All occurrences of "char*" will be replaced by "_cstring",
-- and all occurrences of "void*" will be replaced by "_userdata"
_basic = {
['void'] = '',
['char'] = 'number',
['int'] = 'number',
['short'] = 'number',
['long'] = 'number',
['unsigned'] = 'number',
['float'] = 'number',
['double'] = 'number',
['_cstring'] = 'string',
['_userdata'] = 'userdata',
['char*'] = 'string',
['void*'] = 'userdata',
['bool'] = 'boolean',
['lua_Object'] = 'value',
['LUA_VALUE'] = 'value', -- for compatibility with tolua 4.0
['lua_State*'] = 'state',
['_lstate'] = 'state',
['lua_Function'] = 'value',
-- modified by PeakGao
['__int64'] = 'number',
['wchar_t'] = 'number',
['String'] = 'string',
}
_basic_ctype = {
number = "lua_Number",
string = "const char*",
userdata = "void*",
boolean = "bool",
value = "int",
state = "lua_State*",
}
-- functions the are used to do a 'raw push' of basic types
_basic_raw_push = {}
-- List of user defined types
-- Each type corresponds to a variable name that stores its tag value.
_usertype = {}
-- List of types that have to be collected
_collect = {}
-- List of types
_global_types = {n=0}
_global_types_hash = {}
-- list of classes
_global_classes = {}
-- List of enum constants
_global_enums = {}
-- List of auto renaming
_renaming = {}
function appendrenaming (s)
local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$")
if not b then
error("#Invalid renaming syntax; it should be of the form: pattern@pattern")
end
tinsert(_renaming,{old=old, new=new})
end
function applyrenaming (s)
for i=1,getn(_renaming) do
local m,n = gsub(s,_renaming[i].old,_renaming[i].new)
if n ~= 0 then
return m
end
end
return nil
end
-- Error handler
function tolua_error (s,f)
if _curr_code then
print("***curr code for error is "..tostring(_curr_code))
print(debug.traceback())
end
local out = _OUTPUT
_OUTPUT = _STDERR
if strsub(s,1,1) == '#' then
write("\n** tolua: "..strsub(s,2)..".\n\n")
if _curr_code then
local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line
if s==nil then s = _curr_code end
s = gsub(s,"_userdata","void*") -- return with 'void*'
s = gsub(s,"_cstring","char*") -- return with 'char*'
s = gsub(s,"_lstate","lua_State*") -- return with 'lua_State*'
write("Code being processed:\n"..s.."\n")
end
else
if not f then f = "(f is nil)" end
print("\n** tolua internal error: "..f..s..".\n\n")
return
end
_OUTPUT = out
end
function warning (msg)
local out = _OUTPUT
_OUTPUT = _STDERR
write("\n** tolua warning: "..msg..".\n\n")
_OUTPUT = out
end
-- register an user defined type: returns full type
function regtype (t)
--if isbasic(t) then
-- return t
--end
local ft = findtype(t)
if not _usertype[ft] then
return appendusertype(t)
end
return ft
end
-- return type name: returns full type
function typevar(type)
if type == '' or type == 'void' then
return type
else
local ft = findtype(type)
if ft then
return ft
end
_usertype[type] = type
return type
end
end
-- check if basic type
function isbasic (type)
local t = gsub(type,'const ','')
local m,t = applytypedef('', t)
local b = _basic[t]
if b then
return b,_basic_ctype[b]
end
return nil
end
-- split string using a token
function split (s,t)
local l = {n=0}
local f = function (s)
l.n = l.n + 1
l[l.n] = s
return ""
end
local p = "%s*(.-)%s*"..t.."%s*"
s = gsub(s,"^%s+","")
s = gsub(s,"%s+$","")
s = gsub(s,p,f)
l.n = l.n + 1
l[l.n] = gsub(s,"(%s%s*)$","")
return l
end
-- splits a string using a pattern, considering the spacial cases of C code (templates, function parameters, etc)
-- pattern can't contain the '^' (as used to identify the begining of the line)
-- also strips whitespace
function split_c_tokens(s, pat)
s = string.gsub(s, "^%s*", "")
s = string.gsub(s, "%s*$", "")
local token_begin = 1
local token_end = 1
local ofs = 1
local ret = {n=0}
function add_token(ofs)
local t = string.sub(s, token_begin, ofs)
t = string.gsub(t, "^%s*", "")
t = string.gsub(t, "%s*$", "")
ret.n = ret.n + 1
ret[ret.n] = t
end
while ofs <= string.len(s) do
local sub = string.sub(s, ofs, -1)
local b,e = string.find(sub, "^"..pat)
if b then
add_token(ofs-1)
ofs = ofs+e
token_begin = ofs
else
local char = string.sub(s, ofs, ofs)
if char == "(" or char == "<" then
local block
if char == "(" then block = "^%b()" end
if char == "<" then block = "^%b<>" end
b,e = string.find(sub, block)
if not b then
-- unterminated block?
ofs = ofs+1
else
ofs = ofs + e
end
else
ofs = ofs+1
end
end
end
add_token(ofs)
--if ret.n == 0 then
-- ret.n=1
-- ret[1] = ""
--end
return ret
end
-- concatenate strings of a table
function concat (t,f,l,jstr)
jstr = jstr or " "
local s = ''
local i=f
while i<=l do
s = s..t[i]
i = i+1
if i <= l then s = s..jstr end
end
return s
end
-- concatenate all parameters, following output rules
function concatparam (line, ...)
local i=1
while i<=arg.n do
if _cont and not strfind(_cont,'[%(,"]') and
strfind(arg[i],"^[%a_~]") then
line = line .. ' '
end
line = line .. arg[i]
if arg[i] ~= '' then
_cont = strsub(arg[i],-1,-1)
end
i = i+1
end
if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
_cont=nil line = line .. '\n'
end
return line
end
-- output line
function output (...)
local i=1
while i<=arg.n do
if _cont and not strfind(_cont,'[%(,"]') and
strfind(arg[i],"^[%a_~]") then
write(' ')
end
write(arg[i])
if arg[i] ~= '' then
_cont = strsub(arg[i],-1,-1)
end
i = i+1
end
if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
_cont=nil write('\n')
end
end
function get_property_methods(ptype, name)
if get_property_methods_hook and get_property_methods_hook(ptype,name) then
return get_property_methods_hook(ptype, name)
end
if ptype == "default" then -- get_name, set_name
return "get_"..name, "set_"..name
end
if ptype == "qt" then -- name, setName
return name, "set"..string.upper(string.sub(name, 1, 1))..string.sub(name, 2, -1)
end
if ptype == "overload" then -- name, name
return name,name
end
return nil
end
-------------- the hooks
-- called right after processing the $[ichl]file directives,
-- right before processing anything else
-- takes the package object as the parameter
-- modified by PeakGao
myTypeDef = {
"Void", "HEntity","HItem",
"Bool",
"Int8", "Uint8",
"Int16", "Uint16",
"Int", "Uint", "size_t",
"Int32", "Uint32",
"Int64", "Uint64",
"Float", "Double",
"AChar", "WChar", "Char",
"PAChar", "PWChar", "PChar",
"CPAChar", "CPWChar", "CPChar",
"SString",
"Range",
"UID",
"PT_KEY",
}
myTypeDefReplace = {
"void", "unsigned long","unsigned long",
"bool",
"char", "unsigned char",
"short", "unsigned short",
"int", "unsigned int", "unsigned int",
"long", "unsigned long",
"__int64", "unsigned __int64",
"float", "double",
"char", "wchar_t", "char",
"char*", "wchar_t*", "char*",
"const char*", "const wchar_t*", "const char*",
"const char*",
"__int64",
"__int64",
"unsigned long",
}
function preprocess_hook(p)
-- p.code has all the input code from the pkg
--print(p.code)
--local _, _, key = strfind(p.code, "#ifndef%s*([%w_]+)")
--p.code = gsub(p.code, "#define%s*"..key, "");
p.code = gsub(p.code, "(#define%s*[%w_]+%()", "// %1") -- ע<>ͺ<EFBFBD><CDBA><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD>
p.code = gsub(p.code, "#define%s*[%w_]+%s*%c*\n", "") -- ע<><D7A2>ͷ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD><EFBFBD>ĺ<EFBFBD>
p.code = gsub(p.code, "%s*class%s*[%w_]+%s*;", "") -- ɾ<><C9BE>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
p.code = gsub(p.code, "%s*struct%s*[%w_]+%s*;", "") -- ɾ<><C9BE>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľṹ
--print(p.code)
local count = table.getn(myTypeDef)
local mode
local mode_replace
for i, count in pairs(myTypeDef) do
mode = "([^%w_])" .. myTypeDef[i] .. "([^%w_])"
mode_replace = "%1" .. myTypeDefReplace[i] .. "%2"
p.code = gsub(p.code, mode, mode_replace)
end
--print(p.code)
end
-- called for every $ifile directive
-- takes a table with a string called 'code' inside, the filename, and any extra arguments
-- passed to $ifile. no return value
function include_file_hook(t, filename, ...)
end
-- called after processing anything that's not code (like '$renaming', comments, etc)
-- and right before parsing the actual code.
-- takes the Package object with all the code on the 'code' key. no return value
function preparse_hook(package)
-- modified by PeakGao
--print(package.code)
package.code = gsub(package.code, "%s?Inline(%s)", "%1") -- eliminate 'Inline' keyword
package.code = gsub(package.code, "%s?InlineFC(%s)", "%1") -- eliminate 'InlineFC' keyword
package.code = gsub(package.code, "(%s*)FCL_CLASS_DECL(%s*)", " ") -- eliminate 'FCL_CLASS_DECL' keyword
package.code = gsub(package.code, "(%s*)FCLAPI(%s*)", "") -- eliminate 'FCLAPI' keyword
package.code = gsub(package.code, "(%s*)SDK_API(%s*)", "") -- eliminate 'FCLAPI' keyword
package.code = gsub(package.code, "(%s*)DECAPI(%s*)", "") -- eliminate 'FCLAPI' keyword
package.code = gsub(package.code, "(%s*)MT_API(%s*)", "") -- eliminate 'MT_API' keyword
package.code = gsub(package.code, "(%s*)GAME_ENGINE_API(%s*)", "") -- eliminate 'GAME_ENGINE_API' keyword
package.code = gsub(package.code, "(%s*)LUASVR_API(%s*)", "") -- eliminate 'LUASVR_API' keyword
package.code = gsub(package.code, "BEGIN_NAMESPACE_FCL", "")
package.code = gsub(package.code, "END_NAMESPACE", "")
package.code = gsub(package.code, "BEGIN_NAMESPACE_MMORPG", "")
package.code = gsub(package.code, "BEGIN_API", "")
package.code = gsub(package.code, "END_API", "")
package.code = gsub(package.code, "([^%w_])%s*IN%s*([^%w_])", "%1%2")
package.code = gsub(package.code, "([^%w_])%s*OUT%s*([^%w_])", "%1%2")
--print(package.code)
end
-- called after writing all the output.
-- takes the Package object
function post_output_hook(package)
end
-- called from 'get_property_methods' to get the methods to retrieve a property
-- according to its type
function get_property_methods_hook(property_type, name)
end
-- called from ClassContainer:doparse with the string being parsed
-- return nil, or a substring
function parser_hook(s)
return nil
end