Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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