xref: /openbsd-src/gnu/llvm/lldb/examples/python/lldbtk.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1*be691f3bSpatrick#!/usr/bin/env python
2061da546Spatrick
3061da546Spatrickimport lldb
4061da546Spatrickimport shlex
5061da546Spatrickimport sys
6061da546Spatricktry:
7061da546Spatrick    from tkinter import *
8061da546Spatrick    import tkinter.ttk as ttk
9061da546Spatrickexcept ImportError:
10061da546Spatrick    from Tkinter import *
11061da546Spatrick    import ttk
12061da546Spatrick
13061da546Spatrick
14061da546Spatrickclass ValueTreeItemDelegate(object):
15061da546Spatrick
16061da546Spatrick    def __init__(self, value):
17061da546Spatrick        self.value = value
18061da546Spatrick
19061da546Spatrick    def get_item_dictionary(self):
20061da546Spatrick        name = self.value.name
21061da546Spatrick        if name is None:
22061da546Spatrick            name = ''
23061da546Spatrick        typename = self.value.type
24061da546Spatrick        if typename is None:
25061da546Spatrick            typename = ''
26061da546Spatrick        value = self.value.value
27061da546Spatrick        if value is None:
28061da546Spatrick            value = ''
29061da546Spatrick        summary = self.value.summary
30061da546Spatrick        if summary is None:
31061da546Spatrick            summary = ''
32061da546Spatrick        has_children = self.value.MightHaveChildren()
33061da546Spatrick        return {'#0': name,
34061da546Spatrick                'typename': typename,
35061da546Spatrick                'value': value,
36061da546Spatrick                'summary': summary,
37061da546Spatrick                'children': has_children,
38061da546Spatrick                'tree-item-delegate': self}
39061da546Spatrick
40061da546Spatrick    def get_child_item_dictionaries(self):
41061da546Spatrick        item_dicts = list()
42061da546Spatrick        for i in range(self.value.num_children):
43061da546Spatrick            item_delegate = ValueTreeItemDelegate(
44061da546Spatrick                self.value.GetChildAtIndex(i))
45061da546Spatrick            item_dicts.append(item_delegate.get_item_dictionary())
46061da546Spatrick        return item_dicts
47061da546Spatrick
48061da546Spatrick
49061da546Spatrickclass FrameTreeItemDelegate(object):
50061da546Spatrick
51061da546Spatrick    def __init__(self, frame):
52061da546Spatrick        self.frame = frame
53061da546Spatrick
54061da546Spatrick    def get_item_dictionary(self):
55061da546Spatrick        id = self.frame.GetFrameID()
56061da546Spatrick        name = 'frame #%u' % (id)
57061da546Spatrick        value = '0x%16.16x' % (self.frame.GetPC())
58061da546Spatrick        stream = lldb.SBStream()
59061da546Spatrick        self.frame.GetDescription(stream)
60061da546Spatrick        summary = stream.GetData().split("`")[1]
61061da546Spatrick        return {
62061da546Spatrick            '#0': name,
63061da546Spatrick            'value': value,
64061da546Spatrick            'summary': summary,
65061da546Spatrick            'children': self.frame.GetVariables(
66061da546Spatrick                True,
67061da546Spatrick                True,
68061da546Spatrick                True,
69061da546Spatrick                True).GetSize() > 0,
70061da546Spatrick            'tree-item-delegate': self}
71061da546Spatrick
72061da546Spatrick    def get_child_item_dictionaries(self):
73061da546Spatrick        item_dicts = list()
74061da546Spatrick        variables = self.frame.GetVariables(True, True, True, True)
75061da546Spatrick        n = variables.GetSize()
76061da546Spatrick        for i in range(n):
77061da546Spatrick            item_delegate = ValueTreeItemDelegate(variables[i])
78061da546Spatrick            item_dicts.append(item_delegate.get_item_dictionary())
79061da546Spatrick        return item_dicts
80061da546Spatrick
81061da546Spatrick
82061da546Spatrickclass ThreadTreeItemDelegate(object):
83061da546Spatrick
84061da546Spatrick    def __init__(self, thread):
85061da546Spatrick        self.thread = thread
86061da546Spatrick
87061da546Spatrick    def get_item_dictionary(self):
88061da546Spatrick        num_frames = self.thread.GetNumFrames()
89061da546Spatrick        name = 'thread #%u' % (self.thread.GetIndexID())
90061da546Spatrick        value = '0x%x' % (self.thread.GetThreadID())
91061da546Spatrick        summary = '%u frames' % (num_frames)
92061da546Spatrick        return {'#0': name,
93061da546Spatrick                'value': value,
94061da546Spatrick                'summary': summary,
95061da546Spatrick                'children': num_frames > 0,
96061da546Spatrick                'tree-item-delegate': self}
97061da546Spatrick
98061da546Spatrick    def get_child_item_dictionaries(self):
99061da546Spatrick        item_dicts = list()
100061da546Spatrick        for frame in self.thread:
101061da546Spatrick            item_delegate = FrameTreeItemDelegate(frame)
102061da546Spatrick            item_dicts.append(item_delegate.get_item_dictionary())
103061da546Spatrick        return item_dicts
104061da546Spatrick
105061da546Spatrick
106061da546Spatrickclass ProcessTreeItemDelegate(object):
107061da546Spatrick
108061da546Spatrick    def __init__(self, process):
109061da546Spatrick        self.process = process
110061da546Spatrick
111061da546Spatrick    def get_item_dictionary(self):
112061da546Spatrick        id = self.process.GetProcessID()
113061da546Spatrick        num_threads = self.process.GetNumThreads()
114061da546Spatrick        value = str(self.process.GetProcessID())
115061da546Spatrick        summary = self.process.target.executable.fullpath
116061da546Spatrick        return {'#0': 'process',
117061da546Spatrick                'value': value,
118061da546Spatrick                'summary': summary,
119061da546Spatrick                'children': num_threads > 0,
120061da546Spatrick                'tree-item-delegate': self}
121061da546Spatrick
122061da546Spatrick    def get_child_item_dictionaries(self):
123061da546Spatrick        item_dicts = list()
124061da546Spatrick        for thread in self.process:
125061da546Spatrick            item_delegate = ThreadTreeItemDelegate(thread)
126061da546Spatrick            item_dicts.append(item_delegate.get_item_dictionary())
127061da546Spatrick        return item_dicts
128061da546Spatrick
129061da546Spatrick
130061da546Spatrickclass TargetTreeItemDelegate(object):
131061da546Spatrick
132061da546Spatrick    def __init__(self, target):
133061da546Spatrick        self.target = target
134061da546Spatrick
135061da546Spatrick    def get_item_dictionary(self):
136061da546Spatrick        value = str(self.target.triple)
137061da546Spatrick        summary = self.target.executable.fullpath
138061da546Spatrick        return {'#0': 'target',
139061da546Spatrick                'value': value,
140061da546Spatrick                'summary': summary,
141061da546Spatrick                'children': True,
142061da546Spatrick                'tree-item-delegate': self}
143061da546Spatrick
144061da546Spatrick    def get_child_item_dictionaries(self):
145061da546Spatrick        item_dicts = list()
146061da546Spatrick        image_item_delegate = TargetImagesTreeItemDelegate(self.target)
147061da546Spatrick        item_dicts.append(image_item_delegate.get_item_dictionary())
148061da546Spatrick        return item_dicts
149061da546Spatrick
150061da546Spatrick
151061da546Spatrickclass TargetImagesTreeItemDelegate(object):
152061da546Spatrick
153061da546Spatrick    def __init__(self, target):
154061da546Spatrick        self.target = target
155061da546Spatrick
156061da546Spatrick    def get_item_dictionary(self):
157061da546Spatrick        value = str(self.target.triple)
158061da546Spatrick        summary = self.target.executable.fullpath
159061da546Spatrick        num_modules = self.target.GetNumModules()
160061da546Spatrick        return {'#0': 'images',
161061da546Spatrick                'value': '',
162061da546Spatrick                'summary': '%u images' % num_modules,
163061da546Spatrick                'children': num_modules > 0,
164061da546Spatrick                'tree-item-delegate': self}
165061da546Spatrick
166061da546Spatrick    def get_child_item_dictionaries(self):
167061da546Spatrick        item_dicts = list()
168061da546Spatrick        for i in range(self.target.GetNumModules()):
169061da546Spatrick            module = self.target.GetModuleAtIndex(i)
170061da546Spatrick            image_item_delegate = ModuleTreeItemDelegate(
171061da546Spatrick                self.target, module, i)
172061da546Spatrick            item_dicts.append(image_item_delegate.get_item_dictionary())
173061da546Spatrick        return item_dicts
174061da546Spatrick
175061da546Spatrick
176061da546Spatrickclass ModuleTreeItemDelegate(object):
177061da546Spatrick
178061da546Spatrick    def __init__(self, target, module, index):
179061da546Spatrick        self.target = target
180061da546Spatrick        self.module = module
181061da546Spatrick        self.index = index
182061da546Spatrick
183061da546Spatrick    def get_item_dictionary(self):
184061da546Spatrick        name = 'module %u' % (self.index)
185061da546Spatrick        value = self.module.file.basename
186061da546Spatrick        summary = self.module.file.dirname
187061da546Spatrick        return {'#0': name,
188061da546Spatrick                'value': value,
189061da546Spatrick                'summary': summary,
190061da546Spatrick                'children': True,
191061da546Spatrick                'tree-item-delegate': self}
192061da546Spatrick
193061da546Spatrick    def get_child_item_dictionaries(self):
194061da546Spatrick        item_dicts = list()
195061da546Spatrick        sections_item_delegate = ModuleSectionsTreeItemDelegate(
196061da546Spatrick            self.target, self.module)
197061da546Spatrick        item_dicts.append(sections_item_delegate.get_item_dictionary())
198061da546Spatrick
199061da546Spatrick        symbols_item_delegate = ModuleSymbolsTreeItemDelegate(
200061da546Spatrick            self.target, self.module)
201061da546Spatrick        item_dicts.append(symbols_item_delegate.get_item_dictionary())
202061da546Spatrick
203061da546Spatrick        comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(
204061da546Spatrick            self.target, self.module)
205061da546Spatrick        item_dicts.append(comp_units_item_delegate.get_item_dictionary())
206061da546Spatrick        return item_dicts
207061da546Spatrick
208061da546Spatrick
209061da546Spatrickclass ModuleSectionsTreeItemDelegate(object):
210061da546Spatrick
211061da546Spatrick    def __init__(self, target, module):
212061da546Spatrick        self.target = target
213061da546Spatrick        self.module = module
214061da546Spatrick
215061da546Spatrick    def get_item_dictionary(self):
216061da546Spatrick        name = 'sections'
217061da546Spatrick        value = ''
218061da546Spatrick        summary = '%u sections' % (self.module.GetNumSections())
219061da546Spatrick        return {'#0': name,
220061da546Spatrick                'value': value,
221061da546Spatrick                'summary': summary,
222061da546Spatrick                'children': True,
223061da546Spatrick                'tree-item-delegate': self}
224061da546Spatrick
225061da546Spatrick    def get_child_item_dictionaries(self):
226061da546Spatrick        item_dicts = list()
227061da546Spatrick        num_sections = self.module.GetNumSections()
228061da546Spatrick        for i in range(num_sections):
229061da546Spatrick            section = self.module.GetSectionAtIndex(i)
230061da546Spatrick            image_item_delegate = SectionTreeItemDelegate(self.target, section)
231061da546Spatrick            item_dicts.append(image_item_delegate.get_item_dictionary())
232061da546Spatrick        return item_dicts
233061da546Spatrick
234061da546Spatrick
235061da546Spatrickclass SectionTreeItemDelegate(object):
236061da546Spatrick
237061da546Spatrick    def __init__(self, target, section):
238061da546Spatrick        self.target = target
239061da546Spatrick        self.section = section
240061da546Spatrick
241061da546Spatrick    def get_item_dictionary(self):
242061da546Spatrick        name = self.section.name
243061da546Spatrick        section_load_addr = self.section.GetLoadAddress(self.target)
244061da546Spatrick        if section_load_addr != lldb.LLDB_INVALID_ADDRESS:
245061da546Spatrick            value = '0x%16.16x' % (section_load_addr)
246061da546Spatrick        else:
247061da546Spatrick            value = '0x%16.16x *' % (self.section.file_addr)
248061da546Spatrick        summary = ''
249061da546Spatrick        return {'#0': name,
250061da546Spatrick                'value': value,
251061da546Spatrick                'summary': summary,
252061da546Spatrick                'children': self.section.GetNumSubSections() > 0,
253061da546Spatrick                'tree-item-delegate': self}
254061da546Spatrick
255061da546Spatrick    def get_child_item_dictionaries(self):
256061da546Spatrick        item_dicts = list()
257061da546Spatrick        num_sections = self.section.GetNumSubSections()
258061da546Spatrick        for i in range(num_sections):
259061da546Spatrick            section = self.section.GetSubSectionAtIndex(i)
260061da546Spatrick            image_item_delegate = SectionTreeItemDelegate(self.target, section)
261061da546Spatrick            item_dicts.append(image_item_delegate.get_item_dictionary())
262061da546Spatrick        return item_dicts
263061da546Spatrick
264061da546Spatrick
265061da546Spatrickclass ModuleCompileUnitsTreeItemDelegate(object):
266061da546Spatrick
267061da546Spatrick    def __init__(self, target, module):
268061da546Spatrick        self.target = target
269061da546Spatrick        self.module = module
270061da546Spatrick
271061da546Spatrick    def get_item_dictionary(self):
272061da546Spatrick        name = 'compile units'
273061da546Spatrick        value = ''
274061da546Spatrick        summary = '%u compile units' % (self.module.GetNumSections())
275061da546Spatrick        return {'#0': name,
276061da546Spatrick                'value': value,
277061da546Spatrick                'summary': summary,
278061da546Spatrick                'children': self.module.GetNumCompileUnits() > 0,
279061da546Spatrick                'tree-item-delegate': self}
280061da546Spatrick
281061da546Spatrick    def get_child_item_dictionaries(self):
282061da546Spatrick        item_dicts = list()
283061da546Spatrick        num_cus = self.module.GetNumCompileUnits()
284061da546Spatrick        for i in range(num_cus):
285061da546Spatrick            cu = self.module.GetCompileUnitAtIndex(i)
286061da546Spatrick            image_item_delegate = CompileUnitTreeItemDelegate(self.target, cu)
287061da546Spatrick            item_dicts.append(image_item_delegate.get_item_dictionary())
288061da546Spatrick        return item_dicts
289061da546Spatrick
290061da546Spatrick
291061da546Spatrickclass CompileUnitTreeItemDelegate(object):
292061da546Spatrick
293061da546Spatrick    def __init__(self, target, cu):
294061da546Spatrick        self.target = target
295061da546Spatrick        self.cu = cu
296061da546Spatrick
297061da546Spatrick    def get_item_dictionary(self):
298061da546Spatrick        name = self.cu.GetFileSpec().basename
299061da546Spatrick        value = ''
300061da546Spatrick        num_lines = self.cu.GetNumLineEntries()
301061da546Spatrick        summary = ''
302061da546Spatrick        return {'#0': name,
303061da546Spatrick                'value': value,
304061da546Spatrick                'summary': summary,
305061da546Spatrick                'children': num_lines > 0,
306061da546Spatrick                'tree-item-delegate': self}
307061da546Spatrick
308061da546Spatrick    def get_child_item_dictionaries(self):
309061da546Spatrick        item_dicts = list()
310061da546Spatrick        item_delegate = LineTableTreeItemDelegate(self.target, self.cu)
311061da546Spatrick        item_dicts.append(item_delegate.get_item_dictionary())
312061da546Spatrick        return item_dicts
313061da546Spatrick
314061da546Spatrick
315061da546Spatrickclass LineTableTreeItemDelegate(object):
316061da546Spatrick
317061da546Spatrick    def __init__(self, target, cu):
318061da546Spatrick        self.target = target
319061da546Spatrick        self.cu = cu
320061da546Spatrick
321061da546Spatrick    def get_item_dictionary(self):
322061da546Spatrick        name = 'line table'
323061da546Spatrick        value = ''
324061da546Spatrick        num_lines = self.cu.GetNumLineEntries()
325061da546Spatrick        summary = '%u line entries' % (num_lines)
326061da546Spatrick        return {'#0': name,
327061da546Spatrick                'value': value,
328061da546Spatrick                'summary': summary,
329061da546Spatrick                'children': num_lines > 0,
330061da546Spatrick                'tree-item-delegate': self}
331061da546Spatrick
332061da546Spatrick    def get_child_item_dictionaries(self):
333061da546Spatrick        item_dicts = list()
334061da546Spatrick        num_lines = self.cu.GetNumLineEntries()
335061da546Spatrick        for i in range(num_lines):
336061da546Spatrick            line_entry = self.cu.GetLineEntryAtIndex(i)
337061da546Spatrick            item_delegate = LineEntryTreeItemDelegate(
338061da546Spatrick                self.target, line_entry, i)
339061da546Spatrick            item_dicts.append(item_delegate.get_item_dictionary())
340061da546Spatrick        return item_dicts
341061da546Spatrick
342061da546Spatrick
343061da546Spatrickclass LineEntryTreeItemDelegate(object):
344061da546Spatrick
345061da546Spatrick    def __init__(self, target, line_entry, index):
346061da546Spatrick        self.target = target
347061da546Spatrick        self.line_entry = line_entry
348061da546Spatrick        self.index = index
349061da546Spatrick
350061da546Spatrick    def get_item_dictionary(self):
351061da546Spatrick        name = str(self.index)
352061da546Spatrick        address = self.line_entry.GetStartAddress()
353061da546Spatrick        load_addr = address.GetLoadAddress(self.target)
354061da546Spatrick        if load_addr != lldb.LLDB_INVALID_ADDRESS:
355061da546Spatrick            value = '0x%16.16x' % (load_addr)
356061da546Spatrick        else:
357061da546Spatrick            value = '0x%16.16x *' % (address.file_addr)
358061da546Spatrick        summary = self.line_entry.GetFileSpec().fullpath + ':' + \
359061da546Spatrick            str(self.line_entry.line)
360061da546Spatrick        return {'#0': name,
361061da546Spatrick                'value': value,
362061da546Spatrick                'summary': summary,
363061da546Spatrick                'children': False,
364061da546Spatrick                'tree-item-delegate': self}
365061da546Spatrick
366061da546Spatrick    def get_child_item_dictionaries(self):
367061da546Spatrick        item_dicts = list()
368061da546Spatrick        return item_dicts
369061da546Spatrick
370061da546Spatrick
371061da546Spatrickclass InstructionTreeItemDelegate(object):
372061da546Spatrick
373061da546Spatrick    def __init__(self, target, instr):
374061da546Spatrick        self.target = target
375061da546Spatrick        self.instr = instr
376061da546Spatrick
377061da546Spatrick    def get_item_dictionary(self):
378061da546Spatrick        address = self.instr.GetAddress()
379061da546Spatrick        load_addr = address.GetLoadAddress(self.target)
380061da546Spatrick        if load_addr != lldb.LLDB_INVALID_ADDRESS:
381061da546Spatrick            name = '0x%16.16x' % (load_addr)
382061da546Spatrick        else:
383061da546Spatrick            name = '0x%16.16x *' % (address.file_addr)
384061da546Spatrick        value = self.instr.GetMnemonic(
385061da546Spatrick            self.target) + ' ' + self.instr.GetOperands(self.target)
386061da546Spatrick        summary = self.instr.GetComment(self.target)
387061da546Spatrick        return {'#0': name,
388061da546Spatrick                'value': value,
389061da546Spatrick                'summary': summary,
390061da546Spatrick                'children': False,
391061da546Spatrick                'tree-item-delegate': self}
392061da546Spatrick
393061da546Spatrick
394061da546Spatrickclass ModuleSymbolsTreeItemDelegate(object):
395061da546Spatrick
396061da546Spatrick    def __init__(self, target, module):
397061da546Spatrick        self.target = target
398061da546Spatrick        self.module = module
399061da546Spatrick
400061da546Spatrick    def get_item_dictionary(self):
401061da546Spatrick        name = 'symbols'
402061da546Spatrick        value = ''
403061da546Spatrick        summary = '%u symbols' % (self.module.GetNumSymbols())
404061da546Spatrick        return {'#0': name,
405061da546Spatrick                'value': value,
406061da546Spatrick                'summary': summary,
407061da546Spatrick                'children': True,
408061da546Spatrick                'tree-item-delegate': self}
409061da546Spatrick
410061da546Spatrick    def get_child_item_dictionaries(self):
411061da546Spatrick        item_dicts = list()
412061da546Spatrick        num_symbols = self.module.GetNumSymbols()
413061da546Spatrick        for i in range(num_symbols):
414061da546Spatrick            symbol = self.module.GetSymbolAtIndex(i)
415061da546Spatrick            image_item_delegate = SymbolTreeItemDelegate(
416061da546Spatrick                self.target, symbol, i)
417061da546Spatrick            item_dicts.append(image_item_delegate.get_item_dictionary())
418061da546Spatrick        return item_dicts
419061da546Spatrick
420061da546Spatrick
421061da546Spatrickclass SymbolTreeItemDelegate(object):
422061da546Spatrick
423061da546Spatrick    def __init__(self, target, symbol, index):
424061da546Spatrick        self.target = target
425061da546Spatrick        self.symbol = symbol
426061da546Spatrick        self.index = index
427061da546Spatrick
428061da546Spatrick    def get_item_dictionary(self):
429061da546Spatrick        address = self.symbol.GetStartAddress()
430061da546Spatrick        name = '[%u]' % self.index
431061da546Spatrick        symbol_load_addr = address.GetLoadAddress(self.target)
432061da546Spatrick        if symbol_load_addr != lldb.LLDB_INVALID_ADDRESS:
433061da546Spatrick            value = '0x%16.16x' % (symbol_load_addr)
434061da546Spatrick        else:
435061da546Spatrick            value = '0x%16.16x *' % (address.file_addr)
436061da546Spatrick        summary = self.symbol.name
437061da546Spatrick        return {'#0': name,
438061da546Spatrick                'value': value,
439061da546Spatrick                'summary': summary,
440061da546Spatrick                'children': False,
441061da546Spatrick                'tree-item-delegate': self}
442061da546Spatrick
443061da546Spatrick    def get_child_item_dictionaries(self):
444061da546Spatrick        item_dicts = list()
445061da546Spatrick        return item_dicts
446061da546Spatrick
447061da546Spatrick
448061da546Spatrickclass DelegateTree(ttk.Frame):
449061da546Spatrick
450061da546Spatrick    def __init__(self, column_dicts, delegate, title, name):
451061da546Spatrick        ttk.Frame.__init__(self, name=name)
452061da546Spatrick        self.pack(expand=Y, fill=BOTH)
453061da546Spatrick        self.master.title(title)
454061da546Spatrick        self.delegate = delegate
455061da546Spatrick        self.columns_dicts = column_dicts
456061da546Spatrick        self.item_id_to_item_dict = dict()
457061da546Spatrick        frame = Frame(self)
458061da546Spatrick        frame.pack(side=TOP, fill=BOTH, expand=Y)
459061da546Spatrick        self._create_treeview(frame)
460061da546Spatrick        self._populate_root()
461061da546Spatrick
462061da546Spatrick    def _create_treeview(self, parent):
463061da546Spatrick        frame = ttk.Frame(parent)
464061da546Spatrick        frame.pack(side=TOP, fill=BOTH, expand=Y)
465061da546Spatrick
466061da546Spatrick        column_ids = list()
467061da546Spatrick        for i in range(1, len(self.columns_dicts)):
468061da546Spatrick            column_ids.append(self.columns_dicts[i]['id'])
469061da546Spatrick        # create the tree and scrollbars
470061da546Spatrick        self.tree = ttk.Treeview(columns=column_ids)
471061da546Spatrick
472061da546Spatrick        scroll_bar_v = ttk.Scrollbar(orient=VERTICAL, command=self.tree.yview)
473061da546Spatrick        scroll_bar_h = ttk.Scrollbar(
474061da546Spatrick            orient=HORIZONTAL, command=self.tree.xview)
475061da546Spatrick        self.tree['yscroll'] = scroll_bar_v.set
476061da546Spatrick        self.tree['xscroll'] = scroll_bar_h.set
477061da546Spatrick
478061da546Spatrick        # setup column headings and columns properties
479061da546Spatrick        for columns_dict in self.columns_dicts:
480061da546Spatrick            self.tree.heading(
481061da546Spatrick                columns_dict['id'],
482061da546Spatrick                text=columns_dict['text'],
483061da546Spatrick                anchor=columns_dict['anchor'])
484061da546Spatrick            self.tree.column(
485061da546Spatrick                columns_dict['id'],
486061da546Spatrick                stretch=columns_dict['stretch'])
487061da546Spatrick
488061da546Spatrick        # add tree and scrollbars to frame
489061da546Spatrick        self.tree.grid(in_=frame, row=0, column=0, sticky=NSEW)
490061da546Spatrick        scroll_bar_v.grid(in_=frame, row=0, column=1, sticky=NS)
491061da546Spatrick        scroll_bar_h.grid(in_=frame, row=1, column=0, sticky=EW)
492061da546Spatrick
493061da546Spatrick        # set frame resizing priorities
494061da546Spatrick        frame.rowconfigure(0, weight=1)
495061da546Spatrick        frame.columnconfigure(0, weight=1)
496061da546Spatrick
497061da546Spatrick        # action to perform when a node is expanded
498061da546Spatrick        self.tree.bind('<<TreeviewOpen>>', self._update_tree)
499061da546Spatrick
500061da546Spatrick    def insert_items(self, parent_id, item_dicts):
501061da546Spatrick        for item_dict in item_dicts:
502061da546Spatrick            name = None
503061da546Spatrick            values = list()
504061da546Spatrick            first = True
505061da546Spatrick            for columns_dict in self.columns_dicts:
506061da546Spatrick                if first:
507061da546Spatrick                    name = item_dict[columns_dict['id']]
508061da546Spatrick                    first = False
509061da546Spatrick                else:
510061da546Spatrick                    values.append(item_dict[columns_dict['id']])
511061da546Spatrick            item_id = self.tree.insert(parent_id,  # root item has an empty name
512061da546Spatrick                                       END,
513061da546Spatrick                                       text=name,
514061da546Spatrick                                       values=values)
515061da546Spatrick            self.item_id_to_item_dict[item_id] = item_dict
516061da546Spatrick            if item_dict['children']:
517061da546Spatrick                self.tree.insert(item_id, END, text='dummy')
518061da546Spatrick
519061da546Spatrick    def _populate_root(self):
520061da546Spatrick        # use current directory as root node
521061da546Spatrick        self.insert_items('', self.delegate.get_child_item_dictionaries())
522061da546Spatrick
523061da546Spatrick    def _update_tree(self, event):
524061da546Spatrick        # user expanded a node - build the related directory
525061da546Spatrick        item_id = self.tree.focus()      # the id of the expanded node
526061da546Spatrick        children = self.tree.get_children(item_id)
527061da546Spatrick        if len(children):
528061da546Spatrick            first_child = children[0]
529061da546Spatrick            # if the node only has a 'dummy' child, remove it and
530061da546Spatrick            # build new directory; skip if the node is already
531061da546Spatrick            # populated
532061da546Spatrick            if self.tree.item(first_child, option='text') == 'dummy':
533061da546Spatrick                self.tree.delete(first_child)
534061da546Spatrick                item_dict = self.item_id_to_item_dict[item_id]
535061da546Spatrick                item_dicts = item_dict[
536061da546Spatrick                    'tree-item-delegate'].get_child_item_dictionaries()
537061da546Spatrick                self.insert_items(item_id, item_dicts)
538061da546Spatrick
539061da546Spatrick
540061da546Spatrick@lldb.command("tk-variables")
541061da546Spatrickdef tk_variable_display(debugger, command, result, dict):
542061da546Spatrick    # needed for tree creation in TK library as it uses sys.argv...
543061da546Spatrick    sys.argv = ['tk-variables']
544061da546Spatrick    target = debugger.GetSelectedTarget()
545061da546Spatrick    if not target:
546061da546Spatrick        print("invalid target", file=result)
547061da546Spatrick        return
548061da546Spatrick    process = target.GetProcess()
549061da546Spatrick    if not process:
550061da546Spatrick        print("invalid process", file=result)
551061da546Spatrick        return
552061da546Spatrick    thread = process.GetSelectedThread()
553061da546Spatrick    if not thread:
554061da546Spatrick        print("invalid thread", file=result)
555061da546Spatrick        return
556061da546Spatrick    frame = thread.GetSelectedFrame()
557061da546Spatrick    if not frame:
558061da546Spatrick        print("invalid frame", file=result)
559061da546Spatrick        return
560061da546Spatrick    # Parse command line args
561061da546Spatrick    command_args = shlex.split(command)
562061da546Spatrick    column_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
563061da546Spatrick                    {'id': 'typename', 'text': 'Type', 'anchor': W, 'stretch': 0},
564061da546Spatrick                    {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
565061da546Spatrick                    {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
566061da546Spatrick    tree = DelegateTree(
567061da546Spatrick        column_dicts,
568061da546Spatrick        FrameTreeItemDelegate(frame),
569061da546Spatrick        'Variables',
570061da546Spatrick        'lldb-tk-variables')
571061da546Spatrick    tree.mainloop()
572061da546Spatrick
573061da546Spatrick
574061da546Spatrick@lldb.command("tk-process")
575061da546Spatrickdef tk_process_display(debugger, command, result, dict):
576061da546Spatrick    # needed for tree creation in TK library as it uses sys.argv...
577061da546Spatrick    sys.argv = ['tk-process']
578061da546Spatrick    target = debugger.GetSelectedTarget()
579061da546Spatrick    if not target:
580061da546Spatrick        print("invalid target", file=result)
581061da546Spatrick        return
582061da546Spatrick    process = target.GetProcess()
583061da546Spatrick    if not process:
584061da546Spatrick        print("invalid process", file=result)
585061da546Spatrick        return
586061da546Spatrick    # Parse command line args
587061da546Spatrick    columnd_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
588061da546Spatrick                     {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
589061da546Spatrick                     {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
590061da546Spatrick    command_args = shlex.split(command)
591061da546Spatrick    tree = DelegateTree(
592061da546Spatrick        columnd_dicts,
593061da546Spatrick        ProcessTreeItemDelegate(process),
594061da546Spatrick        'Process',
595061da546Spatrick        'lldb-tk-process')
596061da546Spatrick    tree.mainloop()
597061da546Spatrick
598061da546Spatrick
599061da546Spatrick@lldb.command("tk-target")
600061da546Spatrickdef tk_target_display(debugger, command, result, dict):
601061da546Spatrick    # needed for tree creation in TK library as it uses sys.argv...
602061da546Spatrick    sys.argv = ['tk-target']
603061da546Spatrick    target = debugger.GetSelectedTarget()
604061da546Spatrick    if not target:
605061da546Spatrick        print("invalid target", file=result)
606061da546Spatrick        return
607061da546Spatrick    # Parse command line args
608061da546Spatrick    columnd_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
609061da546Spatrick                     {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
610061da546Spatrick                     {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
611061da546Spatrick    command_args = shlex.split(command)
612061da546Spatrick    tree = DelegateTree(
613061da546Spatrick        columnd_dicts,
614061da546Spatrick        TargetTreeItemDelegate(target),
615061da546Spatrick        'Target',
616061da546Spatrick        'lldb-tk-target')
617061da546Spatrick    tree.mainloop()
618