* An alias is just another name for a command, or for more commands * Execute it as well. * @param alias is the alias of the command * @param tokens are the parameters given to the original command (0 is the first param) * @param recurse_count the number of re-entrant calls to this function */
| 182 | * @param recurse_count the number of re-entrant calls to this function |
| 183 | */ |
| 184 | static void IConsoleAliasExec(const IConsoleAlias *alias, std::span<std::string> tokens, uint recurse_count) |
| 185 | { |
| 186 | Debug(console, 6, "Requested command is an alias; parsing..."); |
| 187 | |
| 188 | if (recurse_count > ICON_MAX_RECURSE) { |
| 189 | IConsolePrint(CC_ERROR, "Too many alias expansions, recursion limit reached."); |
| 190 | return; |
| 191 | } |
| 192 | |
| 193 | std::string buffer; |
| 194 | StringBuilder builder{buffer}; |
| 195 | |
| 196 | StringConsumer consumer{alias->cmdline}; |
| 197 | while (consumer.AnyBytesLeft()) { |
| 198 | auto c = consumer.TryReadUtf8(); |
| 199 | if (!c.has_value()) { |
| 200 | IConsolePrint(CC_ERROR, "Alias '{}' ('{}') contains malformed characters.", alias->name, alias->cmdline); |
| 201 | return; |
| 202 | } |
| 203 | |
| 204 | switch (*c) { |
| 205 | case '\'': // ' will double for "" |
| 206 | builder.PutChar('\"'); |
| 207 | break; |
| 208 | |
| 209 | case ';': // Cmd separator; execute previous and start new command |
| 210 | IConsoleCmdExec(builder.GetString(), recurse_count); |
| 211 | |
| 212 | buffer.clear(); |
| 213 | break; |
| 214 | |
| 215 | case '%': // Some or all parameters |
| 216 | c = consumer.ReadUtf8(); |
| 217 | switch (*c) { |
| 218 | case '+': { // All parameters separated: "[param 1]" "[param 2]" |
| 219 | for (size_t i = 0; i < tokens.size(); ++i) { |
| 220 | if (i != 0) builder.PutChar(' '); |
| 221 | builder.PutChar('\"'); |
| 222 | builder += tokens[i]; |
| 223 | builder.PutChar('\"'); |
| 224 | } |
| 225 | break; |
| 226 | } |
| 227 | |
| 228 | case '!': { // Merge the parameters to one: "[param 1] [param 2] [param 3...]" |
| 229 | builder.PutChar('\"'); |
| 230 | for (size_t i = 0; i < tokens.size(); ++i) { |
| 231 | if (i != 0) builder.PutChar(' '); |
| 232 | builder += tokens[i]; |
| 233 | } |
| 234 | builder.PutChar('\"'); |
| 235 | break; |
| 236 | } |
| 237 | |
| 238 | default: { // One specific parameter: %A = [param 1] %B = [param 2] ... |
| 239 | size_t param = *c - 'A'; |
| 240 | |
| 241 | if (param >= tokens.size()) { |
no test coverage detected