Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/CommandExecutor.cc @ 7191

Last change on this file since 7191 was 7189, checked in by landauf, 14 years ago

changed passing of the returnvalue in the command execution pipeline:

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