10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Pretty-printer utilities.
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Copyright (C) 2010-2016 Free Software Foundation, Inc.
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This program is free software; you can redistribute it and/or modify
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# it under the terms of the GNU General Public License as published by
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the Free Software Foundation; either version 3 of the License, or
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (at your option) any later version.
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This program is distributed in the hope that it will be useful,
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# but WITHOUT ANY WARRANTY; without even the implied warranty of
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# GNU General Public License for more details.
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# You should have received a copy of the GNU General Public License
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# along with this program.  If not, see <http://www.gnu.org/licenses/>.
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Utilities for working with pretty-printers."""
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport gdb
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport gdb.types
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport re
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif sys.version_info[0] > 2:
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Python 3 removed basestring and long
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    basestring = str
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    long = int
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass PrettyPrinter(object):
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """A basic pretty-printer.
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Attributes:
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name: A unique string among all printers for the context in which
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            it is defined (objfile, progspace, or global(gdb)), and should
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            meaningfully describe what can be pretty-printed.
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            E.g., "StringPiece" or "protobufs".
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        subprinters: An iterable object with each element having a `name'
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            attribute, and, potentially, "enabled" attribute.
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            Or this is None if there are no subprinters.
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        enabled: A boolean indicating if the printer is enabled.
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Subprinters are for situations where "one" pretty-printer is actually a
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    collection of several printers.  E.g., The libstdc++ pretty-printer has
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    a pretty-printer for each of several different types, based on regexps.
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # While one might want to push subprinters into the subclass, it's
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # present here to formalize such support to simplify
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # commands/pretty_printers.py.
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, name, subprinters=None):
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name = name
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.subprinters = subprinters
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.enabled = True
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __call__(self, val):
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The subclass must define this.
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise NotImplementedError("PrettyPrinter __call__")
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SubPrettyPrinter(object):
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Baseclass for sub-pretty-printers.
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Sub-pretty-printers needn't use this, but it formalizes what's needed.
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Attributes:
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name: The name of the subprinter.
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        enabled: A boolean indicating if the subprinter is enabled.
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, name):
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name = name
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.enabled = True
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef register_pretty_printer(obj, printer, replace=False):
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Register pretty-printer PRINTER with OBJ.
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    The printer is added to the front of the search list, thus one can override
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    an existing printer if one needs to.  Use a different name when overriding
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    an existing printer, otherwise an exception will be raised; multiple
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    printers with the same name are disallowed.
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Arguments:
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        obj: Either an objfile, progspace, or None (in which case the printer
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            is registered globally).
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        printer: Either a function of one argument (old way) or any object
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            which has attributes: name, enabled, __call__.
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        replace: If True replace any existing copy of the printer.
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            Otherwise if the printer already exists raise an exception.
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Returns:
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Nothing.
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Raises:
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TypeError: A problem with the type of the printer.
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ValueError: The printer's name contains a semicolon ";".
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        RuntimeError: A printer with the same name is already registered.
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If the caller wants the printer to be listable and disableable, it must
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    follow the PrettyPrinter API.  This applies to the old way (functions) too.
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If printer is an object, __call__ is a method of two arguments:
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    self, and the value to be pretty-printed.  See PrettyPrinter.
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Watch for both __name__ and name.
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Functions get the former for free, but we don't want to use an
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # attribute named __foo__ for pretty-printers-as-objects.
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # If printer has both, we use `name'.
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not hasattr(printer, "__name__") and not hasattr(printer, "name"):
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise TypeError("printer missing attribute: name")
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if hasattr(printer, "name") and not hasattr(printer, "enabled"):
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise TypeError("printer missing attribute: enabled")
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not hasattr(printer, "__call__"):
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise TypeError("printer missing attribute: __call__")
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if hasattr(printer, "name"):
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      name = printer.name
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      name = printer.__name__
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if obj is None or obj is gdb:
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if gdb.parameter("verbose"):
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            gdb.write("Registering global %s pretty-printer ...\n" % name)
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        obj = gdb
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if gdb.parameter("verbose"):
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            gdb.write("Registering %s pretty-printer for %s ...\n" % (
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                name, obj.filename))
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Printers implemented as functions are old-style.  In order to not risk
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # breaking anything we do not check __name__ here.
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if hasattr(printer, "name"):
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not isinstance(printer.name, basestring):
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise TypeError("printer name is not a string")
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # If printer provides a name, make sure it doesn't contain ";".
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Semicolon is used by the info/enable/disable pretty-printer commands
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # to delimit subprinters.
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if printer.name.find(";") >= 0:
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise ValueError("semicolon ';' in printer name")
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Also make sure the name is unique.
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Alas, we can't do the same for functions and __name__, they could
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # all have a canonical name like "lookup_function".
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # PERF: gdb records printers in a list, making this inefficient.
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for p in obj.pretty_printers:
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if hasattr(p, "name") and p.name == printer.name:
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if replace:
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    del obj.pretty_printers[i]
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    break
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  raise RuntimeError("pretty-printer already registered: %s" %
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     printer.name)
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i = i + 1
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    obj.pretty_printers.insert(0, printer)
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass RegexpCollectionPrettyPrinter(PrettyPrinter):
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Class for implementing a collection of regular-expression based pretty-printers.
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Intended usage:
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pretty_printer = RegexpCollectionPrettyPrinter("my_library")
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pretty_printer.add_printer("myclass1", "^myclass1$", MyClass1Printer)
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ...
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pretty_printer.add_printer("myclassN", "^myclassN$", MyClassNPrinter)
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    register_pretty_printer(obj, pretty_printer)
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    class RegexpSubprinter(SubPrettyPrinter):
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def __init__(self, name, regexp, gen_printer):
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            super(RegexpCollectionPrettyPrinter.RegexpSubprinter, self).__init__(name)
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.regexp = regexp
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.gen_printer = gen_printer
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.compiled_re = re.compile(regexp)
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, name):
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(RegexpCollectionPrettyPrinter, self).__init__(name, [])
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def add_printer(self, name, regexp, gen_printer):
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Add a printer to the list.
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        The printer is added to the end of the list.
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Arguments:
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            name: The name of the subprinter.
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            regexp: The regular expression, as a string.
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            gen_printer: A function/method that given a value returns an
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                object to pretty-print it.
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Returns:
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            Nothing.
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # NOTE: A previous version made the name of each printer the regexp.
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # That makes it awkward to pass to the enable/disable commands (it's
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # cumbersome to make a regexp of a regexp).  So now the name is a
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # separate parameter.
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.subprinters.append(self.RegexpSubprinter(name, regexp,
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                                      gen_printer))
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __call__(self, val):
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Lookup the pretty-printer for the provided value."""
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Get the type name.
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        typename = gdb.types.get_basic_type(val.type).tag
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not typename:
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            typename = val.type.name
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not typename:
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return None
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Iterate over table of type regexps to determine
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # if a printer is registered for that type.
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Return an instantiation of the printer if found.
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for printer in self.subprinters:
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if printer.enabled and printer.compiled_re.search(typename):
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return printer.gen_printer(val)
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Cannot find a pretty printer.  Return None.
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return None
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# A helper class for printing enum types.  This class is instantiated
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# with a list of enumerators to print a particular Value.
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass _EnumInstance:
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, enumerators, val):
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.enumerators = enumerators
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.val = val
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def to_string(self):
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        flag_list = []
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        v = long(self.val)
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        any_found = False
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for (e_name, e_value) in self.enumerators:
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if v & e_value != 0:
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                flag_list.append(e_name)
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                v = v & ~e_value
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                any_found = True
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not any_found or v != 0:
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Leftover value.
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            flag_list.append('<unknown: 0x%x>' % v)
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return "0x%x [%s]" % (int(self.val), " | ".join(flag_list))
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FlagEnumerationPrinter(PrettyPrinter):
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """A pretty-printer which can be used to print a flag-style enumeration.
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A flag-style enumeration is one where the enumerators are or'd
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    together to create values.  The new printer will print these
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    symbolically using '|' notation.  The printer must be registered
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    manually.  This printer is most useful when an enum is flag-like,
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    but has some overlap.  GDB's built-in printing will not handle
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    this case, but this printer will attempt to."""
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, enum_type):
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(FlagEnumerationPrinter, self).__init__(enum_type)
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.initialized = False
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __call__(self, val):
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not self.initialized:
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.initialized = True
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            flags = gdb.lookup_type(self.name)
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.enumerators = []
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for field in flags.fields():
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.enumerators.append((field.name, field.enumval))
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Sorting the enumerators by value usually does the right
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # thing.
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.enumerators.sort(key = lambda x: x[1])
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.enabled:
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return _EnumInstance(self.enumerators, val)
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return None
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Builtin pretty-printers.
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# The set is defined as empty, and files in printing/*.py add their printers
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# to this with add_builtin_pretty_printer.
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_builtin_pretty_printers = RegexpCollectionPrettyPrinter("builtin")
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoregister_pretty_printer(None, _builtin_pretty_printers)
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Add a builtin pretty-printer.
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef add_builtin_pretty_printer(name, regexp, printer):
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _builtin_pretty_printers.add_printer(name, regexp, printer)
286