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