# Copyright (C) 2019-2021 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 is 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 is None or type.name is 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)
