Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/particles2/src/libraries/core/CommandExecutor.cc @ 6372

Last change on this file since 6372 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

  • Property svn:eol-style set to native
File size: 30.7 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
31#include "util/Debug.h"
32#include "util/StringUtils.h"
33#include "ConsoleCommand.h"
34#include "Identifier.h"
35#include "Language.h"
36#include "TclBind.h"
37
38namespace orxonox
39{
40    CommandExecutor& CommandExecutor::getInstance()
41    {
42        static CommandExecutor instance;
43        return instance;
44    }
45
46    CommandEvaluation& CommandExecutor::getEvaluation()
47    {
48        return CommandExecutor::getInstance().evaluation_;
49    }
50
51    const CommandEvaluation& CommandExecutor::getLastEvaluation()
52    {
53        return CommandExecutor::getInstance().evaluation_;
54    }
55
56    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command, bool bDeleteAtExit)
57    {
58        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(command->getName());
59        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
60        {
61            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << "." << std::endl;
62        }
63
64        // Make sure we can also delete the external ConsoleCommands that don't belong to an Identifier
65        if (command && bDeleteAtExit)
66        {
67            CommandExecutor::getInstance().consoleCommandExternals_.insert(command);
68        }
69
70        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
71        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
72        return (*command);
73    }
74
75    /**
76        @brief Returns the executor of a console command shortcut with given name.
77        @brief name The name of the requested console command shortcut
78        @return The executor of the requested console command shortcut
79    */
80    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
81    {
82        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
83        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
84            return (*it).second;
85        else
86            return 0;
87    }
88
89    /**
90        @brief Returns the executor of a console command shortcut with given name in lowercase.
91        @brief name The name of the requested console command shortcut in lowercase
92        @return The executor of the requested console command shortcut
93    */
94    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
95    {
96        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
97        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
98            return (*it).second;
99        else
100            return 0;
101    }
102
103    bool CommandExecutor::execute(const std::string& command, bool useTcl)
104    {
105        if (useTcl)
106            return TclBind::eval(command);
107
108        CommandExecutor::parseIfNeeded(command);
109        return CommandExecutor::getEvaluation().execute();
110    }
111
112    MultiType CommandExecutor::getReturnValue()
113    {
114        return CommandExecutor::getEvaluation().getReturnvalue();
115    }
116
117    std::string CommandExecutor::getReturnValueString()
118    {
119        return CommandExecutor::getEvaluation().getReturnvalue().getString();
120    }
121
122    std::string CommandExecutor::complete(const std::string& command)
123    {
124        CommandExecutor::parseIfNeeded(command);
125        return CommandExecutor::getEvaluation().complete();
126    }
127
128    std::string CommandExecutor::hint(const std::string& command)
129    {
130        CommandExecutor::parseIfNeeded(command);
131        return CommandExecutor::getEvaluation().hint();
132    }
133
134    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
135    {
136        CommandExecutor::parse(command);
137        CommandExecutor::getEvaluation().evaluateParams();
138        return CommandExecutor::getEvaluation();
139    }
140
141    void CommandExecutor::parseIfNeeded(const std::string& command)
142    {
143        if (CommandExecutor::getEvaluation().state_ == CommandState::Uninitialized)
144        {
145            CommandExecutor::parse(command);
146        }
147        else if (CommandExecutor::getEvaluation().originalCommand_ != command)
148        {
149            if (CommandExecutor::getEvaluation().command_ == command)
150            {
151                CommandExecutor::parse(command);
152                CommandExecutor::getEvaluation().bNewCommand_ = false;
153            }
154            else
155            {
156                CommandExecutor::parse(command);
157            }
158        }
159    }
160
161    void CommandExecutor::parse(const std::string& command, bool bInitialize)
162    {
163        if (bInitialize)
164            CommandExecutor::getEvaluation().initialize(command);
165
166        CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
167        CommandExecutor::getEvaluation().command_ = command;
168
169        switch (CommandExecutor::getEvaluation().state_)
170        {
171            case CommandState::Uninitialized:
172            {
173                // Impossible
174                break;
175            }
176            case CommandState::Empty:
177            {
178                if (CommandExecutor::argumentsGiven() == 0)
179                {
180                    CommandExecutor::createListOfPossibleFunctions("");
181                    CommandExecutor::createListOfPossibleIdentifiers("");
182                    break;
183                }
184                else
185                {
186                    CommandExecutor::getEvaluation().state_ = CommandState::ShortcutOrIdentifier;
187                    // Move on to next case
188                }
189            }
190            case CommandState::ShortcutOrIdentifier:
191            {
192                if (CommandExecutor::argumentsGiven() > 1)
193                {
194                    // There's a finished first argument - check if it's a shortcut or a classname
195                    CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
196                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
197
198                    if (CommandExecutor::getEvaluation().function_)
199                    {
200                        // It's a shortcut
201                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
202                        CommandExecutor::getEvaluation().functionclass_ = 0;
203                        // Move on to next case
204                    }
205                    else if (CommandExecutor::getEvaluation().functionclass_)
206                    {
207                        // It's a functionname
208                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
209                        CommandExecutor::getEvaluation().function_ = 0;
210                        // Move on to next case
211                    }
212                    else
213                    {
214                        // The first argument is bad
215                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
216                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
217                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
218                        return;
219                    }
220                }
221                else
222                {
223                    // There's no finished first argument - search possible shortcuts or classnames
224                    CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0));
225                    CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0));
226
227                    unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
228                    unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size();
229
230                    if (num_functions == 1 && num_identifiers == 0)
231                    {
232                        // It's a shortcut
233                        std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
234                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
235                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
236                        {
237                            // Unfinished shortcut
238                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
239                        }
240                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
241                        CommandExecutor::getEvaluation().functionclass_ = 0;
242                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
243                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
244                        {
245                            CommandExecutor::getEvaluation().command_ += " ";
246                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
247                        }
248                        // Move on to next case
249                    }
250                    else if (num_identifiers == 1 && num_functions == 0)
251                    {
252                        // It's a classname
253                        std::string classname = *(*CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()).first;
254                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
255                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
256                        {
257                            // Unfinished classname
258                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
259                        }
260                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
261                        CommandExecutor::getEvaluation().function_ = 0;
262                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
263                        // Move on to next case
264                    }
265                    else if (num_identifiers == 0 && num_functions == 0)
266                    {
267                        // No possibilities
268                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
269                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
270                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
271                        return;
272                    }
273                    else
274                    {
275                        // There are several possiblilities
276                        std::list<std::pair<const std::string*, const std::string*> > temp;
277                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end());
278                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end());
279                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp);
280                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
281                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
282                        CommandExecutor::getEvaluation().bCommandChanged_ = true;
283                        return;
284                    }
285                }
286            }
287            case CommandState::Function:
288            {
289                if (CommandExecutor::getEvaluation().functionclass_)
290                {
291                    // There is a classname - search for the commandname
292                    if (CommandExecutor::argumentsGiven() > 2)
293                    {
294                        // There is a finished second argument - check if it's a commandname
295                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
296
297                        if (CommandExecutor::getEvaluation().function_)
298                        {
299                            // It's a function
300                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
301                            // Move on to next case
302                        }
303                        else
304                        {
305                            // The second argument is bad
306                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
307                            AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of");
308                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + ".";
309                            return;
310                        }
311                    }
312                    else
313                    {
314                        // There is no finished second argument - search for possibilities
315                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
316                        unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
317
318                        if (num_functions == 1)
319                        {
320                            // It's a function
321                            std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
322                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
323                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
324                            {
325                                // Unfinished function
326                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
327                            }
328                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
329                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
330                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
331                            {
332                                CommandExecutor::getEvaluation().command_ += " ";
333                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
334                            }
335                            // Move on to next case
336                        }
337                        else if (num_functions == 0)
338                        {
339                            // No possibilities
340                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
341                            AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
342                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + ".";
343                            return;
344                        }
345                        else
346                        {
347                            // There are several possibilities
348                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
349                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
350                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
351                            return;
352                        }
353                    }
354                }
355                else
356                {
357                    // There is no classname - move on to CommandState::ParamPreparation
358                }
359            }
360            case CommandState::ParamPreparation:
361            {
362                if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_))
363                {
364                    CommandExecutor::getEvaluation().state_ = CommandState::Finished;
365                    return;
366                }
367                else
368                {
369                    unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2;
370                    if (CommandExecutor::getEvaluation().functionclass_)
371                        argumentNumber -= 1;
372
373                    CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
374                    CommandExecutor::getEvaluation().state_ = CommandState::Params;
375
376                    if (CommandExecutor::getEvaluation().bCommandChanged_)
377                    {
378                        // Don't do more than one change
379                        return;
380                    }
381                }
382            }
383            case CommandState::Params:
384            {
385                if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
386                {
387                    // There is exactly one possible argument
388                    CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
389                    CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
390                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
391                    return;
392                }
393                else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0)
394                {
395                    // The user tries something new - we let him do
396                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
397                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
398                    return;
399                }
400                else
401                {
402                    // There are several possibilities
403                    unsigned int argumentNumber = CommandExecutor::argumentsGiven();
404                    if (argumentNumber > 0)
405                        --argumentNumber;
406                    if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0)
407                        --argumentNumber;
408
409                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
410                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
411                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
412                    return;
413                }
414            }
415            case CommandState::Finished:
416            {
417                // Nothing more to do
418                break;
419            }
420            case CommandState::Error:
421            {
422                // Bad, very bad
423                break;
424            }
425        }
426    }
427
428    unsigned int CommandExecutor::argumentsFinished()
429    {
430        unsigned int argumentsGiven = CommandExecutor::argumentsGiven();
431        if (argumentsGiven > 0)
432            return argumentsGiven - 1;
433        else
434            return 0;
435    }
436
437    unsigned int CommandExecutor::argumentsGiven()
438    {
439        if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ')
440            return CommandExecutor::getEvaluation().commandTokens_.size() + 1;
441        else
442            return CommandExecutor::getEvaluation().commandTokens_.size();
443    }
444
445    bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command)
446    {
447        if (CommandExecutor::getEvaluation().functionclass_)
448            return (CommandExecutor::argumentsGiven() > (2 + command->getParamCount()));
449        else
450            return (CommandExecutor::argumentsGiven() > (1 + command->getParamCount()));
451    }
452
453    std::string CommandExecutor::getArgument(unsigned int index)
454    {
455        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
456            return CommandExecutor::getEvaluation().commandTokens_[index];
457        else
458            return "";
459    }
460
461    std::string CommandExecutor::getLastArgument()
462    {
463        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
464    }
465
466    void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment)
467    {
468        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
469        std::string lowercase = getLowercase(fragment);
470        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMapBegin(); it != Identifier::getLowercaseStringIdentifierMapEnd(); ++it)
471            if ((*it).second->hasConsoleCommands())
472                if ((*it).first.find(lowercase) == 0 || fragment == "")
473                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
474    }
475
476    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
477    {
478        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
479        std::string lowercase = getLowercase(fragment);
480        if (!identifier)
481        {
482            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
483                if ((*it).first.find(lowercase) == 0 || fragment == "")
484                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
485        }
486        else
487        {
488            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
489                if ((*it).first.find(lowercase) == 0 || fragment == "")
490                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
491        }
492    }
493
494    void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param)
495    {
496        CommandExecutor::createArgumentCompletionList(command, param);
497
498        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
499        std::string lowercase = getLowercase(fragment);
500        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
501        {
502            if ((*it).lowercaseComparison())
503            {
504                if ((*it).getComparable().find(lowercase) == 0 || fragment == "")
505                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
506            }
507            else
508            {
509                if ((*it).getComparable().find(fragment) == 0 || fragment == "")
510                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
511            }
512        }
513    }
514
515    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
516    {
517        std::string lowercase = getLowercase(name);
518        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMap().find(lowercase);
519        if ((it != Identifier::getLowercaseStringIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
520            return (*it).second;
521
522        return 0;
523    }
524
525    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
526    {
527        std::string lowercase = getLowercase(name);
528        if (!identifier)
529        {
530            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
531            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
532                return (*it).second;
533        }
534        else
535        {
536            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
537            if (it != identifier->getLowercaseConsoleCommandMapEnd())
538                return (*it).second;
539        }
540        return 0;
541    }
542
543    std::string CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
544    {
545        CommandExecutor::createArgumentCompletionList(command, param);
546
547        std::string lowercase = getLowercase(name);
548        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
549        {
550            if ((*it).lowercaseComparison())
551            {
552                if ((*it).getComparable() == lowercase)
553                    return (*it).getString();
554            }
555            else
556            {
557                if ((*it).getComparable() == name)
558                    return (*it).getString();
559            }
560        }
561
562        return "";
563    }
564
565    void CommandExecutor::createArgumentCompletionList(ConsoleCommand* command, unsigned int param)
566    {
567        std::string params[5];
568
569        unsigned int index = 0;
570        unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0);
571
572        for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i)
573        {
574            params[index] = CommandExecutor::getArgument(i);
575            ++index;
576            if (index >= 5)
577                break;
578        }
579
580        command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]);
581    }
582
583    std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list)
584    {
585        if (list.size() == 0)
586        {
587            return "";
588        }
589        else if (list.size() == 1)
590        {
591            return ((*(*list.begin()).first) + " ");
592        }
593        else
594        {
595            std::string output = "";
596            for (unsigned int i = 0; true; i++)
597            {
598                char temp = 0;
599                for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
600                {
601                    if ((*(*it).first).size() > i)
602                    {
603                        if (it == list.begin())
604                        {
605                            temp = (*(*it).first)[i];
606                        }
607                        else
608                        {
609                            if (temp != (*(*it).first)[i])
610                                return output;
611                        }
612                    }
613                    else
614                    {
615                        return output;
616                    }
617                }
618                output += temp;
619            }
620            return output;
621        }
622    }
623
624    std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list)
625    {
626        if (list.size() == 0)
627        {
628            return "";
629        }
630        else if (list.size() == 1)
631        {
632            return ((*list.begin()).getComparable() + " ");
633        }
634        else
635        {
636            std::string output = "";
637            for (unsigned int i = 0; true; i++)
638            {
639                char temp = 0;
640                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
641                {
642                    std::string argument = (*it).getComparable();
643                    if (argument.size() > i)
644                    {
645                        if (it == list.begin())
646                        {
647                            temp = argument[i];
648                        }
649                        else
650                        {
651                            if (temp != argument[i])
652                                return output;
653                        }
654                    }
655                    else
656                    {
657                        return output;
658                    }
659                }
660                output += temp;
661            }
662            return output;
663        }
664    }
665
666    void CommandExecutor::destroyExternalCommands()
667    {
668        for (std::set<ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandExternals_.begin();
669            it != CommandExecutor::getInstance().consoleCommandExternals_.end(); ++it)
670            delete *it;
671    }
672}
Note: See TracBrowser for help on using the repository browser.