# Type printer commands.
# Copyright (C) 2010-2013 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.name))
                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()
