]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.python/py-xmethods.py
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.python / py-xmethods.py
CommitLineData
1d506c26 1# Copyright 2014-2024 Free Software Foundation, Inc.
883964a7
SC
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 test the xmethods support
17# in the Python extension language.
18
19import gdb
20import re
21
22from gdb.xmethod import XMethod
23from gdb.xmethod import XMethodMatcher, XMethodWorker
24from gdb.xmethod import SimpleXMethodMatcher
25
26
27def A_plus_A(obj, opr):
13123da8
SM
28 print("From Python <A_plus_A>:")
29 return obj["a"] + opr["a"]
883964a7
SC
30
31
32def plus_plus_A(obj):
13123da8
SM
33 print("From Python <plus_plus_A>:")
34 return obj["a"] + 1
883964a7
SC
35
36
37def A_geta(obj):
13123da8
SM
38 print("From Python <A_geta>:")
39 return obj["a"]
883964a7
SC
40
41
bae19789
MR
42def A_getarray(obj):
43 print("From Python <A_getarray>:")
44 return obj["array"]
45
46
883964a7 47def A_getarrayind(obj, index):
13123da8
SM
48 print("From Python <A_getarrayind>:")
49 return obj["array"][index]
50
883964a7 51
4c082a81 52def A_indexoper(obj, index):
13123da8
SM
53 return obj["array"][index].reference_value()
54
4c082a81 55
bae19789
MR
56def B_getarray(obj):
57 print("From Python <B_getarray>:")
58 return obj["array"].const_value()
59
60
4c082a81 61def B_indexoper(obj, index):
13123da8 62 return obj["array"][index].const_value().reference_value()
4c082a81 63
883964a7 64
13123da8
SM
65type_A = gdb.parse_and_eval("(dop::A *) 0").type.target()
66type_B = gdb.parse_and_eval("(dop::B *) 0").type.target()
bae19789 67type_array = gdb.parse_and_eval("(int[10] *) 0").type.target()
13123da8 68type_int = gdb.parse_and_eval("(int *) 0").type.target()
883964a7
SC
69
70
71# The E class matcher and worker test two things:
72# 1. xmethod returning None.
73# 2. Matcher returning a list of workers.
74
13123da8 75
883964a7
SC
76class E_method_char_worker(XMethodWorker):
77 def __init__(self):
78 pass
79
80 def get_arg_types(self):
13123da8 81 return gdb.lookup_type("char")
883964a7 82
2ce1cdbf 83 def get_result_type(self, obj, arg):
13123da8 84 return gdb.lookup_type("void")
2ce1cdbf 85
883964a7 86 def __call__(self, obj, arg):
13123da8 87 print("From Python <E_method_char>")
883964a7
SC
88 return None
89
90
91class E_method_int_worker(XMethodWorker):
92 def __init__(self):
93 pass
94
95 def get_arg_types(self):
13123da8 96 return gdb.lookup_type("int")
883964a7 97
2ce1cdbf
DE
98 # Note: get_result_type method elided on purpose
99
883964a7 100 def __call__(self, obj, arg):
13123da8 101 print("From Python <E_method_int>")
883964a7
SC
102 return None
103
104
105class E_method_matcher(XMethodMatcher):
106 def __init__(self):
13123da8
SM
107 XMethodMatcher.__init__(self, "E_methods")
108 self.methods = [XMethod("method_int"), XMethod("method_char")]
883964a7
SC
109
110 def match(self, class_type, method_name):
111 class_tag = class_type.unqualified().tag
13123da8 112 if not re.match("^dop::E$", class_tag):
883964a7 113 return None
13123da8 114 if not re.match("^method$", method_name):
883964a7
SC
115 return None
116 workers = []
117 if self.methods[0].enabled:
118 workers.append(E_method_int_worker())
119 if self.methods[1].enabled:
120 workers.append(E_method_char_worker())
121 return workers
122
123
124# The G class method matcher and worker illustrate how to write
125# xmethod matchers and workers for template classes and template
126# methods.
127
13123da8 128
883964a7
SC
129class G_size_diff_worker(XMethodWorker):
130 def __init__(self, class_template_type, method_template_type):
131 self._class_template_type = class_template_type
132 self._method_template_type = method_template_type
133
134 def get_arg_types(self):
135 pass
136
137 def __call__(self, obj):
13123da8
SM
138 print("From Python G<>::size_diff()")
139 return self._method_template_type.sizeof - self._class_template_type.sizeof
883964a7
SC
140
141
142class G_size_mul_worker(XMethodWorker):
143 def __init__(self, class_template_type, method_template_val):
144 self._class_template_type = class_template_type
145 self._method_template_val = method_template_val
146
147 def get_arg_types(self):
148 pass
149
150 def __call__(self, obj):
13123da8 151 print("From Python G<>::size_mul()")
883964a7
SC
152 return self._class_template_type.sizeof * self._method_template_val
153
154
155class G_mul_worker(XMethodWorker):
156 def __init__(self, class_template_type, method_template_type):
157 self._class_template_type = class_template_type
158 self._method_template_type = method_template_type
159
160 def get_arg_types(self):
161 return self._method_template_type
162
163 def __call__(self, obj, arg):
13123da8
SM
164 print("From Python G<>::mul()")
165 return obj["t"] * arg
883964a7
SC
166
167
168class G_methods_matcher(XMethodMatcher):
169 def __init__(self):
13123da8
SM
170 XMethodMatcher.__init__(self, "G_methods")
171 self.methods = [XMethod("size_diff"), XMethod("size_mul"), XMethod("mul")]
883964a7
SC
172
173 def _is_enabled(self, name):
174 for method in self.methods:
175 if method.name == name and method.enabled:
176 return True
177
178 def match(self, class_type, method_name):
179 class_tag = class_type.unqualified().tag
13123da8 180 if not re.match("^dop::G<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", class_tag):
883964a7
SC
181 return None
182 t_name = class_tag[7:-1]
183 try:
184 t_type = gdb.lookup_type(t_name)
185 except gdb.error:
186 return None
13123da8
SM
187 if re.match("^size_diff<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", method_name):
188 if not self._is_enabled("size_diff"):
883964a7
SC
189 return None
190 t1_name = method_name[10:-1]
191 try:
192 t1_type = gdb.lookup_type(t1_name)
193 return G_size_diff_worker(t_type, t1_type)
194 except gdb.error:
195 return None
13123da8
SM
196 if re.match("^size_mul<[ ]*[0-9]+[ ]*>$", method_name):
197 if not self._is_enabled("size_mul"):
883964a7
SC
198 return None
199 m_val = int(method_name[9:-1])
200 return G_size_mul_worker(t_type, m_val)
13123da8
SM
201 if re.match("^mul<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", method_name):
202 if not self._is_enabled("mul"):
883964a7
SC
203 return None
204 t1_name = method_name[4:-1]
205 try:
206 t1_type = gdb.lookup_type(t1_name)
207 return G_mul_worker(t_type, t1_type)
208 except gdb.error:
209 return None
210
211
212global_dm_list = [
13123da8
SM
213 SimpleXMethodMatcher(
214 r"A_plus_A",
215 r"^dop::A$",
216 r"operator\+",
217 A_plus_A,
218 # This is a replacement, hence match the arg type
219 # exactly!
220 type_A.const().reference(),
221 ),
222 SimpleXMethodMatcher(r"plus_plus_A", r"^dop::A$", r"operator\+\+", plus_plus_A),
223 SimpleXMethodMatcher(r"A_geta", r"^dop::A$", r"^geta$", A_geta),
bae19789
MR
224 SimpleXMethodMatcher(
225 r"A_getarray", r"^dop::A$", r"^getarray$", A_getarray, type_array
226 ),
13123da8
SM
227 SimpleXMethodMatcher(
228 r"A_getarrayind", r"^dop::A$", r"^getarrayind$", A_getarrayind, type_int
229 ),
230 SimpleXMethodMatcher(
231 r"A_indexoper", r"^dop::A$", r"operator\[\]", A_indexoper, type_int
232 ),
bae19789
MR
233 SimpleXMethodMatcher(
234 r"B_getarray", r"^dop::B$", r"^getarray$", B_getarray, type_array
235 ),
13123da8
SM
236 SimpleXMethodMatcher(
237 r"B_indexoper", r"^dop::B$", r"operator\[\]", B_indexoper, type_int
238 ),
883964a7
SC
239]
240
241for matcher in global_dm_list:
242 gdb.xmethod.register_xmethod_matcher(gdb, matcher)
13123da8
SM
243gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(), G_methods_matcher())
244gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(), E_method_matcher())