# Pretty-printer commands.
# Copyright (C) 2010, 2011 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/>.

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

import copy
import gdb
import re


def parse_printer_regexps(arg):
    """Internal utility to parse a pretty-printer command argv.

    Arguments:
        arg: The arguments to the command.  The format is:
             [object-regexp [name-regexp]].
             Individual printers in a collection are named as
             printer-name;subprinter-name.

    Returns:
        The result is a 3-tuple of compiled regular expressions, except that
        the resulting compiled subprinter regexp is None if not provided.

    Raises:
        SyntaxError: an error processing ARG
    """

    argv = gdb.string_to_argv(arg);
    argc = len(argv)
    object_regexp = ""  # match everything
    name_regexp = ""  # match everything
    subname_regexp = None
    if argc > 3:
        raise SyntaxError("too many arguments")
    if argc >= 1:
        object_regexp = argv[0]
    if argc >= 2:
        name_subname = argv[1].split(";", 1)
        name_regexp = name_subname[0]
        if len(name_subname) == 2:
            subname_regexp = name_subname[1]
    # That re.compile raises SyntaxError was determined empirically.
    # We catch it and reraise it to provide a slightly more useful
    # error message for the user.
    try:
        object_re = re.compile(object_regexp)
    except SyntaxError:
        raise SyntaxError("invalid object regexp: %s" % object_regexp)
    try:
        name_re = re.compile (name_regexp)
    except SyntaxError:
        raise SyntaxError("invalid name regexp: %s" % name_regexp)
    if subname_regexp is not None:
        try:
            subname_re = re.compile(subname_regexp)
        except SyntaxError:
            raise SyntaxError("invalid subname regexp: %s" % subname_regexp)
    else:
        subname_re = None
    return(object_re, name_re, subname_re)


def printer_enabled_p(printer):
    """Internal utility to see if printer (or subprinter) is enabled."""
    if hasattr(printer, "enabled"):
        return printer.enabled
    else:
        return True


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

    Usage: info pretty-printer [object-regexp [name-regexp]]

    OBJECT-REGEXP is a regular expression matching the objects to list.
    Objects are "global", the program space's file, and the objfiles within
    that program space.

    NAME-REGEXP matches the name of the pretty-printer.
    Individual printers in a collection are named as
    printer-name;subprinter-name.
    """

    def __init__ (self):
        super(InfoPrettyPrinter, self).__init__("info pretty-printer",
                                                 gdb.COMMAND_DATA)

    @staticmethod
    def enabled_string(printer):
        """Return "" if PRINTER is enabled, otherwise " [disabled]"."""
        if printer_enabled_p(printer):
            return ""
        else:
            return " [disabled]"

    @staticmethod
    def printer_name(printer):
        """Return the printer's name."""
        if hasattr(printer, "name"):
            return printer.name
        if hasattr(printer, "__name__"):
            return printer.__name__
        # This "shouldn't happen", but the public API allows for
        # direct additions to the pretty-printer list, and we shouldn't
        # crash because someone added a bogus printer.
        # Plus we want to give the user a way to list unknown printers.
        return "unknown"

    def list_pretty_printers(self, pretty_printers, name_re, subname_re):
        """Print a list of pretty-printers."""
        # A potential enhancement is to provide an option to list printers in
        # "lookup order" (i.e. unsorted).
        sorted_pretty_printers = copy.copy(pretty_printers)
        sorted_pretty_printers.sort(lambda x, y:
                                        cmp(self.printer_name(x),
                                            self.printer_name(y)))
        for printer in sorted_pretty_printers:
            name = self.printer_name(printer)
            enabled = self.enabled_string(printer)
            if name_re.match(name):
                print "  %s%s" % (name, enabled)
                if (hasattr(printer, "subprinters") and
                    printer.subprinters is not None):
                    sorted_subprinters = copy.copy(printer.subprinters)
                    sorted_subprinters.sort(lambda x, y:
                                                cmp(self.printer_name(x),
                                                    self.printer_name(y)))
                    for subprinter in sorted_subprinters:
                        if (not subname_re or
                            subname_re.match(subprinter.name)):
                            print ("    %s%s" %
                                   (subprinter.name,
                                    self.enabled_string(subprinter)))

    def invoke1(self, title, printer_list,
                obj_name_to_match, object_re, name_re, subname_re):
        """Subroutine of invoke to simplify it."""
        if printer_list and object_re.match(obj_name_to_match):
            print title
            self.list_pretty_printers(printer_list, name_re, subname_re)

    def invoke(self, arg, from_tty):
        """GDB calls this to perform the command."""
        (object_re, name_re, subname_re) = parse_printer_regexps(arg)
        self.invoke1("global pretty-printers:", gdb.pretty_printers,
                     "global", object_re, name_re, subname_re)
        cp = gdb.current_progspace()
        self.invoke1("progspace %s pretty-printers:" % cp.filename,
                     cp.pretty_printers, "progspace",
                     object_re, name_re, subname_re)
        for objfile in gdb.objfiles():
            self.invoke1("  objfile %s pretty-printers:" % objfile.filename,
                         objfile.pretty_printers, objfile.filename,
                         object_re, name_re, subname_re)


