Added 'provide-module' and 'require-module' commands

This commit is contained in:
Justin Frank 2019-03-12 10:34:30 -07:00
parent 670f8192c8
commit 6092852640
3 changed files with 52 additions and 1 deletions

View File

@ -40,6 +40,33 @@ void CommandManager::register_command(String command_name,
std::move(completer) };
}
bool CommandManager::module_defined(StringView module_name) const
{
return m_modules.find(module_name) != m_modules.end();
}
void CommandManager::register_module(String module_name, String commands)
{
auto module = m_modules.find(module_name);
if (module != m_modules.end() and module->value.loaded)
throw runtime_error{format("module already loaded: '{}'", module_name)};
m_modules[module_name] = { false, std::move(commands) };
}
void CommandManager::load_module(StringView module_name, Context& context)
{
auto module = m_modules.find(module_name);
if (module == m_modules.end())
throw runtime_error{format("no such module: '{}'", module_name)};
if (module->value.loaded)
return;
module->value.loaded = true;
execute(module->value.commands, context);
module->value.commands.clear();
}
struct parse_error : runtime_error
{
parse_error(StringView error)

View File

@ -123,6 +123,12 @@ public:
void clear_last_complete_command() { m_last_complete_command = String{}; }
bool module_defined(StringView module_name) const;
void register_module(String module_name, String commands);
void load_module(StringView module_name, Context& context);
private:
void execute_single_command(CommandParameters params,
Context& context,
@ -143,6 +149,14 @@ private:
String m_last_complete_command;
int m_command_depth = 0;
struct Module
{
bool loaded;
String commands;
};
using ModuleMap = HashMap<String, Module, MemoryDomain::Commands>;
ModuleMap m_modules;
CommandMap::const_iterator find_command(const Context& context,
StringView name) const;
};

View File

@ -2417,8 +2417,17 @@ const CommandDesc provide_module_cmd = {
CommandFlags::None,
CommandHelper{},
CommandCompleter{},
[](const ParametersParser& parse, Context& context, const ShellContext&)
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
const String& module_name = parser[0];
auto& cm = CommandManager::instance();
if (not all_of(module_name, is_identifier))
throw runtime_error(format("invalid module name: '{}'", module_name));
if (cm.module_defined(module_name) and not parser.get_switch("override"))
throw runtime_error(format("module '{}' already defined", module_name));
cm.register_module(module_name, parser[1]);
}
};
@ -2432,6 +2441,7 @@ const CommandDesc require_module_cmd = {
CommandCompleter{},
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
CommandManager::instance().load_module(parser[0], context);
}
};