Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/input/src/core/CommandExecutor.cc @ 1433

Last change on this file since 1433 was 1323, checked in by rgrieder, 17 years ago

Basically, almost everything about the input management is written, but I wasn't yet able to test things.

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