# Copyright (C) 2013-2020 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/>.

# This file is part of the GDB testsuite.  It tests Python-based
# frame-filters.
import gdb
import itertools
from gdb.FrameDecorator import FrameDecorator
import copy

class Reverse_Function (FrameDecorator):

    def __init__(self, fobj):
        super(Reverse_Function, self).__init__(fobj)
        self.fobj = fobj

    def function (self):
        fname = str (self.fobj.function())
        if (fname == None or fname == ""):
            return None
        if fname == 'end_func':
            extra = self.fobj.inferior_frame().read_var('str').string()
        else:
            extra = ''
        fname = fname[::-1] + extra
        return fname

class Dummy (FrameDecorator):

    def __init__(self, fobj):
        super(Dummy, self).__init__(fobj)
        self.fobj = fobj

    def function (self):
        return "Dummy function"

    def address (self):
        return 0x123

    def filename (self):
        return "Dummy filename"

    def frame_args (self):
        return [("Foo",gdb.Value(12)),("Bar","Stuff"), ("FooBar",42)]

    def frame_locals (self):
        return []

    def line (self):
        return 0

    def elided (self):
        return None

class FrameFilter ():

    def __init__ (self):
        self.name = "Reverse"
        self.priority = 100
        self.enabled = True
        gdb.frame_filters [self.name] = self

    def filter (self, frame_iter):
        # Python 3.x moved the itertools.imap functionality to map(),
        # so check if it is available.
        if hasattr(itertools, "imap"):
            frame_iter = itertools.imap (Reverse_Function,
                                         frame_iter)
        else:
            frame_iter = map(Reverse_Function, frame_iter)

        return frame_iter

class ElidingFrameDecorator(FrameDecorator):

    def __init__(self, frame, elided_frames):
        super(ElidingFrameDecorator, self).__init__(frame)
        self.elided_frames = elided_frames

    def elided(self):
        return iter(self.elided_frames)

    def address (self):
        # Regression test for an overflow in the python layer.
        bitsize = 8 * gdb.lookup_type('void').pointer().sizeof
        mask = (1 << bitsize) - 1
        return 0xffffffffffffffff & mask

class ElidingIterator:
    def __init__(self, ii):
        self.input_iterator = ii

    def __iter__(self):
        return self

    def next(self):
        frame = next(self.input_iterator)
        if str(frame.function()) != 'func1':
            return frame

        # Suppose we want to return the 'func1' frame but elide the
        # next frame.  E.g., if call in our interpreter language takes
        # two C frames to implement, and the first one we see is the
        # "sentinel".
        elided = next(self.input_iterator)
        return ElidingFrameDecorator(frame, [elided])

    # Python 3.x requires __next__(self) while Python 2.x requires
    # next(self).  Define next(self), and for Python 3.x create this
    # wrapper.
    def __next__(self):
        return self.next()

class FrameElider ():

    def __init__ (self):
        self.name = "Elider"
        self.priority = 900
        self.enabled = True
        gdb.frame_filters [self.name] = self

    def filter (self, frame_iter):
        return ElidingIterator (frame_iter)

# This is here so the test can change the kind of error that is
# thrown.
name_error = RuntimeError

# A simple decorator that gives an error when computing the function.
class ErrorInName(FrameDecorator):
    def __init__(self, frame):
        FrameDecorator.__init__(self, frame)

    def function(self):
        raise name_error('whoops')

# A filter that supplies buggy frames.  Disabled by default.
class ErrorFilter():
    def __init__ (self):
        self.name = "Error"
        self.priority = 1
        self.enabled = False
        gdb.frame_filters [self.name] = self

    def filter(self, frame_iter):
        # Python 3.x moved the itertools.imap functionality to map(),
        # so check if it is available.
        if hasattr(itertools, "imap"):
            return itertools.imap (ErrorInName, frame_iter)
        else:
            return map(ErrorInName, frame_iter)

FrameFilter()
FrameElider()
ErrorFilter()
