# Copyright (C) 2008, 2009 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 pretty
# printers.

import re

# Test returning a Value from a printer.
class string_print:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return self.val['whybother']['contents']

# Test a class-based printer.
class ContainerPrinter:
    class _iterator:
        def __init__ (self, pointer, len):
            self.start = pointer
            self.pointer = pointer
            self.end = pointer + len

        def __iter__(self):
            return self

        def next(self):
            if self.pointer == self.end:
                raise StopIteration
            result = self.pointer
            self.pointer = self.pointer + 1
            return ('[%d]' % int (result - self.start), result.dereference())

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return 'container %s with %d elements' % (self.val['name'], self.val['len'])

    def children(self):
        return self._iterator(self.val['elements'], self.val['len'])

class pp_s:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        a = self.val["a"]
        b = self.val["b"]
        if a.address != b:
            raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b)))
        return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"

class pp_ss:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"

class pp_sss:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "a=<" + str(self.val['a']) + "> b=<" + str(self.val["b"]) + ">"

class pp_multiple_virtual:
    def __init__ (self, val):
        self.val = val

    def to_string (self):
        return "pp value variable is: " + str (self.val['value'])

class pp_vbase1:
    def __init__ (self, val):
        self.val = val

    def to_string (self):
        return "pp class name: " + self.val.type.tag

class pp_nullstr:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return self.val['s'].string(gdb.parameter('target-charset'))

class pp_ns:
    "Print a std::basic_string of some kind"

    def __init__(self, val):
        self.val = val

    def to_string(self):
        len = self.val['length']
        return self.val['null_str'].string (gdb.parameter ('target-charset'), length = len)

    def display_hint (self):
        return 'string'

class pp_outer:
    "Print struct outer"

    def __init__ (self, val):
        self.val = val

    def to_string (self):
        return "x = %s" % self.val['x']

    def children (self):
        yield 's', self.val['s']
        yield 'x', self.val['x']

def lookup_function (val):
    "Look-up and return a pretty-printer that can print val."

    # Get the type.
    type = val.type

    # If it points to a reference, get the reference.
    if type.code == gdb.TYPE_CODE_REF:
        type = type.target ()

    # Get the unqualified type, stripped of typedefs.
    type = type.unqualified ().strip_typedefs ()

    # Get the type name.    
    typename = type.tag

    if typename == None:
        return None

    # Iterate over local dictionary of types to determine
    # if a printer is registered for that type.  Return an
    # instantiation of the printer if found.
    for function in pretty_printers_dict:
        if function.match (typename):
            return pretty_printers_dict[function] (val)
        
    # Cannot find a pretty printer.  Return None.

    return None


def register_pretty_printers ():
    pretty_printers_dict[re.compile ('^struct s$')]   = pp_s
    pretty_printers_dict[re.compile ('^s$')]   = pp_s
    pretty_printers_dict[re.compile ('^S$')]   = pp_s

    pretty_printers_dict[re.compile ('^struct ss$')]  = pp_ss
    pretty_printers_dict[re.compile ('^ss$')]  = pp_ss
    pretty_printers_dict[re.compile ('^const S &$')]   = pp_s
    pretty_printers_dict[re.compile ('^SSS$')]  = pp_sss
    
    pretty_printers_dict[re.compile ('^VirtualTest$')] =  pp_multiple_virtual
    pretty_printers_dict[re.compile ('^Vbase1$')] =  pp_vbase1

    pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
    pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
    
    # Note that we purposely omit the typedef names here.
    # Printer lookup is based on canonical name.
    # However, we do need both tagged and untagged variants, to handle
    # both the C and C++ cases.
    pretty_printers_dict[re.compile ('^struct string_repr$')] = string_print
    pretty_printers_dict[re.compile ('^struct container$')] = ContainerPrinter
    pretty_printers_dict[re.compile ('^string_repr$')] = string_print
    pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter
    
    pretty_printers_dict[re.compile ('^struct ns$')]  = pp_ns
    pretty_printers_dict[re.compile ('^ns$')]  = pp_ns

    pretty_printers_dict[re.compile ('^struct outerstruct$')]  = pp_outer
    pretty_printers_dict[re.compile ('^outerstruct$')]  = pp_outer

pretty_printers_dict = {}

register_pretty_printers ()
gdb.pretty_printers.append (lookup_function)
