Differences From
Artifact [889180c92d]:
34 34 code[#code+1] = quote var n = v in
35 35 lib.io.send(2, n, lib.str.sz(n)) end
36 36 end
37 37 end
38 38 code[#code+1] = `lib.io.send(2, '\n', 1)
39 39 return code
40 40 end;
41 + trn = macro(function(cond, i, e)
42 + return quote
43 + var c: bool = [cond]
44 + var r: i.tree.type
45 + if c == true then r = i else r = e end
46 + in r end
47 + end);
41 48 proc = {
42 49 exit = terralib.externfunction('exit', int -> {});
43 50 getenv = terralib.externfunction('getenv', rawstring -> rawstring);
44 51 };
45 52 io = {
46 - open = terralib.externfunction('open', {rawstring, int} -> int);
47 - close = terralib.externfunction('close', {int} -> int);
48 53 send = terralib.externfunction('write', {int, rawstring, intptr} -> ptrdiff);
49 54 recv = terralib.externfunction('read', {int, rawstring, intptr} -> ptrdiff);
50 55 say = macro(function(msg) return `lib.io.send(2, msg, [#(msg:asvalue())]) end);
51 56 fmt = terralib.externfunction('printf',
52 57 terralib.types.funcpointer({rawstring},{int},true));
53 58 };
54 59 str = {
55 60 sz = terralib.externfunction('strlen', rawstring -> intptr);
56 61 cmp = terralib.externfunction('strcmp', {rawstring, rawstring} -> int);
62 + ncmp = terralib.externfunction('strncmp', {rawstring, rawstring, intptr} -> int);
57 63 cpy = terralib.externfunction('stpcpy',{rawstring, rawstring} -> rawstring);
58 64 ncpy = terralib.externfunction('stpncpy',{rawstring, rawstring, intptr} -> rawstring);
65 + ndup = terralib.externfunction('strndup',{rawstring, intptr} -> rawstring);
59 66 fmt = terralib.externfunction('asprintf',
60 67 terralib.types.funcpointer({&rawstring},{int},true));
61 68 };
69 + copy = function(tbl)
70 + local new = {}
71 + for k,v in pairs(tbl) do new[k] = v end
72 + setmetatable(new, getmetatable(tbl))
73 + return new
74 + end;
62 75 mem = {
63 76 zero = macro(function(r)
64 77 return quote
65 78 for i = 0, [r.tree.type.N] do r[i] = 0 end
66 79 end
67 80 end);
68 81 heapa_raw = terralib.externfunction('malloc', intptr -> &opaque);
................................................................................
76 89 ct = sz;
77 90 }
78 91 end)
79 92 };
80 93 }
81 94
82 95 local noise = global(uint8,1)
96 +local noise_header = function(code,txt,mod)
97 + if mod then
98 + return string.format('\27[%s;1m(parsav::%s %s)\27[m ', code,mod,txt)
99 + else
100 + return string.format('\27[%s;1m(parsav %s)\27[m ', code,txt)
101 + end
102 +end
83 103 local defrep = function(level,n,code)
84 104 return macro(function(...)
85 - local q = lib.emit("\27["..code..";1m(parsav "..n..")\27[m ", ...)
105 + local q = lib.emit(noise_header(code,n), ...)
86 106 return quote
87 107 if noise >= level then [q] end
88 108 end
89 109 end);
90 110 end
91 111 lib.dbg = defrep(3,'debug', '32')
92 112 lib.report = defrep(2,'info', '35')
93 113 lib.warn = defrep(1,'warn', '33')
94 114 lib.bail = macro(function(...)
95 - local q = lib.emit("\27[31;1m(parsav fatal)\27[m ", ...)
115 + local q = lib.emit(noise_header('31','fatal'), ...)
96 116 return quote
97 117 [q]
98 118 lib.proc.exit(1)
99 119 end
100 120 end);
121 +lib.stat = terralib.memoize(function(ty)
122 + local n = struct {
123 + ok: bool
124 + union {
125 + error: uint8
126 + val: ty
127 + }
128 + }
129 + n.name = string.format("stat<%s>", ty.name)
130 + n.stat_basetype = ty
131 + return n
132 +end)
133 +lib.enum = function(tbl)
134 + local ty = uint8
135 + if #tbl >= 2^32 then ty = uint64 -- hey, can't be too safe
136 + elseif #tbl >= 2^16 then ty = uint32
137 + elseif #tbl >= 2^8 then ty = uint16 end
138 + local o = { t = ty }
139 + for i, name in ipairs(tbl) do
140 + o[name] = i
141 + end
142 + return o
143 +end
101 144 lib.mem.ptr = terralib.memoize(function(ty)
102 145 local t = terralib.types.newstruct(string.format('ptr<%s>', ty))
103 146 t.entries = {
104 147 {'ptr', &ty};
105 148 {'ct', intptr};
106 149 }
150 + t.ptr_basetype = ty
107 151 local recurse = false
108 152 if ty:isstruct() then
109 153 if ty.methods.free then recurse = true end
110 154 end
111 155 t.methods = {
112 156 free = terra(self: &t): bool
113 157 [recurse and quote
................................................................................
139 183 self.ct = newct
140 184 return true
141 185 else return false end
142 186 end;
143 187 }
144 188 return t
145 189 end)
190 +lib.mem.vec = terralib.memoize(function(ty)
191 + local v = terralib.types.newstruct(string.format('vec<%s>', ty.name))
192 + v.entries = {
193 + {field = 'storage', type = lib.mem.ptr(ty)};
194 + {field = 'sz', type = intptr};
195 + {field = 'run', type = intptr};
196 + }
197 + local terra biggest(a: intptr, b: intptr)
198 + if a > b then return a else return b end
199 + end
200 + terra v:assure(n: intptr)
201 + if self.storage.ct < n then
202 + self.storage:resize(biggest(n, self.storage.ct + self.run))
203 + end
204 + end
205 + v.methods = {
206 + init = terra(self: &v, run: intptr): bool
207 + if not self.storage:init(run) then return false end
208 + self.run = run
209 + self.sz = 0
210 + return true
211 + end;
212 + new = terra(self: &v): &ty
213 + self:assure(self.sz + 1)
214 + self.sz = self.sz + 1
215 + return self.storage.ptr + (self.sz - 1)
216 + end;
217 + push = terra(self: &v, val: ty)
218 + self:assure(self.sz + 1)
219 + self.storage.ptr[self.sz] = val
220 + self.sz = self.sz + 1
221 + end;
222 + free = terra(self: &v) self.storage:free() end;
223 + last = terra(self: &v, idx: intptr): &ty
224 + if self.sz > idx then
225 + return self.storage.ptr + (self.sz - (idx+1))
226 + else lib.bail('vector underrun!') end
227 + end;
228 + crush = terra(self: &v)
229 + self.storage:resize(self.sz)
230 + return self.storage
231 + end;
232 + }
233 + v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index??
234 + if self.sz > idx then
235 + return self.storage.ptr + idx
236 + else lib.bail('vector overrun!') end
237 + end
238 + return v
239 +end)
146 240
147 241 lib.err = lib.loadlib('mbedtls','mbedtls/error.h')
148 242 lib.rsa = lib.loadlib('mbedtls','mbedtls/rsa.h')
149 243 lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
150 244 lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
151 245 lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
152 246 lib.net = lib.loadlib('mongoose','mongoose.h')
153 247 lib.pq = lib.loadlib('libpq','libpq-fe.h')
248 +lib.file = terralib.loadfile('file.t')()
249 +lib.math = terralib.loadfile('math.t')()
154 250 lib.crypt = terralib.loadfile('crypt.t')()
155 251 lib.http = terralib.loadfile('http.t')()
156 252 lib.tpl = terralib.loadfile('tpl.t')()
157 253 lib.string = terralib.loadfile('string.t')()
158 254 lib.store = terralib.loadfile('store.t')()
255 +
256 +local be = {}
257 +for _, b in pairs { 'pgsql' } do
258 + be[#be+1] = terralib.loadfile('backend/' .. b .. '.t')()
259 +end
260 +lib.store.backends = global(`array([be]))
261 +
159 262 lib.cmdparse = terralib.loadfile('cmdparse.t')()
263 +lib.srv = terralib.loadfile('srv.t')()
160 264
161 265 do local collate = function(path,f, ...)
162 266 return loadfile(path..'/'..f..'.lua')(path, ...)
163 267 end
164 268 data = {
165 269 view = collate('view','load');
166 270 } end
................................................................................
181 285 lib.crypt.pem(pub, &kp, buf)
182 286 lib.io.send(1, msg, [#msg])
183 287 lib.io.send(1, [rawstring](&buf), lib.str.sz([rawstring](&buf)))
184 288 lib.io.send(1, '\n', 1)
185 289 end
186 290 end)
187 291
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
197 - end;
198 -}
199 292 do
200 293 local p = string.format('parsav: %s\nbuilt on %s\n', config.build.str, config.build.when)
201 294 terra version() lib.io.send(1, p, [#p]) end
202 295 end
203 296 terra noise_init()
204 297 var n = lib.proc.getenv('parsav_noise')
205 298 if n ~= nil then
................................................................................
217 310 help = {'h', 'display this list'}
218 311 }
219 312
220 313 terra entry(argc: int, argv: &rawstring): int
221 314 noise_init()
222 315 [lib.init]
223 316
317 + -- shut mongoose the fuck up
318 + lib.net.mg_log_set_callback([terra(msg: &opaque, sz: int, u: &opaque) end], nil)
319 +
224 320 var mode: options
225 321 mode:parse(argc,argv)
226 322 if mode.version then
227 323 version()
228 324 return 0
229 325 end
230 326 if mode.help then
231 327 lib.io.send(1, [options.helptxt], [#options.helptxt])
232 328 return 0
233 329 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 -
330 + var srv: lib.srv
331 + srv:start('backend.conf')
332 + lib.report('listening for requests')
243 333 while true do
244 - lib.net.mg_mgr_poll(&nm,1000)
334 + srv:poll()
245 335 end
336 + srv:shutdown()
246 337
247 - lib.net.mg_mgr_free(&nm)
248 338 return 0
249 339 end
250 340
251 341 local bflag = function(long,short)
252 342 if short and util.has(buildopts, short) then return true end
253 343 if long and util.has(buildopts, long) then return true end
254 344 return false