def count_enabled_printers(pretty_printers):
    """Return a 2-tuple of number of enabled and total printers."""
    enabled = 0
    total = 0
    for printer in pretty_printers:
        if (hasattr(printer, "subprinters")
            and printer.subprinters is not None):
            if printer_enabled_p(printer):
                for subprinter in printer.subprinters:
                    if printer_enabled_p(subprinter):
                        enabled += 1
            total += len(printer.subprinters)
        else:
            if printer_enabled_p(printer):
                enabled += 1
            total += 1
    return (enabled, total)


def count_all_enabled_printers():
    """Return a 2-tuble of the enabled state and total number of all printers.
    This includes subprinters.
    """
    enabled_count = 0
    total_count = 0
    (t_enabled, t_total) = count_enabled_printers(gdb.pretty_printers)
    enabled_count += t_enabled
    total_count += t_total
    (t_enabled, t_total) = count_enabled_printers(gdb.current_progspace().pretty_printers)
    enabled_count += t_enabled
    total_count += t_total
    for objfile in gdb.objfiles():
        (t_enabled, t_total) = count_enabled_printers(objfile.pretty_printers)
        enabled_count += t_enabled
        total_count += t_total
    return (enabled_count, total_count)


def pluralize(text, n, suffix="s"):
    """Return TEXT pluralized if N != 1."""
    if n != 1:
        return "%s%s" % (text, suffix)
    else:
        return text


def show_pretty_printer_enabled_summary():
    """Print the number of printers enabled/disabled.
    We count subprinters individually.
    """
    (enabled_count, total_count) = count_all_enabled_printers()
    print "%d of %d printers enabled" % (enabled_count, total_count)


def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
    """Worker for enabling/disabling pretty-printers.

    Arguments:
        pretty_printers: list of pretty-printers
        name_re: regular-expression object to select printers
        subname_re: regular expression object to select subprinters or None
                    if all are affected
        flag: True for Enable, False for Disable

    Returns:
        The number of printers affected.
        This is just for informational purposes for the user.
    """
    total = 0
    for printer in pretty_printers:
        if (hasattr(printer, "name") and name_re.match(printer.name) or
            hasattr(printer, "__name__") and name_re.match(printer.__name__)):
            if (hasattr(printer, "subprinters") and
                printer.subprinters is not None):
                if not subname_re:
                    # Only record printers that change state.
                    if printer_enabled_p(printer) != flag:
                        for subprinter in printer.subprinters:
                            if printer_enabled_p(subprinter):
                                total += 1
                    # NOTE: We preserve individual subprinter settings.
                    printer.enabled = flag
                else:
                    # NOTE: Whether this actually disables the subprinter
                    # depends on whether the printer's lookup function supports
                    # the "enable" API.  We can only assume it does.
                    for subprinter in printer.subprinters:
                        if subname_re.match(subprinter.name):
                            # Only record printers that change state.
                           if (printer_enabled_p(printer) and
                               printer_enabled_p(subprinter) != flag):
                               total += 1
                           subprinter.enabled = flag
            else:
                # This printer has no subprinters.
                # If the user does "disable pretty-printer .* .* foo"
                # should we disable printers that don't have subprinters?
                # How do we apply "foo" in this context?  Since there is no
                # "foo" subprinter it feels like we should skip this printer.
                # There's still the issue of how to handle
                # "disable pretty-printer .* .* .*", and every other variation
                # that can match everything.  For now punt and only support
                # "disable pretty-printer .* .*" (i.e. subname is elided)
                # to disable everything.
                if not subname_re:
                    # Only record printers that change state.
                    if printer_enabled_p(printer) != flag:
                        total += 1
                    printer.enabled = flag
    return total


