Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/CommandExecutor.cc @ 949

Last change on this file since 949 was 949, checked in by landauf, 16 years ago

made CommandExecutor a singleton

File size: 41.6 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28#include "CommandExecutor.h"
29#include "ConsoleCommand.h"
30#include "util/String.h"
31#include "Identifier.h"
32#include "Language.h"
33#include "Debug.h"
34#include "Executor.h"
35#include "ConfigValueContainer.h"
36
37#define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE "set"
38#define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY "tset"
39#define COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND "bind"
40
41namespace orxonox
42{
43    ConsoleCommandShortcutGeneric(keyword1, createExecutor((FunctorStatic*)0, "set", AccessLevel::User));
44    ConsoleCommandShortcutGeneric(keyword2, createExecutor((FunctorStatic*)0, "tset", AccessLevel::User));
45    ConsoleCommandShortcutGeneric(keyword3, createExecutor((FunctorStatic*)0, "bind", AccessLevel::User));
46
47    CommandExecutor& CommandExecutor::getInstance()
48    {
49        static CommandExecutor instance;
50        return instance;
51    }
52
53    bool CommandExecutor::addConsoleCommandShortcut(ExecutorStatic* executor)
54    {
55        CommandExecutor::getInstance().consoleCommandShortcuts_s[executor->getName()] = executor;
56        CommandExecutor::getInstance().consoleCommandShortcuts_LC_s[getLowercase(executor->getName())] = executor;
57        return true;
58    }
59
60    /**
61        @brief Returns the executor of a console command shortcut with given name.
62        @brief name The name of the requested console command shortcut
63        @return The executor of the requested console command shortcut
64    */
65    ExecutorStatic* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
66    {
67        std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_s.find(name);
68        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_s.end())
69            return (*it).second;
70        else
71            return 0;
72    }
73
74    /**
75        @brief Returns the executor of a console command shortcut with given name in lowercase.
76        @brief name The name of the requested console command shortcut in lowercase
77        @return The executor of the requested console command shortcut
78    */
79    ExecutorStatic* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
80    {
81        std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_s.find(name);
82        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_s.end())
83            return (*it).second;
84        else
85            return 0;
86    }
87
88    bool CommandExecutor::execute(const std::string& command)
89    {
90        if (CommandExecutor::getInstance().lastProcessedCommand_s != command)
91            CommandExecutor::parse(command);
92
93        CommandExecutor::getInstance().tokens_s.split(command, " ", SubString::WhiteSpaces, false, '\\', '"', '(', ')', '\0');
94
95        switch (CommandExecutor::getInstance().state_s)
96        {
97            case CS_Empty:
98                break;
99            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
100                break;
101            case CS_Shortcut_Params:
102                // not enough parameters
103                break;
104            case CS_Shortcut_Finished:
105                // call the shortcut
106                if (CommandExecutor::getInstance().shortcut_s != 0)
107                    return CommandExecutor::getInstance().shortcut_s->parse(CommandExecutor::getInstance().tokens_s.subSet(1).join());
108                break;
109            case CS_Function:
110                break;
111            case CS_Function_Params:
112                // not enough parameters
113                break;
114            case CS_Function_Finished:
115                // call the shortcut
116                if (CommandExecutor::getInstance().function_s != 0)
117                    return CommandExecutor::getInstance().function_s->parse(CommandExecutor::getInstance().tokens_s.subSet(2).join());
118                break;
119            case CS_ConfigValueClass:
120                break;
121            case CS_ConfigValue:
122                break;
123            case CS_ConfigValueType:
124                // not enough parameters
125                break;
126            case CS_ConfigValueFinished:
127                // set the config value
128                if (CommandExecutor::getInstance().configvalue_s != 0)
129                    return CommandExecutor::getInstance().configvalue_s->parseString(CommandExecutor::getInstance().tokens_s.subSet(3).join());
130                break;
131            case CS_KeybindKey:
132                break;
133            case CS_KeybindCommand:
134                // not enough parameters
135                break;
136            case CS_KeybindFinished:
137                // set the keybind
138                // ...todo
139                break;
140            case CS_Error:
141                break;
142        }
143
144        return false;
145    }
146
147    std::string CommandExecutor::complete(const std::string& command)
148    {
149        if (CommandExecutor::getInstance().lastProcessedCommand_s != command)
150            CommandExecutor::parse(command);
151
152        CommandExecutor::getInstance().tokens_s.split(command, " ", SubString::WhiteSpaces, false, '\\', '"', '(', ')', '\0');
153
154        std::list<const std::string*> temp;
155        if (CommandExecutor::getInstance().state_s == CS_Empty)
156        {
157            temp.insert(temp.end(), CommandExecutor::getInstance().listOfPossibleShortcuts_s.begin(), CommandExecutor::getInstance().listOfPossibleShortcuts_s.end());
158            temp.insert(temp.end(), CommandExecutor::getInstance().listOfPossibleFunctionClasses_s.begin(), CommandExecutor::getInstance().listOfPossibleFunctionClasses_s.end());
159        }
160
161        switch (CommandExecutor::getInstance().state_s)
162        {
163            case CS_Empty:
164                return (CommandExecutor::getInstance().tokens_s.subSet(0, CommandExecutor::getInstance().tokens_s.size() - 1).join() + " " + CommandExecutor::getCommonBegin(temp));
165                break;
166            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
167                break;
168            case CS_Shortcut_Params:
169                if (command[command.size() - 1] != ' ')
170                    return (command + " ");
171                break;
172            case CS_Shortcut_Finished:
173                break;
174            case CS_Function:
175                return (CommandExecutor::getInstance().tokens_s.subSet(0, CommandExecutor::getInstance().tokens_s.size() - 1).join() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getInstance().listOfPossibleFunctions_s));
176                break;
177            case CS_Function_Params:
178                if (command[command.size() - 1] != ' ')
179                    return (command + " ");
180                break;
181            case CS_Function_Finished:
182                break;
183            case CS_ConfigValueClass:
184                return (CommandExecutor::getInstance().tokens_s.subSet(0, CommandExecutor::getInstance().tokens_s.size() - 1).join() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getInstance().listOfPossibleConfigValueClasses_s));
185                break;
186            case CS_ConfigValue:
187                return (CommandExecutor::getInstance().tokens_s.subSet(0, CommandExecutor::getInstance().tokens_s.size() - 1).join() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getInstance().listOfPossibleConfigValues_s));
188                break;
189            case CS_ConfigValueType:
190                if (command[command.size() - 1] != ' ')
191                    return (command + " ");
192                break;
193            case CS_ConfigValueFinished:
194                break;
195            case CS_KeybindKey:
196                return (CommandExecutor::getInstance().tokens_s.subSet(0, CommandExecutor::getInstance().tokens_s.size() - 1).join() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getInstance().listOfPossibleKeys_s));
197                break;
198            case CS_KeybindCommand:
199                if (command[command.size() - 1] != ' ')
200                    return (command + " ");
201                break;
202            case CS_KeybindFinished:
203                break;
204            case CS_Error:
205                break;
206        }
207
208        return CommandExecutor::getInstance().lastProcessedCommand_s;
209    }
210
211    std::string CommandExecutor::hint(const std::string& command)
212    {
213        if (CommandExecutor::getInstance().lastProcessedCommand_s != command)
214            CommandExecutor::parse(command);
215
216        CommandExecutor::getInstance().tokens_s.split(command, " ", SubString::WhiteSpaces, false, '\\', '"', '(', ')', '\0');
217
218        switch (CommandExecutor::getInstance().state_s)
219        {
220            case CS_Empty:
221                return (CommandExecutor::dump(CommandExecutor::getInstance().listOfPossibleShortcuts_s) + "\n" + CommandExecutor::dump(CommandExecutor::getInstance().listOfPossibleFunctionClasses_s));
222                break;
223            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
224                break;
225            case CS_Shortcut_Params:
226                if (CommandExecutor::getInstance().shortcut_s != 0)
227                    return CommandExecutor::dump(CommandExecutor::getInstance().shortcut_s);
228                break;
229            case CS_Shortcut_Finished:
230                if (CommandExecutor::getInstance().shortcut_s != 0)
231                    return CommandExecutor::dump(CommandExecutor::getInstance().shortcut_s);
232                break;
233            case CS_Function:
234                return CommandExecutor::dump(CommandExecutor::getInstance().listOfPossibleFunctions_s);
235                break;
236            case CS_Function_Params:
237                if (CommandExecutor::getInstance().function_s != 0)
238                    return CommandExecutor::dump(CommandExecutor::getInstance().function_s);
239                break;
240            case CS_Function_Finished:
241                if (CommandExecutor::getInstance().function_s != 0)
242                    return CommandExecutor::dump(CommandExecutor::getInstance().function_s);
243                break;
244            case CS_ConfigValueClass:
245                return CommandExecutor::dump(CommandExecutor::getInstance().listOfPossibleConfigValueClasses_s);
246                break;
247            case CS_ConfigValue:
248                return CommandExecutor::dump(CommandExecutor::getInstance().listOfPossibleConfigValues_s);
249                break;
250            case CS_ConfigValueType:
251                if (CommandExecutor::getInstance().configvalue_s != 0)
252                    return CommandExecutor::dump(CommandExecutor::getInstance().configvalue_s);
253                break;
254            case CS_ConfigValueFinished:
255                if (CommandExecutor::getInstance().configvalue_s != 0)
256                    return CommandExecutor::dump(CommandExecutor::getInstance().configvalue_s);
257                break;
258            case CS_KeybindKey:
259                return CommandExecutor::dump(CommandExecutor::getInstance().listOfPossibleKeys_s);
260                break;
261            case CS_KeybindCommand:
262                if (CommandExecutor::getInstance().key_s != 0)
263                    return CommandExecutor::dump(CommandExecutor::getInstance().key_s);
264                break;
265            case CS_KeybindFinished:
266                if (CommandExecutor::getInstance().key_s != 0)
267                    return CommandExecutor::dump(CommandExecutor::getInstance().key_s);
268                break;
269            case CS_Error:
270                return "Error";
271                break;
272        }
273
274        return "";
275    }
276
277    void CommandExecutor::parse(const std::string& command, bool bInitialize)
278    {
279        CommandExecutor::getInstance().tokens_s.split((command + COMMAND_EXECUTOR_CURSOR), " ", SubString::WhiteSpaces, false, '\\', '"', '(', ')', '\0');
280        CommandExecutor::getInstance().lastProcessedCommand_s = command;
281
282        if (bInitialize)
283            CommandExecutor::initialize();
284
285        switch (CommandExecutor::getInstance().state_s)
286        {
287            case CS_Empty:
288                if (CommandExecutor::argumentsGiven() == 0)
289                {
290                    // We want a hint for the first token
291                    // Check if there is already a perfect match
292                    CommandExecutor::getInstance().functionclass_s = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
293                    CommandExecutor::getInstance().shortcut_s = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
294
295                    if ((CommandExecutor::getInstance().functionclass_s != 0) || (CommandExecutor::getInstance().shortcut_s != 0))
296                    {
297                        // Yes, there is a class or a shortcut with the searched name
298                        // Add a whitespace and continue parsing
299                        CommandExecutor::getInstance().state_s = CS_FunctionClass_Or_Shortcut_Or_Keyword;
300                        CommandExecutor::parse(command + " ", false);
301                        return;
302                    }
303
304                    // No perfect match: Create the lists of all possible classes and shortcuts and return
305                    CommandExecutor::createListOfPossibleFunctionClasses(CommandExecutor::getToken(0));
306                    CommandExecutor::createListOfPossibleShortcuts(CommandExecutor::getToken(0));
307                    return;
308                }
309                else
310                {
311                    // There is at least one argument: Check if it's a shortcut, a classname or a special keyword
312                    CommandExecutor::getInstance().state_s = CS_FunctionClass_Or_Shortcut_Or_Keyword;
313                    CommandExecutor::parse(command, false);
314                    return;
315                }
316                break;
317            case CS_FunctionClass_Or_Shortcut_Or_Keyword:
318                if (CommandExecutor::argumentsGiven() >= 1)
319                {
320                    if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
321                    {
322                        // We want to set a config value
323                        CommandExecutor::getInstance().state_s = CS_ConfigValueClass;
324                        CommandExecutor::parse(command, false);
325                        return;
326                    }
327                    else if (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
328                    {
329                        // We want to set a keybinding
330                        CommandExecutor::getInstance().state_s = CS_KeybindKey;
331                        CommandExecutor::parse(command, false);
332                        return;
333                    }
334
335                    if (CommandExecutor::getInstance().functionclass_s == 0)
336                        CommandExecutor::getInstance().functionclass_s = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
337                    if (CommandExecutor::getInstance().shortcut_s == 0)
338                        CommandExecutor::getInstance().shortcut_s = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
339
340                    if ((CommandExecutor::getInstance().functionclass_s == 0) && (CommandExecutor::getInstance().shortcut_s == 0))
341                    {
342                        // Argument 1 seems to be wrong
343                        AddLanguageEntry("CommandExecutor::NoSuchCommandOrClassName", "No such command or classname");
344                        CommandExecutor::getInstance().errorMessage_s = (CommandExecutor::getToken(0) + ": " + GetLocalisation("CommandExecutor::NoSuchCommandOrClassName"));
345                        CommandExecutor::getInstance().state_s = CS_Error;
346                        return;
347                    }
348                    else if (CommandExecutor::getInstance().shortcut_s != 0)
349                    {
350                        // Argument 1 is a shortcut: Return the needed parameter types
351                        CommandExecutor::getInstance().state_s = CS_Shortcut_Params;
352                        CommandExecutor::parse(command, false);
353                        return;
354                    }
355                    else
356                    {
357                        // Argument 1 is a classname: Return the possible functions
358                        CommandExecutor::getInstance().state_s = CS_Function;
359                        CommandExecutor::parse(command, false);
360                        return;
361                    }
362                }
363                else
364                {
365                    CommandExecutor::getInstance().state_s = CS_Error;
366                    return;
367                }
368                break;
369            case CS_Shortcut_Params:
370                if (CommandExecutor::getInstance().shortcut_s != 0)
371                {
372                    // Valid command
373                    // Check if there are enough parameters
374                    if (CommandExecutor::enoughParametersGiven(1, CommandExecutor::getInstance().shortcut_s))
375                    {
376                        CommandExecutor::getInstance().state_s = CS_Shortcut_Finished;
377                        return;
378                    }
379                }
380                else
381                {
382                    // Something is wrong
383                    CommandExecutor::getInstance().state_s = CS_Error;
384                    return;
385                }
386                break;
387            case CS_Function:
388                if (CommandExecutor::getInstance().functionclass_s != 0)
389                {
390                    // We have a valid classname
391                    // Check if there is a second argument
392                    if (CommandExecutor::argumentsGiven() >= 2)
393                    {
394                        // There is a second argument: Check if it's a valid functionname
395                        CommandExecutor::getInstance().function_s = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getInstance().functionclass_s);
396                        if (CommandExecutor::getInstance().function_s == 0)
397                        {
398                            // Argument 2 seems to be wrong
399                            AddLanguageEntry("CommandExecutor::NoSuchFunctionnameIn", "No such functionname in");
400                            CommandExecutor::getInstance().errorMessage_s = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchFunctionnameIn") + " " + CommandExecutor::getInstance().functionclass_s->getName());
401                            CommandExecutor::getInstance().state_s = CS_Error;
402                            return;
403                        }
404                        else
405                        {
406                            // Argument 2 seems to be a valid functionname: Get the parameters
407                            CommandExecutor::getInstance().state_s = CS_Function_Params;
408                            CommandExecutor::parse(command, false);
409                            return;
410                        }
411                    }
412                    else
413                    {
414                        // There is no finished second argument
415                        // Check if there's already a perfect match
416                        if (CommandExecutor::getInstance().tokens_s.size() >= 2)
417                        {
418                            CommandExecutor::getInstance().function_s = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getInstance().functionclass_s);
419                            if (CommandExecutor::getInstance().function_s != 0)
420                            {
421                                // There is a perfect match: Add a whitespace and continue parsing
422                                CommandExecutor::getInstance().state_s = CS_Function_Params;
423                                CommandExecutor::parse(command + " ", false);
424                                return;
425                            }
426                        }
427
428                        // No perfect match: Create the list of all possible functions and return
429                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getToken(1), CommandExecutor::getInstance().functionclass_s);
430                        return;
431                    }
432                }
433                else
434                {
435                    CommandExecutor::getInstance().state_s = CS_Error;
436                    return;
437                }
438                break;
439            case CS_Function_Params:
440                if ((CommandExecutor::getInstance().functionclass_s != 0) && (CommandExecutor::getInstance().function_s != 0))
441                {
442                    // Valid command
443                    // Check if there are enough parameters
444                    if (CommandExecutor::enoughParametersGiven(2, CommandExecutor::getInstance().function_s))
445                    {
446                        CommandExecutor::getInstance().state_s = CS_Function_Finished;
447                        return;
448                    }
449                }
450                else
451                {
452                    // Something is wrong
453                    CommandExecutor::getInstance().state_s = CS_Error;
454                    return;
455                }
456                break;
457            case CS_ConfigValueClass:
458                if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)))
459                {
460                    // We want to set a config value
461                    // Check if there is a second argument
462                    if (CommandExecutor::argumentsGiven() >= 2)
463                    {
464                        // There is a second argument: Check if it's a valid classname
465                        CommandExecutor::getInstance().configvalueclass_s = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
466                        if (CommandExecutor::getInstance().configvalueclass_s == 0)
467                        {
468                            // Argument 2 seems to be wrong
469                            AddLanguageEntry("CommandExecutor::NoSuchClassWithConfigValues", "No such class with config values");
470                            CommandExecutor::getInstance().errorMessage_s = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchClassWithConfigValues"));
471                            CommandExecutor::getInstance().state_s = CS_Error;
472                            return;
473                        }
474                        else
475                        {
476                            // Argument 2 seems to be a valid classname: Search for possible config values
477                            CommandExecutor::getInstance().state_s = CS_ConfigValue;
478                            CommandExecutor::parse(command, false);
479                            return;
480                        }
481                    }
482                    else
483                    {
484                        // There's no finished second argument
485                        // Check if there's already a perfect match
486                        if (CommandExecutor::getInstance().tokens_s.size() >= 2)
487                        {
488                            CommandExecutor::getInstance().configvalueclass_s = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
489                            if (CommandExecutor::getInstance().configvalueclass_s != 0)
490                            {
491                                // There is a perfect match: Add a whitespace and continue parsing
492                                CommandExecutor::getInstance().state_s = CS_ConfigValue;
493                                CommandExecutor::parse(command + " ", false);
494                                return;
495                            }
496                        }
497
498                        // No perfect match: Create the list of all possible classnames and return
499                        CommandExecutor::createListOfPossibleConfigValueClasses(CommandExecutor::getToken(1));
500                        return;
501                    }
502                }
503                else
504                {
505                    // Something is wrong
506                    CommandExecutor::getInstance().state_s = CS_Error;
507                    return;
508                }
509                break;
510            case CS_ConfigValue:
511                if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && (CommandExecutor::getInstance().configvalueclass_s != 0))
512                {
513                    // Check if there is a third argument
514                    if (CommandExecutor::argumentsGiven() >= 3)
515                    {
516                        // There is a third argument: Check if it's a valid config value
517                        CommandExecutor::getInstance().configvalue_s = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getInstance().configvalueclass_s);
518                        if (CommandExecutor::getInstance().configvalue_s == 0)
519                        {
520                            // Argument 3 seems to be wrong
521                            AddLanguageEntry("CommandExecutor::NoSuchConfigValueIn", "No such config value in");
522                            CommandExecutor::getInstance().errorMessage_s = (CommandExecutor::getToken(2) + ": " + GetLocalisation("CommandExecutor::NoSuchConfigValueIn") + " " + CommandExecutor::getInstance().configvalueclass_s->getName());
523                            CommandExecutor::getInstance().state_s = CS_Error;
524                            return;
525                        }
526                        else
527                        {
528                            // Argument 3 seems to be a valid config value: Get the type
529                            CommandExecutor::getInstance().state_s = CS_ConfigValueType;
530                            CommandExecutor::parse(command, false);
531                            return;
532                        }
533                    }
534                    else
535                    {
536                        // There is no finished third argument
537                        // Check if there's already a perfect match
538                        if (CommandExecutor::getInstance().tokens_s.size() >= 3)
539                        {
540                            CommandExecutor::getInstance().configvalue_s = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getInstance().configvalueclass_s);
541                            if (CommandExecutor::getInstance().configvalueclass_s != 0)
542                            {
543                                // There is a perfect match: Add a whitespace and continue parsing
544                                CommandExecutor::getInstance().state_s = CS_ConfigValueType;
545                                CommandExecutor::parse(command + " ", false);
546                                return;
547                            }
548                        }
549
550                        // No perfect match: Create the list of all possible config values
551                        CommandExecutor::createListOfPossibleConfigValues(CommandExecutor::getToken(2), CommandExecutor::getInstance().configvalueclass_s);
552                        return;
553                    }
554                }
555                else
556                {
557                    // Something is wrong
558                    CommandExecutor::getInstance().state_s = CS_Error;
559                    return;
560                }
561                break;
562            case CS_ConfigValueType:
563                if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && (CommandExecutor::getInstance().configvalueclass_s != 0) && (CommandExecutor::getInstance().configvalue_s != 0))
564                {
565                    // Valid command
566                    // Check if there are enough parameters
567                    if (CommandExecutor::getInstance().tokens_s.size() >= 4)
568                    {
569                        CommandExecutor::getInstance().state_s = CS_ConfigValueFinished;
570                        return;
571                    }
572                }
573                else
574                {
575                    // Something is wrong
576                    CommandExecutor::getInstance().state_s = CS_Error;
577                    return;
578                }
579                break;
580            case CS_KeybindKey:
581                if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
582                {
583                    // todo
584                }
585                else
586                {
587                    // Something is wrong
588                    CommandExecutor::getInstance().state_s = CS_Error;
589                    return;
590                }
591                break;
592            case CS_KeybindCommand:
593                if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) && (false)) // todo
594                {
595                    // Valid command
596                    // Check if there are enough parameters
597                    if (CommandExecutor::getInstance().tokens_s.size() >= 3)
598                    {
599                        CommandExecutor::getInstance().state_s = CS_KeybindFinished;
600                        return;
601                    }
602
603                }
604                else
605                {
606                    // Something is wrong
607                    CommandExecutor::getInstance().state_s = CS_Error;
608                    return;
609                }
610                break;
611            case CS_Shortcut_Finished:
612                // Nothing to do
613                break;
614            case CS_Function_Finished:
615                // Nothing to do
616                break;
617            case CS_ConfigValueFinished:
618                // Nothing to do
619                break;
620            case CS_KeybindFinished:
621                // Nothing to do
622                break;
623            case CS_Error:
624                // This is bad
625                break;
626        }
627    }
628
629    void CommandExecutor::initialize()
630    {
631        CommandExecutor::getInstance().listOfPossibleFunctionClasses_s.clear();
632        CommandExecutor::getInstance().listOfPossibleShortcuts_s.clear();
633        CommandExecutor::getInstance().listOfPossibleFunctions_s.clear();
634        CommandExecutor::getInstance().listOfPossibleConfigValueClasses_s.clear();
635        CommandExecutor::getInstance().listOfPossibleConfigValues_s.clear();
636        CommandExecutor::getInstance().listOfPossibleKeys_s.clear();
637
638        CommandExecutor::getInstance().functionclass_s = 0;
639        CommandExecutor::getInstance().configvalueclass_s = 0;
640        CommandExecutor::getInstance().shortcut_s = 0;
641        CommandExecutor::getInstance().function_s = 0;
642        CommandExecutor::getInstance().configvalue_s = 0;
643        CommandExecutor::getInstance().key_s = 0;
644
645        CommandExecutor::getInstance().errorMessage_s = "";
646        CommandExecutor::getInstance().state_s = CS_Empty;
647    }
648
649    bool CommandExecutor::argumentsGiven(unsigned int num)
650    {
651        // Because we added a cursor we have +1 arguments
652        // There are num arguments given if there are at least num arguments + one cursor
653        return (CommandExecutor::getInstance().tokens_s.size() >= (num + 1));
654    }
655
656    unsigned int CommandExecutor::argumentsGiven()
657    {
658        // Because we added a cursor we have +1 arguments
659        if (CommandExecutor::getInstance().tokens_s.size() >= 1)
660            return (CommandExecutor::getInstance().tokens_s.size() - 1);
661        else
662            return 0;
663    }
664
665    std::string CommandExecutor::getToken(unsigned int index)
666    {
667        if ((index >= 0) && (index < (CommandExecutor::getInstance().tokens_s.size() - 1)))
668            return CommandExecutor::getInstance().tokens_s[index];
669        else if (index == (CommandExecutor::getInstance().tokens_s.size() - 1))
670            return CommandExecutor::getInstance().tokens_s[index].substr(0, CommandExecutor::getInstance().tokens_s[index].size() - 1);
671        else
672            return "";
673    }
674
675    bool CommandExecutor::enoughParametersGiven(unsigned int head, Executor* executor)
676    {
677        unsigned int neededParams = head + executor->getParamCount();
678        for (unsigned int i = executor->getParamCount() - 1; i >= 0; i--)
679        {
680            if (executor->defaultValueSet(i))
681                neededParams--;
682            else
683                break;
684        }
685        return (CommandExecutor::getInstance().tokens_s.size() >= neededParams);
686    }
687
688    void CommandExecutor::createListOfPossibleFunctionClasses(const std::string& fragment)
689    {
690        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
691        {
692            if ((*it).second->hasConsoleCommands())
693            {
694                if ((*it).first.find(getLowercase(fragment)) == 0)
695                {
696                    CommandExecutor::getInstance().listOfPossibleFunctionClasses_s.push_back(&(*it).first);
697                }
698            }
699        }
700
701        CommandExecutor::getInstance().listOfPossibleFunctionClasses_s.sort(CommandExecutor::compareStringsInList);
702    }
703
704    void CommandExecutor::createListOfPossibleShortcuts(const std::string& fragment)
705    {
706        for (std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
707        {
708            if ((*it).first.find(getLowercase(fragment)) == 0)
709            {
710                CommandExecutor::getInstance().listOfPossibleShortcuts_s.push_back(&(*it).first);
711            }
712        }
713
714        CommandExecutor::getInstance().listOfPossibleShortcuts_s.sort(CommandExecutor::compareStringsInList);
715    }
716
717    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
718    {
719        for (std::map<std::string, ExecutorStatic*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
720        {
721            if ((*it).first.find(getLowercase(fragment)) == 0)
722            {
723                CommandExecutor::getInstance().listOfPossibleFunctions_s.push_back(&(*it).first);
724            }
725        }
726
727        CommandExecutor::getInstance().listOfPossibleFunctions_s.sort(CommandExecutor::compareStringsInList);
728    }
729
730    void CommandExecutor::createListOfPossibleConfigValueClasses(const std::string& fragment)
731    {
732        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
733        {
734            if ((*it).second->hasConfigValues())
735            {
736                if ((*it).first.find(getLowercase(fragment)) == 0)
737                {
738                    CommandExecutor::getInstance().listOfPossibleConfigValueClasses_s.push_back(&(*it).first);
739                }
740            }
741        }
742
743        CommandExecutor::getInstance().listOfPossibleConfigValueClasses_s.sort(CommandExecutor::compareStringsInList);
744    }
745
746    void CommandExecutor::createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier)
747    {
748        for (std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMapBegin(); it != identifier->getLowercaseConfigValueMapEnd(); ++it)
749        {
750            if ((*it).first.find(getLowercase(fragment)) == 0)
751            {
752                CommandExecutor::getInstance().listOfPossibleConfigValues_s.push_back(&(*it).first);
753            }
754        }
755
756        CommandExecutor::getInstance().listOfPossibleConfigValues_s.sort(CommandExecutor::compareStringsInList);
757    }
758
759    void CommandExecutor::createListOfPossibleKeys(const std::string& fragment)
760    {
761        // todo
762
763        CommandExecutor::getInstance().listOfPossibleKeys_s.sort(CommandExecutor::compareStringsInList);
764    }
765
766    bool CommandExecutor::compareStringsInList(const std::string* first, const std::string* second)
767    {
768        return ((*first) < (*second));
769    }
770
771    Identifier* CommandExecutor::getIdentifierOfPossibleFunctionClass(const std::string& name)
772    {
773        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
774        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
775            return (*it).second;
776
777        return 0;
778    }
779
780    ExecutorStatic* CommandExecutor::getExecutorOfPossibleShortcut(const std::string& name)
781    {
782        std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(getLowercase(name));
783        if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
784            return (*it).second;
785
786        return 0;
787    }
788
789    ExecutorStatic* CommandExecutor::getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier)
790    {
791        std::map<std::string, ExecutorStatic*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(getLowercase(name));
792        if (it != identifier->getLowercaseConsoleCommandMapEnd())
793            return (*it).second;
794
795        return 0;
796    }
797
798    Identifier* CommandExecutor::getIdentifierOfPossibleConfigValueClass(const std::string& name)
799    {
800        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
801        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConfigValues())
802            return (*it).second;
803
804        return 0;
805    }
806
807    ConfigValueContainer* CommandExecutor::getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier)
808    {
809        std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMap().find(getLowercase(name));
810        if (it != identifier->getLowercaseConfigValueMapEnd())
811            return (*it).second;
812
813        return 0;
814    }
815
816    ConfigValueContainer* CommandExecutor::getContainerOfPossibleKey(const std::string& name)
817    {
818        // todo
819
820        return 0;
821    }
822
823    std::string CommandExecutor::dump(const std::list<const std::string*>& list)
824    {
825        std::string output = "";
826        for (std::list<const std::string*>::const_iterator it = list.begin(); it != list.end(); ++it)
827        {
828            if (it != list.begin())
829                output += " ";
830
831            output += (**it);
832        }
833        return output;
834    }
835
836    std::string CommandExecutor::dump(const ExecutorStatic* executor)
837    {
838        std::string output = "";
839        for (unsigned int i = 0; i < executor->getParamCount(); i++)
840        {
841            if (i != 0)
842                output += " ";
843
844            if (executor->defaultValueSet(i))
845                output += "[";
846            else
847                output += "{";
848
849            output += executor->getTypenameParam(i);
850
851            if (executor->defaultValueSet(i))
852                output += "]";
853            else
854                output += "}";
855        }
856        return output;
857    }
858
859    std::string CommandExecutor::dump(const ConfigValueContainer* container)
860    {
861        return container->getTypename();
862    }
863
864    std::string CommandExecutor::getCommonBegin(const std::list<const std::string*>& list)
865    {
866        if (list.size() == 0)
867        {
868            return "";
869        }
870        else if (list.size() == 1)
871        {
872            return ((**list.begin()) + " ");
873        }
874        else
875        {
876            std::string output = "";
877            for (unsigned int i = 0; true; i++)
878            {
879                char temp = 0;
880                for (std::list<const std::string*>::const_iterator it = list.begin(); it != list.end(); ++it)
881                {
882                    if ((**it).size() > i)
883                    {
884                        if (it == list.begin())
885                        {
886                            temp = (**it)[i];
887                        }
888                        else
889                        {
890                            if (temp != (**it)[i])
891                                return output;
892                        }
893                    }
894                    else
895                    {
896                        return output;
897                    }
898                }
899                output += temp;
900            }
901            return output;
902        }
903    }
904}
Note: See TracBrowser for help on using the repository browser.