This repository has been archived by the owner on Jun 26, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen_binding.lua
102 lines (88 loc) · 2.56 KB
/
gen_binding.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
local fname = arg[1]
local fname_out = arg[2]
if not fname or not fname_out then
io.stderr:write("Usage: gen_binding.lua input_name output_name clang_options...\n")
os.exit(1)
end
local utils = require("gen_binding.utils")
local parser = require("gen_binding.parser")
local generator = require("gen_binding.generator")
local cl = require("ljclang")
local vr = cl.ChildVisitResult
-- add general options
local args = {
"-DLIBSHIT_BINDING_GENERATOR",
"-DLIBSHIT_WITH_LUA=1",
"-nostdinc++",
"-isystem", "ext/libcxx/include",
"-isystem", "libshit/ext/libcxx/include",
"-isystem", "ext/libcxxabi/include",
"-isystem", "libshit/ext/libcxxabi/include",
"-Isrc",
"-Iext/boost",
"-Iext/ljx/src",
"-Iext/doctest/doctest",
"-Ilibshit/src",
"-Ilibshit/ext/boost",
"-Ilibshit/ext/ljx/src",
"-Ilibshit/ext/doctest/doctest",
"-std=c++17",
"-Wno-undefined-inline", "-Wno-undefined-internal", -- skip function bodies
"-Wno-assume"
}
-- hack: -isystem /usr/lib/clang/<version>/include automatically
local clang_ver = cl.clangVersion():match("%d+%.%d+%.%d+")
if clang_ver then
local path = (os.getenv("PREFIX") or "/usr").."/lib/clang/"..clang_ver
local f = io.open(path.."/include/stddef.h")
if f then
f:close()
args[#args+1] = "-resource-dir"
args[#args+1] = path
end
end
for i=3,#arg do args[#args+1] = arg[i] end
-- let's go
local idx = cl.createIndex()
local tu = idx:parse(fname, args, {"KeepGoing", "SkipFunctionBodies"})
if tu == nil then
io.stderr:write("\27[31mParse failed\27[0m\n")
os.exit(-1)
end
for _,d in ipairs(tu:diagnostics()) do
if d.severity == "CXDiagnostic_Warning" then
utils.print_warning(d.text)
elseif d.severity >= "CXDiagnostic_Error" then
utils.print_error(d.text)
else
io.stderr:write(d.text, "\n")
end
end
-- main enumeration
local function remove_ext(name)
return name and name:gsub("%.[^.]*$", "")
end
local match_fname = remove_ext(fname)
local fname_map = {}
local check_alias_v = cl.regCursorVisitor(function(c)
if c:kind() == "AnnotateAttr" and c:name():sub(1, 11) == "alias_file " then
fname_map[c:location()] = c:name():sub(12)
end
return vr.Break
end)
local function parse_filter(c, par)
c:children(check_alias_v)
local loc = c:location()
if fname_map[loc] then loc = fname_map[loc] end
return remove_ext(loc) == match_fname
end
local classes = parser.parse(tu:cursor(), parse_filter)
local gen = generator.generate(classes)
if fname_out == "-" then
io.stdout:write(gen)
else
local f = io.open(fname_out, "wb")
f:write(gen)
f:close()
end
os.exit(utils.fail and 1 or 0)