Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/CommandExecutor.cc @ 994

Last change on this file since 994 was 994, checked in by landauf, 16 years ago
  • added some symbols to the CommandExecutor: a) expression | expression: the pipe leads the output from the right expression into the left one b) expression > file: writes the output of the expression into a file c) expression < file: reads a file and uses it's content as input for the expression
  • added new console commands: a) echo text: returns the input b) read file: reads a file and returns the content c) write file text: writes text into a file d) append file text: appends text to a file
  • added stripEnclosingQuotes function to String.h, that removes enclosing quotes (if there are some). whitespaces outside the quotes are stripped, whitespaces inside the quotes stay. removes the quotes only if there is nothing else than whitespaces outside of them. what it changes: "expression" → expression what it let unchanged:
    • ex"press"ion
    • a"expression"b
    • a"expression"
    • "expression"b
    • express"ion
  • extended SubString: added some bools to determine the behaviour when dividing a string like the following up into pieces: mytext "this is a quoted area" blub (0, 1, 2)

this usually results in:
mytext / this is a quoted area / blub / 0, 1, 2

but now you can change it to:
mytext / "this is a quoted area" / blub / (0, 1, 2)

this is important if the string wents through several substring splitups and the quotes and brackets should stay.

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