1# Copyright (C) 2019-2020 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 22def _iterator1 (pointer, len): 23 while len > 0: 24 map = pointer.dereference() 25 yield ('', map['name']) 26 yield ('', map.dereference()) 27 pointer += 1 28 len -= 1 29 30def _iterator2 (pointer1, pointer2, len): 31 while len > 0: 32 yield ("", pointer1.dereference()) 33 yield ("", pointer2.dereference()) 34 pointer1 += 1 35 pointer2 += 1 36 len -= 1 37 38class pp_map (object): 39 def __init__(self, val): 40 self.val = val 41 42 def to_string(self): 43 if (self.val['show_header'] == 0): 44 return None 45 else: 46 return "pp_map" 47 48 def children(self): 49 return _iterator2(self.val['keys'], 50 self.val['values'], 51 self.val['length']) 52 53 def display_hint (self): 54 return 'map' 55 56class pp_map_map (object): 57 def __init__(self, val): 58 self.val = val 59 60 def to_string(self): 61 if (self.val['show_header'] == 0): 62 return None 63 else: 64 return "pp_map_map" 65 66 def children(self): 67 return _iterator1(self.val['values'], 68 self.val['length']) 69 70 def display_hint (self): 71 return 'map' 72 73def lookup_function (val): 74 "Look-up and return a pretty-printer that can print val." 75 76 # Get the type. 77 type = val.type 78 79 # If it points to a reference, get the reference. 80 if type.code == gdb.TYPE_CODE_REF: 81 type = type.target () 82 83 # Get the unqualified type, stripped of typedefs. 84 type = type.unqualified ().strip_typedefs () 85 86 # Get the type name. 87 typename = type.tag 88 89 if typename == None: 90 return None 91 92 # Iterate over local dictionary of types to determine 93 # if a printer is registered for that type. Return an 94 # instantiation of the printer if found. 95 for function in pretty_printers_dict: 96 if function.match (typename): 97 return pretty_printers_dict[function] (val) 98 99 # Cannot find a pretty printer. Return None. 100 return None 101 102# Lookup a printer for VAL in the typedefs dict. 103def lookup_typedefs_function (val): 104 "Look-up and return a pretty-printer that can print val (typedefs)." 105 106 # Get the type. 107 type = val.type 108 109 if type == None or type.name == None or type.code != gdb.TYPE_CODE_TYPEDEF: 110 return None 111 112 # Iterate over local dictionary of typedef types to determine if a 113 # printer is registered for that type. Return an instantiation of 114 # the printer if found. 115 for function in typedefs_pretty_printers_dict: 116 if function.match (type.name): 117 return typedefs_pretty_printers_dict[function] (val) 118 119 # Cannot find a pretty printer. 120 return None 121 122def register_pretty_printers (): 123 pretty_printers_dict[re.compile ('^struct map_t$')] = pp_map 124 pretty_printers_dict[re.compile ('^map_t$')] = pp_map 125 pretty_printers_dict[re.compile ('^struct map_map_t$')] = pp_map_map 126 pretty_printers_dict[re.compile ('^map_map_t$')] = pp_map_map 127 128# Dict for struct types with typedefs fully stripped. 129pretty_printers_dict = {} 130# Dict for typedef types. 131typedefs_pretty_printers_dict = {} 132 133register_pretty_printers () 134gdb.pretty_printers.append (lookup_function) 135gdb.pretty_printers.append (lookup_typedefs_function) 136