Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1049 was 1049, checked in by landauf, 16 years ago

config-value accepts now strings with special chars like \n or \t and hopefully every other. strings are enclosed by "…", but the quotes are only visible in the config-file. if you want something like " ← whitespace" you must add quotes, otherwise this would be stripped to "← whitespace".

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