Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/core/CommandExecutor.cc @ 1269

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

added some control commands to TclThreadManager (status, dump, flush) and changed some small details.
calls to a TclThread are no longer hidden from the main-interpreter. if you want to pass expressions with variables to a thread, put them into {curly braces} - the expression will then be transfered untouched to the sub-interpreter. without braces, the variables will be replaced by the main-interpreter.
the advantage is: you can use a variable to pass the ID of a thread to TclThreadManager, which wasn't possible with the old solution. an example is remote.tcl that creates a thread, saves it's ID in a variable and executes a command on this thread.

oh, and if you didn't understood a word - no problem, this is only important for people using Tcl in Orxonox ;)

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