# 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()
