Home | History | Annotate | Download | only in Interpreter
      1 //===-- CommandObjectRegexCommand.cpp ---------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/lldb-python.h"
     11 
     12 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
     13 
     14 // C Includes
     15 // C++ Includes
     16 // Other libraries and framework includes
     17 // Project includes
     18 #include "lldb/Interpreter/CommandInterpreter.h"
     19 #include "lldb/Interpreter/CommandReturnObject.h"
     20 
     21 using namespace lldb;
     22 using namespace lldb_private;
     23 
     24 //----------------------------------------------------------------------
     25 // CommandObjectRegexCommand constructor
     26 //----------------------------------------------------------------------
     27 CommandObjectRegexCommand::CommandObjectRegexCommand
     28 (
     29     CommandInterpreter &interpreter,
     30     const char *name,
     31     const char *help,
     32     const char *syntax,
     33     uint32_t max_matches,
     34     uint32_t completion_type_mask
     35 ) :
     36     CommandObjectRaw (interpreter, name, help, syntax),
     37     m_max_matches (max_matches),
     38     m_completion_type_mask (completion_type_mask),
     39     m_entries ()
     40 {
     41 }
     42 
     43 //----------------------------------------------------------------------
     44 // Destructor
     45 //----------------------------------------------------------------------
     46 CommandObjectRegexCommand::~CommandObjectRegexCommand()
     47 {
     48 }
     49 
     50 
     51 bool
     52 CommandObjectRegexCommand::DoExecute
     53 (
     54     const char *command,
     55     CommandReturnObject &result
     56 )
     57 {
     58     if (command)
     59     {
     60         EntryCollection::const_iterator pos, end = m_entries.end();
     61         for (pos = m_entries.begin(); pos != end; ++pos)
     62         {
     63             RegularExpression::Match regex_match(m_max_matches);
     64 
     65             if (pos->regex.Execute (command, &regex_match))
     66             {
     67                 std::string new_command(pos->command);
     68                 std::string match_str;
     69                 char percent_var[8];
     70                 size_t idx, percent_var_idx;
     71                 for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx)
     72                 {
     73                     if (regex_match.GetMatchAtIndex (command, match_idx, match_str))
     74                     {
     75                         const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx);
     76                         for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; )
     77                         {
     78                             new_command.erase(percent_var_idx, percent_var_len);
     79                             new_command.insert(percent_var_idx, match_str);
     80                             idx += percent_var_idx + match_str.size();
     81                         }
     82                     }
     83                 }
     84                 // Interpret the new command and return this as the result!
     85                 if (m_interpreter.GetExpandRegexAliases())
     86                     result.GetOutputStream().Printf("%s\n", new_command.c_str());
     87                 // Pass in true for "no context switching".  The command that called us should have set up the context
     88                 // appropriately, we shouldn't have to redo that.
     89                 return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, NULL, true, true);
     90             }
     91         }
     92         result.SetStatus(eReturnStatusFailed);
     93         if (GetSyntax() != NULL)
     94             result.AppendError (GetSyntax());
     95         else
     96             result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n",
     97                                           command,
     98                                           m_cmd_name.c_str());
     99         return false;
    100     }
    101     result.AppendError("empty command passed to regular expression command");
    102     result.SetStatus(eReturnStatusFailed);
    103     return false;
    104 }
    105 
    106 
    107 bool
    108 CommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *command_cstr)
    109 {
    110     m_entries.resize(m_entries.size() + 1);
    111     // Only add the regular expression if it compiles
    112     if (m_entries.back().regex.Compile (re_cstr, REG_EXTENDED))
    113     {
    114         m_entries.back().command.assign (command_cstr);
    115         return true;
    116     }
    117     // The regex didn't compile...
    118     m_entries.pop_back();
    119     return false;
    120 }
    121 
    122 int
    123 CommandObjectRegexCommand::HandleCompletion (Args &input,
    124                                              int &cursor_index,
    125                                              int &cursor_char_position,
    126                                              int match_start_point,
    127                                              int max_return_elements,
    128                                              bool &word_complete,
    129                                              StringList &matches)
    130 {
    131     if (m_completion_type_mask)
    132     {
    133         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    134         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    135                                                              m_completion_type_mask,
    136                                                              completion_str.c_str(),
    137                                                              match_start_point,
    138                                                              max_return_elements,
    139                                                              NULL,
    140                                                              word_complete,
    141                                                              matches);
    142         return matches.GetSize();
    143     }
    144     else
    145     {
    146         matches.Clear();
    147         word_complete = false;
    148     }
    149     return 0;
    150 }
    151