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:
parent
145cf843dd
commit
ddc307b8e9
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user