Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 1, 2008, 3:54:20 PM (16 years ago)
Author:
rgrieder
Message:
  • @everyone: Do not create a branch until I've added the svn:eol-style property correctly. Otherwise this would cost me another 4 hours or so when we want to merge back.
  • merged network branch back to trunk
  • I had to omit the changes from last evening concerning the line endings
  • might not work yet because of the line endings
  • @beni: script branch is the only branch still open. you probably will have to apply a patch because of inconsistent new lines
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/core/CommandExecutor.cc

    r1349 r1502  
    3131#include "util/String.h"
    3232#include "util/Convert.h"
    33 #include "util/SubString.h"
    3433#include "Identifier.h"
    3534#include "Language.h"
    3635#include "Debug.h"
    37 #include "Executor.h"
    38 #include "ConfigValueContainer.h"
    3936#include "TclBind.h"
    40 
    41 #define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE "set"
    42 #define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY "tset"
    43 #define COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND "bind"
    4437
    4538namespace orxonox
    4639{
    47     ConsoleCommandShortcutGeneric(keyword1, createExecutor((FunctorStatic*)0, "set", AccessLevel::User));
    48     ConsoleCommandShortcutGeneric(keyword2, createExecutor((FunctorStatic*)0, "tset", AccessLevel::User));
    49     ConsoleCommandShortcutGeneric(keyword3, createExecutor((FunctorStatic*)0, "bind", AccessLevel::User));
    50 
    51     ConsoleCommandShortcutExtern(exec, AccessLevel::None);
    52     ConsoleCommandShortcutExtern(echo, AccessLevel::None);
    53 
    54     ConsoleCommandShortcutExtern(read, AccessLevel::None);
    55     ConsoleCommandShortcutExtern(append, AccessLevel::None);
    56     ConsoleCommandShortcutExtern(write, AccessLevel::None);
    57 
    58     void exec(const std::string& filename)
    59     {
    60         static std::set<std::string> executingFiles;
    61 
    62         std::set<std::string>::const_iterator it = executingFiles.find(filename);
    63         if (it != executingFiles.end())
    64         {
    65             COUT(1) << "Error: Recurring exec command in \"" << filename << "\". Stopped execution." << std::endl;
    66             return;
    67         }
    68 
    69         // Open the file
    70         std::ifstream file;
    71         file.open(filename.c_str(), std::fstream::in);
    72 
    73         if (!file.is_open())
    74         {
    75             COUT(1) << "Error: Couldn't execute file \"" << filename << "\"." << std::endl;
    76             return;
    77         }
    78 
    79         executingFiles.insert(filename);
    80 
    81         // Iterate through the file and put the lines into the CommandExecutor
    82         char line[1024];
    83         while (file.good() && !file.eof())
    84         {
    85             file.getline(line, 1024);
    86             CommandExecutor::execute(line);
    87         }
    88 
    89         executingFiles.erase(filename);
    90         file.close();
    91     }
    92 
    93     std::string echo(const std::string& text)
    94     {
    95         return text;
    96     }
    97 
    98     void write(const std::string& filename, const std::string& text)
    99     {
    100         std::ofstream file;
    101         file.open(filename.c_str(), std::fstream::out);
    102 
    103         if (!file.is_open())
    104         {
    105             COUT(1) << "Error: Couldn't write to file \"" << filename << "\"." << std::endl;
    106             return;
    107         }
    108 
    109         file << text << std::endl;
    110         file.close();
    111     }
    112 
    113     void append(const std::string& filename, const std::string& text)
    114     {
    115         std::ofstream file;
    116         file.open(filename.c_str(), std::fstream::app);
    117 
    118         if (!file.is_open())
    119         {
    120             COUT(1) << "Error: Couldn't append to file \"" << filename << "\"." << std::endl;
    121             return;
    122         }
    123 
    124         file << text << std::endl;
    125         file.close();
    126     }
    127 
    128     std::string read(const std::string& filename)
    129     {
    130         std::ifstream file;
    131         file.open(filename.c_str(), std::fstream::in);
    132 
    133         if (!file.is_open())
    134         {
    135             COUT(1) << "Error: Couldn't read from file \"" << filename << "\"." << std::endl;
    136             return "";
    137         }
    138 
    139         std::string output = "";
    140         char line[1024];
    141         while (file.good() && !file.eof())
    142         {
    143             file.getline(line, 1024);
    144             output += line;
    145             output += "\n";
    146         }
    147 
    148         file.close();
    149 
    150         return output;
    151     }
    152 
    153 
    154     ///////////////////////
    155     // CommandEvaluation //
    156     ///////////////////////
    157     CommandEvaluation::CommandEvaluation()
    158     {
    159         this->processedCommand_ = "";
    160         this->additionalParameter_ = "";
    161 
    162         this->functionclass_ = 0;
    163         this->configvalueclass_ = 0;
    164         this->shortcut_ = 0;
    165         this->function_ = 0;
    166         this->configvalue_ = 0;
    167         this->key_ = 0;
    168 
    169         this->errorMessage_ = "";
    170         this->state_ = CS_Uninitialized;
    171 
    172         this->bEvaluatedParams_ = false;
    173         this->evaluatedExecutor_ = 0;
    174     }
    175 
    176     KeybindMode::Enum CommandEvaluation::getKeybindMode()
    177     {
    178         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    179         {
    180 //            if (this->shortcut_ != 0)
    181 //                return this->shortcut_->getKeybindMode();
    182         }
    183         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    184         {
    185 //            if (this->function_ != 0)
    186 //                return this->function_->getKeybindMode();
    187         }
    188         else if (this->state_ == CS_ConfigValueType || this->state_ == CS_ConfigValueFinished)
    189         {
    190 //            return KeybindMode::onPress;
    191         }
    192         else if (this->state_ == CS_KeybindCommand || this->state_ == CS_KeybindFinished)
    193         {
    194 //            return KeybindMode::onPress;
    195         }
    196         else
    197         {
    198 //            return KeybindMode::onPress;
    199         }
    200         // FIXME: Had to insert a return statement
    201         return (KeybindMode::Enum)0;
    202     }
    203 
    204     bool CommandEvaluation::isValid() const
    205     {
    206         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    207         {
    208             return this->shortcut_;
    209         }
    210         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    211         {
    212             return (this->functionclass_ && this->function_);
    213         }
    214         else if (this->state_ == CS_ConfigValueType || this->state_ == CS_ConfigValueFinished)
    215         {
    216             return (this->configvalueclass_ && this->configvalue_);
    217         }
    218         else if (this->state_ == CS_KeybindCommand || this->state_ == CS_KeybindFinished)
    219         {
    220             return this->key_;
    221         }
    222         else
    223         {
    224             return false;
    225         }
    226     }
    227 
    228     void CommandEvaluation::evaluateParams()
    229     {
    230         this->bEvaluatedParams_ = false;
    231         this->evaluatedExecutor_ = 0;
    232 
    233         for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
    234             this->param_[i] = MT_null;
    235 
    236         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    237         {
    238             if (this->shortcut_)
    239             {
    240                 if (this->tokens_.size() <= 1)
    241                 {
    242                     if (this->shortcut_->evaluate(this->getAdditionalParameter(), this->param_, " "))
    243                     {
    244                         this->bEvaluatedParams_ = true;
    245                         this->evaluatedExecutor_ = this->shortcut_;
    246                     }
    247                 }
    248                 else if (this->tokens_.size() > 1)
    249                 {
    250                     if (this->shortcut_->evaluate(this->tokens_.subSet(1).join() + this->getAdditionalParameter(), this->param_, " "))
    251                     {
    252                         this->bEvaluatedParams_ = true;
    253                         this->evaluatedExecutor_ = this->shortcut_;
    254                     }
    255                 }
    256             }
    257         }
    258         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    259         {
    260             if (this->function_)
    261             {
    262                 if (this->tokens_.size() <= 2)
    263                 {
    264                     if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " "))
    265                     {
    266                         this->bEvaluatedParams_ = true;
    267                         this->evaluatedExecutor_ = this->function_;
    268                     }
    269                 }
    270                 else if (this->tokens_.size() > 2)
    271                 {
    272                     if (this->function_->evaluate(this->tokens_.subSet(2).join() + this->getAdditionalParameter(), this->param_, " "))
    273                     {
    274                         this->bEvaluatedParams_ = true;
    275                         this->evaluatedExecutor_ = this->function_;
    276                     }
    277                 }
    278             }
    279         }
    280     }
    281 
    282     void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiTypeMath param)
    283     {
    284         if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS)
    285             this->param_[index] = param;
    286     }
    287 
    288     MultiTypeMath CommandEvaluation::getEvaluatedParameter(unsigned int index) const
    289     {
    290         if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS)
    291             return this->param_[index];
    292 
    293         return MT_null;
    294     }
    295 
    296     bool CommandEvaluation::hasReturnvalue() const
    297     {
    298         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    299         {
    300             if (this->shortcut_)
    301                 return this->shortcut_->hasReturnvalue();
    302         }
    303         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    304         {
    305             if (this->function_)
    306                 return this->function_->hasReturnvalue();
    307         }
    308 
    309         return MT_null;
    310     }
    311 
    312     MultiTypeMath CommandEvaluation::getReturnvalue() const
    313     {
    314         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    315         {
    316             if (this->shortcut_)
    317                 return this->shortcut_->getReturnvalue();
    318         }
    319         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    320         {
    321             if (this->function_)
    322                 return this->function_->getReturnvalue();
    323         }
    324 
    325         return MT_null;
    326     }
    327 
    328 
    329     /////////////////////
    330     // CommandExecutor //
    331     /////////////////////
    33240    CommandExecutor& CommandExecutor::getInstance()
    33341    {
     
    34654    }
    34755
    348     Executor& CommandExecutor::addConsoleCommandShortcut(ExecutorStatic* executor)
    349     {
    350         CommandExecutor::getInstance().consoleCommandShortcuts_[executor->getName()] = executor;
    351         CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(executor->getName())] = executor;
    352         return (*executor);
     56    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command)
     57    {
     58        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(command->getName());
     59        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
     60        {
     61            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << "." << std::endl;
     62        }
     63
     64
     65        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
     66        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
     67        return (*command);
    35368    }
    35469
     
    35873        @return The executor of the requested console command shortcut
    35974    */
    360     ExecutorStatic* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
    361     {
    362         std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
     75    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
     76    {
     77        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
    36378        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
    36479            return (*it).second;
     
    37287        @return The executor of the requested console command shortcut
    37388    */
    374     ExecutorStatic* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
    375     {
    376         std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
     89    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
     90    {
     91        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
    37792        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
    37893            return (*it).second;
     
    38499    {
    385100        if (useTcl)
    386         {
    387101            return TclBind::eval(command);
    388         }
    389         else
    390         {
    391             if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
    392                 CommandExecutor::parse(command);
    393 
    394             return CommandExecutor::execute(CommandExecutor::getEvaluation());
    395         }
    396     }
    397 
    398 
    399     bool CommandExecutor::execute(const CommandEvaluation& evaluation)
    400     {
    401         SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    402 
    403         if (evaluation.bEvaluatedParams_ && evaluation.evaluatedExecutor_)
    404         {
    405 std::cout << "CE_execute (evaluation): " << evaluation.evaluatedExecutor_->getName() << " " << evaluation.param_[0] << " " << evaluation.param_[1] << " " << evaluation.param_[2] << " " << evaluation.param_[3] << " " << evaluation.param_[4] << std::endl;
    406             (*evaluation.evaluatedExecutor_)(evaluation.param_[0], evaluation.param_[1], evaluation.param_[2], evaluation.param_[3], evaluation.param_[4]);
    407             return true;
    408         }
    409 
    410 std::cout << "CE_execute: " << evaluation.processedCommand_ << "\n";
    411         switch (evaluation.state_)
    412         {
    413             case CS_Uninitialized:
    414                 break;
    415             case CS_Empty:
    416                 break;
    417             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    418                 break;
    419             case CS_Shortcut_Params:
    420                 // not enough parameters but lets hope there are some additional parameters and go on
    421             case CS_Shortcut_Finished:
    422                 // call the shortcut
    423                 if (evaluation.shortcut_)
    424                 {
    425                     if (tokens.size() >= 2)
    426                         return evaluation.shortcut_->parse(removeSlashes(tokens.subSet(1).join() + evaluation.getAdditionalParameter()));
    427                     else
    428                         return evaluation.shortcut_->parse(removeSlashes(evaluation.additionalParameter_));
    429                 }
    430                 break;
    431             case CS_Function:
    432                 break;
    433             case CS_Function_Params:
    434                 // not enough parameters but lets hope there are some additional parameters and go on
    435             case CS_Function_Finished:
    436                 // call the shortcut
    437                 if (evaluation.function_)
    438                 {
    439                     if (tokens.size() >= 3)
    440                         return evaluation.function_->parse(removeSlashes(tokens.subSet(2).join() + evaluation.getAdditionalParameter()));
    441                     else
    442                         return evaluation.function_->parse(removeSlashes(evaluation.additionalParameter_));
    443                 }
    444                 break;
    445             case CS_ConfigValueClass:
    446                 break;
    447             case CS_ConfigValue:
    448                 break;
    449             case CS_ConfigValueType:
    450                 // not enough parameters but lets hope there are some additional parameters and go on
    451             case CS_ConfigValueFinished:
    452                 // set the config value
    453                 if (evaluation.configvalue_)
    454                 {
    455                     if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE))
    456                     {
    457                         if (tokens.size() >= 4)
    458                             return evaluation.configvalue_->set(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter()));
    459                         else
    460                             return evaluation.configvalue_->set(removeSlashes(evaluation.additionalParameter_));
    461                     }
    462                     else if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
    463                     {
    464                         if (tokens.size() >= 4)
    465                             return evaluation.configvalue_->tset(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter()));
    466                         else
    467                             return evaluation.configvalue_->tset(removeSlashes(evaluation.additionalParameter_));
    468                     }
    469                 }
    470                 break;
    471             case CS_KeybindKey:
    472                 break;
    473             case CS_KeybindCommand:
    474                 // not enough parameters but lets hope there are some additional parameters and go on
    475             case CS_KeybindFinished:
    476                 // set the keybind
    477                 // ...todo
    478                 break;
    479             case CS_Error:
    480                 break;
    481         }
    482 
    483         return false;
     102
     103        CommandExecutor::parseIfNeeded(command);
     104        return CommandExecutor::getEvaluation().execute();
    484105    }
    485106
    486107    std::string CommandExecutor::complete(const std::string& command)
    487108    {
    488         if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
    489             CommandExecutor::parse(command);
    490 
    491         return CommandExecutor::complete(CommandExecutor::getEvaluation());
    492     }
    493 
    494     std::string CommandExecutor::complete(const CommandEvaluation& evaluation)
    495     {
    496         SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    497 
    498         std::list<std::pair<const std::string*, const std::string*> > temp;
    499         if (evaluation.state_ == CS_Empty)
    500         {
    501             temp.insert(temp.end(), evaluation.listOfPossibleShortcuts_.begin(), evaluation.listOfPossibleShortcuts_.end());
    502             temp.insert(temp.end(), evaluation.listOfPossibleFunctionClasses_.begin(), evaluation.listOfPossibleFunctionClasses_.end());
    503         }
    504 
    505         switch (evaluation.state_)
    506         {
    507             case CS_Uninitialized:
    508                 break;
    509             case CS_Empty:
    510                 return (CommandExecutor::getCommonBegin(temp));
    511                 break;
    512             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    513                 break;
    514             case CS_Shortcut_Params:
    515                 if (evaluation.shortcut_)
    516                     return (evaluation.shortcut_->getName() + " ");
    517                 break;
    518             case CS_Shortcut_Finished:
    519                 if (evaluation.shortcut_)
    520                 {
    521                     if (evaluation.shortcut_->getParamCount() == 0)
    522                         return (evaluation.shortcut_->getName());
    523                     else if (tokens.size() >= 2)
    524                         return (evaluation.shortcut_->getName() + " " + tokens.subSet(1).join());
    525                 }
    526                 break;
    527             case CS_Function:
    528                 if (evaluation.functionclass_)
    529                     return (evaluation.functionclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleFunctions_));
    530                 break;
    531             case CS_Function_Params:
    532                 if (evaluation.functionclass_ && evaluation.function_)
    533                     return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " ");
    534                 break;
    535             case CS_Function_Finished:
    536                 if (evaluation.functionclass_ && evaluation.function_)
    537                 {
    538                     if (evaluation.function_->getParamCount() == 0)
    539                         return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName());
    540                     else if (tokens.size() >= 3)
    541                         return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " " + tokens.subSet(2).join());
    542                 }
    543                 break;
    544             case CS_ConfigValueClass:
    545                 if (tokens.size() >= 1)
    546                     return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValueClasses_));
    547                 break;
    548             case CS_ConfigValue:
    549                 if ((tokens.size() >= 1) && evaluation.configvalueclass_)
    550                     return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValues_));
    551                 break;
    552             case CS_ConfigValueType:
    553                 if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_)
    554                     return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " ");
    555                 break;
    556             case CS_ConfigValueFinished:
    557                 if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_ && (tokens.size() >= 4))
    558                     return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " " + tokens.subSet(3).join());
    559                 break;
    560             case CS_KeybindKey:
    561                 if (tokens.size() >= 1)
    562                     return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleKeys_));
    563                 break;
    564             case CS_KeybindCommand:
    565                 if ((evaluation.processedCommand_.size() >= 1) && (evaluation.processedCommand_[evaluation.processedCommand_.size() - 1] != ' '))
    566                     return (evaluation.processedCommand_ + " ");
    567                 break;
    568             case CS_KeybindFinished:
    569                 break;
    570             case CS_Error:
    571                 break;
    572         }
    573 
    574         return evaluation.processedCommand_;
     109        CommandExecutor::parseIfNeeded(command);
     110        return CommandExecutor::getEvaluation().complete();
    575111    }
    576112
    577113    std::string CommandExecutor::hint(const std::string& command)
    578114    {
    579         if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
    580             CommandExecutor::parse(command);
    581 
    582         return CommandExecutor::hint(CommandExecutor::getEvaluation());
    583     }
    584 
    585     std::string CommandExecutor::hint(const CommandEvaluation& evaluation)
    586     {
    587         SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    588 
    589         switch (evaluation.state_)
    590         {
    591             case CS_Uninitialized:
    592                 break;
    593             case CS_Empty:
    594                 return (CommandExecutor::dump(evaluation.listOfPossibleShortcuts_) + "\n" + CommandExecutor::dump(evaluation.listOfPossibleFunctionClasses_));
    595                 break;
    596             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    597                 break;
    598             case CS_Shortcut_Params:
    599                 if (evaluation.shortcut_)
    600                     return CommandExecutor::dump(evaluation.shortcut_);
    601                 break;
    602             case CS_Shortcut_Finished:
    603                 if (evaluation.shortcut_)
    604                     return CommandExecutor::dump(evaluation.shortcut_);
    605                 break;
    606             case CS_Function:
    607                 return CommandExecutor::dump(evaluation.listOfPossibleFunctions_);
    608                 break;
    609             case CS_Function_Params:
    610                 if (evaluation.function_)
    611                     return CommandExecutor::dump(evaluation.function_);
    612                 break;
    613             case CS_Function_Finished:
    614                 if (evaluation.function_)
    615                     return CommandExecutor::dump(evaluation.function_);
    616                 break;
    617             case CS_ConfigValueClass:
    618                 return CommandExecutor::dump(evaluation.listOfPossibleConfigValueClasses_);
    619                 break;
    620             case CS_ConfigValue:
    621                 return CommandExecutor::dump(evaluation.listOfPossibleConfigValues_);
    622                 break;
    623             case CS_ConfigValueType:
    624                 if (evaluation.configvalue_)
    625                     return CommandExecutor::dump(evaluation.configvalue_);
    626                 break;
    627             case CS_ConfigValueFinished:
    628                 if (evaluation.configvalue_)
    629                     return CommandExecutor::dump(evaluation.configvalue_);
    630                 break;
    631             case CS_KeybindKey:
    632                 return CommandExecutor::dump(evaluation.listOfPossibleKeys_);
    633                 break;
    634             case CS_KeybindCommand:
    635                 if (evaluation.key_)
    636                     return CommandExecutor::dump(evaluation.key_);
    637                 break;
    638             case CS_KeybindFinished:
    639                 if (evaluation.key_)
    640                     return CommandExecutor::dump(evaluation.key_);
    641                 break;
    642             case CS_Error:
    643                 return CommandExecutor::getEvaluation().errorMessage_;
    644                 break;
    645         }
    646 
    647         return "";
     115        CommandExecutor::parseIfNeeded(command);
     116        return CommandExecutor::getEvaluation().hint();
    648117    }
    649118
    650119    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
    651120    {
    652         CommandExecutor::parse(command, true);
    653 
    654         if (CommandExecutor::getEvaluation().tokens_.size() > 0)
    655         {
    656             std::string lastToken;
    657             lastToken = CommandExecutor::getEvaluation().tokens_[CommandExecutor::getEvaluation().tokens_.size() - 1];
    658             lastToken = lastToken.substr(0, lastToken.size() - 1);
    659             CommandExecutor::getEvaluation().tokens_.pop_back();
    660             CommandExecutor::getEvaluation().tokens_.append(SubString(lastToken, " ", "", true, '\0', false, '\0', false, '\0', '\0', false, '\0'));
    661         }
    662 
     121        CommandExecutor::parse(command);
    663122        CommandExecutor::getEvaluation().evaluateParams();
    664123        return CommandExecutor::getEvaluation();
    665124    }
    666125
     126    void CommandExecutor::parseIfNeeded(const std::string& command)
     127    {
     128        if (CommandExecutor::getEvaluation().state_ == CS_Uninitialized)
     129        {
     130            CommandExecutor::parse(command);
     131        }
     132        else if (CommandExecutor::getEvaluation().originalCommand_ != command)
     133        {
     134            if (CommandExecutor::getEvaluation().command_ == command)
     135            {
     136                CommandExecutor::parse(command);
     137                CommandExecutor::getEvaluation().bNewCommand_ = false;
     138            }
     139            else
     140            {
     141                CommandExecutor::parse(command);
     142            }
     143        }
     144    }
     145
    667146    void CommandExecutor::parse(const std::string& command, bool bInitialize)
    668147    {
    669         CommandExecutor::getEvaluation().tokens_.split((command + COMMAND_EXECUTOR_CURSOR), " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    670         CommandExecutor::getEvaluation().processedCommand_ = command;
    671 
    672148        if (bInitialize)
    673             CommandExecutor::initialize(command);
     149            CommandExecutor::getEvaluation().initialize(command);
     150
     151        CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
     152        CommandExecutor::getEvaluation().command_ = command;
    674153
    675154        switch (CommandExecutor::getEvaluation().state_)
    676155        {
    677156            case CS_Uninitialized:
     157            {
    678158                // Impossible
    679159                break;
     160            }
    680161            case CS_Empty:
     162            {
    681163                if (CommandExecutor::argumentsGiven() == 0)
    682164                {
    683                     // We want a hint for the first token
    684                     // Check if there is already a perfect match
    685                     CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
    686                     CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
    687 
    688                     if ((CommandExecutor::getEvaluation().functionclass_) || (CommandExecutor::getEvaluation().shortcut_))
    689                     {
    690                         // Yes, there is a class or a shortcut with the searched name
    691                         // Add a whitespace and continue parsing
    692                         CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword;
    693                         CommandExecutor::parse(command + " ", false);
     165                    CommandExecutor::createListOfPossibleFunctions("");
     166                    CommandExecutor::createListOfPossibleIdentifiers("");
     167                    break;
     168                }
     169                else
     170                {
     171                    CommandExecutor::getEvaluation().state_ = CS_ShortcutOrIdentifier;
     172                    // Move on to next case
     173                }
     174            }
     175            case CS_ShortcutOrIdentifier:
     176            {
     177                if (CommandExecutor::argumentsGiven() > 1)
     178                {
     179                    // There's a finished first argument - check if it's a shortcut or a classname
     180                    CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
     181                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
     182
     183                    if (CommandExecutor::getEvaluation().function_)
     184                    {
     185                        // It's a shortcut
     186                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     187                        CommandExecutor::getEvaluation().functionclass_ = 0;
     188                        // Move on to next case
     189                    }
     190                    else if (CommandExecutor::getEvaluation().functionclass_)
     191                    {
     192                        // It's a functionname
     193                        CommandExecutor::getEvaluation().state_ = CS_Function;
     194                        CommandExecutor::getEvaluation().function_ = 0;
     195                        // Move on to next case
     196                    }
     197                    else
     198                    {
     199                        // The first argument is bad
     200                        CommandExecutor::getEvaluation().state_ = CS_Error;
     201                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
     202                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
    694203                        return;
    695204                    }
    696 
    697                     // No perfect match: Create the lists of all possible classes and shortcuts and return
    698                     CommandExecutor::createListOfPossibleFunctionClasses(CommandExecutor::getToken(0));
    699                     CommandExecutor::createListOfPossibleShortcuts(CommandExecutor::getToken(0));
    700 
    701                     // Check if there's only one possiblility
    702                     if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 1) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 0))
    703                     {
    704                         // There's only one possible class
     205                }
     206                else
     207                {
     208                    // There's no finished first argument - search possible shortcuts or classnames
     209                    CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0));
     210                    CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0));
     211
     212                    unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
     213                    unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size();
     214
     215                    if (num_functions == 1 && num_identifiers == 0)
     216                    {
     217                        // It's a shortcut
     218                        std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
     219                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
     220                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
     221                        {
     222                            // Unfinished shortcut
     223                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     224                        }
     225                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     226                        CommandExecutor::getEvaluation().functionclass_ = 0;
     227                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
     228                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
     229                        {
     230                            CommandExecutor::getEvaluation().command_ += " ";
     231                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     232                        }
     233                        // Move on to next case
     234                    }
     235                    else if (num_identifiers == 1 && num_functions == 0)
     236                    {
     237                        // It's a classname
     238                        std::string classname = *(*CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()).first;
     239                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
     240                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
     241                        {
     242                            // Unfinished classname
     243                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     244                        }
    705245                        CommandExecutor::getEvaluation().state_ = CS_Function;
    706                         CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first);
    707                         CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first + " ", false);
     246                        CommandExecutor::getEvaluation().function_ = 0;
     247                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
     248                        // Move on to next case
     249                    }
     250                    else if (num_identifiers == 0 && num_functions == 0)
     251                    {
     252                        // No possibilities
     253                        CommandExecutor::getEvaluation().state_ = CS_Error;
     254                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
     255                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
    708256                        return;
    709257                    }
    710                     else if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 0) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 1))
    711                     {
    712                         if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)
    713                          && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)
    714                          && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
    715                         {
    716                             // There's only one possible shortcut
    717                             CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params;
    718                             CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first);
    719                         }
    720                         else if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)
    721                               || (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
    722                         {
    723                             // It's the 'set' or 'tset' keyword
    724                             CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass;
    725                         }
    726                         else if (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
    727                         {
    728                             // It's the 'bind' keyword
    729                             CommandExecutor::getEvaluation().state_ = CS_KeybindKey;
    730                         }
    731 
    732                         CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first + " ", false);
     258                    else
     259                    {
     260                        // There are several possiblilities
     261                        std::list<std::pair<const std::string*, const std::string*> > temp;
     262                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end());
     263                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end());
     264                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp);
     265                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
     266                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
     267                        CommandExecutor::getEvaluation().bCommandChanged_ = true;
    733268                        return;
    734269                    }
    735 
    736                     // It's ambiguous
     270                }
     271            }
     272            case CS_Function:
     273            {
     274                if (CommandExecutor::getEvaluation().functionclass_)
     275                {
     276                    // There is a classname - search for the commandname
     277                    if (CommandExecutor::argumentsGiven() > 2)
     278                    {
     279                        // There is a finished second argument - check if it's a commandname
     280                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
     281
     282                        if (CommandExecutor::getEvaluation().function_)
     283                        {
     284                            // It's a function
     285                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     286                            // Move on to next case
     287                        }
     288                        else
     289                        {
     290                            // The second argument is bad
     291                            CommandExecutor::getEvaluation().state_ = CS_Error;
     292                            AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of");
     293                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + ".";
     294                            return;
     295                        }
     296                    }
     297                    else
     298                    {
     299                        // There is no finished second argument - search for possibilities
     300                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
     301                        unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
     302
     303                        if (num_functions == 1)
     304                        {
     305                            // It's a function
     306                            std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
     307                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
     308                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
     309                            {
     310                                // Unfinished function
     311                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
     312                            }
     313                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     314                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
     315                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
     316                            {
     317                                CommandExecutor::getEvaluation().command_ += " ";
     318                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
     319                            }
     320                            // Move on to next case
     321                        }
     322                        else if (num_functions == 0)
     323                        {
     324                            // No possibilities
     325                            CommandExecutor::getEvaluation().state_ = CS_Error;
     326                            AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
     327                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + ".";
     328                            return;
     329                        }
     330                        else
     331                        {
     332                            // There are several possibilities
     333                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
     334                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
     335                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     336                            return;
     337                        }
     338                    }
     339                }
     340                else
     341                {
     342                    // There is no classname - move on to CS_ParamPreparation
     343                }
     344            }
     345            case CS_ParamPreparation:
     346            {
     347                if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_))
     348                {
     349                    CommandExecutor::getEvaluation().state_ = CS_Finished;
    737350                    return;
    738351                }
    739352                else
    740353                {
    741                     // There is at least one argument: Check if it's a shortcut, a classname or a special keyword
    742                     CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword;
    743                     CommandExecutor::parse(command, false);
     354                    unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2;
     355                    if (CommandExecutor::getEvaluation().functionclass_)
     356                        argumentNumber -= 1;
     357
     358                    CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
     359                    CommandExecutor::getEvaluation().state_ = CS_Params;
     360
     361                    if (CommandExecutor::getEvaluation().bCommandChanged_)
     362                    {
     363                        // Don't do more than one change
     364                        return;
     365                    }
     366                }
     367            }
     368            case CS_Params:
     369            {
     370                if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
     371                {
     372                    // There is exactly one possible argument
     373                    CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
     374                    CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
     375                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
    744376                    return;
    745377                }
     378                else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0)
     379                {
     380                    // The user tries something new - we let him do
     381                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     382                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
     383                    return;
     384                }
     385                else
     386                {
     387                    // There are several possibilities
     388                    unsigned int argumentNumber = CommandExecutor::argumentsGiven();
     389                    if (argumentNumber > 0)
     390                        --argumentNumber;
     391                    if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0)
     392                        --argumentNumber;
     393
     394                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
     395                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
     396                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     397                    return;
     398                }
     399            }
     400            case CS_Finished:
     401            {
     402                // Nothing more to do
    746403                break;
    747             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    748                 if (CommandExecutor::argumentsGiven() >= 1)
    749                 {
    750                     if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
    751                     {
    752                         // We want to set a config value
    753                         CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass;
    754                         CommandExecutor::parse(command, false);
    755                         return;
    756                     }
    757                     else if (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
    758                     {
    759                         // We want to set a keybinding
    760                         CommandExecutor::getEvaluation().state_ = CS_KeybindKey;
    761                         CommandExecutor::parse(command, false);
    762                         return;
    763                     }
    764 
    765                     if (!CommandExecutor::getEvaluation().functionclass_)
    766                         CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
    767                     if (!CommandExecutor::getEvaluation().shortcut_)
    768                         CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
    769 
    770                     if ((!CommandExecutor::getEvaluation().functionclass_) && (!CommandExecutor::getEvaluation().shortcut_))
    771                     {
    772                         // Argument 1 seems to be wrong
    773                         AddLanguageEntry("CommandExecutor::NoSuchCommandOrClassName", "No such command or classname");
    774                         CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(0) + ": " + GetLocalisation("CommandExecutor::NoSuchCommandOrClassName"));
    775                         CommandExecutor::getEvaluation().state_ = CS_Error;
    776                         return;
    777                     }
    778                     else if (CommandExecutor::getEvaluation().shortcut_)
    779                     {
    780                         // Argument 1 is a shortcut: Return the needed parameter types
    781                         CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params;
    782                         CommandExecutor::parse(command, false);
    783                         return;
    784                     }
    785                     else
    786                     {
    787                         // Argument 1 is a classname: Return the possible functions
    788                         CommandExecutor::getEvaluation().state_ = CS_Function;
    789                         CommandExecutor::parse(command, false);
    790                         return;
    791                     }
    792                 }
    793                 else
    794                 {
    795                     CommandExecutor::getEvaluation().state_ = CS_Error;
    796                     return;
    797                 }
     404            }
     405            case CS_Error:
     406            {
     407                // Bad, very bad
    798408                break;
    799             case CS_Shortcut_Params:
    800                 if (CommandExecutor::getEvaluation().shortcut_)
    801                 {
    802                     // Valid command
    803                     // Check if there are enough parameters
    804                     if (CommandExecutor::enoughParametersGiven(1, CommandExecutor::getEvaluation().shortcut_))
    805                     {
    806                         CommandExecutor::getEvaluation().state_ = CS_Shortcut_Finished;
    807                         return;
    808                     }
    809                 }
    810                 else
    811                 {
    812                     // Something is wrong
    813                     CommandExecutor::getEvaluation().state_ = CS_Error;
    814                     return;
    815                 }
    816                 break;
    817             case CS_Function:
    818                 if (CommandExecutor::getEvaluation().functionclass_)
    819                 {
    820                     // We have a valid classname
    821                     // Check if there is a second argument
    822                     if (CommandExecutor::argumentsGiven() >= 2)
    823                     {
    824                         // There is a second argument: Check if it's a valid functionname
    825                         CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
    826                         if (!CommandExecutor::getEvaluation().function_)
    827                         {
    828                             // Argument 2 seems to be wrong
    829                             AddLanguageEntry("CommandExecutor::NoSuchFunctionnameIn", "No such functionname in");
    830                             CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchFunctionnameIn") + " " + CommandExecutor::getEvaluation().functionclass_->getName());
    831                             CommandExecutor::getEvaluation().state_ = CS_Error;
    832                             return;
    833                         }
    834                         else
    835                         {
    836                             // Argument 2 seems to be a valid functionname: Get the parameters
    837                             CommandExecutor::getEvaluation().state_ = CS_Function_Params;
    838                             CommandExecutor::parse(command, false);
    839                             return;
    840                         }
    841                     }
    842                     else
    843                     {
    844                         // There is no finished second argument
    845                         // Check if there's already a perfect match
    846                         if (CommandExecutor::getEvaluation().tokens_.size() >= 2)
    847                         {
    848                             CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
    849                             if (CommandExecutor::getEvaluation().function_)
    850                             {
    851                                 // There is a perfect match: Add a whitespace and continue parsing
    852                                 CommandExecutor::getEvaluation().state_ = CS_Function_Params;
    853                                 CommandExecutor::parse(command + " ", false);
    854                                 return;
    855                             }
    856                         }
    857 
    858                         // No perfect match: Create the list of all possible functions and return
    859                         CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
    860 
    861                         // Check if there's only one possiblility
    862                         if (CommandExecutor::getEvaluation().listOfPossibleFunctions_.size() == 1)
    863                         {
    864                             // There's only one possible function
    865                             CommandExecutor::getEvaluation().state_ = CS_Function_Params;
    866                             CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(*(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first, CommandExecutor::getEvaluation().functionclass_);
    867                             CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first + " ", false);
    868                             return;
    869                         }
    870 
    871                         // It's ambiguous
    872                         return;
    873                     }
    874                 }
    875                 else
    876                 {
    877                     CommandExecutor::getEvaluation().state_ = CS_Error;
    878                     return;
    879                 }
    880                 break;
    881             case CS_Function_Params:
    882                 if (CommandExecutor::getEvaluation().functionclass_ && CommandExecutor::getEvaluation().function_)
    883                 {
    884                     // Valid command
    885                     // Check if there are enough parameters
    886                     if (CommandExecutor::enoughParametersGiven(2, CommandExecutor::getEvaluation().function_))
    887                     {
    888                         CommandExecutor::getEvaluation().state_ = CS_Function_Finished;
    889                         return;
    890                     }
    891                 }
    892                 else
    893                 {
    894                     // Something is wrong
    895                     CommandExecutor::getEvaluation().state_ = CS_Error;
    896                     return;
    897                 }
    898                 break;
    899             case CS_ConfigValueClass:
    900                 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)))
    901                 {
    902                     // We want to set a config value
    903                     // Check if there is a second argument
    904                     if (CommandExecutor::argumentsGiven() >= 2)
    905                     {
    906                         // There is a second argument: Check if it's a valid classname
    907                         CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
    908                         if (!CommandExecutor::getEvaluation().configvalueclass_)
    909                         {
    910                             // Argument 2 seems to be wrong
    911                             AddLanguageEntry("CommandExecutor::NoSuchClassWithConfigValues", "No such class with config values");
    912                             CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchClassWithConfigValues"));
    913                             CommandExecutor::getEvaluation().state_ = CS_Error;
    914                             return;
    915                         }
    916                         else
    917                         {
    918                             // Argument 2 seems to be a valid classname: Search for possible config values
    919                             CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
    920                             CommandExecutor::parse(command, false);
    921                             return;
    922                         }
    923                     }
    924                     else
    925                     {
    926                         // There's no finished second argument
    927                         // Check if there's already a perfect match
    928                         if (CommandExecutor::getEvaluation().tokens_.size() >= 2)
    929                         {
    930                             CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
    931                             if (CommandExecutor::getEvaluation().configvalueclass_)
    932                             {
    933                                 // There is a perfect match: Add a whitespace and continue parsing
    934                                 CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
    935                                 CommandExecutor::parse(command + " ", false);
    936                                 return;
    937                             }
    938                         }
    939 
    940                         // No perfect match: Create the list of all possible classnames and return
    941                         CommandExecutor::createListOfPossibleConfigValueClasses(CommandExecutor::getToken(1));
    942 
    943                         // Check if there's only one possiblility
    944                         if (CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.size() == 1)
    945                         {
    946                             // There's only one possible classname
    947                             CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
    948                             CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first);
    949                             CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first + " ", false);
    950                             return;
    951                         }
    952 
    953                         // It's ambiguous
    954                         return;
    955                     }
    956                 }
    957                 else
    958                 {
    959                     // Something is wrong
    960                     CommandExecutor::getEvaluation().state_ = CS_Error;
    961                     return;
    962                 }
    963                 break;
    964             case CS_ConfigValue:
    965                 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && (CommandExecutor::getEvaluation().configvalueclass_))
    966                 {
    967                     // Check if there is a third argument
    968                     if (CommandExecutor::argumentsGiven() >= 3)
    969                     {
    970                         // There is a third argument: Check if it's a valid config value
    971                         CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
    972                         if (!CommandExecutor::getEvaluation().configvalue_)
    973                         {
    974                             // Argument 3 seems to be wrong
    975                             AddLanguageEntry("CommandExecutor::NoSuchConfigValueIn", "No such config value in");
    976                             CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(2) + ": " + GetLocalisation("CommandExecutor::NoSuchConfigValueIn") + " " + CommandExecutor::getEvaluation().configvalueclass_->getName());
    977                             CommandExecutor::getEvaluation().state_ = CS_Error;
    978                             return;
    979                         }
    980                         else
    981                         {
    982                             // Argument 3 seems to be a valid config value: Get the type
    983                             CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
    984                             CommandExecutor::parse(command, false);
    985                             return;
    986                         }
    987                     }
    988                     else
    989                     {
    990                         // There is no finished third argument
    991                         // Check if there's already a perfect match
    992                         if (CommandExecutor::getEvaluation().tokens_.size() >= 3)
    993                         {
    994                             CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
    995                             if (CommandExecutor::getEvaluation().configvalue_)
    996                             {
    997                                 // There is a perfect match: Add a whitespace and continue parsing
    998                                 CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
    999                                 CommandExecutor::parse(command + " ", false);
    1000                                 return;
    1001                             }
    1002                         }
    1003 
    1004                         // No perfect match: Create the list of all possible config values
    1005                         CommandExecutor::createListOfPossibleConfigValues(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
    1006 
    1007                         // Check if there's only one possiblility
    1008                         if (CommandExecutor::getEvaluation().listOfPossibleConfigValues_.size() == 1)
    1009                         {
    1010                             // There's only one possible config value
    1011                             CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
    1012                             CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first, CommandExecutor::getEvaluation().configvalueclass_);
    1013                             CommandExecutor::parse(CommandExecutor::getToken(0) + " " + CommandExecutor::getToken(1) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first + " ", false);
    1014                             return;
    1015                         }
    1016 
    1017                         // It's ambiguous
    1018                         return;
    1019                     }
    1020                 }
    1021                 else
    1022                 {
    1023                     // Something is wrong
    1024                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1025                     return;
    1026                 }
    1027                 break;
    1028             case CS_ConfigValueType:
    1029                 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && CommandExecutor::getEvaluation().configvalueclass_ && CommandExecutor::getEvaluation().configvalue_)
    1030                 {
    1031                     // Valid command
    1032                     // Check if there are enough parameters
    1033                     if ((CommandExecutor::getEvaluation().tokens_.size() >= 4) && (CommandExecutor::getEvaluation().tokens_[3] != COMMAND_EXECUTOR_CURSOR))
    1034                     {
    1035                         CommandExecutor::getEvaluation().state_ = CS_ConfigValueFinished;
    1036                         return;
    1037                     }
    1038                 }
    1039                 else
    1040                 {
    1041                     // Something is wrong
    1042                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1043                     return;
    1044                 }
    1045                 break;
    1046             case CS_KeybindKey:
    1047                 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
    1048                 {
    1049                     // todo
    1050                 }
    1051                 else
    1052                 {
    1053                     // Something is wrong
    1054                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1055                     return;
    1056                 }
    1057                 break;
    1058             case CS_KeybindCommand:
    1059                 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) && (false)) // todo
    1060                 {
    1061                     // Valid command
    1062                     // Check if there are enough parameters
    1063                     if (CommandExecutor::getEvaluation().tokens_.size() >= 3)
    1064                     {
    1065                         CommandExecutor::getEvaluation().state_ = CS_KeybindFinished;
    1066                         return;
    1067                     }
    1068 
    1069                 }
    1070                 else
    1071                 {
    1072                     // Something is wrong
    1073                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1074                     return;
    1075                 }
    1076                 break;
    1077             case CS_Shortcut_Finished:
    1078                 // Nothing to do
    1079                 break;
    1080             case CS_Function_Finished:
    1081                 // Nothing to do
    1082                 break;
    1083             case CS_ConfigValueFinished:
    1084                 // Nothing to do
    1085                 break;
    1086             case CS_KeybindFinished:
    1087                 // Nothing to do
    1088                 break;
    1089             case CS_Error:
    1090                 // This is bad
    1091                 break;
    1092         }
    1093     }
    1094 
    1095     void CommandExecutor::initialize(const std::string& command)
    1096     {
    1097         CommandExecutor::getEvaluation().processedCommand_ = command;
    1098         CommandExecutor::getEvaluation().additionalParameter_ = "";
    1099 
    1100         CommandExecutor::getEvaluation().bEvaluatedParams_ = false;
    1101         CommandExecutor::getEvaluation().evaluatedExecutor_ = 0;
    1102 
    1103         CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.clear();
    1104         CommandExecutor::getEvaluation().listOfPossibleShortcuts_.clear();
     409            }
     410        }
     411    }
     412
     413    unsigned int CommandExecutor::argumentsFinished()
     414    {
     415        unsigned int argumentsGiven = CommandExecutor::argumentsGiven();
     416        if (argumentsGiven > 0)
     417            return argumentsGiven - 1;
     418        else
     419            return 0;
     420    }
     421
     422    unsigned int CommandExecutor::argumentsGiven()
     423    {
     424        if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ')
     425            return CommandExecutor::getEvaluation().commandTokens_.size() + 1;
     426        else
     427            return CommandExecutor::getEvaluation().commandTokens_.size();
     428    }
     429
     430    bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command)
     431    {
     432        if (CommandExecutor::getEvaluation().functionclass_)
     433            return (CommandExecutor::argumentsGiven() > (2 + command->getParamCount()));
     434        else
     435            return (CommandExecutor::argumentsGiven() > (1 + command->getParamCount()));
     436    }
     437
     438    std::string CommandExecutor::getArgument(unsigned int index)
     439    {
     440        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
     441            return CommandExecutor::getEvaluation().commandTokens_[index];
     442        else
     443            return "";
     444    }
     445
     446    std::string CommandExecutor::getLastArgument()
     447    {
     448        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
     449    }
     450
     451    void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment)
     452    {
     453        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
     454        std::string lowercase = getLowercase(fragment);
     455        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
     456            if ((*it).second->hasConsoleCommands())
     457                if ((*it).first.find(lowercase) == 0 || fragment == "")
     458                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     459    }
     460
     461    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
     462    {
    1105463        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
    1106         CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.clear();
    1107         CommandExecutor::getEvaluation().listOfPossibleConfigValues_.clear();
    1108         CommandExecutor::getEvaluation().listOfPossibleKeys_.clear();
    1109 
    1110         CommandExecutor::getEvaluation().functionclass_ = 0;
    1111         CommandExecutor::getEvaluation().configvalueclass_ = 0;
    1112         CommandExecutor::getEvaluation().shortcut_ = 0;
    1113         CommandExecutor::getEvaluation().function_ = 0;
    1114         CommandExecutor::getEvaluation().configvalue_ = 0;
    1115         CommandExecutor::getEvaluation().key_ = 0;
    1116 
    1117         CommandExecutor::getEvaluation().errorMessage_ = "";
    1118         CommandExecutor::getEvaluation().state_ = CS_Empty;
    1119     }
    1120 
    1121     bool CommandExecutor::argumentsGiven(unsigned int num)
    1122     {
    1123         // Because we added a cursor we have +1 arguments
    1124         // There are num arguments given if there are at least num arguments + one cursor
    1125         return (CommandExecutor::getEvaluation().tokens_.size() >= (num + 1));
    1126     }
    1127 
    1128     unsigned int CommandExecutor::argumentsGiven()
    1129     {
    1130         // Because we added a cursor we have +1 arguments
    1131         if (CommandExecutor::getEvaluation().tokens_.size() >= 1)
    1132             return (CommandExecutor::getEvaluation().tokens_.size() - 1);
    1133         else
    1134             return 0;
    1135     }
    1136 
    1137     std::string CommandExecutor::getToken(unsigned int index)
    1138     {
    1139         if ((index >= 0) && (index < (CommandExecutor::getEvaluation().tokens_.size() - 1)))
    1140             return CommandExecutor::getEvaluation().tokens_[index];
    1141         else if (index == (CommandExecutor::getEvaluation().tokens_.size() - 1))
    1142             return CommandExecutor::getEvaluation().tokens_[index].substr(0, CommandExecutor::getEvaluation().tokens_[index].size() - 1);
    1143         else
    1144             return "";
    1145     }
    1146 
    1147     bool CommandExecutor::enoughParametersGiven(unsigned int head, Executor* executor)
    1148     {
    1149         unsigned int neededParams = head + executor->getParamCount();
    1150         /*
    1151         for (unsigned int i = executor->getParamCount() - 1; i >= 0; i--)
    1152         {
    1153             if (executor->defaultValueSet(i))
    1154                 neededParams--;
     464        std::string lowercase = getLowercase(fragment);
     465        if (!identifier)
     466        {
     467            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
     468                if ((*it).first.find(lowercase) == 0 || fragment == "")
     469                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     470        }
     471        else
     472        {
     473            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
     474                if ((*it).first.find(lowercase) == 0 || fragment == "")
     475                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     476        }
     477    }
     478
     479    void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param)
     480    {
     481        CommandExecutor::createArgumentCompletionList(command, param);
     482
     483        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
     484        std::string lowercase = getLowercase(fragment);
     485        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
     486        {
     487            if ((*it).lowercaseComparison())
     488            {
     489                if ((*it).getComparable().find(lowercase) == 0 || fragment == "")
     490                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
     491            }
    1155492            else
    1156                 break;
    1157         }
    1158         */
    1159         return ((CommandExecutor::getEvaluation().tokens_.size() >= neededParams) && (CommandExecutor::getEvaluation().tokens_[neededParams - 1] != COMMAND_EXECUTOR_CURSOR));
    1160     }
    1161 
    1162     void CommandExecutor::createListOfPossibleFunctionClasses(const std::string& fragment)
    1163     {
    1164         for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
    1165         {
    1166             if ((*it).second->hasConsoleCommands())
    1167             {
    1168                 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1169                 {
    1170                     CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1171                 }
    1172             }
    1173         }
    1174 
    1175         CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.sort(CommandExecutor::compareStringsInList);
    1176     }
    1177 
    1178     void CommandExecutor::createListOfPossibleShortcuts(const std::string& fragment)
    1179     {
    1180         for (std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
    1181         {
    1182             if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1183             {
    1184                 CommandExecutor::getEvaluation().listOfPossibleShortcuts_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1185             }
    1186         }
    1187 
    1188         CommandExecutor::getEvaluation().listOfPossibleShortcuts_.sort(CommandExecutor::compareStringsInList);
    1189     }
    1190 
    1191     void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
    1192     {
    1193         for (std::map<std::string, ExecutorStatic*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
    1194         {
    1195             if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1196             {
    1197                 CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1198             }
    1199         }
    1200 
    1201         CommandExecutor::getEvaluation().listOfPossibleFunctions_.sort(CommandExecutor::compareStringsInList);
    1202     }
    1203 
    1204     void CommandExecutor::createListOfPossibleConfigValueClasses(const std::string& fragment)
    1205     {
    1206         for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
    1207         {
    1208             if ((*it).second->hasConfigValues())
    1209             {
    1210                 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1211                 {
    1212                     CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1213                 }
    1214             }
    1215         }
    1216 
    1217         CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.sort(CommandExecutor::compareStringsInList);
    1218     }
    1219 
    1220     void CommandExecutor::createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier)
    1221     {
    1222         for (std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMapBegin(); it != identifier->getLowercaseConfigValueMapEnd(); ++it)
    1223         {
    1224             if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1225             {
    1226                 CommandExecutor::getEvaluation().listOfPossibleConfigValues_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1227             }
    1228         }
    1229 
    1230         CommandExecutor::getEvaluation().listOfPossibleConfigValues_.sort(CommandExecutor::compareStringsInList);
    1231     }
    1232 
    1233     void CommandExecutor::createListOfPossibleKeys(const std::string& fragment)
    1234     {
    1235         // todo
    1236 
    1237         CommandExecutor::getEvaluation().listOfPossibleKeys_.sort(CommandExecutor::compareStringsInList);
    1238     }
    1239 
    1240     bool CommandExecutor::compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second)
    1241     {
    1242         return ((*first.first) < (*second.first));
    1243     }
    1244 
    1245     Identifier* CommandExecutor::getIdentifierOfPossibleFunctionClass(const std::string& name)
    1246     {
    1247         std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
     493            {
     494                if ((*it).getComparable().find(fragment) == 0 || fragment == "")
     495                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
     496            }
     497        }
     498    }
     499
     500    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
     501    {
     502        std::string lowercase = getLowercase(name);
     503        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(lowercase);
    1248504        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
    1249505            return (*it).second;
     
    1252508    }
    1253509
    1254     ExecutorStatic* CommandExecutor::getExecutorOfPossibleShortcut(const std::string& name)
    1255     {
    1256         std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(getLowercase(name));
    1257         if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
    1258             return (*it).second;
    1259 
     510    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
     511    {
     512        std::string lowercase = getLowercase(name);
     513        if (!identifier)
     514        {
     515            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
     516            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
     517                return (*it).second;
     518        }
     519        else
     520        {
     521            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
     522            if (it != identifier->getLowercaseConsoleCommandMapEnd())
     523                return (*it).second;
     524        }
    1260525        return 0;
    1261526    }
    1262527
    1263     ExecutorStatic* CommandExecutor::getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier)
    1264     {
    1265         std::map<std::string, ExecutorStatic*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(getLowercase(name));
    1266         if (it != identifier->getLowercaseConsoleCommandMapEnd())
    1267             return (*it).second;
    1268 
    1269         return 0;
    1270     }
    1271 
    1272     Identifier* CommandExecutor::getIdentifierOfPossibleConfigValueClass(const std::string& name)
    1273     {
    1274         std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
    1275         if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConfigValues())
    1276             return (*it).second;
    1277 
    1278         return 0;
    1279     }
    1280 
    1281     ConfigValueContainer* CommandExecutor::getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier)
    1282     {
    1283         std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMap().find(getLowercase(name));
    1284         if (it != identifier->getLowercaseConfigValueMapEnd())
    1285         {
    1286             return (*it).second;
    1287         }
    1288 
    1289         return 0;
    1290     }
    1291 
    1292     ConfigValueContainer* CommandExecutor::getContainerOfPossibleKey(const std::string& name)
    1293     {
    1294         // todo
    1295 
    1296         return 0;
    1297     }
    1298 
    1299     std::string CommandExecutor::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
    1300     {
    1301         std::string output = "";
    1302         for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
    1303         {
    1304             if (it != list.begin())
    1305                 output += " ";
    1306 
    1307             output += *(*it).second;
    1308         }
    1309         return output;
    1310     }
    1311 
    1312     std::string CommandExecutor::dump(const ExecutorStatic* executor)
    1313     {
    1314         std::string output = "";
    1315         for (unsigned int i = 0; i < executor->getParamCount(); i++)
    1316         {
    1317             if (i != 0)
    1318                 output += " ";
    1319 
    1320             if (executor->defaultValueSet(i))
    1321                 output += "[";
     528    std::string CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
     529    {
     530        CommandExecutor::createArgumentCompletionList(command, param);
     531
     532        std::string lowercase = getLowercase(name);
     533        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
     534        {
     535            if ((*it).lowercaseComparison())
     536            {
     537                if ((*it).getComparable() == lowercase)
     538                    return (*it).getString();
     539            }
    1322540            else
    1323                 output += "{";
    1324 
    1325             output += executor->getTypenameParam(i);
    1326 
    1327             if (executor->defaultValueSet(i))
    1328                 output += "=" + executor->getDefaultValue(i).toString() + "]";
    1329             else
    1330                 output += "}";
    1331         }
    1332         return output;
    1333     }
    1334 
    1335     std::string CommandExecutor::dump(const ConfigValueContainer* container)
    1336     {
    1337         AddLanguageEntry("CommandExecutor::oldvalue", "old value");
    1338         if (!container->isVector())
    1339             return ("{" + container->getTypename() + "} (" + GetLocalisation("CommandExecutor::oldvalue") + ": " + container->toString() + ")");
    1340         else
    1341             return ("(vector<" + container->getTypename() + ">) (size: " + getConvertedValue<unsigned int, std::string>(container->getVectorSize()) + ")");
     541            {
     542                if ((*it).getComparable() == name)
     543                    return (*it).getString();
     544            }
     545        }
     546
     547        return "";
     548    }
     549
     550    void CommandExecutor::createArgumentCompletionList(ConsoleCommand* command, unsigned int param)
     551    {
     552        std::string params[5];
     553
     554        unsigned int index = 0;
     555        unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0);
     556
     557        for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i)
     558        {
     559            params[index] = CommandExecutor::getArgument(i);
     560            ++index;
     561            if (index >= 5)
     562                break;
     563        }
     564
     565        command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]);
    1342566    }
    1343567
     
    1382606        }
    1383607    }
     608
     609    std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list)
     610    {
     611        if (list.size() == 0)
     612        {
     613            return "";
     614        }
     615        else if (list.size() == 1)
     616        {
     617            return ((*list.begin()).getComparable() + " ");
     618        }
     619        else
     620        {
     621            std::string output = "";
     622            for (unsigned int i = 0; true; i++)
     623            {
     624                char temp = 0;
     625                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
     626                {
     627                    std::string argument = (*it).getComparable();
     628                    if (argument.size() > i)
     629                    {
     630                        if (it == list.begin())
     631                        {
     632                            temp = argument[i];
     633                        }
     634                        else
     635                        {
     636                            if (temp != argument[i])
     637                                return output;
     638                        }
     639                    }
     640                    else
     641                    {
     642                        return output;
     643                    }
     644                }
     645                output += temp;
     646            }
     647            return output;
     648        }
     649    }
    1384650}
Note: See TracChangeset for help on using the changeset viewer.