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