parsav  Diff

Differences From Artifact [889180c92d]:

To Artifact [ce122c09dc]:


    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