1# Type printer commands.
2# Copyright (C) 2010-2020 Free Software Foundation, Inc.
3
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17import copy
18import gdb
19
20"""GDB commands for working with type-printers."""
21
22class InfoTypePrinter(gdb.Command):
23    """GDB command to list all registered type-printers.
24
25Usage: info type-printers"""
26
27    def __init__ (self):
28        super(InfoTypePrinter, self).__init__("info type-printers",
29                                              gdb.COMMAND_DATA)
30
31    def list_type_printers(self, type_printers):
32        """Print a list of type printers."""
33        # A potential enhancement is to provide an option to list printers in
34        # "lookup order" (i.e. unsorted).
35        sorted_type_printers = sorted (copy.copy(type_printers),
36                                       key = lambda x: x.name)
37        for printer in sorted_type_printers:
38            if printer.enabled:
39                enabled = ''
40            else:
41                enabled = " [disabled]"
42            print ("  %s%s" % (printer.name, enabled))
43
44    def invoke(self, arg, from_tty):
45        """GDB calls this to perform the command."""
46        sep = ''
47        for objfile in gdb.objfiles():
48            if objfile.type_printers:
49                print ("%sType printers for %s:" % (sep, objfile.filename))
50                self.list_type_printers(objfile.type_printers)
51                sep = '\n'
52        if gdb.current_progspace().type_printers:
53            print ("%sType printers for program space:" % sep)
54            self.list_type_printers(gdb.current_progspace().type_printers)
55            sep = '\n'
56        if gdb.type_printers:
57            print ("%sGlobal type printers:" % sep)
58            self.list_type_printers(gdb.type_printers)
59
60class _EnableOrDisableCommand(gdb.Command):
61    def __init__(self, setting, name):
62        super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA)
63        self.setting = setting
64
65    def set_some(self, name, printers):
66        result = False
67        for p in printers:
68            if name == p.name:
69                p.enabled = self.setting
70                result = True
71        return result
72
73    def invoke(self, arg, from_tty):
74        """GDB calls this to perform the command."""
75        for name in arg.split():
76            ok = False
77            for objfile in gdb.objfiles():
78                if self.set_some(name, objfile.type_printers):
79                    ok = True
80            if self.set_some(name, gdb.current_progspace().type_printers):
81                ok = True
82            if self.set_some(name, gdb.type_printers):
83                ok = True
84            if not ok:
85                print ("No type printer named '%s'" % name)
86
87    def add_some(self, result, word, printers):
88        for p in printers:
89            if p.name.startswith(word):
90                result.append(p.name)
91
92    def complete(self, text, word):
93        result = []
94        for objfile in gdb.objfiles():
95            self.add_some(result, word, objfile.type_printers)
96        self.add_some(result, word, gdb.current_progspace().type_printers)
97        self.add_some(result, word, gdb.type_printers)
98        return result
99
100class EnableTypePrinter(_EnableOrDisableCommand):
101    """GDB command to enable the specified type printer.
102
103Usage: enable type-printer NAME
104
105NAME is the name of the type-printer."""
106
107    def __init__(self):
108        super(EnableTypePrinter, self).__init__(True, "enable type-printer")
109
110class DisableTypePrinter(_EnableOrDisableCommand):
111    """GDB command to disable the specified type-printer.
112
113Usage: disable type-printer NAME
114
115NAME is the name of the type-printer."""
116
117    def __init__(self):
118        super(DisableTypePrinter, self).__init__(False, "disable type-printer")
119
120InfoTypePrinter()
121EnableTypePrinter()
122DisableTypePrinter()
123