CommandObjectRegexCommand.cpp revision 254721
1254721Semaste//===-- CommandObjectRegexCommand.cpp ---------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/Interpreter/CommandObjectRegexCommand.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Interpreter/CommandInterpreter.h"
19254721Semaste#include "lldb/Interpreter/CommandReturnObject.h"
20254721Semaste
21254721Semasteusing namespace lldb;
22254721Semasteusing namespace lldb_private;
23254721Semaste
24254721Semaste//----------------------------------------------------------------------
25254721Semaste// CommandObjectRegexCommand constructor
26254721Semaste//----------------------------------------------------------------------
27254721SemasteCommandObjectRegexCommand::CommandObjectRegexCommand
28254721Semaste(
29254721Semaste    CommandInterpreter &interpreter,
30254721Semaste    const char *name,
31254721Semaste    const char *help,
32254721Semaste    const char *syntax,
33254721Semaste    uint32_t max_matches,
34254721Semaste    uint32_t completion_type_mask
35254721Semaste) :
36254721Semaste    CommandObjectRaw (interpreter, name, help, syntax),
37254721Semaste    m_max_matches (max_matches),
38254721Semaste    m_completion_type_mask (completion_type_mask),
39254721Semaste    m_entries ()
40254721Semaste{
41254721Semaste}
42254721Semaste
43254721Semaste//----------------------------------------------------------------------
44254721Semaste// Destructor
45254721Semaste//----------------------------------------------------------------------
46254721SemasteCommandObjectRegexCommand::~CommandObjectRegexCommand()
47254721Semaste{
48254721Semaste}
49254721Semaste
50254721Semaste
51254721Semastebool
52254721SemasteCommandObjectRegexCommand::DoExecute
53254721Semaste(
54254721Semaste    const char *command,
55254721Semaste    CommandReturnObject &result
56254721Semaste)
57254721Semaste{
58254721Semaste    if (command)
59254721Semaste    {
60254721Semaste        EntryCollection::const_iterator pos, end = m_entries.end();
61254721Semaste        for (pos = m_entries.begin(); pos != end; ++pos)
62254721Semaste        {
63254721Semaste            RegularExpression::Match regex_match(m_max_matches);
64254721Semaste
65254721Semaste            if (pos->regex.Execute (command, &regex_match))
66254721Semaste            {
67254721Semaste                std::string new_command(pos->command);
68254721Semaste                std::string match_str;
69254721Semaste                char percent_var[8];
70254721Semaste                size_t idx, percent_var_idx;
71254721Semaste                for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx)
72254721Semaste                {
73254721Semaste                    if (regex_match.GetMatchAtIndex (command, match_idx, match_str))
74254721Semaste                    {
75254721Semaste                        const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx);
76254721Semaste                        for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; )
77254721Semaste                        {
78254721Semaste                            new_command.erase(percent_var_idx, percent_var_len);
79254721Semaste                            new_command.insert(percent_var_idx, match_str);
80254721Semaste                            idx += percent_var_idx + match_str.size();
81254721Semaste                        }
82254721Semaste                    }
83254721Semaste                }
84254721Semaste                // Interpret the new command and return this as the result!
85254721Semaste                if (m_interpreter.GetExpandRegexAliases())
86254721Semaste                    result.GetOutputStream().Printf("%s\n", new_command.c_str());
87254721Semaste                // Pass in true for "no context switching".  The command that called us should have set up the context
88254721Semaste                // appropriately, we shouldn't have to redo that.
89254721Semaste                return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, NULL, true, true);
90254721Semaste            }
91254721Semaste        }
92254721Semaste        result.SetStatus(eReturnStatusFailed);
93254721Semaste        if (GetSyntax() != NULL)
94254721Semaste            result.AppendError (GetSyntax());
95254721Semaste        else
96254721Semaste            result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n",
97254721Semaste                                          command,
98254721Semaste                                          m_cmd_name.c_str());
99254721Semaste        return false;
100254721Semaste    }
101254721Semaste    result.AppendError("empty command passed to regular expression command");
102254721Semaste    result.SetStatus(eReturnStatusFailed);
103254721Semaste    return false;
104254721Semaste}
105254721Semaste
106254721Semaste
107254721Semastebool
108254721SemasteCommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *command_cstr)
109254721Semaste{
110254721Semaste    m_entries.resize(m_entries.size() + 1);
111254721Semaste    // Only add the regular expression if it compiles
112254721Semaste    if (m_entries.back().regex.Compile (re_cstr, REG_EXTENDED))
113254721Semaste    {
114254721Semaste        m_entries.back().command.assign (command_cstr);
115254721Semaste        return true;
116254721Semaste    }
117254721Semaste    // The regex didn't compile...
118254721Semaste    m_entries.pop_back();
119254721Semaste    return false;
120254721Semaste}
121254721Semaste
122254721Semasteint
123254721SemasteCommandObjectRegexCommand::HandleCompletion (Args &input,
124254721Semaste                                             int &cursor_index,
125254721Semaste                                             int &cursor_char_position,
126254721Semaste                                             int match_start_point,
127254721Semaste                                             int max_return_elements,
128254721Semaste                                             bool &word_complete,
129254721Semaste                                             StringList &matches)
130254721Semaste{
131254721Semaste    if (m_completion_type_mask)
132254721Semaste    {
133254721Semaste        std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
134254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
135254721Semaste                                                             m_completion_type_mask,
136254721Semaste                                                             completion_str.c_str(),
137254721Semaste                                                             match_start_point,
138254721Semaste                                                             max_return_elements,
139254721Semaste                                                             NULL,
140254721Semaste                                                             word_complete,
141254721Semaste                                                             matches);
142254721Semaste        return matches.GetSize();
143254721Semaste    }
144254721Semaste    else
145254721Semaste    {
146254721Semaste        matches.Clear();
147254721Semaste        word_complete = false;
148254721Semaste    }
149254721Semaste    return 0;
150254721Semaste}
151