Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/CommandExecutor.cc @ 1348

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

merged console-branch back to trunk.
IMPORTANT: update your media directory!

you need TCL to compile. TCL is available here: http://www.tcl.tk/
another option is to check out https://svn.orxonox.net/ogre/tcl8.5.2/ and compile it by yourself. makefiles are in the 'macosx', 'unix' and 'win' subfolders.
FindTCL.cmake searches in the usual locations and in ../libs/tcl8.5.2/

the orxonox console can be activated with numpad-enter. whatever you enter will be parsed by TCL. if TCL doesn't know a command, it gets executed by orxonox.

simple tcl commands are: "puts text" to write "text" into the console, "expr 1+1" to calculate the result of the given expression. just try it by yourself with "puts [expr 1+1]".
[x] means: evaluate x and use the returnvalue as an argument. in this case the returned value is "2" and the resulting command therefore "puts 2".

you can combine orxonox and tcl commands. a simple orxonox command is "log text" that writes text into the console and the logfile. test it with "log [expr 1+1]" to write "2" into all output channels of orxonox. something more advanced: "log [clock seconds]" writes the seconds since 1970 into the logfile. feel free to combine both: "log [clock seconds]: 1+1 is [expr 1+1]"

TCL uses variables. to set a new variable, use "set varname value". you can use the variable wherever you want with $varname. with this we can make the above command a bit more elegant:
set myexpression 1+1
log [clock seconds]: $myexpression is [expr $myexpression]

read more about tcl in the wiki: http://wiki.tcl.tk/

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