1##===-- breakwin.py ------------------------------------------*- Python -*-===##
2##
3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6##
7##===----------------------------------------------------------------------===##
8
9import cui
10import curses
11import lldb
12import lldbutil
13import re
14
15
16class BreakWin(cui.ListWin):
17
18    def __init__(self, driver, x, y, w, h):
19        super(BreakWin, self).__init__(x, y, w, h)
20        self.driver = driver
21        self.update()
22        self.showDetails = {}
23
24    def handleEvent(self, event):
25        if isinstance(event, lldb.SBEvent):
26            if lldb.SBBreakpoint.EventIsBreakpointEvent(event):
27                self.update()
28        if isinstance(event, int):
29            if event == ord('d'):
30                self.deleteSelected()
31            if event == curses.ascii.NL or event == curses.ascii.SP:
32                self.toggleSelected()
33            elif event == curses.ascii.TAB:
34                if self.getSelected() != -1:
35                    target = self.driver.getTarget()
36                    if not target.IsValid():
37                        return
38                    i = target.GetBreakpointAtIndex(self.getSelected()).id
39                    self.showDetails[i] = not self.showDetails[i]
40                    self.update()
41        super(BreakWin, self).handleEvent(event)
42
43    def toggleSelected(self):
44        if self.getSelected() == -1:
45            return
46        target = self.driver.getTarget()
47        if not target.IsValid():
48            return
49        bp = target.GetBreakpointAtIndex(self.getSelected())
50        bp.SetEnabled(not bp.IsEnabled())
51
52    def deleteSelected(self):
53        if self.getSelected() == -1:
54            return
55        target = self.driver.getTarget()
56        if not target.IsValid():
57            return
58        bp = target.GetBreakpointAtIndex(self.getSelected())
59        target.BreakpointDelete(bp.id)
60
61    def update(self):
62        target = self.driver.getTarget()
63        if not target.IsValid():
64            self.win.erase()
65            self.win.noutrefresh()
66            return
67        selected = self.getSelected()
68        self.clearItems()
69        for i in range(0, target.GetNumBreakpoints()):
70            bp = target.GetBreakpointAtIndex(i)
71            if bp.IsInternal():
72                continue
73            text = lldbutil.get_description(bp)
74            # FIXME: Use an API for this, not parsing the description.
75            match = re.search('SBBreakpoint: id = ([^,]+), (.*)', text)
76            try:
77                id = match.group(1)
78                desc = match.group(2).strip()
79                if bp.IsEnabled():
80                    text = '%s: %s' % (id, desc)
81                else:
82                    text = '%s: (disabled) %s' % (id, desc)
83            except ValueError as e:
84                # bp unparsable
85                pass
86
87            if self.showDetails.setdefault(bp.id, False):
88                for location in bp:
89                    desc = lldbutil.get_description(
90                        location, lldb.eDescriptionLevelFull)
91                    text += '\n  ' + desc
92            self.addItem(text)
93        self.setSelected(selected)
94