def do_enable_pretty_printer (arg, flag):
    """Internal worker for enabling/disabling pretty-printers."""
    (object_re, name_re, subname_re) = parse_printer_regexps(arg)

    total = 0
    if object_re.match("global"):
        total += do_enable_pretty_printer_1(gdb.pretty_printers,
                                            name_re, subname_re, flag)
    cp = gdb.current_progspace()
    if object_re.match("progspace"):
        total += do_enable_pretty_printer_1(cp.pretty_printers,
                                            name_re, subname_re, flag)
    for objfile in gdb.objfiles():
        if object_re.match(objfile.filename):
            total += do_enable_pretty_printer_1(objfile.pretty_printers,
                                                name_re, subname_re, flag)

    if flag:
        state = "enabled"
    else:
        state = "disabled"
    print "%d %s %s" % (total, pluralize("printer", total), state)

    # Print the total list of printers currently enabled/disabled.
    # This is to further assist the user in determining whether the result
    # is expected.  Since we use regexps to select it's useful.
    show_pretty_printer_enabled_summary()


# Enable/Disable one or more pretty-printers.
#
# This is intended for use when a broken pretty-printer is shipped/installed
# and the user wants to disable that printer without disabling all the other
# printers.
#
# A useful addition would be -v (verbose) to show each printer affected.

class EnablePrettyPrinter (gdb.Command):
    """GDB command to enable the specified pretty-printer.

    Usage: enable pretty-printer [object-regexp [name-regexp]]

    OBJECT-REGEXP is a regular expression matching the objects to examine.
    Objects are "global", the program space's file, and the objfiles within
    that program space.

    NAME-REGEXP matches the name of the pretty-printer.
    Individual printers in a collection are named as
    printer-name;subprinter-name.
    """

    def __init__(self):
        super(EnablePrettyPrinter, self).__init__("enable pretty-printer",
                                                   gdb.COMMAND_DATA)

    def invoke(self, arg, from_tty):
        """GDB calls this to perform the command."""
        do_enable_pretty_printer(arg, True)


class DisablePrettyPrinter (gdb.Command):
    """GDB command to disable the specified pretty-printer.

    Usage: disable pretty-printer [object-regexp [name-regexp]]

    OBJECT-REGEXP is a regular expression matching the objects to examine.
    Objects are "global", the program space's file, and the objfiles within
    that program space.

    NAME-REGEXP matches the name of the pretty-printer.
    Individual printers in a collection are named as
    printer-name;subprinter-name.
    """

    def __init__(self):
        super(DisablePrettyPrinter, self).__init__("disable pretty-printer",
                                                   gdb.COMMAND_DATA)

    def invoke(self, arg, from_tty):
        """GDB calls this to perform the command."""
        do_enable_pretty_printer(arg, False)


def register_pretty_printer_commands():
    """Call from a top level script to install the pretty-printer commands."""
    InfoPrettyPrinter()
    EnablePrettyPrinter()
    DisablePrettyPrinter()

register_pretty_printer_commands()
