# Type printer commands.
# Copyright (C) 2010-2021 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import copy
import gdb

"""GDB commands for working with type-printers."""


class InfoTypePrinter(gdb.Command):
    """GDB command to list all registered type-printers.

    Usage: info type-printers"""

    def __init__(self):
        super(InfoTypePrinter, self).__init__("info type-printers", gdb.COMMAND_DATA)

    def list_type_printers(self, type_printers):
        """Print a list of type printers."""
        # A potential enhancement is to provide an option to list printers in
        # "lookup order" (i.e. unsorted).
        sorted_type_printers = sorted(copy.copy(type_printers), key=lambda x: x.name)
        for printer in sorted_type_printers:
            if printer.enabled:
                enabled = ""
            else:
                enabled = " [disabled]"
            print("  %s%s" % (printer.name, enabled))

    def invoke(self, arg, from_tty):
        """GDB calls this to perform the command."""
        sep = ""
        for objfile in gdb.objfiles():
            if objfile.type_printers:
                print("%sType printers for %s:" % (sep, objfile.filename))
                self.list_type_printers(objfile.type_printers)
                sep = "\n"
        if gdb.current_progspace().type_printers:
            print("%sType printers for program space:" % sep)
            self.list_type_printers(gdb.current_progspace().type_printers)
            sep = "\n"
        if gdb.type_printers:
            print("%sGlobal type printers:" % sep)
            self.list_type_printers(gdb.type_printers)


class _EnableOrDisableCommand(gdb.Command):
    def __init__(self, setting, name):
        super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA)
        self.setting = setting

    def set_some(self, name, printers):
        result = False
        for p in printers:
            if name == p.name:
                p.enabled = self.setting
                result = True
        return result

    def invoke(self, arg, from_tty):
        """GDB calls this to perform the command."""
        for name in arg.split():
            ok = False
            for objfile in gdb.objfiles():
                if self.set_some(name, objfile.type_printers):
                    ok = True
            if self.set_some(name, gdb.current_progspace().type_printers):
                ok = True
            if self.set_some(name, gdb.type_printers):
                ok = True
            if not ok:
                print("No type printer named '%s'" % name)

    def add_some(self, result, word, printers):
        for p in printers:
            if p.name.startswith(word):
                result.append(p.name)

    def complete(self, text, word):
        result = []
        for objfile in gdb.objfiles():
            self.add_some(result, word, objfile.type_printers)
        self.add_some(result, word, gdb.current_progspace().type_printers)
        self.add_some(result, word, gdb.type_printers)
        return result


class EnableTypePrinter(_EnableOrDisableCommand):
    """GDB command to enable the specified type printer.

    Usage: enable type-printer NAME

    NAME is the name of the type-printer."""

    def __init__(self):
        super(EnableTypePrinter, self).__init__(True, "enable type-printer")


class DisableTypePrinter(_EnableOrDisableCommand):
    """GDB command to disable the specified type-printer.

    Usage: disable type-printer NAME

    NAME is the name of the type-printer."""

    def __init__(self):
        super(DisableTypePrinter, self).__init__(False, "disable type-printer")


InfoTypePrinter()
EnableTypePrinter()
DisableTypePrinter()
