util/argparse.lua
author Kim Alvefur <zash@zash.se>
Tue, 14 May 2024 17:07:47 +0200
changeset 13494 6f840763fc73
parent 13164 4ee9a912ceea
permissions -rw-r--r--
net.server_epoll: Add support for systemd socket activation Allows creating listening sockets and accepting client connections before Prosody starts. This is unlike normal Prosody dynamic resource management, where ports may added and removed at any time, and the ports defined by the config. Weird things happen if these are closed (e.g. due to reload) so here we prevent closing and ensure sockets are reused when opened again.

local function parse(arg, config)
	local short_params = config and config.short_params or {};
	local value_params = config and config.value_params or {};
	local array_params = config and config.array_params or {};

	local parsed_opts = {};

	if #arg == 0 then
		return parsed_opts;
	end
	while true do
		local raw_param = arg[1];
		if not raw_param then
			break;
		end

		local prefix = raw_param:match("^%-%-?");
		if not prefix then
			break;
		elseif prefix == "--" and raw_param == "--" then
			table.remove(arg, 1);
			break;
		end
		local param = table.remove(arg, 1):sub(#prefix+1);
		if #param == 1 and short_params then
			param = short_params[param];
		end

		if not param then
			return nil, "param-not-found", raw_param;
		end

		local param_k, param_v;
		if value_params[param] or array_params[param] then
			param_k, param_v = param, table.remove(arg, 1);
			if not param_v then
				return nil, "missing-value", raw_param;
			end
		else
			param_k, param_v = param:match("^([^=]+)=(.+)$");
			if not param_k then
				if param:match("^no%-") then
					param_k, param_v = param:sub(4), false;
				else
					param_k, param_v = param, true;
				end
			end
			param_k = param_k:gsub("%-", "_");
		end
		if array_params[param] then
			if parsed_opts[param_k] then
				table.insert(parsed_opts[param_k], param_v);
			else
				parsed_opts[param_k] = { param_v };
			end
		else
			parsed_opts[param_k] = param_v;
		end
	end
	for i = 1, #arg do
		parsed_opts[i] = arg[i];
	end
	return parsed_opts;
end

return {
	parse = parse;
}