Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

big commit, but not much changes in code:

  • put CommandEvaluation into it's own .cc and .h files
  • put some basic ConsoleCommands into ConsoleCommandCompilation.cc and .h
  • created a new class, ConsoleCommand, inheriting from ExecutorStatic, implementing all command-related features that were located in the Executor until now (at the moment only accessLevel_, but more will come - from reto and me)
  • renamed ConsoleCommand-macros to SetConsoleCommand (all related macros were changed the same way)
  • added a new command named "killdelays", that kills all delayed commands. helpful to stop disco ;)
File size: 53.9 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    SetConsoleCommandShortcutGeneric(keyword1, createExecutor((FunctorStatic*)0, "set")).setAccessLevel(AccessLevel::User);
47    SetConsoleCommandShortcutGeneric(keyword2, createExecutor((FunctorStatic*)0, "tset")).setAccessLevel(AccessLevel::User);
48    SetConsoleCommandShortcutGeneric(keyword3, createExecutor((FunctorStatic*)0, "bind")).setAccessLevel(AccessLevel::User);
49
50    CommandExecutor& CommandExecutor::getInstance()
51    {
52        static CommandExecutor instance;
53        return instance;
54    }
55
56    CommandEvaluation& CommandExecutor::getEvaluation()
57    {
58        return CommandExecutor::getInstance().evaluation_;
59    }
60
61    const CommandEvaluation& CommandExecutor::getLastEvaluation()
62    {
63        return CommandExecutor::getInstance().evaluation_;
64    }
65
66    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command)
67    {
68        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
69        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
70        return (*command);
71    }
72
73    /**
74        @brief Returns the executor of a console command shortcut with given name.
75        @brief name The name of the requested console command shortcut
76        @return The executor of the requested console command shortcut
77    */
78    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
79    {
80        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
81        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
82            return (*it).second;
83        else
84            return 0;
85    }
86
87    /**
88        @brief Returns the executor of a console command shortcut with given name in lowercase.
89        @brief name The name of the requested console command shortcut in lowercase
90        @return The executor of the requested console command shortcut
91    */
92    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
93    {
94        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
95        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
96            return (*it).second;
97        else
98            return 0;
99    }
100
101    bool CommandExecutor::execute(const std::string& command, bool useTcl)
102    {
103        if (useTcl)
104        {
105//            std::string temp = getLowercase(removeTrailingWhitespaces(command));
106//            if (!(temp.substr(0, 16) == "tclthreadmanager" || temp.substr(0, 10) == "tclexecute" || temp.substr(0, 8) == "tclquery"))
107                return TclBind::eval(command);
108        }
109
110        if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
111            CommandExecutor::parse(command);
112
113        return CommandExecutor::execute(CommandExecutor::getEvaluation());
114    }
115
116
117    bool CommandExecutor::execute(const CommandEvaluation& evaluation)
118    {
119        SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
120
121        if (evaluation.bEvaluatedParams_ && evaluation.evaluatedExecutor_)
122        {
123            COUT(4) << "CE_execute (evaluation): " << evaluation.evaluatedExecutor_->getName() << " " << evaluation.param_[0] << " " << evaluation.param_[1] << " " << evaluation.param_[2] << " " << evaluation.param_[3] << " " << evaluation.param_[4] << std::endl;
124            (*evaluation.evaluatedExecutor_)(evaluation.param_[0], evaluation.param_[1], evaluation.param_[2], evaluation.param_[3], evaluation.param_[4]);
125            return true;
126        }
127
128        COUT(4) << "CE_execute: " << evaluation.processedCommand_ << "\n";
129        switch (evaluation.state_)
130        {
131            case CS_Uninitialized:
132                break;
133            case CS_Empty:
134                break;
135            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
136                break;
137            case CS_Shortcut_Params:
138                // not enough parameters but lets hope there are some additional parameters and go on
139            case CS_Shortcut_Finished:
140                // call the shortcut
141                if (evaluation.shortcut_)
142                {
143                    if (tokens.size() >= 2)
144                        return evaluation.shortcut_->parse(removeSlashes(tokens.subSet(1).join() + evaluation.getAdditionalParameter()));
145                    else
146                        return evaluation.shortcut_->parse(removeSlashes(evaluation.additionalParameter_));
147                }
148                break;
149            case CS_Function:
150                break;
151            case CS_Function_Params:
152                // not enough parameters but lets hope there are some additional parameters and go on
153            case CS_Function_Finished:
154                // call the shortcut
155                if (evaluation.function_)
156                {
157                    if (tokens.size() >= 3)
158                        return evaluation.function_->parse(removeSlashes(tokens.subSet(2).join() + evaluation.getAdditionalParameter()));
159                    else
160                        return evaluation.function_->parse(removeSlashes(evaluation.additionalParameter_));
161                }
162                break;
163            case CS_ConfigValueClass:
164                break;
165            case CS_ConfigValue:
166                break;
167            case CS_ConfigValueType:
168                // not enough parameters but lets hope there are some additional parameters and go on
169            case CS_ConfigValueFinished:
170                // set the config value
171                if (evaluation.configvalue_)
172                {
173                    if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE))
174                    {
175                        if (tokens.size() >= 4)
176                            return evaluation.configvalue_->set(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter()));
177                        else
178                            return evaluation.configvalue_->set(removeSlashes(evaluation.additionalParameter_));
179                    }
180                    else if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
181                    {
182                        if (tokens.size() >= 4)
183                            return evaluation.configvalue_->tset(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter()));
184                        else
185                            return evaluation.configvalue_->tset(removeSlashes(evaluation.additionalParameter_));
186                    }
187                }
188                break;
189            case CS_KeybindKey:
190                break;
191            case CS_KeybindCommand:
192                // not enough parameters but lets hope there are some additional parameters and go on
193            case CS_KeybindFinished:
194                // set the keybind
195                // ...todo
196                break;
197            case CS_Error:
198                break;
199        }
200
201        return false;
202    }
203
204    std::string CommandExecutor::complete(const std::string& command)
205    {
206        if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
207            CommandExecutor::parse(command);
208
209        return CommandExecutor::complete(CommandExecutor::getEvaluation());
210    }
211
212    std::string CommandExecutor::complete(const CommandEvaluation& evaluation)
213    {
214        SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
215
216        std::list<std::pair<const std::string*, const std::string*> > temp;
217        if (evaluation.state_ == CS_Empty)
218        {
219            temp.insert(temp.end(), evaluation.listOfPossibleShortcuts_.begin(), evaluation.listOfPossibleShortcuts_.end());
220            temp.insert(temp.end(), evaluation.listOfPossibleFunctionClasses_.begin(), evaluation.listOfPossibleFunctionClasses_.end());
221        }
222
223        switch (evaluation.state_)
224        {
225            case CS_Uninitialized:
226                break;
227            case CS_Empty:
228                return (CommandExecutor::getCommonBegin(temp));
229                break;
230            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
231                break;
232            case CS_Shortcut_Params:
233                if (evaluation.shortcut_)
234                    return (evaluation.shortcut_->getName() + " ");
235                break;
236            case CS_Shortcut_Finished:
237                if (evaluation.shortcut_)
238                {
239                    if (evaluation.shortcut_->getParamCount() == 0)
240                        return (evaluation.shortcut_->getName());
241                    else if (tokens.size() >= 2)
242                        return (evaluation.shortcut_->getName() + " " + tokens.subSet(1).join());
243                }
244                break;
245            case CS_Function:
246                if (evaluation.functionclass_)
247                    return (evaluation.functionclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleFunctions_));
248                break;
249            case CS_Function_Params:
250                if (evaluation.functionclass_ && evaluation.function_)
251                    return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " ");
252                break;
253            case CS_Function_Finished:
254                if (evaluation.functionclass_ && evaluation.function_)
255                {
256                    if (evaluation.function_->getParamCount() == 0)
257                        return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName());
258                    else if (tokens.size() >= 3)
259                        return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " " + tokens.subSet(2).join());
260                }
261                break;
262            case CS_ConfigValueClass:
263                if (tokens.size() >= 1)
264                    return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValueClasses_));
265                break;
266            case CS_ConfigValue:
267                if ((tokens.size() >= 1) && evaluation.configvalueclass_)
268                    return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValues_));
269                break;
270            case CS_ConfigValueType:
271                if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_)
272                    return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " ");
273                break;
274            case CS_ConfigValueFinished:
275                if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_ && (tokens.size() >= 4))
276                    return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " " + tokens.subSet(3).join());
277                break;
278            case CS_KeybindKey:
279                if (tokens.size() >= 1)
280                    return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleKeys_));
281                break;
282            case CS_KeybindCommand:
283                if ((evaluation.processedCommand_.size() >= 1) && (evaluation.processedCommand_[evaluation.processedCommand_.size() - 1] != ' '))
284                    return (evaluation.processedCommand_ + " ");
285                break;
286            case CS_KeybindFinished:
287                break;
288            case CS_Error:
289                break;
290        }
291
292        return evaluation.processedCommand_;
293    }
294
295    std::string CommandExecutor::hint(const std::string& command)
296    {
297        if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
298            CommandExecutor::parse(command);
299
300        return CommandExecutor::hint(CommandExecutor::getEvaluation());
301    }
302
303    std::string CommandExecutor::hint(const CommandEvaluation& evaluation)
304    {
305        SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
306
307        switch (evaluation.state_)
308        {
309            case CS_Uninitialized:
310                break;
311            case CS_Empty:
312                return (CommandExecutor::dump(evaluation.listOfPossibleShortcuts_) + "\n" + CommandExecutor::dump(evaluation.listOfPossibleFunctionClasses_));
313                break;
314            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
315                break;
316            case CS_Shortcut_Params:
317                if (evaluation.shortcut_)
318                    return CommandExecutor::dump(evaluation.shortcut_);
319                break;
320            case CS_Shortcut_Finished:
321                if (evaluation.shortcut_)
322                    return CommandExecutor::dump(evaluation.shortcut_);
323                break;
324            case CS_Function:
325                return CommandExecutor::dump(evaluation.listOfPossibleFunctions_);
326                break;
327            case CS_Function_Params:
328                if (evaluation.function_)
329                    return CommandExecutor::dump(evaluation.function_);
330                break;
331            case CS_Function_Finished:
332                if (evaluation.function_)
333                    return CommandExecutor::dump(evaluation.function_);
334                break;
335            case CS_ConfigValueClass:
336                return CommandExecutor::dump(evaluation.listOfPossibleConfigValueClasses_);
337                break;
338            case CS_ConfigValue:
339                return CommandExecutor::dump(evaluation.listOfPossibleConfigValues_);
340                break;
341            case CS_ConfigValueType:
342                if (evaluation.configvalue_)
343                    return CommandExecutor::dump(evaluation.configvalue_);
344                break;
345            case CS_ConfigValueFinished:
346                if (evaluation.configvalue_)
347                    return CommandExecutor::dump(evaluation.configvalue_);
348                break;
349            case CS_KeybindKey:
350                return CommandExecutor::dump(evaluation.listOfPossibleKeys_);
351                break;
352            case CS_KeybindCommand:
353                if (evaluation.key_)
354                    return CommandExecutor::dump(evaluation.key_);
355                break;
356            case CS_KeybindFinished:
357                if (evaluation.key_)
358                    return CommandExecutor::dump(evaluation.key_);
359                break;
360            case CS_Error:
361                return CommandExecutor::getEvaluation().errorMessage_;
362                break;
363        }
364
365        return "";
366    }
367
368    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
369    {
370        CommandExecutor::parse(command, true);
371
372        if (CommandExecutor::getEvaluation().tokens_.size() > 0)
373        {
374            std::string lastToken;
375            lastToken = CommandExecutor::getEvaluation().tokens_[CommandExecutor::getEvaluation().tokens_.size() - 1];
376            lastToken = lastToken.substr(0, lastToken.size() - 1);
377            CommandExecutor::getEvaluation().tokens_.pop_back();
378            CommandExecutor::getEvaluation().tokens_.append(SubString(lastToken, " ", "", true, '\0', false, '\0', false, '\0', '\0', false, '\0'));
379        }
380
381        CommandExecutor::getEvaluation().evaluateParams();
382        return CommandExecutor::getEvaluation();
383    }
384
385    void CommandExecutor::parse(const std::string& command, bool bInitialize)
386    {
387        CommandExecutor::getEvaluation().tokens_.split((command + COMMAND_EXECUTOR_CURSOR), " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
388        CommandExecutor::getEvaluation().processedCommand_ = command;
389
390        if (bInitialize)
391            CommandExecutor::initialize(command);
392
393        switch (CommandExecutor::getEvaluation().state_)
394        {
395            case CS_Uninitialized:
396                // Impossible
397                break;
398            case CS_Empty:
399                if (CommandExecutor::argumentsGiven() == 0)
400                {
401                    // We want a hint for the first token
402                    // Check if there is already a perfect match
403                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
404                    CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
405
406                    if ((CommandExecutor::getEvaluation().functionclass_) || (CommandExecutor::getEvaluation().shortcut_))
407                    {
408                        // Yes, there is a class or a shortcut with the searched name
409                        // Add a whitespace and continue parsing
410                        CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword;
411                        CommandExecutor::parse(command + " ", false);
412                        return;
413                    }
414
415                    // No perfect match: Create the lists of all possible classes and shortcuts and return
416                    CommandExecutor::createListOfPossibleFunctionClasses(CommandExecutor::getToken(0));
417                    CommandExecutor::createListOfPossibleShortcuts(CommandExecutor::getToken(0));
418
419                    // Check if there's only one possiblility
420                    if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 1) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 0))
421                    {
422                        // There's only one possible class
423                        CommandExecutor::getEvaluation().state_ = CS_Function;
424                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first);
425                        CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first + " ", false);
426                        return;
427                    }
428                    else if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 0) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 1))
429                    {
430                        if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)
431                         && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)
432                         && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
433                        {
434                            // There's only one possible shortcut
435                            CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params;
436                            CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first);
437                        }
438                        else if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)
439                              || (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
440                        {
441                            // It's the 'set' or 'tset' keyword
442                            CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass;
443                        }
444                        else if (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
445                        {
446                            // It's the 'bind' keyword
447                            CommandExecutor::getEvaluation().state_ = CS_KeybindKey;
448                        }
449
450                        CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first + " ", false);
451                        return;
452                    }
453
454                    // It's ambiguous
455                    return;
456                }
457                else
458                {
459                    // There is at least one argument: Check if it's a shortcut, a classname or a special keyword
460                    CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword;
461                    CommandExecutor::parse(command, false);
462                    return;
463                }
464                break;
465            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
466                if (CommandExecutor::argumentsGiven() >= 1)
467                {
468                    if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
469                    {
470                        // We want to set a config value
471                        CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass;
472                        CommandExecutor::parse(command, false);
473                        return;
474                    }
475                    else if (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
476                    {
477                        // We want to set a keybinding
478                        CommandExecutor::getEvaluation().state_ = CS_KeybindKey;
479                        CommandExecutor::parse(command, false);
480                        return;
481                    }
482
483                    if (!CommandExecutor::getEvaluation().functionclass_)
484                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
485                    if (!CommandExecutor::getEvaluation().shortcut_)
486                        CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
487
488                    if ((!CommandExecutor::getEvaluation().functionclass_) && (!CommandExecutor::getEvaluation().shortcut_))
489                    {
490                        // Argument 1 seems to be wrong
491                        AddLanguageEntry("CommandExecutor::NoSuchCommandOrClassName", "No such command or classname");
492                        CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(0) + ": " + GetLocalisation("CommandExecutor::NoSuchCommandOrClassName"));
493                        CommandExecutor::getEvaluation().state_ = CS_Error;
494                        return;
495                    }
496                    else if (CommandExecutor::getEvaluation().shortcut_)
497                    {
498                        // Argument 1 is a shortcut: Return the needed parameter types
499                        CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params;
500                        CommandExecutor::parse(command, false);
501                        return;
502                    }
503                    else
504                    {
505                        // Argument 1 is a classname: Return the possible functions
506                        CommandExecutor::getEvaluation().state_ = CS_Function;
507                        CommandExecutor::parse(command, false);
508                        return;
509                    }
510                }
511                else
512                {
513                    CommandExecutor::getEvaluation().state_ = CS_Error;
514                    return;
515                }
516                break;
517            case CS_Shortcut_Params:
518                if (CommandExecutor::getEvaluation().shortcut_)
519                {
520                    // Valid command
521                    // Check if there are enough parameters
522                    if (CommandExecutor::enoughParametersGiven(1, CommandExecutor::getEvaluation().shortcut_))
523                    {
524                        CommandExecutor::getEvaluation().state_ = CS_Shortcut_Finished;
525                        return;
526                    }
527                }
528                else
529                {
530                    // Something is wrong
531                    CommandExecutor::getEvaluation().state_ = CS_Error;
532                    return;
533                }
534                break;
535            case CS_Function:
536                if (CommandExecutor::getEvaluation().functionclass_)
537                {
538                    // We have a valid classname
539                    // Check if there is a second argument
540                    if (CommandExecutor::argumentsGiven() >= 2)
541                    {
542                        // There is a second argument: Check if it's a valid functionname
543                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
544                        if (!CommandExecutor::getEvaluation().function_)
545                        {
546                            // Argument 2 seems to be wrong
547                            AddLanguageEntry("CommandExecutor::NoSuchFunctionnameIn", "No such functionname in");
548                            CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchFunctionnameIn") + " " + CommandExecutor::getEvaluation().functionclass_->getName());
549                            CommandExecutor::getEvaluation().state_ = CS_Error;
550                            return;
551                        }
552                        else
553                        {
554                            // Argument 2 seems to be a valid functionname: Get the parameters
555                            CommandExecutor::getEvaluation().state_ = CS_Function_Params;
556                            CommandExecutor::parse(command, false);
557                            return;
558                        }
559                    }
560                    else
561                    {
562                        // There is no finished second argument
563                        // Check if there's already a perfect match
564                        if (CommandExecutor::getEvaluation().tokens_.size() >= 2)
565                        {
566                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
567                            if (CommandExecutor::getEvaluation().function_)
568                            {
569                                // There is a perfect match: Add a whitespace and continue parsing
570                                CommandExecutor::getEvaluation().state_ = CS_Function_Params;
571                                CommandExecutor::parse(command + " ", false);
572                                return;
573                            }
574                        }
575
576                        // No perfect match: Create the list of all possible functions and return
577                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
578
579                        // Check if there's only one possiblility
580                        if (CommandExecutor::getEvaluation().listOfPossibleFunctions_.size() == 1)
581                        {
582                            // There's only one possible function
583                            CommandExecutor::getEvaluation().state_ = CS_Function_Params;
584                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(*(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first, CommandExecutor::getEvaluation().functionclass_);
585                            CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first + " ", false);
586                            return;
587                        }
588
589                        // It's ambiguous
590                        return;
591                    }
592                }
593                else
594                {
595                    CommandExecutor::getEvaluation().state_ = CS_Error;
596                    return;
597                }
598                break;
599            case CS_Function_Params:
600                if (CommandExecutor::getEvaluation().functionclass_ && CommandExecutor::getEvaluation().function_)
601                {
602                    // Valid command
603                    // Check if there are enough parameters
604                    if (CommandExecutor::enoughParametersGiven(2, CommandExecutor::getEvaluation().function_))
605                    {
606                        CommandExecutor::getEvaluation().state_ = CS_Function_Finished;
607                        return;
608                    }
609                }
610                else
611                {
612                    // Something is wrong
613                    CommandExecutor::getEvaluation().state_ = CS_Error;
614                    return;
615                }
616                break;
617            case CS_ConfigValueClass:
618                if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)))
619                {
620                    // We want to set a config value
621                    // Check if there is a second argument
622                    if (CommandExecutor::argumentsGiven() >= 2)
623                    {
624                        // There is a second argument: Check if it's a valid classname
625                        CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
626                        if (!CommandExecutor::getEvaluation().configvalueclass_)
627                        {
628                            // Argument 2 seems to be wrong
629                            AddLanguageEntry("CommandExecutor::NoSuchClassWithConfigValues", "No such class with config values");
630                            CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchClassWithConfigValues"));
631                            CommandExecutor::getEvaluation().state_ = CS_Error;
632                            return;
633                        }
634                        else
635                        {
636                            // Argument 2 seems to be a valid classname: Search for possible config values
637                            CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
638                            CommandExecutor::parse(command, false);
639                            return;
640                        }
641                    }
642                    else
643                    {
644                        // There's no finished second argument
645                        // Check if there's already a perfect match
646                        if (CommandExecutor::getEvaluation().tokens_.size() >= 2)
647                        {
648                            CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
649                            if (CommandExecutor::getEvaluation().configvalueclass_)
650                            {
651                                // There is a perfect match: Add a whitespace and continue parsing
652                                CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
653                                CommandExecutor::parse(command + " ", false);
654                                return;
655                            }
656                        }
657
658                        // No perfect match: Create the list of all possible classnames and return
659                        CommandExecutor::createListOfPossibleConfigValueClasses(CommandExecutor::getToken(1));
660
661                        // Check if there's only one possiblility
662                        if (CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.size() == 1)
663                        {
664                            // There's only one possible classname
665                            CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
666                            CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first);
667                            CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first + " ", false);
668                            return;
669                        }
670
671                        // It's ambiguous
672                        return;
673                    }
674                }
675                else
676                {
677                    // Something is wrong
678                    CommandExecutor::getEvaluation().state_ = CS_Error;
679                    return;
680                }
681                break;
682            case CS_ConfigValue:
683                if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && (CommandExecutor::getEvaluation().configvalueclass_))
684                {
685                    // Check if there is a third argument
686                    if (CommandExecutor::argumentsGiven() >= 3)
687                    {
688                        // There is a third argument: Check if it's a valid config value
689                        CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
690                        if (!CommandExecutor::getEvaluation().configvalue_)
691                        {
692                            // Argument 3 seems to be wrong
693                            AddLanguageEntry("CommandExecutor::NoSuchConfigValueIn", "No such config value in");
694                            CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(2) + ": " + GetLocalisation("CommandExecutor::NoSuchConfigValueIn") + " " + CommandExecutor::getEvaluation().configvalueclass_->getName());
695                            CommandExecutor::getEvaluation().state_ = CS_Error;
696                            return;
697                        }
698                        else
699                        {
700                            // Argument 3 seems to be a valid config value: Get the type
701                            CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
702                            CommandExecutor::parse(command, false);
703                            return;
704                        }
705                    }
706                    else
707                    {
708                        // There is no finished third argument
709                        // Check if there's already a perfect match
710                        if (CommandExecutor::getEvaluation().tokens_.size() >= 3)
711                        {
712                            CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
713                            if (CommandExecutor::getEvaluation().configvalue_)
714                            {
715                                // There is a perfect match: Add a whitespace and continue parsing
716                                CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
717                                CommandExecutor::parse(command + " ", false);
718                                return;
719                            }
720                        }
721
722                        // No perfect match: Create the list of all possible config values
723                        CommandExecutor::createListOfPossibleConfigValues(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
724
725                        // Check if there's only one possiblility
726                        if (CommandExecutor::getEvaluation().listOfPossibleConfigValues_.size() == 1)
727                        {
728                            // There's only one possible config value
729                            CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
730                            CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first, CommandExecutor::getEvaluation().configvalueclass_);
731                            CommandExecutor::parse(CommandExecutor::getToken(0) + " " + CommandExecutor::getToken(1) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first + " ", false);
732                            return;
733                        }
734
735                        // It's ambiguous
736                        return;
737                    }
738                }
739                else
740                {
741                    // Something is wrong
742                    CommandExecutor::getEvaluation().state_ = CS_Error;
743                    return;
744                }
745                break;
746            case CS_ConfigValueType:
747                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_)
748                {
749                    // Valid command
750                    // Check if there are enough parameters
751                    if ((CommandExecutor::getEvaluation().tokens_.size() >= 4) && (CommandExecutor::getEvaluation().tokens_[3] != COMMAND_EXECUTOR_CURSOR))
752                    {
753                        CommandExecutor::getEvaluation().state_ = CS_ConfigValueFinished;
754                        return;
755                    }
756                }
757                else
758                {
759                    // Something is wrong
760                    CommandExecutor::getEvaluation().state_ = CS_Error;
761                    return;
762                }
763                break;
764            case CS_KeybindKey:
765                if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
766                {
767                    // todo
768                }
769                else
770                {
771                    // Something is wrong
772                    CommandExecutor::getEvaluation().state_ = CS_Error;
773                    return;
774                }
775                break;
776            case CS_KeybindCommand:
777                if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) && (false)) // todo
778                {
779                    // Valid command
780                    // Check if there are enough parameters
781                    if (CommandExecutor::getEvaluation().tokens_.size() >= 3)
782                    {
783                        CommandExecutor::getEvaluation().state_ = CS_KeybindFinished;
784                        return;
785                    }
786
787                }
788                else
789                {
790                    // Something is wrong
791                    CommandExecutor::getEvaluation().state_ = CS_Error;
792                    return;
793                }
794                break;
795            case CS_Shortcut_Finished:
796                // Nothing to do
797                break;
798            case CS_Function_Finished:
799                // Nothing to do
800                break;
801            case CS_ConfigValueFinished:
802                // Nothing to do
803                break;
804            case CS_KeybindFinished:
805                // Nothing to do
806                break;
807            case CS_Error:
808                // This is bad
809                break;
810        }
811    }
812
813    void CommandExecutor::initialize(const std::string& command)
814    {
815        CommandExecutor::getEvaluation().processedCommand_ = command;
816        CommandExecutor::getEvaluation().additionalParameter_ = "";
817
818        CommandExecutor::getEvaluation().bEvaluatedParams_ = false;
819        CommandExecutor::getEvaluation().evaluatedExecutor_ = 0;
820
821        CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.clear();
822        CommandExecutor::getEvaluation().listOfPossibleShortcuts_.clear();
823        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
824        CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.clear();
825        CommandExecutor::getEvaluation().listOfPossibleConfigValues_.clear();
826        CommandExecutor::getEvaluation().listOfPossibleKeys_.clear();
827
828        CommandExecutor::getEvaluation().functionclass_ = 0;
829        CommandExecutor::getEvaluation().configvalueclass_ = 0;
830        CommandExecutor::getEvaluation().shortcut_ = 0;
831        CommandExecutor::getEvaluation().function_ = 0;
832        CommandExecutor::getEvaluation().configvalue_ = 0;
833        CommandExecutor::getEvaluation().key_ = 0;
834
835        CommandExecutor::getEvaluation().errorMessage_ = "";
836        CommandExecutor::getEvaluation().state_ = CS_Empty;
837    }
838
839    bool CommandExecutor::argumentsGiven(unsigned int num)
840    {
841        // Because we added a cursor we have +1 arguments
842        // There are num arguments given if there are at least num arguments + one cursor
843        return (CommandExecutor::getEvaluation().tokens_.size() >= (num + 1));
844    }
845
846    unsigned int CommandExecutor::argumentsGiven()
847    {
848        // Because we added a cursor we have +1 arguments
849        if (CommandExecutor::getEvaluation().tokens_.size() >= 1)
850            return (CommandExecutor::getEvaluation().tokens_.size() - 1);
851        else
852            return 0;
853    }
854
855    std::string CommandExecutor::getToken(unsigned int index)
856    {
857        if ((index >= 0) && (index < (CommandExecutor::getEvaluation().tokens_.size() - 1)))
858            return CommandExecutor::getEvaluation().tokens_[index];
859        else if (index == (CommandExecutor::getEvaluation().tokens_.size() - 1))
860            return CommandExecutor::getEvaluation().tokens_[index].substr(0, CommandExecutor::getEvaluation().tokens_[index].size() - 1);
861        else
862            return "";
863    }
864
865    bool CommandExecutor::enoughParametersGiven(unsigned int head, Executor* executor)
866    {
867        unsigned int neededParams = head + executor->getParamCount();
868        /*
869        for (unsigned int i = executor->getParamCount() - 1; i >= 0; i--)
870        {
871            if (executor->defaultValueSet(i))
872                neededParams--;
873            else
874                break;
875        }
876        */
877        return ((CommandExecutor::getEvaluation().tokens_.size() >= neededParams) && (CommandExecutor::getEvaluation().tokens_[neededParams - 1] != COMMAND_EXECUTOR_CURSOR));
878    }
879
880    void CommandExecutor::createListOfPossibleFunctionClasses(const std::string& fragment)
881    {
882        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
883        {
884            if ((*it).second->hasConsoleCommands())
885            {
886                if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
887                {
888                    CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
889                }
890            }
891        }
892
893        CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.sort(CommandExecutor::compareStringsInList);
894    }
895
896    void CommandExecutor::createListOfPossibleShortcuts(const std::string& fragment)
897    {
898        for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
899        {
900            if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
901            {
902                CommandExecutor::getEvaluation().listOfPossibleShortcuts_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
903            }
904        }
905
906        CommandExecutor::getEvaluation().listOfPossibleShortcuts_.sort(CommandExecutor::compareStringsInList);
907    }
908
909    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
910    {
911        for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
912        {
913            if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
914            {
915                CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
916            }
917        }
918
919        CommandExecutor::getEvaluation().listOfPossibleFunctions_.sort(CommandExecutor::compareStringsInList);
920    }
921
922    void CommandExecutor::createListOfPossibleConfigValueClasses(const std::string& fragment)
923    {
924        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
925        {
926            if ((*it).second->hasConfigValues())
927            {
928                if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
929                {
930                    CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
931                }
932            }
933        }
934
935        CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.sort(CommandExecutor::compareStringsInList);
936    }
937
938    void CommandExecutor::createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier)
939    {
940        for (std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMapBegin(); it != identifier->getLowercaseConfigValueMapEnd(); ++it)
941        {
942            if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
943            {
944                CommandExecutor::getEvaluation().listOfPossibleConfigValues_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
945            }
946        }
947
948        CommandExecutor::getEvaluation().listOfPossibleConfigValues_.sort(CommandExecutor::compareStringsInList);
949    }
950
951    void CommandExecutor::createListOfPossibleKeys(const std::string& fragment)
952    {
953        // todo
954
955        CommandExecutor::getEvaluation().listOfPossibleKeys_.sort(CommandExecutor::compareStringsInList);
956    }
957
958    bool CommandExecutor::compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second)
959    {
960        return ((*first.first) < (*second.first));
961    }
962
963    Identifier* CommandExecutor::getIdentifierOfPossibleFunctionClass(const std::string& name)
964    {
965        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
966        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
967            return (*it).second;
968
969        return 0;
970    }
971
972    ConsoleCommand* CommandExecutor::getExecutorOfPossibleShortcut(const std::string& name)
973    {
974        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(getLowercase(name));
975        if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
976            return (*it).second;
977
978        return 0;
979    }
980
981    ConsoleCommand* CommandExecutor::getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier)
982    {
983        std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(getLowercase(name));
984        if (it != identifier->getLowercaseConsoleCommandMapEnd())
985            return (*it).second;
986
987        return 0;
988    }
989
990    Identifier* CommandExecutor::getIdentifierOfPossibleConfigValueClass(const std::string& name)
991    {
992        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
993        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConfigValues())
994            return (*it).second;
995
996        return 0;
997    }
998
999    ConfigValueContainer* CommandExecutor::getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier)
1000    {
1001        std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMap().find(getLowercase(name));
1002        if (it != identifier->getLowercaseConfigValueMapEnd())
1003        {
1004            return (*it).second;
1005        }
1006
1007        return 0;
1008    }
1009
1010    ConfigValueContainer* CommandExecutor::getContainerOfPossibleKey(const std::string& name)
1011    {
1012        // todo
1013
1014        return 0;
1015    }
1016
1017    std::string CommandExecutor::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
1018    {
1019        std::string output = "";
1020        for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
1021        {
1022            if (it != list.begin())
1023                output += " ";
1024
1025            output += *(*it).second;
1026        }
1027        return output;
1028    }
1029
1030    std::string CommandExecutor::dump(const ConsoleCommand* command)
1031    {
1032        std::string output = "";
1033        for (unsigned int i = 0; i < command->getParamCount(); i++)
1034        {
1035            if (i != 0)
1036                output += " ";
1037
1038            if (command->defaultValueSet(i))
1039                output += "[";
1040            else
1041                output += "{";
1042
1043            output += command->getTypenameParam(i);
1044
1045            if (command->defaultValueSet(i))
1046                output += "=" + command->getDefaultValue(i).toString() + "]";
1047            else
1048                output += "}";
1049        }
1050        return output;
1051    }
1052
1053    std::string CommandExecutor::dump(const ConfigValueContainer* container)
1054    {
1055        AddLanguageEntry("CommandExecutor::oldvalue", "old value");
1056        if (!container->isVector())
1057            return ("{" + container->getTypename() + "} (" + GetLocalisation("CommandExecutor::oldvalue") + ": " + container->toString() + ")");
1058        else
1059            return ("(vector<" + container->getTypename() + ">) (size: " + getConvertedValue<unsigned int, std::string>(container->getVectorSize()) + ")");
1060    }
1061
1062    std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list)
1063    {
1064        if (list.size() == 0)
1065        {
1066            return "";
1067        }
1068        else if (list.size() == 1)
1069        {
1070            return ((*(*list.begin()).first) + " ");
1071        }
1072        else
1073        {
1074            std::string output = "";
1075            for (unsigned int i = 0; true; i++)
1076            {
1077                char temp = 0;
1078                for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
1079                {
1080                    if ((*(*it).first).size() > i)
1081                    {
1082                        if (it == list.begin())
1083                        {
1084                            temp = (*(*it).first)[i];
1085                        }
1086                        else
1087                        {
1088                            if (temp != (*(*it).first)[i])
1089                                return output;
1090                        }
1091                    }
1092                    else
1093                    {
1094                        return output;
1095                    }
1096                }
1097                output += temp;
1098            }
1099            return output;
1100        }
1101    }
1102}
Note: See TracBrowser for help on using the repository browser.