Mercurial > pub > dyncall > bindings
comparison lua/luadyncall/src/dynport.lua @ 0:0cfcc391201f
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:26:28 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0cfcc391201f |
---|---|
1 require "dynload" | |
2 require "dyncall" | |
3 require "path" | |
4 | |
5 local function makewrapper(addr, signature) | |
6 return function(...) return dyncall(addr, signature, ...) end | |
7 end | |
8 | |
9 loaded = { } | |
10 | |
11 --- The dynport path is initialized by LDP_PATH environment. | |
12 -- @usage Defaults to dynport_syspath. | |
13 dynport_path = pathinit("LDP_PATH","?.dynport;/usr/local/share/dynport/?.dynport;/opt/local/share/dynport/?.dynport") | |
14 | |
15 local function find(name) | |
16 return pathfind( dynport_path, name, io.open ) | |
17 end | |
18 | |
19 --[[ | |
20 local LDP_PATH = "?.dynport;/usr/local/share/dynport/?.dynport;/opt/local/share/dynport/?.dynport" | |
21 local path = os.getenv("LDP_PATH") or LDP_PATH | |
22 | |
23 local function find(name) | |
24 local replaced = path:gsub("?", name) | |
25 local f = nil | |
26 local hist = {} | |
27 for filename in replaced:gmatch("([^;]+)") do | |
28 f = io.open(filename) | |
29 if f then break else | |
30 table.insert(hist, "\tno file '") | |
31 table.insert(hist, filename) | |
32 table.insert(hist, "'\n") | |
33 end | |
34 end | |
35 if f then | |
36 return f | |
37 else | |
38 error("dynport '"..name.."' not found:\n"..table.concat(hist), 3) | |
39 end | |
40 end | |
41 ]] | |
42 | |
43 | |
44 --- Process dynport files. | |
45 -- Files will be opened and processed according to the dynport format. | |
46 -- Function wrappers and constants will be installed. | |
47 -- Structure/Union type information have not been implemented yet. | |
48 -- @param name dynport name to lookup. | |
49 -- @unit table to use for import. | |
50 -- @field _dynport_libs contains. | |
51 -- @return unit table with imports. | |
52 | |
53 function dynport_NEW(portname, t) | |
54 local t = t or _G | |
55 local port = loaded[portname] | |
56 if port then return port end | |
57 local file, errmsg = searchpath(portname, path) | |
58 if not file then error(errmsg) end | |
59 end | |
60 | |
61 function dynportImport(name, unit) | |
62 | |
63 local file = find(name) | |
64 | |
65 if not unit._dynport_libs then | |
66 unit._dynport_libs = { } | |
67 end | |
68 | |
69 local cached = unit._dynport_libs[name] | |
70 if cached then return unit end | |
71 | |
72 if not file then | |
73 error("dynport "..name.. " not found") | |
74 end | |
75 | |
76 local iter = file:lines() | |
77 | |
78 local libs = { } | |
79 | |
80 function dolib() | |
81 local libnames = "" | |
82 for line in iter do | |
83 if line == "." then break end | |
84 libnames = line | |
85 end | |
86 libs[#libs+1] = dynload(libnames) | |
87 end | |
88 | |
89 function dofun() | |
90 local index = 1 | |
91 local unresolved = {} | |
92 for line in iter do | |
93 | |
94 if line == "." then break end | |
95 | |
96 local pos = line:find("[(]") | |
97 local symbol = line:sub(1, pos-1) | |
98 local stop = line:find("[;]", pos+1) | |
99 local signature = line:sub(pos+1,stop-1) | |
100 | |
101 local addr = dynsym(libs[#libs], symbol) | |
102 | |
103 if type(addr) == "userdata" then | |
104 rawset(unit, symbol, makewrapper(addr, signature) ) | |
105 -- module[symbol] = makewrapper(addr, signature) | |
106 else | |
107 unresolved[#unresolved] = symbol | |
108 end | |
109 | |
110 end | |
111 | |
112 if #unresolved ~= 0 then | |
113 print("unresolved symbols:") | |
114 print(table.concat(unresolved,"\n")) | |
115 end | |
116 end | |
117 | |
118 function doconst() | |
119 for line in iter do | |
120 if line == "." then break end | |
121 local pos = line:find("=") | |
122 local key = line:sub(1, pos-1) | |
123 local value = line:sub(pos+1) | |
124 -- module[key] = tonumber(value) | |
125 rawset( unit, key, tonumber(value) ) | |
126 end | |
127 end | |
128 | |
129 function dostruct() | |
130 for line in iter do | |
131 if line == "." then break end | |
132 end | |
133 end | |
134 | |
135 function dounion() | |
136 for line in iter do | |
137 if line == "." then break end | |
138 end | |
139 end | |
140 | |
141 for line in iter do | |
142 if line == "." then break | |
143 elseif line == ":lib" then dolib() | |
144 elseif line == ":fun" then dofun() | |
145 elseif line == ":const" then doconst() | |
146 elseif line == ":struct" then dostruct() | |
147 elseif line == ":union" then dounion() | |
148 end | |
149 end | |
150 | |
151 unit._dynport_libs[name] = libs | |
152 | |
153 return unit | |
154 | |
155 end | |
156 | |
157 --- Dynamic bind C library Interfaces. | |
158 -- @param name dynport name which will be searched by | |
159 function dynport(portname) | |
160 return dynportImport(portname, _G) | |
161 end | |
162 | |
163 |