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