# Copyright (C) 2019-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 GDB's printing of
# nested map like structures.

import re
import gdb

def _iterator1 (pointer, len):
    while len > 0:
        map = pointer.dereference()
        yield ('', map['name'])
        yield ('', map.dereference())
        pointer += 1
        len -= 1

def _iterator2 (pointer1, pointer2, len):
    while len > 0:
        yield ("", pointer1.dereference())
        yield ("", pointer2.dereference())
        pointer1 += 1
        pointer2 += 1
        len -= 1

class pp_map (object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        if (self.val['show_header'] == 0):
            return None
        else:
            return "pp_map"

    def children(self):
        return _iterator2(self.val['keys'],
                          self.val['values'],
                          self.val['length'])

    def display_hint (self):
        return 'map'

class pp_map_map (object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        if (self.val['show_header'] == 0):
            return None
        else:
            return "pp_map_map"

    def children(self):
        return _iterator1(self.val['values'],
                          self.val['length'])

    def display_hint (self):
        return 'map'

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

# Lookup a printer for VAL in the typedefs dict.
def lookup_typedefs_function (val):
    "Look-up and return a pretty-printer that can print val (typedefs)."

    # Get the type.
    type = val.type

    if type == None or type.name == None or type.code != gdb.TYPE_CODE_TYPEDEF:
        return None

    # Iterate over local dictionary of typedef types to determine if a
    # printer is registered for that type.  Return an instantiation of
    # the printer if found.
    for function in typedefs_pretty_printers_dict:
        if function.match (type.name):
            return typedefs_pretty_printers_dict[function] (val)

    # Cannot find a pretty printer.
    return None

def register_pretty_printers ():
    pretty_printers_dict[re.compile ('^struct map_t$')] = pp_map
    pretty_printers_dict[re.compile ('^map_t$')] = pp_map
    pretty_printers_dict[re.compile ('^struct map_map_t$')] = pp_map_map
    pretty_printers_dict[re.compile ('^map_map_t$')] = pp_map_map

# Dict for struct types with typedefs fully stripped.
pretty_printers_dict = {}
# Dict for typedef types.
typedefs_pretty_printers_dict = {}

register_pretty_printers ()
gdb.pretty_printers.append (lookup_function)
gdb.pretty_printers.append (lookup_typedefs_function)
