1# Copyright (C) 2019-2023 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# This file is part of the GDB testsuite. It tests GDB's printing of 17# nested map like structures. 18 19import re 20import gdb 21 22 23def _iterator1(pointer, len): 24 while len > 0: 25 map = pointer.dereference() 26 yield ("", map["name"]) 27 yield ("", map.dereference()) 28 pointer += 1 29 len -= 1 30 31 32def _iterator2(pointer1, pointer2, len): 33 while len > 0: 34 yield ("", pointer1.dereference()) 35 yield ("", pointer2.dereference()) 36 pointer1 += 1 37 pointer2 += 1 38 len -= 1 39 40 41class pp_map(object): 42 def __init__(self, val): 43 self.val = val 44 45 def to_string(self): 46 if self.val["show_header"] == 0: 47 return None 48 else: 49 return "pp_map" 50 51 def children(self): 52 return _iterator2(self.val["keys"], self.val["values"], self.val["length"]) 53 54 def display_hint(self): 55 return "map" 56 57 58class pp_map_map(object): 59 def __init__(self, val): 60 self.val = val 61 62 def to_string(self): 63 if self.val["show_header"] == 0: 64 return None 65 else: 66 return "pp_map_map" 67 68 def children(self): 69 return _iterator1(self.val["values"], self.val["length"]) 70 71 def display_hint(self): 72 return "map" 73 74 75def lookup_function(val): 76 "Look-up and return a pretty-printer that can print val." 77 78 # Get the type. 79 type = val.type 80 81 # If it points to a reference, get the reference. 82 if type.code == gdb.TYPE_CODE_REF: 83 type = type.target() 84 85 # Get the unqualified type, stripped of typedefs. 86 type = type.unqualified().strip_typedefs() 87 88 # Get the type name. 89 typename = type.tag 90 91 if typename is None: 92 return None 93 94 # Iterate over local dictionary of types to determine 95 # if a printer is registered for that type. Return an 96 # instantiation of the printer if found. 97 for function in pretty_printers_dict: 98 if function.match(typename): 99 return pretty_printers_dict[function](val) 100 101 # Cannot find a pretty printer. Return None. 102 return None 103 104 105# Lookup a printer for VAL in the typedefs dict. 106def lookup_typedefs_function(val): 107 "Look-up and return a pretty-printer that can print val (typedefs)." 108 109 # Get the type. 110 type = val.type 111 112 if type is None or type.name is None or type.code != gdb.TYPE_CODE_TYPEDEF: 113 return None 114 115 # Iterate over local dictionary of typedef types to determine if a 116 # printer is registered for that type. Return an instantiation of 117 # the printer if found. 118 for function in typedefs_pretty_printers_dict: 119 if function.match(type.name): 120 return typedefs_pretty_printers_dict[function](val) 121 122 # Cannot find a pretty printer. 123 return None 124 125 126def register_pretty_printers(): 127 pretty_printers_dict[re.compile("^struct map_t$")] = pp_map 128 pretty_printers_dict[re.compile("^map_t$")] = pp_map 129 pretty_printers_dict[re.compile("^struct map_map_t$")] = pp_map_map 130 pretty_printers_dict[re.compile("^map_map_t$")] = pp_map_map 131 132 133# Dict for struct types with typedefs fully stripped. 134pretty_printers_dict = {} 135# Dict for typedef types. 136typedefs_pretty_printers_dict = {} 137 138register_pretty_printers() 139gdb.pretty_printers.append(lookup_function) 140gdb.pretty_printers.append(lookup_typedefs_function) 141