Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/CommandExecutor.cc @ 3131

Last change on this file since 3131 was 3035, checked in by landauf, 15 years ago

get returnvalue shortcuts in CommandExecutor (for tolua)

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