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