Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

someone likes to chat? well, I do. here's a new IRC client. it connects directly into our irc.datacore.ch / #orxonox channel with a random nickname. use the "say text" command to write text into the channel. there are some more commands without a shortcut, type "IRC" and tab.
please update your media directory.

for some reason, irc-client and telnet-remote don't work together. please use only one feature at the same time. I'm not sure if it's a bug in TCL or in my TclThreadManager class. The problem also occurs with irc or telnet in parallel with another busy tcl-thread… strange thing.

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