command_manager: cleanup command execution, lazy exec shell commands
This commit is contained in:
parent
4dc9973288
commit
39797f87dc
|
@ -172,16 +172,6 @@ TokenList parse(const String& line,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shell_eval(TokenList& params, const String& cmdline,
|
|
||||||
const Context& context, const EnvVarMap& env_vars)
|
|
||||||
{
|
|
||||||
String output = ShellManager::instance().eval(cmdline, context, env_vars);
|
|
||||||
TokenList tokens = parse(output);
|
|
||||||
|
|
||||||
for (auto& token : tokens)
|
|
||||||
params.push_back(std::move(token));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command_not_found : runtime_error
|
struct command_not_found : runtime_error
|
||||||
|
@ -190,6 +180,19 @@ struct command_not_found : runtime_error
|
||||||
: runtime_error(command + " : no such command") {}
|
: runtime_error(command + " : no such command") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void CommandManager::execute_single_command(const CommandParameters& params,
|
||||||
|
const Context& context) const
|
||||||
|
{
|
||||||
|
if (params.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto command_it = m_commands.find(params[0]);
|
||||||
|
if (command_it == m_commands.end())
|
||||||
|
throw command_not_found(params[0]);
|
||||||
|
memoryview<String> param_view(params.begin()+1, params.end());
|
||||||
|
command_it->second.command(param_view, context);
|
||||||
|
}
|
||||||
|
|
||||||
void CommandManager::execute(const String& command_line,
|
void CommandManager::execute(const String& command_line,
|
||||||
const Context& context,
|
const Context& context,
|
||||||
const EnvVarMap& env_vars)
|
const EnvVarMap& env_vars)
|
||||||
|
@ -198,46 +201,32 @@ void CommandManager::execute(const String& command_line,
|
||||||
if (tokens.empty())
|
if (tokens.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TokenList expanded_tokens;
|
std::vector<String> params;
|
||||||
for (auto& token : tokens)
|
for (auto it = tokens.begin(); it != tokens.end(); ++it)
|
||||||
{
|
{
|
||||||
if (token.type() == Token::Type::ShellExpand)
|
if (it->type() == Token::Type::ShellExpand)
|
||||||
shell_eval(expanded_tokens, token.content(),
|
|
||||||
context, env_vars);
|
|
||||||
else
|
|
||||||
expanded_tokens.push_back(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto begin = expanded_tokens.begin();
|
|
||||||
auto end = begin;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
while (end != expanded_tokens.end() and
|
|
||||||
end->type() != Token::Type::CommandSeparator)
|
|
||||||
++end;
|
|
||||||
|
|
||||||
if (end != begin)
|
|
||||||
{
|
{
|
||||||
auto command_it = m_commands.find(begin->content());
|
String output = ShellManager::instance().eval(it->content(),
|
||||||
if (command_it == m_commands.end())
|
context, env_vars);
|
||||||
throw command_not_found(begin->content());
|
TokenList shell_tokens = parse(output);
|
||||||
|
it = tokens.erase(it);
|
||||||
|
for (auto& token : shell_tokens)
|
||||||
|
it = ++tokens.insert(it, std::move(token));
|
||||||
|
it -= shell_tokens.size();
|
||||||
|
|
||||||
std::vector<String> params;
|
// when last token is a ShellExpand which produces no output
|
||||||
for (auto token_it = begin+1; token_it != end; ++token_it)
|
if (it == tokens.end())
|
||||||
{
|
break;
|
||||||
assert(token_it->type() == Token::Type::Raw);
|
|
||||||
params.push_back(token_it->content());
|
|
||||||
}
|
|
||||||
command_it->second.command(params, context);
|
|
||||||
}
|
}
|
||||||
|
if (it->type() == Token::Type::CommandSeparator)
|
||||||
if (end == expanded_tokens.end())
|
{
|
||||||
break;
|
execute_single_command(params, context);
|
||||||
|
params.clear();
|
||||||
begin = end+1;
|
}
|
||||||
end = begin;
|
if (it->type() == Token::Type::Raw)
|
||||||
|
params.push_back(it->content());
|
||||||
}
|
}
|
||||||
|
execute_single_command(params, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
Completions CommandManager::complete(const String& command_line, size_t cursor_pos)
|
Completions CommandManager::complete(const String& command_line, size_t cursor_pos)
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
const CommandCompleter& completer = CommandCompleter());
|
const CommandCompleter& completer = CommandCompleter());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void execute_single_command(const CommandParameters& params,
|
||||||
|
const Context& context) const;
|
||||||
struct CommandDescriptor
|
struct CommandDescriptor
|
||||||
{
|
{
|
||||||
Command command;
|
Command command;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user