Optimize CommandManager::execute handling of tokens

Instead of walking a list of tokens and inserting eventual new
ones in the middle, use a stack of token and push new ones on top.
This commit is contained in:
Maxime Coste 2017-10-17 10:25:20 +08:00
parent 145cf843dd
commit ddc307b8e9

View File

@ -473,36 +473,37 @@ void CommandManager::execute(StringView command_line,
TokenList tokens = parse<true>(command_line); TokenList tokens = parse<true>(command_line);
if (tokens.empty()) if (tokens.empty())
return; return;
// Tokens are going to be read as a stack
std::reverse(tokens.begin(), tokens.end());
DisplayCoord command_coord; DisplayCoord command_coord;
Vector<String> params; Vector<String> params;
for (auto it = tokens.begin(); it != tokens.end(); ) while (not tokens.empty())
{ {
Token token = std::move(tokens.back());
tokens.pop_back();
if (params.empty()) if (params.empty())
command_coord = it->coord; command_coord = token.coord;
if (it->type == Token::Type::CommandSeparator) if (token.type == Token::Type::CommandSeparator)
{ {
execute_single_command(params, context, shell_context, command_coord); execute_single_command(params, context, shell_context, command_coord);
params.clear(); params.clear();
} }
// Shell expand are retokenized // Shell expand are retokenized
else if (it->type == Token::Type::ShellExpand) else if (token.type == Token::Type::ShellExpand)
{ {
auto new_tokens = parse<true>(expand_token(*it, context, auto new_tokens = parse<true>(expand_token(token, context,
shell_context)); shell_context));
it = tokens.insert(tokens.erase(it), tokens.insert(tokens.end(),
std::make_move_iterator(new_tokens.begin()), std::make_move_iterator(new_tokens.rbegin()),
std::make_move_iterator(new_tokens.end())); std::make_move_iterator(new_tokens.rend()));
continue; // skip incrementing, we already point to next token
} }
else if (it->type == Token::Type::ArgExpand and it->content == '@') else if (token.type == Token::Type::ArgExpand and token.content == '@')
params.insert(params.end(), shell_context.params.begin(), params.insert(params.end(), shell_context.params.begin(),
shell_context.params.end()); shell_context.params.end());
else else
params.push_back(expand_token(*it, context, shell_context)); params.push_back(expand_token(token, context, shell_context));
++it;
} }
execute_single_command(params, context, shell_context, command_coord); execute_single_command(params, context, shell_context, command_coord);
} }