-
Notifications
You must be signed in to change notification settings - Fork 1
/
breakpoints.py
146 lines (128 loc) · 5.14 KB
/
breakpoints.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Copyright (c) Anand Krishnamoorthi
# Licensed under the MIT License
from re import compile, search
from prompt_toolkit.layout import Dimension, ScrollOffsets
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.lexers.base import Lexer
from pygments.lexers import get_lexer_by_name, CLexer
from pygments.token import Token
from window import Window
class BreakpointsLexer(Lexer):
def __init__(self):
super(BreakpointsLexer, self).__init__()
self.lexer = PygmentsLexer(CLexer, sync_from_start=False)
def lex_document(self, document):
lexer_lex_line = self.lexer.lex_document(document)
def lex_line(lineno):
line = document.lines[lineno]
if line.strip().startswith('at'):
return [('bold italic fg:DarkOliveGreen', document.lines[lineno])]
parts = lexer_lex_line(lineno)
for i in range(0, len(parts)):
if parts[i][1] == '*':
parts[i] = (parts[i][0] + ' reverse ', parts[i][1])
elif parts[i][1] == 'in':
parts[i+2] = ('bold fg:Olive', parts[i+2][1])
elif parts[i][1] == 'hit':
parts[i+2] = ('bold ' + parts[i+2][0], parts[i+2][1])
return parts
return lex_line
class BreakpointsWindow(Window):
def __init__(self,
app=None,
show=False,
height=Dimension(preferred=5)):
self.lexer = BreakpointsLexer()
self.breakpoints = {}
self.changed = {}
self.database = {}
self.hits = {}
scroll_offsets = ScrollOffsets(top=2,
bottom=2)
super(BreakpointsWindow, self).__init__(app=app,
show=show,
title='[ Breakpoints ]',
scroll_offsets=scroll_offsets)
def has_breakpoint(self, loc):
return loc in self.database
def _build_database(self, output):
database = {}
hits = {}
changed = {}
lines = output.strip().split('\n')
hc = ''
breakpoints = {}
if len(lines) > 1:
ptype = lines[0].find('Type')
pdisp = lines[0].find('Disp', ptype)
penb = lines[0].find('Enb', pdisp)
paddress = lines[0].find('Address', penb)
pwhat = lines[0].find('What', paddress)
rebnum = compile('(\d+\.\d+)|(\d+)')
reddr = compile('(0x.+)')
rhc = compile('hit (\d+) time')
bnum = ''
for line in lines[1:]:
m = rebnum.search(line)
if m and m.start() == 0:
# breakpoint line
bnum = m[1] if m[1] else m[2]
typ = line[ptype:pdisp].strip()
disp = line[pdisp:penb].strip()
enb = line[penb:paddress].strip() == 'y'
address = line[paddress:pwhat].strip()
if address[0:1] == '0':
database[address] = True
what = line[pwhat:].strip()
hits[bnum] = ''
at = ''
pat = what.find('at ')
if pat > 0:
at = what[pat+3:]
database[at] = True
what = what[:pat].strip()
else:
if not what.startswith('in'):
at = what
what = ''
breakpoints[bnum] = (typ, disp, enb, address, what, at)
else:
m = rhc.search(line)
if m:
hc = m[1]
hits[bnum] = hc
if hc != '':
if bnum not in self.hits or self.hits[bnum] != hc:
changed[bnum] = True
self.changed = changed
self.breakpoints = breakpoints
self.database = database
self.hits = hits
def handle_info_breakpoints(self, output):
self._build_database(output)
if len(self.breakpoints) == 0:
self.buffer.text = output
self.fit_to_height()
return
lines = []
for (bnum, val) in self.breakpoints.items():
ch = ' '
if bnum in self.changed and self.changed[bnum]:
ch = '*'
line = ' {}{:<4} {:<10} {:<18} {}'.format(ch, bnum, val[0], val[3], val[4])
if bnum in self.hits:
hc = self.hits[bnum]
if hc != '':
line += ' hit %s time' % hc
if hc != '1':
line += 's'
lines.append(line)
if val[5] != '':
lines.append(' at ' + val[5])
self.buffer.text = '\n'.join(lines)
def reset(self):
self.buffer.text = ''
self.database = {}
self.hits = {}
self.breakpoints = {}
self.changed = {}