1 //===-- BreakpointResolverFileRegex.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/Breakpoint/BreakpointResolverFileRegex.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Core/SourceManager.h"
18 #include "lldb/Core/Log.h"
19 #include "lldb/Core/StreamString.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/lldb-private-log.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 //----------------------------------------------------------------------
27 // BreakpointResolverFileRegex:
28 //----------------------------------------------------------------------
29 BreakpointResolverFileRegex::BreakpointResolverFileRegex
30 (
31     Breakpoint *bkpt,
32     RegularExpression &regex
33 ) :
34     BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
35     m_regex (regex)
36 {
37 }
38 
39 BreakpointResolverFileRegex::~BreakpointResolverFileRegex ()
40 {
41 }
42 
43 Searcher::CallbackReturn
44 BreakpointResolverFileRegex::SearchCallback
45 (
46     SearchFilter &filter,
47     SymbolContext &context,
48     Address *addr,
49     bool containing
50 )
51 {
52 
53     assert (m_breakpoint != NULL);
54     if (!context.target_sp)
55         return eCallbackReturnContinue;
56 
57     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
58 
59     CompileUnit *cu = context.comp_unit;
60     FileSpec cu_file_spec = *(static_cast<FileSpec *>(cu));
61     std::vector<uint32_t> line_matches;
62     context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches);
63     uint32_t num_matches = line_matches.size();
64     for (int i = 0; i < num_matches; i++)
65     {
66         uint32_t start_idx = 0;
67         bool exact = false;
68         while (1)
69         {
70             LineEntry line_entry;
71 
72             // Cycle through all the line entries that might match this one:
73             start_idx = cu->FindLineEntry (start_idx, line_matches[i], NULL, exact, &line_entry);
74             if (start_idx == UINT32_MAX)
75                 break;
76             exact = true;
77             start_idx++;
78 
79             Address line_start = line_entry.range.GetBaseAddress();
80             if (line_start.IsValid())
81             {
82                 if (filter.AddressPasses(line_start))
83                 {
84                     BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start));
85                     if (log && bp_loc_sp && !m_breakpoint->IsInternal())
86                     {
87                         StreamString s;
88                         bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose);
89                         log->Printf ("Added location: %s\n", s.GetData());
90                     }
91                 }
92                 else if (log)
93                 {
94                     log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass filter.\n",
95                                  line_start.GetFileAddress(),
96                                  cu_file_spec.GetFilename().AsCString("<Unknown>"),
97                                  line_matches[i]);
98                 }
99             }
100             else
101             {
102                 if (log)
103                     log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n",
104                                  line_start.GetFileAddress(),
105                                  cu_file_spec.GetFilename().AsCString("<Unknown>"),
106                                  line_matches[i]);
107             }
108 
109         }
110     }
111     assert (m_breakpoint != NULL);
112 
113     return Searcher::eCallbackReturnContinue;
114 }
115 
116 Searcher::Depth
117 BreakpointResolverFileRegex::GetDepth()
118 {
119     return Searcher::eDepthCompUnit;
120 }
121 
122 void
123 BreakpointResolverFileRegex::GetDescription (Stream *s)
124 {
125     s->Printf ("source regex = \"%s\"", m_regex.GetText());
126 }
127 
128 void
129 BreakpointResolverFileRegex::Dump (Stream *s) const
130 {
131 
132 }
133 
134