# Unwinder commands.
# Copyright 2015-2016 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 gdb
import re


def validate_regexp(exp, idstring):
    try:
        return re.compile(exp)
    except SyntaxError:
        raise SyntaxError("Invalid %s regexp: %s." % (idstring, exp))


def parse_unwinder_command_args(arg):
    """Internal utility to parse unwinder command argv.

    Arguments:
        arg: The arguments to the command. The format is:
             [locus-regexp [name-regexp]]

    Returns:
        A 2-tuple of compiled regular expressions.

    Raises:
        SyntaxError: an error processing ARG
    """

    argv = gdb.string_to_argv(arg)
    argc = len(argv)
    if argc > 2:
        raise SyntaxError("Too many arguments.")
    locus_regexp = ""
    name_regexp = ""
    if argc >= 1:
        locus_regexp = argv[0]
        if argc >= 2:
            name_regexp = argv[1]
    return (validate_regexp(locus_regexp, "locus"),
            validate_regexp(name_regexp, "unwinder"))


class InfoUnwinder(gdb.Command):
    """GDB command to list unwinders.

    Usage: info unwinder [locus-regexp [name-regexp]]

    LOCUS-REGEXP is a regular expression matching the location of the
    unwinder.  If it is omitted, all registered unwinders from all
    loci are listed.  A locus can be 'global', 'progspace' to list
    the unwinders from the current progspace, or a regular expression
    matching filenames of objfiles.

    NAME-REGEXP is a regular expression to filter unwinder names.  If
    this omitted for a specified locus, then all registered unwinders
    in the locus are listed.
    """

    def __init__(self):
        super(InfoUnwinder, self).__init__("info unwinder",
                                            gdb.COMMAND_STACK)

    def list_unwinders(self, title, unwinders, name_re):
        """Lists the unwinders whose name matches regexp.

        Arguments:
            title: The line to print before the list.
            unwinders: The list of the unwinders.
            name_re: unwinder name filter.
        """
        if not unwinders:
            return
        print(title)
        for unwinder in unwinders:
            if name_re.match(unwinder.name):
                print("  %s%s" % (unwinder.name,
                                  "" if unwinder.enabled else " [disabled]"))

    def invoke(self, arg, from_tty):
        locus_re, name_re = parse_unwinder_command_args(arg)
        if locus_re.match("global"):
            self.list_unwinders("Global:", gdb.frame_unwinders,
                                name_re)
        if locus_re.match("progspace"):
            cp = gdb.current_progspace()
            self.list_unwinders("Progspace %s:" % cp.filename,
                                cp.frame_unwinders, name_re)
        for objfile in gdb.objfiles():
            if locus_re.match(objfile.filename):
                self.list_unwinders("Objfile %s:" % objfile.filename,
                                    objfile.frame_unwinders, name_re)


def do_enable_unwinder1(unwinders, name_re, flag):
    """Enable/disable unwinders whose names match given regex.

    Arguments:
        unwinders: The list of unwinders.
        name_re: Unwinder name filter.
        flag: Enable/disable.

    Returns:
        The number of unwinders affected.
    """
    total = 0
    for unwinder in unwinders:
        if name_re.match(unwinder.name):
            unwinder.enabled = flag
            total += 1
    return total


def do_enable_unwinder(arg, flag):
    """Enable/disable unwinder(s)."""
    (locus_re, name_re) = parse_unwinder_command_args(arg)
    total = 0
    if locus_re.match("global"):
        total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
    if locus_re.match("progspace"):
        total += do_enable_unwinder1(gdb.current_progspace().frame_unwinders,
                                     name_re, flag)
    for objfile in gdb.objfiles():
        if locus_re.match(objfile.filename):
            total += do_enable_unwinder1(objfile.frame_unwinders, name_re,
                                         flag)
    print("%d unwinder%s %s" % (total, "" if total == 1 else "s",
                                "enabled" if flag else "disabled"))


class EnableUnwinder(gdb.Command):
    """GDB command to enable unwinders.

    Usage: enable unwinder [locus-regexp [name-regexp]]

    LOCUS-REGEXP is a regular expression specifying the unwinders to
    enable.  It can 'global', 'progspace', or the name of an objfile
    within that progspace.

    NAME_REGEXP is a regular expression to filter unwinder names.  If
    this omitted for a specified locus, then all registered unwinders
    in the locus are affected.

    """

    def __init__(self):
        super(EnableUnwinder, self).__init__("enable unwinder",
                                             gdb.COMMAND_STACK)

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


class DisableUnwinder(gdb.Command):
    """GDB command to disable the specified unwinder.

    Usage: disable unwinder [locus-regexp [name-regexp]]

    LOCUS-REGEXP is a regular expression specifying the unwinders to
    disable.  It can 'global', 'progspace', or the name of an objfile
    within that progspace.

    NAME_REGEXP is a regular expression to filter unwinder names.  If
    this omitted for a specified locus, then all registered unwinders
    in the locus are affected.

    """

    def __init__(self):
        super(DisableUnwinder, self).__init__("disable unwinder",
                                              gdb.COMMAND_STACK)

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


def register_unwinder_commands():
    """Installs the unwinder commands."""
    InfoUnwinder()
    EnableUnwinder()
    DisableUnwinder()


register_unwinder_commands()
