diff -rupN src/gdb/data-directory/Makefile.in src_local/gdb/data-directory/Makefile.in
--- src/gdb/data-directory/Makefile.in 2011-08-17 16:11:20.000000000 +0530
+++ src_local/gdb/data-directory/Makefile.in 2011-11-12 12:07:34.802506703 +0530
@@ -58,7 +58,8 @@ PYTHON_FILES = \
gdb/prompt.py \
gdb/command/__init__.py \
gdb/command/pretty_printers.py \
- gdb/command/prompt.py
+ gdb/command/prompt.py \
+ gdb/command/explore.py
FLAGS_TO_PASS = \
"prefix=$(prefix)" \
diff -rupN src/gdb/python/lib/gdb/command/explore.py src_local/gdb/python/lib/gdb/command/explore.py
--- src/gdb/python/lib/gdb/command/explore.py 1970-01-01 05:30:00.000000000 +0530
+++ src_local/gdb/python/lib/gdb/command/explore.py 2011-12-27 10:45:00.090174863 +0530
@@ -0,0 +1,693 @@
+# GDB 'explore' command.
+# Copyright (C) 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+"""Implementation of the GDB 'explore' command using the GDB Python API."""
+
+import gdb
+
+class Explorer(object):
+ """Internal class which invokes other explorers."""
+
+ # This map is filled by the Explorer.init_env() function
+ type_code_to_explorer_map = { }
+
+ _SCALAR_TYPE_LIST = (
+ gdb.TYPE_CODE_CHAR,
+ gdb.TYPE_CODE_INT,
+ gdb.TYPE_CODE_BOOL,
+ gdb.TYPE_CODE_FLT,
+ gdb.TYPE_CODE_VOID,
+ gdb.TYPE_CODE_ENUM,
+ )
+
+ @staticmethod
+ def explore_expr(expr, value, is_child):
+ """Main function to explore an expression value.
+
+ Arguments:
+ expr: The expression string that is being explored.
+ value: The gdb.Value value of the expression.
+ is_child: Boolean value to indicate if the expression is a child.
+ An expression is a child if it is derived from the main
+ expression entered by the user. For example, if the user
+ entered an expression which evaluates to a struct, then
+ when exploring the fields of the struct, is_child is set
+ to True internally.
+
+ Returns:
+ No return value.
+ """
+ type_code = value.type.code
+ if type_code in Explorer.type_code_to_explorer_map:
+ if expr[0] == '*':
+ expr = "(%s)" % expr
+ explorer_class = Explorer.type_code_to_explorer_map[type_code]
+ while explorer_class.explore_expr(expr, value, is_child):
+ pass
+ else:
+ print ("Explorer for type '%s' not yet available.\n" %
+ str(value.type))
+
+ @staticmethod
+ def explore_type(name, datatype, is_child):
+ """Main function to explore a data type.
+
+ Arguments:
+ name: The string representing the path to the data type being
+ explored.
+ datatype: The gdb.Type value of the data type being explored.
+ is_child: Boolean value to indicate if the name is a child.
+ A name is a child if it is derived from the main name
+ entered by the user. For example, if the user entered the
+ name of struct type, then when exploring the fields of the
+ struct, is_child is set to True internally.
+
+ Returns:
+ No return value.
+ """
+ type_code = datatype.code
+ if type_code in Explorer.type_code_to_explorer_map:
+ explorer_class = Explorer.type_code_to_explorer_map[type_code]
+ while explorer_class.explore_type(name, datatype, is_child):
+ pass
+ else:
+ print ("Explorer for type '%s' not yet available.\n" %
+ str(datatype))
+
+ @staticmethod
+ def init_env():
+ """Initializes the Explorer environment.
+ This function should be invoked before starting any exploration. If
+ invoked before an exploration, it need not be invoked for subsequent
+ explorations.
+ """
+ Explorer.type_code_to_explorer_map = {
+ gdb.TYPE_CODE_CHAR : ScalarExplorer,
+ gdb.TYPE_CODE_INT : ScalarExplorer,
+ gdb.TYPE_CODE_BOOL : ScalarExplorer,
+ gdb.TYPE_CODE_FLT : ScalarExplorer,
+ gdb.TYPE_CODE_VOID : ScalarExplorer,
+ gdb.TYPE_CODE_ENUM : ScalarExplorer,
+ gdb.TYPE_CODE_STRUCT : CompoundExplorer,
+ gdb.TYPE_CODE_UNION : CompoundExplorer,
+ gdb.TYPE_CODE_PTR : PointerExplorer,
+ gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
+ gdb.TYPE_CODE_ARRAY : ArrayExplorer
+ }
+
+ @staticmethod
+ def is_scalar_type(type):
+ """Checks whether a type is a scalar type.
+ A type is a scalar type of its type is
+ gdb.TYPE_CODE_CHAR or
+ gdb.TYPE_CODE_INT or
+ gdb.TYPE_CODE_BOOL or
+ gdb.TYPE_CODE_FLT or
+ gdb.TYPE_CODE_VOID or
+ gdb.TYPE_CODE_ENUM.
+
+ Arguments:
+ type: The type to be checked.
+
+ Returns:
+ 'True' if 'type' is a scalar type. 'False' otherwise.
+ """
+ return type.code in Explorer._SCALAR_TYPE_LIST
+
+ @staticmethod
+ def returning_to_parent_value_message():
+ """A utility function which prints that the current exploration session
+ is returning to the parent value. Useful when exploring values.
+ """
+ print "\nReturning to parent value...\n"
+
+ @staticmethod
+ def return_to_parent_value_prompt():
+ """A utility function which prompts the user to press the 'enter' key so
+ that the exploration session can shift back to the parent value. Useful
+ when exploring values.
+ """
+ raw_input("\nPress enter to return to parent value...")
+ Explorer.returning_to_parent_value_message()
+
+ @staticmethod
+ def returning_to_enclosing_type_message():
+ """A utility function which prints that the current exploration session
+ is returning to the enclosing type. Useful when exploring types.
+ """
+ print "\nReturning to enclosing type...\n"
+
+ @staticmethod
+ def return_to_enclosing_type_prompt():
+ """A utility function which prompts the user to press the 'enter' key so
+ that the exploration session can shift back to the enclosing type.
+ Useful when exploring types.
+ """
+ raw_input("\nPress enter to return to enclosing type...")
+ Explorer.returning_to_enclosing_type_message()
+
+
+class ScalarExplorer(object):
+ """Internal class used to explore scalar values."""
+
+ @staticmethod
+ def explore_expr(expr, value, is_child):
+ """Function to explore scalar values.
+ See Explorer.explore_expr and Explorer.is_scalar_type for more
+ information.
+ """
+ print ("'%s' is a scalar value of type '%s'.\n" %
+ (expr, value.type))
+ print " %s = %s" % (expr, str(value))
+
+ if is_child:
+ Explorer.return_to_parent_value_prompt()
+
+ return False
+
+ @staticmethod
+ def explore_type(name, datatype, is_child):
+ """Function to explore scalar types.
+ See Explorer.explore_type and Explorer.is_scalar_type for more
+ information.
+ """
+ if datatype.code == gdb.TYPE_CODE_ENUM:
+ if is_child:
+ print ("%s is of an enumerated type '%s'." %
+ (name, str(datatype)))
+ else:
+ print "%s is an enumerated type." % name
+ else:
+ if is_child:
+ print ("%s is of a primitive scalar type '%s'." %
+ (name, str(datatype)))
+ else:
+ print "%s is a primitive scalar type." % name
+
+ if is_child:
+ Explorer.return_to_enclosing_type_prompt()
+
+ return False
+
+
+class PointerExplorer(object):
+ """Internal class used to explore pointer values."""
+
+ @staticmethod
+ def explore_expr(expr, value, is_child):
+ """Function to explore pointer values.
+ See Explorer.explore_expr for more information.
+ """
+ if str(value) == "0x0":
+ print "\n %s = NULL" % expr
+ if is_child:
+ Explorer.return_to_parent_value_prompt()
+ return False
+
+ print ("\n'%s' is a pointer to a value of type '%s'" %
+ (expr, str(value.type.target())))
+ option = raw_input("\nEnter 's' to continue exploring as a pointer "
+ "to a single value, 'a' to explore as an array: ")
+ if option == "s":
+ deref_value = None
+ try:
+ deref_value = value.dereference()
+ str(deref_value)
+ except gdb.MemoryError:
+ print ("'%s' a pointer pointing to an invalid memory "
+ "location." % expr)
+ if is_child:
+ Explorer.return_to_parent_value_prompt()
+ return False
+ Explorer.explore_expr("*(%s)" % expr, deref_value, is_child)
+ if option == "a":
+ while True:
+ index = 0
+ try:
+ index = int(raw_input("Enter the index to explore: "))
+ except ValueError:
+ break
+ element_expr = "%s[%d]" % (expr, index)
+ element = gdb.parse_and_eval(element_expr)
+ try:
+ str(element)
+ except gdb.MemoryError:
+ print "Cannot read value at index %d." % index
+ continue
+ Explorer.explore_expr(element_expr, element, True)
+ if option != "s" and option != "a":
+ if is_child:
+ Explorer.returning_to_parent_value_message()
+
+ return False
+
+ @staticmethod
+ def explore_type(name, datatype, is_child):
+ """Function to explore pointer types.
+ See Explorer.explore_type for more information.
+ """
+ target_type = datatype.target()
+ print ("\n'%s' is of a pointer type with target type '%s'." %
+ (name, str(target_type)))
+
+ Explorer.explore_type("the value pointed to by %s" % name,
+ target_type,
+ is_child)
+ return False
+
+
+class ArrayExplorer(object):
+ """Internal class used to explore arrays."""
+
+ @staticmethod
+ def _print_array_info(name, target_type):
+ """Internal function which prints the information about the array type.
+ """
+ print ("\n%s is an array of elements of type '%s'." %
+ (name, target_type))
+
+ @staticmethod
+ def explore_expr(expr, value, is_child):
+ """Function to explore array values.
+ See Explorer.explore_expr for more information.
+ """
+ ArrayExplorer._print_array_info("'%s'" % expr, value.type.target())
+ index = 0
+ try:
+ index = int(raw_input("Enter the index to explore: "))
+ except ValueError:
+ if is_child:
+ Explorer.returning_to_parent_value_message()
+ return False
+
+ element = None
+ try:
+ element = value[index]
+ str(element)
+ except gdb.MemoryError:
+ print "Cannot read value at index %d." % index
+ raw_input("Press enter to continue... ")
+ return True
+
+ Explorer.explore_expr("%s[%s]" % (expr, index), element, True)
+ return True
+
+ @staticmethod
+ def explore_type(name, datatype, is_child):
+ """Function to explore array types.
+ See Explorer.explore_type for more information.
+ """
+ target_type = datatype.target()
+ ArrayExplorer._print_array_info(name, target_type)
+
+ entry = raw_input("Enter 's' to step in to exploring the "
+ "type of the elements: ")
+ if entry == "s":
+ Explorer.explore_type("an array element of %s" % name,
+ target_type,
+ True)
+ else:
+ if is_child:
+ Explorer.returning_to_enclosing_type_message()
+ return False
+
+ return True
+
+
+class CompoundExplorer(object):
+ """Internal class used to explore struct, classes and unions."""
+
+ _VALUES = 0
+ _TYPES = 1
+
+ @staticmethod
+ def _print_fields(print_list, print_type):
+ """Internal function which prints the fields of a struct/class/union."""
+ max_type_name_length = 0
+ max_field_name_length = 0
+ for triple in print_list:
+ if max_type_name_length < len(triple[0]):
+ max_type_name_length = len(triple[0])
+ if max_field_name_length < len(triple[1]):
+ max_field_name_length = len(triple[1])
+
+ format_str = ""
+ if print_type == CompoundExplorer._VALUES:
+ format_str = (" {0:>%d} {1:<%d} = {2}" %
+ (max_type_name_length, max_field_name_length))
+ if print_type == CompoundExplorer._TYPES:
+ format_str = (" {0:>%d} {1:<%d} // {2}" %
+ (max_type_name_length, max_field_name_length))
+
+ for triple in print_list:
+ print format_str.format(triple[0], triple[1], triple[2])
+
+ @staticmethod
+ def explore_expr(expr, value, is_child):
+ """Function to explore structs/classes and union values.
+ See Explorer.explore_expr for more information.
+ """
+ type_code = value.type.code
+ if type_code == gdb.TYPE_CODE_STRUCT:
+ print ("\n'%s' is a struct/class of type '%s' "
+ "with the following fields:\n" %
+ (expr, str(value.type)))
+ else:
+ print ("\n'%s' is a union of type '%s' with the following "
+ "fields:\n" %
+ (expr, str(value.type)))
+
+ fields = value.type.fields()
+ has_explorable_fields = False
+ current_choice = 0
+ choice_to_compound_field_map = { }
+ print_list = [ ]
+ for field in fields:
+ field_full_name = expr + "." + field.name
+ field_value = value[field.name]
+ literal_value = ""
+ is_compound_field = False
+ if type_code == gdb.TYPE_CODE_UNION:
+ literal_value = ("" %
+ str(current_choice))
+ is_compound_field = True
+ else:
+ if Explorer.is_scalar_type(field.type):
+ literal_value = str(field_value)
+ else:
+ literal_value = ("" %
+ str(current_choice))
+ is_compound_field = True
+
+ if is_compound_field:
+ choice_to_compound_field_map[str(current_choice)] = (
+ field_full_name, field_value)
+ current_choice = current_choice + 1
+
+ print_list.append((str(field.type), field.name, literal_value))
+
+ CompoundExplorer._print_fields(print_list, CompoundExplorer._VALUES)
+ print ""
+
+ if len(choice_to_compound_field_map) > 0:
+ choice = raw_input("Enter the number of the field you "
+ "want to explore in '%s': " % expr)
+ if choice in choice_to_compound_field_map:
+ Explorer.explore_expr(choice_to_compound_field_map[choice][0],
+ choice_to_compound_field_map[choice][1],
+ True)
+ return True
+ else:
+ if is_child:
+ Explorer.returning_to_parent_value_message()
+ else:
+ if is_child:
+ Explorer.return_to_parent_value_prompt()
+
+ return False
+
+ @staticmethod
+ def explore_type(name, datatype, is_child):
+ """Function to explore struct/class and union types.
+ See Explorer.explore_type for more information.
+ """
+ type_code = datatype.code
+ if type_code == gdb.TYPE_CODE_STRUCT:
+ if is_child:
+ print ("\n%s is a struct/class of type '%s' "
+ "with the following fields:\n" %
+ (name, str(datatype)))
+ else:
+ print ("\n%s is a struct/class with the following "
+ "fields:\n" %
+ name)
+ else:
+ if is_child:
+ print ("\n%s is a union of type '%s' "
+ "with the following fields:\n" %
+ (name, str(datatype)))
+ else:
+ print ("\n%s is a union with the following fields:\n" %
+ name)
+
+ fields = datatype.fields()
+ has_explorable_fields = False
+ current_choice = 0
+ choice_to_compound_field_map = { }
+ print_list = [ ]
+ for field in fields:
+ if Explorer.is_scalar_type(field.type):
+ print_list.append((str(field.type), field.name, "Scalar Value"))
+ else:
+ print_list.append(
+ (str(field.type),
+ field.name,
+ "" % current_choice))
+ choice_to_compound_field_map[str(current_choice)] = (
+ field.name, field.type)
+ current_choice = current_choice + 1
+
+ CompoundExplorer._print_fields(print_list, CompoundExplorer._TYPES)
+ print ""
+
+ if len(choice_to_compound_field_map) > 0:
+ choice = raw_input("Enter the number of the field you want to "
+ "explore : ")
+ if choice in choice_to_compound_field_map:
+ Explorer.explore_type(
+ ("field '%s' of '%s'" %
+ (choice_to_compound_field_map[choice][0], name)),
+ choice_to_compound_field_map[choice][1],
+ True)
+ return True
+ else:
+ if is_child:
+ Explorer.returning_to_enclosing_type_message()
+ else:
+ if is_child:
+ Explorer.return_to_enclosing_type_prompt()
+
+ return False
+
+
+class TypedefExplorer(object):
+ """Internal class used to explore values whose type is a typedef."""
+
+ @staticmethod
+ def explore_expr(expr, value, is_child):
+ """Function to explore typedef values.
+ See Explorer.explore_expr for more information.
+ """
+ actual_type = value.type.strip_typedefs()
+ print ("\n'%s' is a value of type '%s' "
+ "which is a typedef of type '%s'" %
+ (expr, str(value.type), str(actual_type)))
+
+ Explorer.explore_expr(expr, value.cast(actual_type), is_child)
+ return False
+
+ @staticmethod
+ def explore_type(name, datatype, is_child):
+ """Function to explore typedef types.
+ See Explorer.explore_type for more information.
+ """
+ actual_type = datatype.strip_typedefs()
+ print("\n%s is of a type which is a typedef of type '%s'." %
+ (name, str(actual_type)))
+ Explorer.explore_type(name, actual_type, is_child)
+ return False
+
+
+class ExploreUtils(object):
+ """Internal class which provides utilities for the main command classes."""
+
+ @staticmethod
+ def check_args(name, arg_str):
+ """Utility to check if adequate number of arguments are passed to an
+ explore command.
+
+ Arguments:
+ name: The name of the explore command.
+ arg_str: The argument string passed to the explore command.
+
+ Returns:
+ True if adequate arguments are passed, false otherwise.
+
+ Raises:
+ gdb.GdbError if adequate arguments are not passed.
+ """
+ if len(arg_str) < 1:
+ raise gdb.GdbError("ERROR: '%s' command requires an argument."
+ % name)
+ return False
+ else:
+ return True
+
+ @staticmethod
+ def get_type_from_str(type_str):
+ """A utility function to deduce the gdb.Type value from a string
+ representing the type.
+
+ Arguments:
+ type_str: The type string from which the gdb.Type value should be
+ deduced.
+
+ Returns:
+ The deduced gdb.Type value if possible, None otherwise.
+ """
+ try:
+ # Assume the current language to be C/C++ and make a try.
+ return gdb.parse_and_eval("(%s *)0" % type_str).type.target()
+ except RuntimeError:
+ # If assumption of current language to be C/C++ was wrong, then
+ # lookup the type using the API.
+ try:
+ return gdb.lookup_type(type_str)
+ except RuntimeError:
+ return None
+
+ @staticmethod
+ def get_value_from_str(value_str):
+ """A utility function to deduce the gdb.Value value from a string
+ representing the value.
+
+ Arguments:
+ value_str: The value string from which the gdb.Value value should be
+ deduced.
+
+ Returns:
+ The deduced gdb.Value value if possible, None otherwise.
+ """
+ try:
+ return gdb.parse_and_eval(value_str)
+ except RuntimeError:
+ return None
+
+
+class ExploreCommand(gdb.Command):
+ """GDB command to explore expression values and types top down.
+
+ Usage: explore ARG
+
+ ARG is either an expression or a type visible in the current scope.
+
+ If ARG is an expression which evaluates to a scalar value or struct/class
+ with only scalar fields, then the value is printed. If it evaluates to a
+ union, or if it is a class/struct with class/struct fields, or if is as
+ array, the user can interactively explore the value. Exploration here means
+ to observe, starting from the fields/elements of the VALUE, right down to
+ the leaf scalar values embedded in these fields.
+
+ If ARG is a type visible in the current scope, then the user can explore
+ the type top down.
+ """
+
+ def __init__(self):
+ super(ExploreCommand, self).__init__(name = "explore",
+ command_class = gdb.COMMAND_DATA,
+ prefix = True)
+
+ def invoke(self, arg_str, from_tty):
+ if ExploreUtils.check_args("explore", arg_str) == False:
+ return
+
+ # Check if it is a value
+ value = ExploreUtils.get_value_from_str(arg_str)
+ if value is not None:
+ Explorer.explore_expr(arg_str, value, False)
+ return
+
+ # If it is not a value, check if it is a type
+ datatype = ExploreUtils.get_type_from_str(arg_str)
+ if datatype is not None:
+ Explorer.explore_type(arg_str, datatype, False)
+ return
+
+ # If it is neither a value nor a type, raise an error.
+ raise gdb.GdbError(
+ ("'%s' neither evaluates to a value nor is a type "
+ "in the current context." %
+ arg_str))
+
+
+class ExploreValueCommand(gdb.Command):
+ """GDB command to explore expression values top down.
+
+ Usage: explore value ARG
+
+ ARG is an expression visible in the current scope.
+
+ If ARG is an expression which evaluates to a scalar value or struct/class
+ with only scalar fields, then the value is printed. If it evaluates to a
+ union, or if it is a class/struct with class/struct fields, or if is as
+ array, the user can interactively explore the value. Exploration here means
+ to observe, starting from the fields/elements of the VALUE, right down to
+ the leaf scalar values embedded in these fields.
+ """
+
+ def __init__(self):
+ super(ExploreValueCommand, self).__init__(
+ name = "explore value", command_class = gdb.COMMAND_DATA)
+
+ def invoke(self, arg_str, from_tty):
+ if ExploreUtils.check_args("explore value", arg_str) == False:
+ return
+
+ value = ExploreUtils.get_value_from_str(arg_str)
+ if value is None:
+ raise gdb.GdbError(
+ (" '%s' does not evaluate to a value in the current "
+ "context." %
+ arg_str))
+ return
+
+ Explorer.explore_expr(arg_str, value, False)
+
+
+class ExploreTypeCommand(gdb.Command):
+ """GDB command to explore types top down.
+
+ Usage: explore type ARG
+
+ ARG is a type visible in the current scope.
+
+ If ARG is a type visible in the current scope, then the user can explore
+ the type top down.
+ """
+
+ def __init__(self):
+ super(ExploreTypeCommand, self).__init__(
+ name = "explore type", command_class = gdb.COMMAND_DATA)
+
+ def invoke(self, arg_str, from_tty):
+ if ExploreUtils.check_args("explore type", arg_str) == False:
+ return
+
+ datatype = ExploreUtils.get_type_from_str(arg_str)
+ if datatype is None:
+ raise gdb.GdbError(
+ ("'%s' is not a type in the current context." %
+ arg_str))
+ return
+
+ Explorer.explore_type(arg_str, datatype, False)
+
+
+Explorer.init_env()
+
+ExploreCommand()
+ExploreValueCommand()
+ExploreTypeCommand()
diff -rupN src/gdb/testsuite/gdb.python/Makefile.in src_local/gdb/testsuite/gdb.python/Makefile.in
--- src/gdb/testsuite/gdb.python/Makefile.in 2011-05-16 19:26:40.000000000 +0530
+++ src_local/gdb/testsuite/gdb.python/Makefile.in 2011-11-12 11:48:44.872558912 +0530
@@ -4,7 +4,8 @@ srcdir = @srcdir@
EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
py-symbol py-mi py-breakpoint py-inferior py-infthread \
py-shared python lib-types py-events py-evthreads py-frame \
- py-mi py-pp-maint py-progspace py-section-script py-objfile
+ py-mi py-pp-maint py-progspace py-section-script py-objfile \
+ py-explore
MISCELLANEOUS = py-shared-sl.sl
diff -rupN src/gdb/testsuite/gdb.python/py-explore.c src_local/gdb/testsuite/gdb.python/py-explore.c
--- src/gdb/testsuite/gdb.python/py-explore.c 1970-01-01 05:30:00.000000000 +0530
+++ src_local/gdb/testsuite/gdb.python/py-explore.c 2011-12-25 23:46:14.641927363 +0530
@@ -0,0 +1,83 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#define ARRAY_SIZE 10
+
+struct SimpleStruct
+{
+ int a;
+ double d;
+};
+
+union SimpleUnion
+{
+ int i;
+ char c;
+ float f;
+ double d;
+};
+
+typedef struct SimpleStruct SS;
+
+struct ComplexStruct
+{
+ struct SimpleStruct s;
+ union SimpleUnion u;
+ SS sa[ARRAY_SIZE];
+};
+
+union ComplexUnion
+{
+ SS s;
+ struct SimpleStruct sa[ARRAY_SIZE];
+};
+
+int
+main (void)
+{
+ int* invalid_ptr = (int *)10;
+ struct SimpleStruct ss;
+ struct SimpleStruct* ss_ptr = &ss;
+ SS ss_t;
+
+ union SimpleUnion su;
+ struct ComplexStruct cs;
+ struct ComplexStruct* cs_ptr = &cs;
+ union ComplexUnion cu;
+ int i;
+ double darray[5] = {0.1, 0.2, 0.3, 0.4, 0.5};
+ double *darray_ref = darray;
+
+ ss.a = 10;
+ ss.d = 100.01;
+ ss_t = ss;
+
+ su.d = 100.1;
+
+ cs.s = ss;
+ cs.u = su;
+ for (i = 0; i < ARRAY_SIZE; i++)
+ {
+ cs.sa[i].a = i;
+ cs.sa[i].d = 10.10 + i;
+ cu.sa[i].a = i;
+ cu.sa[i].d = 100.10 + i;
+ }
+
+ return 0; /* Break here. */
+}
diff -rupN src/gdb/testsuite/gdb.python/py-explore.exp src_local/gdb/testsuite/gdb.python/py-explore.exp
--- src/gdb/testsuite/gdb.python/py-explore.exp 1970-01-01 05:30:00.000000000 +0530
+++ src_local/gdb/testsuite/gdb.python/py-explore.exp 2011-12-27 01:21:50.302487431 +0530
@@ -0,0 +1,358 @@
+# Copyright (C) 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file is part of the GDB testsuite. It tests the command 'explore'
+# which is implemented using the GDB-Python API.
+
+load_lib gdb-python.exp
+
+set testfile "py-explore"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+set SS "struct SimpleStruct"
+set SU "union SimpleUnion"
+set CS "struct ComplexStruct"
+set CU "union ComplexUnion"
+set return_to_parent_prompt {Press enter to return to parent value...}
+set array_index_prompt {Enter the index to explore: }
+
+proc enter_field_number_prompt { value_name } {
+ return "Enter the number of the field you want to explore in '$value_name': "
+}
+
+proc compound_description { value_name type_kind type_name } {
+ return "'$value_name' is a $type_kind of type '$type_name' with the following fields:\[\r\n\]+"
+}
+
+proc typedef_description { value_name typedef_name type_name } {
+ return "'$value_name' is a value of type '$typedef_name' which is a typedef of type '$type_name'\[\r\n\]+"
+}
+
+proc scalar_description { value_name type } {
+ return "'$value_name' is a scalar value of type '$type'\.\[\r\n\]+"
+}
+
+proc array_description { value_name type } {
+ return "'$value_name' is an array of elements of type '$type'.\[\r\n\]+"
+}
+
+proc pointer_description { value_name type_name } {
+ set type_description "'$value_name' is a pointer to a value of type '$type_name'\[\r\n\]+"
+ set prompt "Enter 's' to continue exploring as a pointer to a single value, 'a' to explore as an array: "
+ return "$type_description$prompt"
+}
+
+proc field_values { args } {
+ set result ""
+ foreach field $args {
+ set result "$result\[ \]*$field\[\r\n\]+"
+ }
+ return $result
+}
+
+proc field_choices { args } {
+ set result ""
+ set field_num 0
+ foreach field $args {
+ set result "$result$field\[ \]+=\[ \]+} {union SimpleUnion u // } {SS \[10\] sa // }]
+set CU_fields_types [field_values {SS s // } {struct SimpleStruct \[10\] sa // }]
+
+gdb_test "explore int" ".*[scalar_primitive_type_decsription {int}].*"
+gdb_test "explore struct SimpleStruct" ".*[compound_type_description $SS {struct/class}].*$SS_fields_types.*"
+gdb_test "explore union SimpleUnion" ".*[compound_type_description $SU {union}].*$SU_fields_types"
+gdb_test "explore SS" ".*[typedef_type_description {SS} $SS].*[compound_type_description {SS} {struct/class}].*$SS_fields_types.*"
+
+gdb_test_multiple "explore type struct ComplexStruct" "" {
+ -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
+ pass "explore type struct ComplexStruct"
+ gdb_test_multiple "0" "explore type struct ComplexStruct field 0" {
+ -re ".*[compound_field_type_description $CS_field_0 {struct/class} $SS].*$SS_fields_types.*" {
+ pass "explore type struct ComplexStruct field 0"
+ gdb_test_multiple " " "return to ComplexStruct from field 0" {
+ -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
+ pass "return to ComplexStruct from field 0"
+ }
+ }
+ }
+ }
+ gdb_test_multiple "1" "explore type struct ComplexStruct field 1" {
+ -re ".*[compound_field_type_description $CS_field_1 {union} $SU].*$SU_fields_types.*" {
+ pass "explore type struct ComplexStruct field 1"
+ gdb_test_multiple " " "return to ComplexStruct from field 1" {
+ -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
+ pass "return to ComplexStruct from field 1"
+ }
+ }
+ }
+ }
+ gdb_test_multiple "2" "explore type struct ComplexStruct field 2" {
+ -re ".*[array_type_description $CS_field_2 {SS}].*" {
+ pass "explore type struct ComplexStruct field 2"
+ gdb_test_multiple "s" "array element of field 2 of ComplexStruct" {
+ -re ".*[compound_field_type_description $CS_field_2_array_element {struct/class} $SS].*$SS_fields_types.*" {
+ pass "array element of field 2 of ComplexStruct"
+ gdb_test_multiple " " "return to ComplexStruct array" {
+ -re ".*[array_type_description $CS_field_2 {SS}].*" {
+ pass "return to ComplexStruct array"
+ gdb_test_multiple " " "return to ComplexStruct from field 2" {
+ -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
+ pass "return to ComplexStruct from field 2"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ gdb_test_multiple " " "return to GDB prompt from ComplexStruct type exploration" {
+ -re "$gdb_prompt" {
+ pass "return to GDB prompt from ComplexStruct type exploration"
+ }
+ }
+ }
+}
+
+gdb_test_multiple "explore type union ComplexUnion" "" {
+ -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
+ pass "explore type union ComplexUnion"
+ gdb_test_multiple "0" "explore type union ComplexStruct field 0" {
+ -re ".*[compound_field_type_description $CU_field_0 {struct/class} $SS].*$SS_fields_types.*" {
+ pass "explore type union ComplexUnion field 0"
+ gdb_test_multiple " " "return to ComplexUnion from field 0" {
+ -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
+ pass "return to ComplexUnion from field 0"
+ }
+ }
+ }
+ }
+ gdb_test_multiple "1" "explore type union ComplexUnion field 1" {
+ -re ".*[array_type_description $CU_field_1 $SS].*" {
+ pass "explore type union ComplexUnion field 1"
+ gdb_test_multiple "s" "array element of field 1 of ComplexUnion" {
+ -re ".*[compound_field_type_description $CU_field_1_array_element {struct/class} $SS].*$SS_fields_types.*" {
+ pass "array element of field 1 of ComplexUnion"
+ gdb_test_multiple " " "return to ComplexUnion array" {
+ -re ".*[array_type_description $CU_field_1 $SS].*" {
+ pass "return to ComplexUnion array"
+ gdb_test_multiple " " "return to ComplexUnion from field 1" {
+ -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
+ pass "return to ComplexUnion from field 1"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ gdb_test_multiple " " "return to GDB prompt from ComplexUnion type exploration" {
+ -re "$gdb_prompt" {
+ pass "return to GDB prompt from ComplexUnion type exploration"
+ }
+ }
+ }
+}