Differences From
Artifact [d2f35b212c]:
1 1 -- vim: ft=terra
2 2
3 3 local util = dofile('common.lua')
4 4 local buildopts, buildargs = util.parseargs{...}
5 +config = dofile('config.lua')
5 6
6 -local config = dofile('config.lua')
7 -
8 -local lib = {
7 +lib = {
8 + init = {};
9 9 loadlib = function(name,hdr)
10 10 local p = config.pkg[name]
11 11 -- for _,v in pairs(p.dylibs) do
12 12 -- terralib.linklibrary(p.libdir .. '/' .. v)
13 13 -- end
14 14 return terralib.includec(p.incdir .. '/' .. hdr)
15 15 end;
16 - randomize = terralib.externfunction('getrandom', {&opaque, intptr, uint} -> ptrdiff);
16 + dispatch = function(tbl)
17 + return macro(function(v,...)
18 + for ty,fn in pairs(tbl) do
19 + if v.tree.type == ty then return fn(v,...) end
20 + end
21 + return (tbl[false])(v,...)
22 + end)
23 + end;
24 + emit = function(...)
25 + local code = {}
26 + for i,v in ipairs{...} do
27 + if type(v) == 'string' or type(v) == 'number' then
28 + local str = tostring(v)
29 + code[#code+1] = `lib.io.send(2, str, [#str])
30 + elseif v.tree:is 'constant' then
31 + local str = tostring(v:asvalue())
32 + code[#code+1] = `lib.io.send(2, str, [#str])
33 + else
34 + code[#code+1] = quote var n = v in
35 + lib.io.send(2, n, lib.str.sz(n)) end
36 + end
37 + end
38 + code[#code+1] = `lib.io.send(2, '\n', 1)
39 + return code
40 + end;
41 + proc = {
42 + exit = terralib.externfunction('exit', int -> {});
43 + getenv = terralib.externfunction('getenv', rawstring -> rawstring);
44 + };
45 + io = {
46 + open = terralib.externfunction('open', {rawstring, int} -> int);
47 + close = terralib.externfunction('close', {int} -> int);
48 + send = terralib.externfunction('write', {int, rawstring, intptr} -> ptrdiff);
49 + recv = terralib.externfunction('read', {int, rawstring, intptr} -> ptrdiff);
50 + say = macro(function(msg) return `lib.io.send(2, msg, [#(msg:asvalue())]) end);
51 + fmt = terralib.externfunction('printf',
52 + terralib.types.funcpointer({rawstring},{int},true));
53 + };
54 + str = {
55 + sz = terralib.externfunction('strlen', rawstring -> intptr);
56 + cmp = terralib.externfunction('strcmp', {rawstring, rawstring} -> int);
57 + cpy = terralib.externfunction('stpcpy',{rawstring, rawstring} -> rawstring);
58 + ncpy = terralib.externfunction('stpncpy',{rawstring, rawstring, intptr} -> rawstring);
59 + fmt = terralib.externfunction('asprintf',
60 + terralib.types.funcpointer({&rawstring},{int},true));
61 + };
62 + mem = {
63 + zero = macro(function(r)
64 + return quote
65 + for i = 0, [r.tree.type.N] do r[i] = 0 end
66 + end
67 + end);
68 + heapa_raw = terralib.externfunction('malloc', intptr -> &opaque);
69 + heapr_raw = terralib.externfunction('realloc', {&opaque, intptr} -> &opaque);
70 + heapf = terralib.externfunction('free', &opaque -> {});
71 + cpy = terralib.externfunction('mempcpy',{&opaque, &opaque, intptr} -> &opaque);
72 + heapa = macro(function(ty, sz)
73 + local p = lib.mem.ptr(ty:astype())
74 + return `p {
75 + ptr = [&ty:astype()](lib.mem.heapa_raw(sizeof(ty) * sz));
76 + ct = sz;
77 + }
78 + end)
79 + };
17 80 }
81 +
82 +local noise = global(uint8,1)
83 +local defrep = function(level,n,code)
84 + return macro(function(...)
85 + local q = lib.emit("\27["..code..";1m(parsav "..n..")\27[m ", ...)
86 + return quote
87 + if noise >= level then [q] end
88 + end
89 + end);
90 +end
91 +lib.dbg = defrep(3,'debug', '32')
92 +lib.report = defrep(2,'info', '35')
93 +lib.warn = defrep(1,'warn', '33')
94 +lib.bail = macro(function(...)
95 + local q = lib.emit("\27[31;1m(parsav fatal)\27[m ", ...)
96 + return quote
97 + [q]
98 + lib.proc.exit(1)
99 + end
100 +end);
101 +lib.mem.ptr = terralib.memoize(function(ty)
102 + local t = terralib.types.newstruct(string.format('ptr<%s>', ty))
103 + t.entries = {
104 + {'ptr', &ty};
105 + {'ct', intptr};
106 + }
107 + local recurse = false
108 + if ty:isstruct() then
109 + if ty.methods.free then recurse = true end
110 + end
111 + t.methods = {
112 + free = terra(self: &t): bool
113 + [recurse and quote
114 + self.ptr:free()
115 + end or {}]
116 + if self.ct > 0 then
117 + lib.mem.heapf(self.ptr)
118 + self.ct = 0
119 + return true
120 + end
121 + return false
122 + end;
123 + init = terra(self: &t, newct: intptr): bool
124 + var nv = [&ty](lib.mem.heapa_raw(sizeof(ty) * newct))
125 + if nv ~= nil then
126 + self.ptr = nv
127 + self.ct = newct
128 + return true
129 + else return false end
130 + end;
131 + resize = terra(self: &t, newct: intptr): bool
132 + var nv: &ty
133 + if self.ct > 0
134 + then nv = [&ty](lib.mem.heapr_raw(self.ptr, sizeof(ty) * newct))
135 + else nv = [&ty](lib.mem.heapa_raw(sizeof(ty) * newct))
136 + end
137 + if nv ~= nil then
138 + self.ptr = nv
139 + self.ct = newct
140 + return true
141 + else return false end
142 + end;
143 + }
144 + return t
145 +end)
146 +
147 +lib.err = lib.loadlib('mbedtls','mbedtls/error.h')
18 148 lib.rsa = lib.loadlib('mbedtls','mbedtls/rsa.h')
19 149 lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
150 +lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
151 +lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
152 +lib.net = lib.loadlib('mongoose','mongoose.h')
153 +lib.pq = lib.loadlib('libpq','libpq-fe.h')
154 +lib.crypt = terralib.loadfile('crypt.t')()
155 +lib.http = terralib.loadfile('http.t')()
156 +lib.tpl = terralib.loadfile('tpl.t')()
157 +lib.string = terralib.loadfile('string.t')()
158 +lib.store = terralib.loadfile('store.t')()
159 +lib.cmdparse = terralib.loadfile('cmdparse.t')()
20 160
21 -local callbacks = {
22 - randomize = terra(ctx: &opaque, dest: &uint8, sz: intptr): int
23 - return lib.randomize(dest, sz, 0)
161 +do local collate = function(path,f, ...)
162 + return loadfile(path..'/'..f..'.lua')(path, ...)
163 +end
164 +data = {
165 + view = collate('view','load');
166 +} end
167 +
168 +-- slightly silly -- because we're using plain lua to gather up
169 +-- the template sources, they have to be actually turned into
170 +-- templates in the terra code, so we "mutate" them here
171 +for k,v in pairs(data.view) do
172 + local t = lib.tpl.mk { body = v, id = 'view/'..k }
173 + data.view[k] = t
174 +end
175 +
176 +local pemdump = macro(function(pub, kp)
177 + local msg = (pub:asvalue() and ' * emitting public key\n') or ' * emitting private key\n'
178 + return quote
179 + var buf: lib.crypt.pemfile
180 + lib.mem.zero(buf)
181 + lib.crypt.pem(pub, &kp, buf)
182 + lib.io.send(1, msg, [#msg])
183 + lib.io.send(1, [rawstring](&buf), lib.str.sz([rawstring](&buf)))
184 + lib.io.send(1, '\n', 1)
185 + end
186 +end)
187 +
188 +local handle = {
189 + http = terra(con: &lib.net.mg_connection, event: int, p: &opaque, ext: &opaque)
190 + switch event do
191 + case lib.net.MG_EV_HTTP_MSG then
192 + lib.dbg('routing HTTP request')
193 + var msg = [&lib.net.mg_http_message](p)
194 +
195 + end
196 + end
24 197 end;
25 198 }
199 +do
200 + local p = string.format('parsav: %s\nbuilt on %s\n', config.build.str, config.build.when)
201 + terra version() lib.io.send(1, p, [#p]) end
202 +end
203 +terra noise_init()
204 + var n = lib.proc.getenv('parsav_noise')
205 + if n ~= nil then
206 + if n[0] >= 0x30 and n[0] <= 0x39 and n[1] == 0 then
207 + noise = n[0] - 0x30
208 + return
209 + end
210 + end
211 + noise = 1
212 +end
213 +
214 +local options = lib.cmdparse {
215 + version = {'V', 'display information about the binary build and exit'};
216 + quiet = {'q', 'do not print to standard out'};
217 + help = {'h', 'display this list'}
218 +}
219 +
220 +terra entry(argc: int, argv: &rawstring): int
221 + noise_init()
222 + [lib.init]
223 +
224 + var mode: options
225 + mode:parse(argc,argv)
226 + if mode.version then
227 + version()
228 + return 0
229 + end
230 + if mode.help then
231 + lib.io.send(1, [options.helptxt], [#options.helptxt])
232 + return 0
233 + end
234 +
235 + var bind = lib.proc.getenv('parsav_bind')
236 + if bind == nil then bind = '[::]:10917' end
237 +
238 + var nm: lib.net.mg_mgr
239 + lib.net.mg_mgr_init(&nm)
240 +
241 + var nmc = lib.net.mg_http_listen(&nm, bind, handle.http, nil)
242 +
243 + while true do
244 + lib.net.mg_mgr_poll(&nm,1000)
245 + end
26 246
27 -terra entry(): int
28 - var pk: lib.pk.mbedtls_pk_context
29 - lib.pk.mbedtls_pk_init(&pk)
30 - lib.pk.mbedtls_pk_setup(&pk, lib.pk.mbedtls_pk_info_from_type(lib.pk.MBEDTLS_PK_RSA))
31 - var rsa = [&lib.rsa.mbedtls_rsa_context](pk.pk_ctx)
32 - lib.rsa.mbedtls_rsa_gen_key(rsa, callbacks.randomize, nil, 2048, 65537)
247 + lib.net.mg_mgr_free(&nm)
33 248 return 0
34 249 end
35 250
36 251 local bflag = function(long,short)
37 252 if short and util.has(buildopts, short) then return true end
38 253 if long and util.has(buildopts, long) then return true end
39 254 return false
................................................................................
45 260 end
46 261
47 262 local emit = print
48 263 if bflag('quiet','q') then emit = function() end end
49 264
50 265 local out = config.exe and 'parsav' or 'parsav.o'
51 266 local linkargs = {}
267 +if config.posix then
268 + linkargs[#linkargs+1] = '-pthread'
269 +end
52 270 for _,p in pairs(config.pkg) do util.append(linkargs, p.linkargs) end
53 271 emit('linking with args',util.dump(linkargs))
54 272 terralib.saveobj(out, {
55 273 main = entry
56 274 },
57 275 linkargs,
58 276 config.tgttrip and terralib.newtarget {
59 277 Triple = config.tgttrip;
60 278 CPU = config.tgtcpu;
61 279 FloatABIHard = config.tgthf;
62 280 } or nil)