Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation3/src/libraries/core/CommandExecutor.cc @ 7158

Last change on this file since 7158 was 6417, checked in by rgrieder, 15 years ago

Merged presentation2 branch back to trunk.
Major new features:

  • Actual GUI with settings, etc.
  • Improved space ship steering (human interaction)
  • Rocket fire and more particle effects
  • Advanced sound framework
  • Property svn:eol-style set to native
File size: 31.1 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                        const 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                        const 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                            const 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    const 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 BLANKSTRING;
459    }
460
461    const 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        const 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.empty())
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        const 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.empty())
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.empty())
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        const 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.empty())
505                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
506            }
507            else
508            {
509                if (it->getComparable().find(fragment) == 0 || fragment.empty())
510                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
511            }
512        }
513    }
514
515    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
516    {
517        const 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        const 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    const std::string& CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
544    {
545        CommandExecutor::createArgumentCompletionList(command, param);
546
547        const 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 BLANKSTRING;
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 tempComparable = 0;
640                char temp = 0;
641                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
642                {
643                    const std::string& argumentComparable = it->getComparable();
644                    const std::string& argument = it->getString();
645                    if (argument.size() > i)
646                    {
647                        if (it == list.begin())
648                        {
649                            tempComparable = argumentComparable[i];
650                            temp = argument[i];
651                        }
652                        else
653                        {
654                            if (tempComparable != argumentComparable[i])
655                                return output;
656                            else if (temp != argument[i])
657                                temp = tempComparable;
658                        }
659                    }
660                    else
661                    {
662                        return output;
663                    }
664                }
665                output += temp;
666            }
667            return output;
668        }
669    }
670
671    void CommandExecutor::destroyExternalCommands()
672    {
673        for (std::set<ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandExternals_.begin();
674            it != CommandExecutor::getInstance().consoleCommandExternals_.end(); ++it)
675            delete *it;
676    }
677}
Note: See TracBrowser for help on using the repository browser.