mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-09 09:08:32 +08:00
Add support for Python 3.
* NEWS: Mention Python 3 support. * varobj.c (value_get_print_value): Use python_string_to_target_string. * python/py-block.c: Use PyVarObject_HEAD_INIT in initialization of type objects. * python/py-breakpoint.c: Ditto. * python/py-cmd.c: Ditto. * python/py-event.c: Ditto. * python/py-event.h: Ditto. * python/py-evtregistry.c: Ditto. * python/py-finishbreakpoint.c: Ditto. * python/py-frame.c: Ditto. * python/py-function.c: Ditto. * python/py-infthread.c: Ditto. * python/py-lazy-string.c: Ditto. * python/py-progspace.c: Ditto. * /python/py-symbol.c: Ditto. * python/py-evts.c: (gdbpy_initialize_py_events): Add module initialization for Python 3. * python/py-inferior.c: Use PyVarObject_HEAD_INIT in initialization of type objects. (infpy_read_memory): Return memoryview object if Python 3. (infpy_write_memory): Use "s*" operand parsing code for Python 3. (infpy_search_memory): Ditto. (get_buffer): New function for Python 3. * python/py-objfile.c: Use PyVarObject_HEAD_INIT in initialization of type objects. (objfpy_dealloc): Use Py_TYPE to call tp_free. * python/py-param.c: Use PyVarObject_HEAD_INIT in initialization of type objects. (get_attr): Use PyUnicode_CompareWithASCIIString if Python 3. (set_attr): Ditto. * python/py-prettyprint.c (print_string_repr): use PyBytes methods instead of PyString methods if Python 3. (print_children): Skip push_dummy_python_frame call if Python 3. * python/py-symtab.c: Use PyVarObject_HEAD_INIT in initialization of type objects. (salpy_dealloc): Use Py_TYPE to call tp_free. * python/py-type.c: Use PyVarObject_HEAD_INIT in initialization of type objects. (field_dealloc): Use Py_TYPE to call tp_free. (typy_dealloc): Ditto. (type_object_as_number): Adjust struct initializations for differences in layout for Python 2 vs. Python 3. * python/py-utils.c (python_string_to_unicode): Omit non-Unicode string case for Python 3. (unicode_to_encoded_python_string): Shorten code (no functional change). (python_string_to_target_python_string): Comment that in Python 3 returned value is a Python "bytes" type. (gdbpy_is_string): Omit non-Unicode string check in Python 3. (gdb_py_object_from_longest): Omit non-long integer case in Python 3. (gdb_py_object_from_ulongest): Ditto. * python/py-value.c: Use PyVarObject_HEAD_INIT in initialization of type objects. (valpy_dealloc): Use Py_TYPE to call tp_free. (valpy_int): Omit function if Python 3. (convert_value_from_python): Use "%S" format (Python object as a string) if Python 3. (value_object_as_number): Adjust struct initializations for differences in layout for Python 2 vs. Python 3. * python/python-config.py: Adjust syntax for Python 3 compatibility. Include "sys.abiflags" string as part of python library name, if that attribute exists (Python 3). * python/python-internal.h (IS_PY3): Define if Python 3. (Py_TPFLAGS_HAVE_ITER, Py_TPFLAGS_CHECKTYPES): Define with placeholder value if Python 3. (PyInt_Check, PyInt_FromLong, PyInt_AsLong, PyString_FromString, PyString_Decode, PyString_FromFormat, PyString_Check): Define as analogous Python 3 API function if Python 3. (PyVarObject_HEAD_INIT): Define if not already defined. (Py_TYPE): Ditto. * python/python.c (eval_python_command): Omit Py_FlushLine call if Python 3. Check return values of all Python API calls for error. Supply dummy "python" and "python-interactive" commands if Python initialization failed. (_initialize_python): Convert argc to wchar_t** if Python 3. Add module initialization for Python 3. (finish_python_initialization): Pass wchar_t * argument to PySys_SetPath if Python 3. * python/lib/gdb/__init__.py: Define "reload" if Python 3. (_GdbFile): New class for common output file behavior. (GdbOutFile): Subclass from _GdbFile. (GdbOutputErrorFile): Ditto. (auto_load_packages): Adjust syntax for Python 3 compatibility. * python/lib/gdb/printing.py: Define basestr and int if Python 3. * python/lib/gdb/prompt.py: Use sorted() function rather than sort() method. * python/lib/gdb/command/explore.py: Define raw_input if Python 3. Adjust syntax for Python 3 compatibility. * python/lib/gdb/command/pretty_printers.py: Use sorted() function rather than sort() method. Adjust syntax for Python 3 compatibility. * python/lib/gdb/command/type_printers.py: Ditto. * doc/gdb.texinfo (Inferior.read_memory): Mention that the return value is a memoryview object if Python 3.
This commit is contained in:
@ -18,9 +18,17 @@ import os
|
||||
import sys
|
||||
import _gdb
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
# Python 3 moved "reload"
|
||||
from imp import reload
|
||||
|
||||
from _gdb import *
|
||||
|
||||
class GdbOutputFile:
|
||||
class _GdbFile (object):
|
||||
# These two are needed in Python 3
|
||||
encoding = "UTF-8"
|
||||
errors = "strict"
|
||||
|
||||
def close(self):
|
||||
# Do nothing.
|
||||
return None
|
||||
@ -28,36 +36,23 @@ class GdbOutputFile:
|
||||
def isatty(self):
|
||||
return False
|
||||
|
||||
def writelines(self, iterable):
|
||||
for line in iterable:
|
||||
self.write(line)
|
||||
|
||||
def flush(self):
|
||||
flush()
|
||||
|
||||
class GdbOutputFile (_GdbFile):
|
||||
def write(self, s):
|
||||
write(s, stream=STDOUT)
|
||||
|
||||
def writelines(self, iterable):
|
||||
for line in iterable:
|
||||
self.write(line)
|
||||
|
||||
def flush(self):
|
||||
flush()
|
||||
|
||||
sys.stdout = GdbOutputFile()
|
||||
|
||||
class GdbOutputErrorFile:
|
||||
def close(self):
|
||||
# Do nothing.
|
||||
return None
|
||||
|
||||
def isatty(self):
|
||||
return False
|
||||
|
||||
class GdbOutputErrorFile (_GdbFile):
|
||||
def write(self, s):
|
||||
write(s, stream=STDERR)
|
||||
|
||||
def writelines(self, iterable):
|
||||
for line in iterable:
|
||||
self.write(line)
|
||||
|
||||
def flush(self):
|
||||
flush()
|
||||
|
||||
sys.stderr = GdbOutputErrorFile()
|
||||
|
||||
# Default prompt hook does nothing.
|
||||
@ -107,7 +102,7 @@ def auto_load_packages():
|
||||
else:
|
||||
__import__(modname)
|
||||
except:
|
||||
print >> sys.stderr, traceback.format_exc()
|
||||
sys.stderr.write (traceback.format_exc() + "\n")
|
||||
|
||||
auto_load_packages()
|
||||
|
||||
|
@ -17,7 +17,12 @@
|
||||
"""Implementation of the GDB 'explore' command using the GDB Python API."""
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
# Python 3 renamed raw_input to input
|
||||
raw_input = input
|
||||
|
||||
class Explorer(object):
|
||||
"""Internal class which invokes other explorers."""
|
||||
|
||||
@ -155,7 +160,7 @@ class Explorer(object):
|
||||
"""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"
|
||||
print ("\nReturning to parent value...\n")
|
||||
|
||||
@staticmethod
|
||||
def return_to_parent_value_prompt():
|
||||
@ -170,7 +175,7 @@ class Explorer(object):
|
||||
"""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"
|
||||
print ("\nReturning to enclosing type...\n")
|
||||
|
||||
@staticmethod
|
||||
def return_to_enclosing_type_prompt():
|
||||
@ -192,7 +197,7 @@ class ScalarExplorer(object):
|
||||
"""
|
||||
print ("'%s' is a scalar value of type '%s'." %
|
||||
(expr, value.type))
|
||||
print "%s = %s" % (expr, str(value))
|
||||
print ("%s = %s" % (expr, str(value)))
|
||||
|
||||
if is_child:
|
||||
Explorer.return_to_parent_value_prompt()
|
||||
@ -211,13 +216,13 @@ class ScalarExplorer(object):
|
||||
print ("%s is of an enumerated type '%s'." %
|
||||
(name, str(datatype)))
|
||||
else:
|
||||
print "'%s' is an enumerated type." % name
|
||||
print ("'%s' is an enumerated type." % name)
|
||||
else:
|
||||
if is_child:
|
||||
print ("%s is of a scalar type '%s'." %
|
||||
(name, str(datatype)))
|
||||
else:
|
||||
print "'%s' is a scalar type." % name
|
||||
print ("'%s' is a scalar type." % name)
|
||||
|
||||
if is_child:
|
||||
Explorer.return_to_enclosing_type_prompt()
|
||||
@ -268,7 +273,7 @@ class PointerExplorer(object):
|
||||
try:
|
||||
str(element)
|
||||
except gdb.MemoryError:
|
||||
print "Cannot read value at index %d." % index
|
||||
print ("Cannot read value at index %d." % index)
|
||||
continue
|
||||
Explorer.explore_expr(element_expr, element, True)
|
||||
return False
|
||||
@ -338,7 +343,7 @@ class ArrayExplorer(object):
|
||||
element = value[index]
|
||||
str(element)
|
||||
except gdb.MemoryError:
|
||||
print "Cannot read value at index %d." % index
|
||||
print ("Cannot read value at index %d." % index)
|
||||
raw_input("Press enter to continue... ")
|
||||
return True
|
||||
|
||||
@ -352,7 +357,7 @@ class ArrayExplorer(object):
|
||||
See Explorer.explore_type for more information.
|
||||
"""
|
||||
target_type = datatype.target()
|
||||
print "%s is an array of '%s'." % (name, str(target_type))
|
||||
print ("%s is an array of '%s'." % (name, str(target_type)))
|
||||
|
||||
Explorer.explore_type("the array element of %s" % name, target_type,
|
||||
is_child)
|
||||
@ -371,9 +376,8 @@ class CompoundExplorer(object):
|
||||
if max_field_name_length < len(pair[0]):
|
||||
max_field_name_length = len(pair[0])
|
||||
|
||||
format_str = " {0:>%d} = {1}" % max_field_name_length
|
||||
for pair in print_list:
|
||||
print format_str.format(pair[0], pair[1])
|
||||
print (" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
|
||||
|
||||
@staticmethod
|
||||
def _get_real_field_count(fields):
|
||||
@ -447,7 +451,7 @@ class CompoundExplorer(object):
|
||||
print_list.append((field.name, literal_value))
|
||||
|
||||
CompoundExplorer._print_fields(print_list)
|
||||
print ""
|
||||
print ("")
|
||||
|
||||
if has_explorable_fields:
|
||||
choice = raw_input("Enter the field number of choice: ")
|
||||
@ -484,7 +488,7 @@ class CompoundExplorer(object):
|
||||
(name, type_desc, str(datatype)))
|
||||
Explorer.return_to_enclosing_type_prompt()
|
||||
else:
|
||||
print "'%s' is a %s with no fields." % (name, type_desc)
|
||||
print ("'%s' is a %s with no fields." % (name, type_desc))
|
||||
return False
|
||||
|
||||
if is_child:
|
||||
@ -515,7 +519,7 @@ class CompoundExplorer(object):
|
||||
current_choice = current_choice + 1
|
||||
|
||||
CompoundExplorer._print_fields(print_list)
|
||||
print ""
|
||||
print ("")
|
||||
|
||||
if len(choice_to_compound_field_map) > 0:
|
||||
choice = raw_input("Enter the field number of choice: ")
|
||||
@ -741,7 +745,7 @@ class ExploreTypeCommand(gdb.Command):
|
||||
|
||||
value = ExploreUtils.get_value_from_str(arg_str)
|
||||
if value is not None:
|
||||
print "'%s' is of type '%s'." % (arg_str, str(value.type))
|
||||
print ("'%s' is of type '%s'." % (arg_str, str(value.type)))
|
||||
Explorer.explore_type(str(value.type), value.type, False)
|
||||
|
||||
raise gdb.GdbError(("'%s' is not a type or value in the current "
|
||||
|
@ -124,21 +124,17 @@ class InfoPrettyPrinter(gdb.Command):
|
||||
"""Print a list of pretty-printers."""
|
||||
# A potential enhancement is to provide an option to list printers in
|
||||
# "lookup order" (i.e. unsorted).
|
||||
sorted_pretty_printers = copy.copy(pretty_printers)
|
||||
sorted_pretty_printers.sort(lambda x, y:
|
||||
cmp(self.printer_name(x),
|
||||
self.printer_name(y)))
|
||||
sorted_pretty_printers = sorted (copy.copy(pretty_printers),
|
||||
key = self.printer_name)
|
||||
for printer in sorted_pretty_printers:
|
||||
name = self.printer_name(printer)
|
||||
enabled = self.enabled_string(printer)
|
||||
if name_re.match(name):
|
||||
print " %s%s" % (name, enabled)
|
||||
print (" %s%s" % (name, enabled))
|
||||
if (hasattr(printer, "subprinters") and
|
||||
printer.subprinters is not None):
|
||||
sorted_subprinters = copy.copy(printer.subprinters)
|
||||
sorted_subprinters.sort(lambda x, y:
|
||||
cmp(self.printer_name(x),
|
||||
self.printer_name(y)))
|
||||
sorted_subprinters = sorted (copy.copy(printer.subprinters),
|
||||
key = self.printer_name)
|
||||
for subprinter in sorted_subprinters:
|
||||
if (not subname_re or
|
||||
subname_re.match(subprinter.name)):
|
||||
@ -150,7 +146,7 @@ class InfoPrettyPrinter(gdb.Command):
|
||||
obj_name_to_match, object_re, name_re, subname_re):
|
||||
"""Subroutine of invoke to simplify it."""
|
||||
if printer_list and object_re.match(obj_name_to_match):
|
||||
print title
|
||||
print (title)
|
||||
self.list_pretty_printers(printer_list, name_re, subname_re)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
@ -219,7 +215,7 @@ def show_pretty_printer_enabled_summary():
|
||||
We count subprinters individually.
|
||||
"""
|
||||
(enabled_count, total_count) = count_all_enabled_printers()
|
||||
print "%d of %d printers enabled" % (enabled_count, total_count)
|
||||
print ("%d of %d printers enabled" % (enabled_count, total_count))
|
||||
|
||||
|
||||
def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
||||
@ -301,7 +297,7 @@ def do_enable_pretty_printer (arg, flag):
|
||||
state = "enabled"
|
||||
else:
|
||||
state = "disabled"
|
||||
print "%d %s %s" % (total, pluralize("printer", total), state)
|
||||
print ("%d %s %s" % (total, pluralize("printer", total), state))
|
||||
|
||||
# Print the total list of printers currently enabled/disabled.
|
||||
# This is to further assist the user in determining whether the result
|
||||
|
@ -33,29 +33,29 @@ class InfoTypePrinter(gdb.Command):
|
||||
"""Print a list of type printers."""
|
||||
# A potential enhancement is to provide an option to list printers in
|
||||
# "lookup order" (i.e. unsorted).
|
||||
sorted_type_printers = copy.copy(type_printers)
|
||||
sorted_type_printers.sort(lambda x, y: cmp(x.name, y.name))
|
||||
sorted_type_printers = sorted (copy.copy(type_printers),
|
||||
key = lambda x: x.name)
|
||||
for printer in sorted_type_printers:
|
||||
if printer.enabled:
|
||||
enabled = ''
|
||||
else:
|
||||
enabled = " [disabled]"
|
||||
print " %s%s" % (printer.name, enabled)
|
||||
print (" %s%s" % (printer.name, enabled))
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
sep = ''
|
||||
for objfile in gdb.objfiles():
|
||||
if objfile.type_printers:
|
||||
print "%sType printers for %s:" % (sep, objfile.name)
|
||||
print ("%sType printers for %s:" % (sep, objfile.name))
|
||||
self.list_type_printers(objfile.type_printers)
|
||||
sep = '\n'
|
||||
if gdb.current_progspace().type_printers:
|
||||
print "%sType printers for program space:" % sep
|
||||
print ("%sType printers for program space:" % sep)
|
||||
self.list_type_printers(gdb.current_progspace().type_printers)
|
||||
sep = '\n'
|
||||
if gdb.type_printers:
|
||||
print "%sGlobal type printers:" % sep
|
||||
print ("%sGlobal type printers:" % sep)
|
||||
self.list_type_printers(gdb.type_printers)
|
||||
|
||||
class _EnableOrDisableCommand(gdb.Command):
|
||||
@ -83,7 +83,7 @@ class _EnableOrDisableCommand(gdb.Command):
|
||||
if self.set_some(name, gdb.type_printers):
|
||||
ok = True
|
||||
if not ok:
|
||||
print "No type printer named '%s'" % name
|
||||
print ("No type printer named '%s'" % name)
|
||||
|
||||
def add_some(self, result, word, printers):
|
||||
for p in printers:
|
||||
|
@ -19,7 +19,12 @@
|
||||
import gdb
|
||||
import gdb.types
|
||||
import re
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
# Python 3 removed basestring and long
|
||||
basestring = str
|
||||
long = int
|
||||
|
||||
class PrettyPrinter(object):
|
||||
"""A basic pretty-printer.
|
||||
|
@ -98,8 +98,7 @@ def prompt_help():
|
||||
functions."""
|
||||
|
||||
result = ''
|
||||
keys = prompt_substitutions.keys()
|
||||
keys.sort()
|
||||
keys = sorted (prompt_substitutions.keys())
|
||||
for key in keys:
|
||||
result += ' \\%s\t%s\n' % (key, prompt_substitutions[key].__doc__)
|
||||
result += """
|
||||
|
Reference in New Issue
Block a user