]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/python/lib/gdb/command/explore.py
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / python / lib / gdb / command / explore.py
CommitLineData
06fc020f 1# GDB 'explore' command.
213516ef 2# Copyright (C) 2012-2023 Free Software Foundation, Inc.
06fc020f
SCR
3
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17"""Implementation of the GDB 'explore' command using the GDB Python API."""
18
19import gdb
9a27f2c6 20import sys
06fc020f 21
13123da8 22
06fc020f
SCR
23class Explorer(object):
24 """Internal class which invokes other explorers."""
25
26 # This map is filled by the Explorer.init_env() function
13123da8 27 type_code_to_explorer_map = {}
06fc020f
SCR
28
29 _SCALAR_TYPE_LIST = (
30 gdb.TYPE_CODE_CHAR,
31 gdb.TYPE_CODE_INT,
32 gdb.TYPE_CODE_BOOL,
33 gdb.TYPE_CODE_FLT,
34 gdb.TYPE_CODE_VOID,
35 gdb.TYPE_CODE_ENUM,
36 )
37
38 @staticmethod
39 def guard_expr(expr):
40 length = len(expr)
41 guard = False
42
13123da8 43 if expr[0] == "(" and expr[length - 1] == ")":
06fc020f
SCR
44 pass
45 else:
46 i = 0
47 while i < length:
48 c = expr[i]
13123da8
SM
49 if (
50 c == "_"
51 or ("a" <= c and c <= "z")
52 or ("A" <= c and c <= "Z")
53 or ("0" <= c and c <= "9")
54 ):
06fc020f
SCR
55 pass
56 else:
57 guard = True
58 break
59 i += 1
60
61 if guard:
62 return "(" + expr + ")"
63 else:
64 return expr
65
66 @staticmethod
67 def explore_expr(expr, value, is_child):
68 """Main function to explore an expression value.
69
70 Arguments:
71 expr: The expression string that is being explored.
72 value: The gdb.Value value of the expression.
73 is_child: Boolean value to indicate if the expression is a child.
74 An expression is a child if it is derived from the main
75 expression entered by the user. For example, if the user
76 entered an expression which evaluates to a struct, then
77 when exploring the fields of the struct, is_child is set
78 to True internally.
79
80 Returns:
81 No return value.
82 """
83 type_code = value.type.code
84 if type_code in Explorer.type_code_to_explorer_map:
85 explorer_class = Explorer.type_code_to_explorer_map[type_code]
86 while explorer_class.explore_expr(expr, value, is_child):
87 pass
88 else:
13123da8 89 print("Explorer for type '%s' not yet available.\n" % str(value.type))
06fc020f
SCR
90
91 @staticmethod
92 def explore_type(name, datatype, is_child):
93 """Main function to explore a data type.
94
95 Arguments:
96 name: The string representing the path to the data type being
97 explored.
98 datatype: The gdb.Type value of the data type being explored.
99 is_child: Boolean value to indicate if the name is a child.
100 A name is a child if it is derived from the main name
101 entered by the user. For example, if the user entered
102 the name of struct type, then when exploring the fields
103 of the struct, is_child is set to True internally.
104
105 Returns:
106 No return value.
107 """
108 type_code = datatype.code
109 if type_code in Explorer.type_code_to_explorer_map:
110 explorer_class = Explorer.type_code_to_explorer_map[type_code]
111 while explorer_class.explore_type(name, datatype, is_child):
112 pass
113 else:
13123da8 114 print("Explorer for type '%s' not yet available.\n" % str(datatype))
06fc020f
SCR
115
116 @staticmethod
117 def init_env():
118 """Initializes the Explorer environment.
119 This function should be invoked before starting any exploration. If
120 invoked before an exploration, it need not be invoked for subsequent
121 explorations.
122 """
123 Explorer.type_code_to_explorer_map = {
13123da8
SM
124 gdb.TYPE_CODE_CHAR: ScalarExplorer,
125 gdb.TYPE_CODE_INT: ScalarExplorer,
126 gdb.TYPE_CODE_BOOL: ScalarExplorer,
127 gdb.TYPE_CODE_FLT: ScalarExplorer,
128 gdb.TYPE_CODE_VOID: ScalarExplorer,
129 gdb.TYPE_CODE_ENUM: ScalarExplorer,
130 gdb.TYPE_CODE_STRUCT: CompoundExplorer,
131 gdb.TYPE_CODE_UNION: CompoundExplorer,
132 gdb.TYPE_CODE_PTR: PointerExplorer,
133 gdb.TYPE_CODE_REF: ReferenceExplorer,
134 gdb.TYPE_CODE_RVALUE_REF: ReferenceExplorer,
135 gdb.TYPE_CODE_TYPEDEF: TypedefExplorer,
136 gdb.TYPE_CODE_ARRAY: ArrayExplorer,
06fc020f
SCR
137 }
138
139 @staticmethod
140 def is_scalar_type(type):
141 """Checks whether a type is a scalar type.
142 A type is a scalar type of its type is
143 gdb.TYPE_CODE_CHAR or
144 gdb.TYPE_CODE_INT or
145 gdb.TYPE_CODE_BOOL or
146 gdb.TYPE_CODE_FLT or
147 gdb.TYPE_CODE_VOID or
148 gdb.TYPE_CODE_ENUM.
149
150 Arguments:
151 type: The type to be checked.
152
153 Returns:
154 'True' if 'type' is a scalar type. 'False' otherwise.
155 """
156 return type.code in Explorer._SCALAR_TYPE_LIST
157
158 @staticmethod
159 def return_to_parent_value():
160 """A utility function which prints that the current exploration session
161 is returning to the parent value. Useful when exploring values.
162 """
13123da8
SM
163 print("\nReturning to parent value...\n")
164
06fc020f
SCR
165 @staticmethod
166 def return_to_parent_value_prompt():
167 """A utility function which prompts the user to press the 'enter' key
168 so that the exploration session can shift back to the parent value.
169 Useful when exploring values.
170 """
edae3fd6 171 input("\nPress enter to return to parent value: ")
13123da8 172
06fc020f
SCR
173 @staticmethod
174 def return_to_enclosing_type():
175 """A utility function which prints that the current exploration session
176 is returning to the enclosing type. Useful when exploring types.
177 """
13123da8
SM
178 print("\nReturning to enclosing type...\n")
179
06fc020f
SCR
180 @staticmethod
181 def return_to_enclosing_type_prompt():
182 """A utility function which prompts the user to press the 'enter' key
183 so that the exploration session can shift back to the enclosing type.
184 Useful when exploring types.
185 """
edae3fd6 186 input("\nPress enter to return to enclosing type: ")
06fc020f
SCR
187
188
189class ScalarExplorer(object):
190 """Internal class used to explore scalar values."""
191
192 @staticmethod
193 def explore_expr(expr, value, is_child):
194 """Function to explore scalar values.
195 See Explorer.explore_expr and Explorer.is_scalar_type for more
196 information.
197 """
13123da8
SM
198 print("'%s' is a scalar value of type '%s'." % (expr, value.type))
199 print("%s = %s" % (expr, str(value)))
06fc020f
SCR
200
201 if is_child:
202 Explorer.return_to_parent_value_prompt()
203 Explorer.return_to_parent_value()
204
205 return False
206
207 @staticmethod
208 def explore_type(name, datatype, is_child):
209 """Function to explore scalar types.
210 See Explorer.explore_type and Explorer.is_scalar_type for more
211 information.
212 """
213 if datatype.code == gdb.TYPE_CODE_ENUM:
214 if is_child:
13123da8 215 print("%s is of an enumerated type '%s'." % (name, str(datatype)))
06fc020f 216 else:
13123da8 217 print("'%s' is an enumerated type." % name)
06fc020f
SCR
218 else:
219 if is_child:
13123da8 220 print("%s is of a scalar type '%s'." % (name, str(datatype)))
06fc020f 221 else:
13123da8 222 print("'%s' is a scalar type." % name)
06fc020f
SCR
223
224 if is_child:
225 Explorer.return_to_enclosing_type_prompt()
226 Explorer.return_to_enclosing_type()
227
228 return False
229
230
231class PointerExplorer(object):
232 """Internal class used to explore pointer values."""
233
234 @staticmethod
235 def explore_expr(expr, value, is_child):
236 """Function to explore pointer values.
237 See Explorer.explore_expr for more information.
238 """
13123da8
SM
239 print(
240 "'%s' is a pointer to a value of type '%s'"
241 % (expr, str(value.type.target()))
242 )
edae3fd6 243 option = input(
13123da8
SM
244 "Continue exploring it as a pointer to a single " "value [y/n]: "
245 )
06fc020f
SCR
246 if option == "y":
247 deref_value = None
248 try:
249 deref_value = value.dereference()
250 str(deref_value)
251 except gdb.MemoryError:
13123da8
SM
252 print(
253 "'%s' a pointer pointing to an invalid memory " "location." % expr
254 )
06fc020f
SCR
255 if is_child:
256 Explorer.return_to_parent_value_prompt()
257 return False
13123da8
SM
258 Explorer.explore_expr(
259 "*%s" % Explorer.guard_expr(expr), deref_value, is_child
260 )
06fc020f 261 return False
13123da8 262
edae3fd6 263 option = input("Continue exploring it as a pointer to an " "array [y/n]: ")
06fc020f
SCR
264 if option == "y":
265 while True:
266 index = 0
267 try:
13123da8 268 index = int(
edae3fd6 269 input(
13123da8
SM
270 "Enter the index of the element you "
271 "want to explore in '%s': " % expr
272 )
273 )
06fc020f
SCR
274 except ValueError:
275 break
276 element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index)
277 element = value[index]
278 try:
279 str(element)
280 except gdb.MemoryError:
13123da8 281 print("Cannot read value at index %d." % index)
06fc020f
SCR
282 continue
283 Explorer.explore_expr(element_expr, element, True)
284 return False
285
286 if is_child:
287 Explorer.return_to_parent_value()
288 return False
289
290 @staticmethod
291 def explore_type(name, datatype, is_child):
292 """Function to explore pointer types.
293 See Explorer.explore_type for more information.
294 """
295 target_type = datatype.target()
13123da8 296 print("\n%s is a pointer to a value of type '%s'." % (name, str(target_type)))
06fc020f 297
13123da8 298 Explorer.explore_type("the pointee type of %s" % name, target_type, is_child)
06fc020f
SCR
299 return False
300
301
302class ReferenceExplorer(object):
303 """Internal class used to explore reference (TYPE_CODE_REF) values."""
304
305 @staticmethod
306 def explore_expr(expr, value, is_child):
307 """Function to explore array values.
308 See Explorer.explore_expr for more information.
309 """
310 referenced_value = value.referenced_value()
311 Explorer.explore_expr(expr, referenced_value, is_child)
312 return False
313
314 @staticmethod
315 def explore_type(name, datatype, is_child):
316 """Function to explore pointer types.
317 See Explorer.explore_type for more information.
318 """
319 target_type = datatype.target()
320 Explorer.explore_type(name, target_type, is_child)
321 return False
322
13123da8 323
06fc020f
SCR
324class ArrayExplorer(object):
325 """Internal class used to explore arrays."""
326
327 @staticmethod
328 def explore_expr(expr, value, is_child):
329 """Function to explore array values.
330 See Explorer.explore_expr for more information.
331 """
332 target_type = value.type.target()
13123da8 333 print("'%s' is an array of '%s'." % (expr, str(target_type)))
06fc020f
SCR
334 index = 0
335 try:
13123da8 336 index = int(
edae3fd6 337 input(
13123da8
SM
338 "Enter the index of the element you want to "
339 "explore in '%s': " % expr
340 )
341 )
06fc020f
SCR
342 except ValueError:
343 if is_child:
344 Explorer.return_to_parent_value()
345 return False
346
347 element = None
348 try:
349 element = value[index]
350 str(element)
351 except gdb.MemoryError:
13123da8 352 print("Cannot read value at index %d." % index)
edae3fd6 353 input("Press enter to continue... ")
06fc020f 354 return True
13123da8
SM
355
356 Explorer.explore_expr(
357 "%s[%d]" % (Explorer.guard_expr(expr), index), element, True
358 )
06fc020f
SCR
359 return True
360
361 @staticmethod
362 def explore_type(name, datatype, is_child):
363 """Function to explore array types.
364 See Explorer.explore_type for more information.
365 """
366 target_type = datatype.target()
13123da8 367 print("%s is an array of '%s'." % (name, str(target_type)))
06fc020f 368
13123da8 369 Explorer.explore_type("the array element of %s" % name, target_type, is_child)
06fc020f
SCR
370 return False
371
372
373class CompoundExplorer(object):
374 """Internal class used to explore struct, classes and unions."""
375
376 @staticmethod
377 def _print_fields(print_list):
13123da8 378 """Internal function which prints the fields of a struct/class/union."""
06fc020f
SCR
379 max_field_name_length = 0
380 for pair in print_list:
381 if max_field_name_length < len(pair[0]):
382 max_field_name_length = len(pair[0])
383
06fc020f 384 for pair in print_list:
13123da8 385 print(" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
06fc020f
SCR
386
387 @staticmethod
388 def _get_real_field_count(fields):
13123da8 389 real_field_count = 0
06fc020f
SCR
390 for field in fields:
391 if not field.artificial:
392 real_field_count = real_field_count + 1
393
394 return real_field_count
395
396 @staticmethod
397 def explore_expr(expr, value, is_child):
398 """Function to explore structs/classes and union values.
399 See Explorer.explore_expr for more information.
400 """
401 datatype = value.type
402 type_code = datatype.code
403 fields = datatype.fields()
404
405 if type_code == gdb.TYPE_CODE_STRUCT:
406 type_desc = "struct/class"
407 else:
408 type_desc = "union"
409
410 if CompoundExplorer._get_real_field_count(fields) == 0:
13123da8
SM
411 print(
412 "The value of '%s' is a %s of type '%s' with no fields."
413 % (expr, type_desc, str(value.type))
414 )
06fc020f
SCR
415 if is_child:
416 Explorer.return_to_parent_value_prompt()
417 return False
418
13123da8
SM
419 print(
420 "The value of '%s' is a %s of type '%s' with the following "
421 "fields:\n" % (expr, type_desc, str(value.type))
422 )
06fc020f
SCR
423
424 has_explorable_fields = False
13123da8 425 choice_to_compound_field_map = {}
06fc020f 426 current_choice = 0
13123da8 427 print_list = []
06fc020f
SCR
428 for field in fields:
429 if field.artificial:
430 continue
431 field_full_name = Explorer.guard_expr(expr) + "." + field.name
432 if field.is_base_class:
433 field_value = value.cast(field.type)
434 else:
435 field_value = value[field.name]
436 literal_value = ""
437 if type_code == gdb.TYPE_CODE_UNION:
13123da8
SM
438 literal_value = "<Enter %d to explore this field of type " "'%s'>" % (
439 current_choice,
440 str(field.type),
441 )
06fc020f
SCR
442 has_explorable_fields = True
443 else:
444 if Explorer.is_scalar_type(field.type):
13123da8
SM
445 literal_value = "%s .. (Value of type '%s')" % (
446 str(field_value),
447 str(field.type),
448 )
06fc020f
SCR
449 else:
450 if field.is_base_class:
451 field_desc = "base class"
452 else:
453 field_desc = "field"
13123da8
SM
454 literal_value = "<Enter %d to explore this %s of type " "'%s'>" % (
455 current_choice,
456 field_desc,
457 str(field.type),
458 )
06fc020f
SCR
459 has_explorable_fields = True
460
461 choice_to_compound_field_map[str(current_choice)] = (
13123da8
SM
462 field_full_name,
463 field_value,
464 )
06fc020f
SCR
465 current_choice = current_choice + 1
466
467 print_list.append((field.name, literal_value))
468
469 CompoundExplorer._print_fields(print_list)
13123da8 470 print("")
06fc020f
SCR
471
472 if has_explorable_fields:
edae3fd6 473 choice = input("Enter the field number of choice: ")
06fc020f 474 if choice in choice_to_compound_field_map:
13123da8
SM
475 Explorer.explore_expr(
476 choice_to_compound_field_map[choice][0],
477 choice_to_compound_field_map[choice][1],
478 True,
479 )
06fc020f
SCR
480 return True
481 else:
482 if is_child:
aa6199c6 483 Explorer.return_to_parent_value()
06fc020f
SCR
484 else:
485 if is_child:
486 Explorer.return_to_parent_value_prompt()
487
488 return False
489
490 @staticmethod
491 def explore_type(name, datatype, is_child):
492 """Function to explore struct/class and union types.
493 See Explorer.explore_type for more information.
494 """
495 type_code = datatype.code
496 type_desc = ""
497 if type_code == gdb.TYPE_CODE_STRUCT:
498 type_desc = "struct/class"
499 else:
500 type_desc = "union"
501
502 fields = datatype.fields()
503 if CompoundExplorer._get_real_field_count(fields) == 0:
504 if is_child:
13123da8
SM
505 print(
506 "%s is a %s of type '%s' with no fields."
507 % (name, type_desc, str(datatype))
508 )
06fc020f
SCR
509 Explorer.return_to_enclosing_type_prompt()
510 else:
13123da8 511 print("'%s' is a %s with no fields." % (name, type_desc))
06fc020f
SCR
512 return False
513
514 if is_child:
13123da8
SM
515 print(
516 "%s is a %s of type '%s' "
517 "with the following fields:\n" % (name, type_desc, str(datatype))
518 )
06fc020f 519 else:
13123da8 520 print("'%s' is a %s with the following " "fields:\n" % (name, type_desc))
06fc020f 521
06fc020f 522 current_choice = 0
13123da8
SM
523 choice_to_compound_field_map = {}
524 print_list = []
06fc020f
SCR
525 for field in fields:
526 if field.artificial:
527 continue
528 if field.is_base_class:
529 field_desc = "base class"
530 else:
531 field_desc = "field"
13123da8
SM
532 rhs = "<Enter %d to explore this %s of type '%s'>" % (
533 current_choice,
534 field_desc,
535 str(field.type),
536 )
06fc020f
SCR
537 print_list.append((field.name, rhs))
538 choice_to_compound_field_map[str(current_choice)] = (
13123da8
SM
539 field.name,
540 field.type,
541 field_desc,
542 )
06fc020f
SCR
543 current_choice = current_choice + 1
544
545 CompoundExplorer._print_fields(print_list)
13123da8 546 print("")
06fc020f
SCR
547
548 if len(choice_to_compound_field_map) > 0:
edae3fd6 549 choice = input("Enter the field number of choice: ")
06fc020f
SCR
550 if choice in choice_to_compound_field_map:
551 if is_child:
13123da8
SM
552 new_name = "%s '%s' of %s" % (
553 choice_to_compound_field_map[choice][2],
554 choice_to_compound_field_map[choice][0],
555 name,
556 )
06fc020f 557 else:
13123da8
SM
558 new_name = "%s '%s' of '%s'" % (
559 choice_to_compound_field_map[choice][2],
560 choice_to_compound_field_map[choice][0],
561 name,
562 )
563 Explorer.explore_type(
564 new_name, choice_to_compound_field_map[choice][1], True
565 )
06fc020f
SCR
566 return True
567 else:
568 if is_child:
569 Explorer.return_to_enclosing_type()
570 else:
571 if is_child:
572 Explorer.return_to_enclosing_type_prompt()
573
574 return False
13123da8 575
06fc020f
SCR
576
577class TypedefExplorer(object):
578 """Internal class used to explore values whose type is a typedef."""
579
580 @staticmethod
581 def explore_expr(expr, value, is_child):
582 """Function to explore typedef values.
583 See Explorer.explore_expr for more information.
584 """
585 actual_type = value.type.strip_typedefs()
13123da8
SM
586 print(
587 "The value of '%s' is of type '%s' "
588 "which is a typedef of type '%s'"
589 % (expr, str(value.type), str(actual_type))
590 )
06fc020f
SCR
591
592 Explorer.explore_expr(expr, value.cast(actual_type), is_child)
593 return False
594
595 @staticmethod
596 def explore_type(name, datatype, is_child):
597 """Function to explore typedef types.
598 See Explorer.explore_type for more information.
599 """
600 actual_type = datatype.strip_typedefs()
601 if is_child:
13123da8
SM
602 print(
603 "The type of %s is a typedef of type '%s'." % (name, str(actual_type))
604 )
06fc020f 605 else:
13123da8 606 print("The type '%s' is a typedef of type '%s'." % (name, str(actual_type)))
06fc020f
SCR
607
608 Explorer.explore_type(name, actual_type, is_child)
609 return False
610
611
612class ExploreUtils(object):
613 """Internal class which provides utilities for the main command classes."""
614
615 @staticmethod
616 def check_args(name, arg_str):
617 """Utility to check if adequate number of arguments are passed to an
618 explore command.
619
620 Arguments:
621 name: The name of the explore command.
622 arg_str: The argument string passed to the explore command.
623
624 Returns:
625 True if adequate arguments are passed, false otherwise.
626
627 Raises:
628 gdb.GdbError if adequate arguments are not passed.
629 """
630 if len(arg_str) < 1:
13123da8 631 raise gdb.GdbError("ERROR: '%s' requires an argument." % name)
06fc020f
SCR
632 return False
633 else:
634 return True
635
636 @staticmethod
637 def get_type_from_str(type_str):
638 """A utility function to deduce the gdb.Type value from a string
639 representing the type.
640
641 Arguments:
642 type_str: The type string from which the gdb.Type value should be
643 deduced.
644
645 Returns:
646 The deduced gdb.Type value if possible, None otherwise.
647 """
648 try:
649 # Assume the current language to be C/C++ and make a try.
650 return gdb.parse_and_eval("(%s *)0" % type_str).type.target()
651 except RuntimeError:
652 # If assumption of current language to be C/C++ was wrong, then
653 # lookup the type using the API.
654 try:
655 return gdb.lookup_type(type_str)
656 except RuntimeError:
657 return None
658
659 @staticmethod
660 def get_value_from_str(value_str):
661 """A utility function to deduce the gdb.Value value from a string
662 representing the value.
663
664 Arguments:
665 value_str: The value string from which the gdb.Value value should
666 be deduced.
667
668 Returns:
669 The deduced gdb.Value value if possible, None otherwise.
670 """
671 try:
672 return gdb.parse_and_eval(value_str)
673 except RuntimeError:
674 return None
675
676
677class ExploreCommand(gdb.Command):
678 """Explore a value or a type valid in the current context.
679
13123da8 680 Usage: explore ARG
06fc020f 681
13123da8
SM
682 - ARG is either a valid expression or a type name.
683 - At any stage of exploration, hit the return key (instead of a
684 choice, if any) to return to the enclosing type or value."""
06fc020f
SCR
685
686 def __init__(self):
13123da8
SM
687 super(ExploreCommand, self).__init__(
688 name="explore", command_class=gdb.COMMAND_DATA, prefix=True
689 )
06fc020f
SCR
690
691 def invoke(self, arg_str, from_tty):
1e9983e7 692 if ExploreUtils.check_args("explore", arg_str) is False:
06fc020f
SCR
693 return
694
695 # Check if it is a value
696 value = ExploreUtils.get_value_from_str(arg_str)
697 if value is not None:
698 Explorer.explore_expr(arg_str, value, False)
699 return
700
701 # If it is not a value, check if it is a type
702 datatype = ExploreUtils.get_type_from_str(arg_str)
703 if datatype is not None:
704 Explorer.explore_type(arg_str, datatype, False)
705 return
706
707 # If it is neither a value nor a type, raise an error.
708 raise gdb.GdbError(
13123da8
SM
709 (
710 "'%s' neither evaluates to a value nor is a type "
711 "in the current context." % arg_str
712 )
713 )
06fc020f
SCR
714
715
716class ExploreValueCommand(gdb.Command):
717 """Explore value of an expression valid in the current context.
718
13123da8
SM
719 Usage: explore value ARG
720
721 - ARG is a valid expression.
722 - At any stage of exploration, hit the return key (instead of a
723 choice, if any) to return to the enclosing value."""
06fc020f 724
06fc020f
SCR
725 def __init__(self):
726 super(ExploreValueCommand, self).__init__(
13123da8
SM
727 name="explore value", command_class=gdb.COMMAND_DATA
728 )
06fc020f
SCR
729
730 def invoke(self, arg_str, from_tty):
1e9983e7 731 if ExploreUtils.check_args("explore value", arg_str) is False:
06fc020f
SCR
732 return
733
734 value = ExploreUtils.get_value_from_str(arg_str)
735 if value is None:
736 raise gdb.GdbError(
13123da8
SM
737 (
738 " '%s' does not evaluate to a value in the current "
739 "context." % arg_str
740 )
741 )
06fc020f
SCR
742 return
743
744 Explorer.explore_expr(arg_str, value, False)
745
746
13123da8 747class ExploreTypeCommand(gdb.Command):
2fb009bb 748 """Explore a type or the type of an expression.
06fc020f 749
13123da8 750 Usage: explore type ARG
06fc020f 751
13123da8
SM
752 - ARG is a valid expression or a type name.
753 - At any stage of exploration, hit the return key (instead of a
754 choice, if any) to return to the enclosing type."""
06fc020f
SCR
755
756 def __init__(self):
757 super(ExploreTypeCommand, self).__init__(
13123da8
SM
758 name="explore type", command_class=gdb.COMMAND_DATA
759 )
06fc020f
SCR
760
761 def invoke(self, arg_str, from_tty):
1e9983e7 762 if ExploreUtils.check_args("explore type", arg_str) is False:
06fc020f
SCR
763 return
764
765 datatype = ExploreUtils.get_type_from_str(arg_str)
766 if datatype is not None:
767 Explorer.explore_type(arg_str, datatype, False)
768 return
769
770 value = ExploreUtils.get_value_from_str(arg_str)
771 if value is not None:
13123da8 772 print("'%s' is of type '%s'." % (arg_str, str(value.type)))
06fc020f 773 Explorer.explore_type(str(value.type), value.type, False)
aa6199c6 774 return
06fc020f 775
13123da8
SM
776 raise gdb.GdbError(
777 ("'%s' is not a type or value in the current " "context." % arg_str)
778 )
06fc020f
SCR
779
780
781Explorer.init_env()
782
783ExploreCommand()
784ExploreValueCommand()
785ExploreTypeCommand()