summaryrefslogtreecommitdiff
path: root/src/command_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-08-06 19:29:51 +0200
committerMaxime Coste <frrrwww@gmail.com>2012-08-06 19:29:51 +0200
commit39797f87dc73675881854b38611489de1dba6b8f (patch)
tree82c1565da2a9166755530ef0b564450e908e328f /src/command_manager.cc
parent4dc9973288f82fe285109fa6c5fd20742f3d81fe (diff)
command_manager: cleanup command execution, lazy exec shell commands
Diffstat (limited to 'src/command_manager.cc')
-rw-r--r--src/command_manager.cc81
1 files changed, 35 insertions, 46 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index a0c8b61c..6b7a33bf 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -172,16 +172,6 @@ TokenList parse(const String& line,
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
@@ -190,6 +180,19 @@ struct command_not_found : runtime_error
: 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,
const Context& context,
const EnvVarMap& env_vars)
@@ -198,46 +201,32 @@ void CommandManager::execute(const String& command_line,
if (tokens.empty())
return;
- TokenList expanded_tokens;
- for (auto& token : tokens)
- {
- if (token.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)
+ std::vector<String> params;
+ for (auto it = tokens.begin(); it != tokens.end(); ++it)
{
- while (end != expanded_tokens.end() and
- end->type() != Token::Type::CommandSeparator)
- ++end;
-
- if (end != begin)
+ if (it->type() == Token::Type::ShellExpand)
{
- auto command_it = m_commands.find(begin->content());
- if (command_it == m_commands.end())
- throw command_not_found(begin->content());
-
- std::vector<String> params;
- for (auto token_it = begin+1; token_it != end; ++token_it)
- {
- assert(token_it->type() == Token::Type::Raw);
- params.push_back(token_it->content());
- }
- command_it->second.command(params, context);
+ String output = ShellManager::instance().eval(it->content(),
+ context, env_vars);
+ 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();
+
+ // when last token is a ShellExpand which produces no output
+ if (it == tokens.end())
+ break;
}
-
- if (end == expanded_tokens.end())
- break;
-
- begin = end+1;
- end = begin;
+ if (it->type() == Token::Type::CommandSeparator)
+ {
+ execute_single_command(params, context);
+ params.clear();
+ }
+ 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)