Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/CommandExecutor.cc @ 1268

Last change on this file since 1268 was 1214, checked in by landauf, 17 years ago

merged console-branch back to trunk.
IMPORTANT: update your media directory!

you need TCL to compile. TCL is available here: http://www.tcl.tk/
another option is to check out https://svn.orxonox.net/ogre/tcl8.5.2/ and compile it by yourself. makefiles are in the 'macosx', 'unix' and 'win' subfolders.
FindTCL.cmake searches in the usual locations and in ../libs/tcl8.5.2/

the orxonox console can be activated with numpad-enter. whatever you enter will be parsed by TCL. if TCL doesn't know a command, it gets executed by orxonox.

simple tcl commands are: "puts text" to write "text" into the console, "expr 1+1" to calculate the result of the given expression. just try it by yourself with "puts [expr 1+1]".
[x] means: evaluate x and use the returnvalue as an argument. in this case the returned value is "2" and the resulting command therefore "puts 2".

you can combine orxonox and tcl commands. a simple orxonox command is "log text" that writes text into the console and the logfile. test it with "log [expr 1+1]" to write "2" into all output channels of orxonox. something more advanced: "log [clock seconds]" writes the seconds since 1970 into the logfile. feel free to combine both: "log [clock seconds]: 1+1 is [expr 1+1]"

TCL uses variables. to set a new variable, use "set varname value". you can use the variable wherever you want with $varname. with this we can make the above command a bit more elegant:
set myexpression 1+1
log [clock seconds]: $myexpression is [expr $myexpression]

read more about tcl in the wiki: http://wiki.tcl.tk/

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