Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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