Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/core/CommandExecutor.cc @ 1434

Last change on this file since 1434 was 1434, checked in by landauf, 16 years ago

autocompletion is almost done

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