# Unwinder commands.
# Copyright 2015-2019 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)
    if total > 0:
        gdb.invalidate_cached_frames()
    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()
