local map = function(lst,fn)
	local new = {} for k,v in pairs(lst) do
		local nv, nk = fn(v,k)
		new[nk or k] = nv
	end
	return new
end

local chomp = function(str)
	while string.sub(str,#str) == '\n' do
		str = string.sub(str,1,#str - 1)
	end
	return str
end

local exec = function(args, val)
	local cmd = table.concat(map(args, function(a)
		return string.format('%q', a)
	end), ' ')
	if val then return os.execute(cmd) else
		local fd = io.popen(cmd,'r')
		local t = fd:read('*a')
		return chomp(t), fd:close()
	end
end

local function dump(v,pfx)
	pfx = pfx or ''
	local np = pfx .. '  '
	if type(v) == 'string' then
		return string.format('%q', v)
	elseif type(v) == 'table' then
		local str = ''
		for k,v in pairs(v) do
			str = str .. string.format('%s[%s] = %s\n', np, dump(k,np), dump(v,np))
		end
		return '{\n' .. str .. pfx .. '}\n'
	else
		return string.format('%s', v)
	end
end
local ping = function(path)
	local f = io.open(path)
	if f then f:close() return true end
	return false
end
local tobool = function(s)
	if s == true then return true
	elseif s == false then return false end
	s = ({
		yes = true, ['true'] = true,   on = true,   ['1'] = true;
		no = false, ['false'] = false, off = false, ['0'] = false;
	})[string.lower(s)]
	if not s then return false end
	return true
end
return {
	exec = exec;
	dump = dump;
	ping = ping;
	chomp = chomp;
	map = map;
	tobool = tobool;
	append = function(a,b)
		for _, v in pairs(b) do a[#a+1] = v end
	end;
	has = function(haystack,needle,eq)
		eq = eq or function(a,b) return a == b end
		for k,v in pairs(haystack) do
			if eq(needle,v) then return k end
		end
	end;
	parseargs = function(a)
		local raw = false
		local opts, args = {}, {}
		for i,v in ipairs(a) do
			if v == '--' then
				raw = true 
			else
				if (not raw) and string.sub(v,1,2) == '--' then -- longopt
					opts[#opts+1] = string.sub(v,3)
				elseif (not raw) and string.sub(v,1,1) == '-' then -- shortopts
					for c in string.gmatch(string.sub(v,2), '.') do
						opts[#opts+1] = c
					end
				else args[#args+1]=v end
			end
		end
		return opts, args
	end;
}
