Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

extracted all config-value related macros from CoreIncludes.h and moved them to ConfigValueIncludes.h.

ConfigValueContainer can now handle std::vector<x> where 'x' is is any type supported by MultiTypeMath (all primitives, pointer, string, vector2, vector3, quaternion, colourvalue, radian, degree).

the vectors size is currently limited to 256 elements. this is just a practical limit, it can be raised if it's necessary. the reason for the limit is: you can add new elements to a vector by simply typing 'set classname varname index value' into the console or adding a new entry in the config-file. if 'index' is bigger than the vectors size, all elements up to 'index' are inserted. if the user accidentally enters a big number, he could end up with >4*109 elements in his config-file, resulting in 10-100gb on the hdd and a completely filled memory. and that's not exactly what i want ;)

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 = getStrippedEnclosingQuotes(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.