local qv = 0
local testn = 0
test = function(name,expr)
	testn = testn + 1
	print(string.format('% 3u ',testn) ..
		(expr and '\x1b[32mPASS\x1b[m' or '\x1b[31mFAIL\x1b[m') ..
		'  ' .. name)
	if not expr and qv == 0 then qv = testn end
end
report = function() os.exit(qv) end

hexdump = function(s)
	local hexlines, charlines = {},{}
	for i=1,#s do
		local line = math.floor((i-1)/16) + 1
		hexlines[line] = (hexlines[line] or '') .. string.format("%02x ",string.byte(s, i))
		charlines[line] = (charlines[line] or '') .. ' ' .. string.gsub(string.sub(s, i, i), '[^%g ]', '\x1b[;35m·\x1b[36;1m') .. ' '
	end
	local str = ''
	for i=1,#hexlines do
		str = str .. '\x1b[1;36m' .. charlines[i] .. '\x1b[m\n' .. hexlines[i] .. '\n'
	end
	return str
end

function dump(o)
	if type(o) == "table" then
		local str = ''
		for k,p in pairs(o) do
			str = str .. (k .. ' = {' .. dump(p) ..'}\n')
		end
		return str
	else
		return tostring(o)
	end
end

