Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 27, 2010, 2:41:03 PM (14 years ago)
Author:
landauf
Message:

re-implemented CommandExecutor and CommandEvaluation. parameter evaluation is currently not implemented, will come soon.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/consolecommands3/src/libraries/core/command/CommandEvaluation.cc

    r7221 r7228  
    2929#include "CommandEvaluation.h"
    3030
    31 #include "util/Debug.h"
    3231#include "util/StringUtils.h"
    33 #include "core/Identifier.h"
     32#include "CommandExecutor.h"
    3433#include "ConsoleCommand.h"
    3534
     
    3938    {
    4039        this->initialize("");
    41         this->state_ = CommandState::Uninitialized;
    4240    }
    4341
    4442    void CommandEvaluation::initialize(const std::string& command)
    4543    {
    46         this->bNewCommand_ = true;
    47         this->bCommandChanged_ = false;
    48         this->originalCommand_ = command;
    49         this->command_ = command;
    50         this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    51 
    52         this->additionalParameter_.clear();
    53 
    54         this->bEvaluatedParams_ = false;
    55 
    56         this->listOfPossibleIdentifiers_.clear();
    57         this->listOfPossibleFunctions_.clear();
    58         this->listOfPossibleArguments_.clear();
    59 
    60         this->functionclass_ = 0;
    61         this->function_ = 0;
    62         this->possibleArgument_.clear();
    63         this->argument_.clear();
    64 
    65         this->errorMessage_.clear();
    66         this->state_ = CommandState::Empty;
    67     }
    68 
    69     bool CommandEvaluation::execute() const
    70     {
    71         bool success;
    72         this->query(&success);
    73         return success;
    74     }
    75 
    76     MultiType CommandEvaluation::query(bool* success) const
    77     {
    78         if (success)
    79             *success = false;
    80 
    81         if (!this->function_ || !this->function_->isActive())
     44        this->execCommand_ = 0;
     45        this->hintCommand_ = 0;
     46        this->string_ = command;
     47        this->execArgumentsOffset_ = 0;
     48        this->hintArgumentsOffset_ = 0;
     49        this->bPossibleArgumentsRetrieved_ = false;
     50        this->possibleArguments_.clear();
     51
     52        this->tokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
     53    }
     54
     55    unsigned int CommandEvaluation::getNumberOfArguments() const
     56    {
     57        unsigned int count = this->tokens_.size();
     58        if (count > 0 && this->string_[this->string_.size() - 1] != ' ')
     59            return count;
     60        else
     61            return count + 1;
     62    }
     63
     64    const std::string& CommandEvaluation::getLastArgument() const
     65    {
     66        if (this->tokens_.size() > 0 && this->string_[this->string_.size() - 1] != ' ')
     67            return this->tokens_.back();
     68        else
     69            return BLANKSTRING;
     70    }
     71
     72    const std::string& CommandEvaluation::getToken(unsigned int i) const
     73    {
     74        if (i < this->tokens_.size())
     75            return this->tokens_[i];
     76        else
     77            return BLANKSTRING;
     78    }
     79
     80    int CommandEvaluation::execute() const
     81    {
     82        int error;
     83        this->query(&error);
     84        return error;
     85    }
     86
     87    MultiType CommandEvaluation::query(int* error) const
     88    {
     89        if (error)
     90        {
     91            *error = CommandExecutor::Success;
     92
     93            if (!this->execCommand_)
     94                *error = CommandExecutor::Error;
     95            else if (!this->execCommand_->isActive())
     96                *error = CommandExecutor::Deactivated;
     97            else if (!this->execCommand_->hasAccess())
     98                *error = CommandExecutor::Denied;
     99
     100            if (*error != CommandExecutor::Success)
     101                return MT_Type::Null;
     102        }
     103
     104        if (this->execCommand_ && this->execCommand_->isActive() && this->execCommand_->hasAccess())
     105            return this->execCommand_->getExecutor()->parse(this->tokens_.subSet(this->execArgumentsOffset_).join(), error, " ", false);
     106        else
    82107            return MT_Type::Null;
    83 
    84         if (this->bEvaluatedParams_ && this->function_)
    85         {
    86             if (success)
    87                 *success = true;
    88             COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << ' ' << this->param_[0] << ' ' << this->param_[1] << ' ' << this->param_[2] << ' ' << this->param_[3] << ' ' << this->param_[4] << std::endl;
    89             return (*this->function_->getExecutor())(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
    90         }
    91 
    92         if (!this->bCommandChanged_ || nocaseCmp(removeTrailingWhitespaces(this->command_), removeTrailingWhitespaces(this->originalCommand_)) == 0)
    93         {
    94             COUT(4) << "CE_execute: " << this->command_ << "\n";
    95 
    96             unsigned int startindex = this->getStartindex();
    97             if (this->commandTokens_.size() > startindex)
    98                 return this->function_->getExecutor()->parse(removeSlashes(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter()), success);
    99             else
    100                 return this->function_->getExecutor()->parse(removeSlashes(this->additionalParameter_), success);
    101         }
    102 
    103         return MT_Type::Null;
    104     }
    105 
    106     const std::string& CommandEvaluation::complete()
    107     {
    108         if (!this->bNewCommand_)
    109         {
    110             switch (this->state_)
    111             {
    112                 case CommandState::Uninitialized:
    113                     break;
    114                 case CommandState::Empty:
    115                     break;
    116                 case CommandState::ShortcutOrIdentifier:
    117                     if (this->function_)
     108    }
     109
     110    std::string CommandEvaluation::complete() const
     111    {
     112        if (!this->hintCommand_ || !this->hintCommand_->isActive())
     113            return this->string_;
     114
     115        if (!this->bPossibleArgumentsRetrieved_)
     116            this->retrievePossibleArguments();
     117
     118        if (this->possibleArguments_.empty())
     119        {
     120            return this->string_;
     121        }
     122        else
     123        {
     124            std::string output;
     125            for (unsigned int i = 0; i < this->getNumberOfArguments() - 1; ++i)
     126                output += this->getToken(i) + ' ';
     127
     128            output += CommandEvaluation::getCommonBegin(this->possibleArguments_);
     129            return output;
     130        }
     131    }
     132
     133    std::string CommandEvaluation::hint() const
     134    {
     135        if (!this->hintCommand_ || !this->hintCommand_->isActive())
     136            return "";
     137
     138        if (!this->bPossibleArgumentsRetrieved_)
     139            this->retrievePossibleArguments();
     140
     141        if (!this->possibleArguments_.empty())
     142            return CommandEvaluation::dump(this->possibleArguments_);
     143
     144        if (this->isValid())
     145        {
     146            return CommandEvaluation::dump(this->hintCommand_);
     147        }
     148        else
     149        {
     150            if (this->getNumberOfArguments() > 2)
     151            {
     152                return std::string("Error: There is no command with name \"") + this->getToken(0) + " " + this->getToken(1) + "\".";
     153            }
     154            else
     155            {
     156                std::string groupLC = getLowercase(this->getToken(0));
     157                std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommands().begin();
     158                for ( ; it_group != _ConsoleCommand::getCommands().end(); ++it_group)
     159                    if (getLowercase(it_group->first) == groupLC)
     160                        return std::string("Error: There is no command in group \"") + this->getToken(0) + "\" starting with \"" + this->getToken(1) + "\".";
     161
     162                return std::string("Error: There is no command starting with \"") + this->getToken(0) + "\".";
     163            }
     164        }
     165    }
     166
     167    void CommandEvaluation::retrievePossibleArguments() const
     168    {
     169        this->bPossibleArgumentsRetrieved_ = true;
     170        unsigned int argumentID = std::min(this->getNumberOfArguments() - this->hintArgumentsOffset_, this->hintCommand_->getExecutor()->getParamCount());
     171        ArgumentCompleter* ac = this->hintCommand_->getArgumentCompleter(argumentID - 1);
     172
     173COUT(0) << "hint: args: " << this->getNumberOfArguments() << ", aID: " << argumentID << ", offset: " << this->hintArgumentsOffset_ << ", ac: " << ac << std::endl;
     174        if (ac)
     175        {
     176            MultiType param[MAX_FUNCTOR_ARGUMENTS];
     177
     178            for (size_t i = 0; i < argumentID; ++i)
     179            {
     180                param[i] = this->getToken(this->getNumberOfArguments() - i - 1);
     181COUT(0) << i << ": " << (this->getNumberOfArguments() - i - 1) << " -> " << this->getToken(this->getNumberOfArguments() - i - 1) << " / " << param[i] << std::endl;
     182            }
     183
     184COUT(0) << "hint: 1: " << param[0] << ", 2: " << param[1] << ", 3: " << param[2] << ", 4: " << param[3] << ", 5: " << param[4] << std::endl;
     185            this->possibleArguments_ = (*ac)(param[0], param[1], param[2], param[3], param[4]);
     186
     187            CommandEvaluation::strip(this->possibleArguments_, param[0]);
     188        }
     189    }
     190
     191    /* static */ void CommandEvaluation::strip(ArgumentCompletionList& list, const std::string& fragment)
     192    {
     193        std::string fragmentLC = getLowercase(fragment);
     194
     195        for (ArgumentCompletionList::iterator it = list.begin(); it != list.end(); )
     196        {
     197            const std::string& entry = it->getComparable();
     198
     199            if (entry.size() < fragmentLC.size())
     200            {
     201                list.erase(it++);
     202            }
     203            else
     204            {
     205                bool bErase = false;
     206                for (size_t i = 0; i < fragmentLC.size(); ++i)
     207                {
     208                    if (fragmentLC[i] != entry[i])
    118209                    {
    119                         if (this->function_->getExecutor()->getParamCount() == 0)
    120                             return (this->command_ = this->function_->getName());
    121                         else
    122                             return (this->command_ = this->function_->getName() + ' ');
     210                        bErase = true;
     211                        break;
    123212                    }
    124                     else if (this->functionclass_)
    125                         return (this->command_ = this->functionclass_->getName() + ' ');
    126                     break;
    127                 case CommandState::Function:
    128                     if (this->function_)
    129                     {
    130                         if (this->function_->getExecutor()->getParamCount() == 0)
    131                             return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName());
    132                         else
    133                             return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName() + ' ');
    134                     }
    135                     break;
    136                 case CommandState::ParamPreparation:
    137                 case CommandState::Params:
    138                 {
    139                     if (this->argument_.empty() && this->possibleArgument_.empty())
    140                         break;
    141 
    142                     unsigned int maxIndex = this->commandTokens_.size();
    143                     if (this->command_[this->command_.size() - 1] != ' ')
    144                         maxIndex -= 1;
    145                     std::string whitespace;
    146 
    147                     if (!this->possibleArgument_.empty())
    148                     {
    149                         this->argument_ = this->possibleArgument_;
    150                         if (this->function_->getExecutor()->getParamCount() > (maxIndex + 1 - this->getStartindex()))
    151                             whitespace = " ";
    152                     }
    153 
    154                     return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + ' ' + this->argument_ + whitespace);
    155                     break;
    156213                }
    157                 case CommandState::Finished:
    158                     break;
    159                 case CommandState::Error:
    160                     break;
    161             }
    162         }
    163         this->bNewCommand_ = false;
    164         return this->command_;
    165     }
    166 
    167     std::string CommandEvaluation::hint() const
    168     {
    169         switch (this->state_)
    170         {
    171             case CommandState::Uninitialized:
    172                 break;
    173             case CommandState::Empty:
    174             case CommandState::ShortcutOrIdentifier:
    175                 if (this->listOfPossibleFunctions_.size() == 0)
    176                     return CommandEvaluation::dump(this->listOfPossibleIdentifiers_);
    177                 else if (this->listOfPossibleIdentifiers_.size() == 0)
    178                     return CommandEvaluation::dump(this->listOfPossibleFunctions_);
     214
     215                if (bErase)
     216                    list.erase(it++);
    179217                else
    180                     return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_));
    181                 break;
    182             case CommandState::Function:
    183                 return CommandEvaluation::dump(this->listOfPossibleFunctions_);
    184                 break;
    185             case CommandState::ParamPreparation:
    186             case CommandState::Params:
    187                 if (this->listOfPossibleArguments_.size() > 0)
    188                     return CommandEvaluation::dump(this->listOfPossibleArguments_);
    189                 else
    190                     return CommandEvaluation::dump(this->function_);
    191             case CommandState::Finished:
    192                 if (this->function_)
    193                     return CommandEvaluation::dump(this->function_);
    194                 break;
    195             case CommandState::Error:
    196                 return this->errorMessage_;
    197                 break;
    198         }
    199 
    200         return "";
    201     }
    202 
    203     void CommandEvaluation::evaluateParams()
    204     {
    205         this->bEvaluatedParams_ = false;
    206 
    207         for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
    208             this->param_[i] = MT_Type::Null;
    209 
    210         if (!this->function_)
    211             return;
    212 
    213         unsigned int startindex = this->getStartindex();
    214 
    215         if (this->commandTokens_.size() <= startindex)
    216         {
    217             if (this->function_->getBaseExecutor()->evaluate(this->getAdditionalParameter(), this->param_, " "))
    218                 this->bEvaluatedParams_ = true;
    219         }
    220         else if (this->commandTokens_.size() > startindex)
    221         {
    222             if (this->function_->getBaseExecutor()->evaluate(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter(), this->param_, " "))
    223                 this->bEvaluatedParams_ = true;
    224         }
    225     }
    226 
    227     void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiType param)
    228     {
    229         if (index < MAX_FUNCTOR_ARGUMENTS)
    230             this->param_[index] = param;
    231     }
    232 
    233     MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const
    234     {
    235         if (index < MAX_FUNCTOR_ARGUMENTS)
    236             return this->param_[index];
    237 
    238         return MT_Type::Null;
    239     }
    240 
    241     unsigned int CommandEvaluation::getStartindex() const
    242     {
    243         if (this->functionclass_ && this->function_)
    244             return 2;
    245         else if (this->function_)
    246             return 1;
    247         else
    248             return 0;
    249     }
    250 
    251     std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
     218                    ++it;
     219            }
     220        }
     221    }
     222
     223    /* static */ std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
    252224    {
    253225        std::string output;
    254         for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
     226        for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
    255227        {
    256228            if (it != list.begin())
    257229                output += ' ';
    258230
    259             output += *(it->second);
     231            output += it->getDisplay();
    260232        }
    261233        return output;
    262234    }
    263235
    264     std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
    265     {
    266         std::string output;
    267         for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
    268         {
    269             if (it != list.begin())
    270                 output += ' ';
    271 
    272             output += it->getDisplay();
    273         }
    274         return output;
    275     }
    276 
    277     std::string CommandEvaluation::dump(const _ConsoleCommand* command)
     236    /* static */ std::string CommandEvaluation::dump(const _ConsoleCommand* command)
    278237    {
    279238        std::string output = command->getName();
     
    300259        return output;
    301260    }
     261
     262    /* static */ std::string CommandEvaluation::getCommonBegin(const ArgumentCompletionList& list)
     263    {
     264        if (list.size() == 0)
     265        {
     266            return "";
     267        }
     268        else if (list.size() == 1)
     269        {
     270            if (list.begin()->hasDisplay())
     271                return (list.begin()->getString());
     272            else
     273                return (list.begin()->getString() + ' ');
     274        }
     275        else
     276        {
     277            std::string output;
     278            for (unsigned int i = 0; true; i++)
     279            {
     280                char tempComparable = 0;
     281                char temp = 0;
     282                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
     283                {
     284                    const std::string& argumentComparable = it->getComparable();
     285                    const std::string& argument = it->getString();
     286                    if (argument.size() > i)
     287                    {
     288                        if (it == list.begin())
     289                        {
     290                            tempComparable = argumentComparable[i];
     291                            temp = argument[i];
     292                        }
     293                        else
     294                        {
     295                            if (tempComparable != argumentComparable[i])
     296                                return output;
     297                            else if (temp != argument[i])
     298                                temp = tempComparable;
     299                        }
     300                    }
     301                    else
     302                    {
     303                        return output;
     304                    }
     305                }
     306                output += temp;
     307            }
     308            return output;
     309        }
     310    }
    302311}
Note: See TracChangeset for help on using the changeset viewer.