15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)"""
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GDB extension that adds Cython support.
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)"""
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from __future__ import with_statement
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import sys
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import textwrap
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import traceback
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import functools
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import itertools
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import collections
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import gdb
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)try:
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    from lxml import etree
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    have_lxml = True
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)except ImportError:
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    have_lxml = False
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    try:
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # Python 2.5
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        from xml.etree import cElementTree as etree
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    except ImportError:
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # Python 2.5
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            from xml.etree import ElementTree as etree
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except ImportError:
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            try:
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                # normal cElementTree install
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                import cElementTree as etree
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            except ImportError:
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                # normal ElementTree install
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                import elementtree.ElementTree as etree
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)try:
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    import pygments.lexers
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    import pygments.formatters
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)except ImportError:
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    pygments = None
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sys.stderr.write("Install pygments for colorized source code.\n")
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)if hasattr(gdb, 'string_to_argv'):
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    from gdb import string_to_argv
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)else:
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    from shlex import split as string_to_argv
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Debugger import libpython
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# C or Python type
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)CObject = 'CObject'
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PythonObject = 'PythonObject'
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)_data_types = dict(CObject=CObject, PythonObject=PythonObject)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)_filesystemencoding = sys.getfilesystemencoding() or 'UTF-8'
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# decorators
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def dont_suppress_errors(function):
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "*sigh*, readline"
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @functools.wraps(function)
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def wrapper(*args, **kwargs):
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return function(*args, **kwargs)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except Exception:
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            traceback.print_exc()
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return wrapper
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def default_selected_gdb_frame(err=True):
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def decorator(function):
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @functools.wraps(function)
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def wrapper(self, frame=None, *args, **kwargs):
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            try:
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                frame = frame or gdb.selected_frame()
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            except RuntimeError:
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise gdb.GdbError("No frame is currently selected.")
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if err and frame.name() is None:
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise NoFunctionNameInFrameError()
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return function(self, frame, *args, **kwargs)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return wrapper
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return decorator
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def require_cython_frame(function):
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @functools.wraps(function)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @require_running_program
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def wrapper(self, *args, **kwargs):
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        frame = kwargs.get('frame') or gdb.selected_frame()
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not self.is_cython_function(frame):
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise gdb.GdbError('Selected frame does not correspond with a '
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               'Cython function we know about.')
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return function(self, *args, **kwargs)
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return wrapper
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def dispatch_on_frame(c_command, python_command=None):
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def decorator(function):
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @functools.wraps(function)
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def wrapper(self, *args, **kwargs):
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            is_cy = self.is_cython_function()
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            is_py = self.is_python_function()
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if is_cy or (is_py and not python_command):
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                function(self, *args, **kwargs)
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            elif is_py:
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gdb.execute(python_command)
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            elif self.is_relevant_function():
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gdb.execute(c_command)
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise gdb.GdbError("Not a function cygdb knows about. "
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   "Use the normal GDB commands instead.")
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return wrapper
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return decorator
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def require_running_program(function):
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @functools.wraps(function)
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def wrapper(*args, **kwargs):
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.selected_frame()
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except RuntimeError:
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise gdb.GdbError("No frame is currently selected.")
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return function(*args, **kwargs)
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return wrapper
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def gdb_function_value_to_unicode(function):
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @functools.wraps(function)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def wrapper(self, string, *args, **kwargs):
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if isinstance(string, gdb.Value):
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            string = string.string()
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return function(self, string, *args, **kwargs)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return wrapper
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Classes that represent the debug information
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Don't rename the parameters of these classes, they come directly from the XML
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonModule(object):
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, module_name, filename, c_filename):
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.name = module_name
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.filename = filename
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.c_filename = c_filename
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.globals = {}
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # {cython_lineno: min(c_linenos)}
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.lineno_cy2c = {}
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # {c_lineno: cython_lineno}
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.lineno_c2cy = {}
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.functions = {}
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonVariable(object):
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, name, cname, qualified_name, type, lineno):
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.name = name
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.cname = cname
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.qualified_name = qualified_name
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.type = type
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.lineno = int(lineno)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonFunction(CythonVariable):
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self,
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 module,
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 name,
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 cname,
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 pf_cname,
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 qualified_name,
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 lineno,
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 type=CObject,
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 is_initmodule_function="False"):
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        super(CythonFunction, self).__init__(name,
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             cname,
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             qualified_name,
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             type,
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             lineno)
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.module = module
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.pf_cname = pf_cname
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.is_initmodule_function = is_initmodule_function == "True"
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.locals = {}
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.arguments = []
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.step_into_functions = set()
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# General purpose classes
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonBase(object):
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame(err=False)
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def is_cython_function(self, frame):
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return frame.name() in self.cy.functions_by_cname
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame(err=False)
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def is_python_function(self, frame):
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Tells if a frame is associated with a Python function.
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        If we can't read the Python frame information, don't regard it as such.
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if frame.name() == 'PyEval_EvalFrameEx':
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            pyframe = libpython.Frame(frame).get_pyop()
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return pyframe and not pyframe.is_optimized_out()
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return False
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_c_function_name(self, frame):
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return frame.name()
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_c_lineno(self, frame):
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return frame.find_sal().line
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_cython_function(self, frame):
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result = self.cy.functions_by_cname.get(frame.name())
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if result is None:
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise NoCythonFunctionInFrameError()
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return result
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_cython_lineno(self, frame):
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Get the current Cython line number. Returns 0 if there is no
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        correspondence between the C and Cython code.
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cyfunc = self.get_cython_function(frame)
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return cyfunc.module.lineno_c2cy.get(self.get_c_lineno(frame), 0)
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_source_desc(self, frame):
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        filename = lineno = lexer = None
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.is_cython_function(frame):
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            filename = self.get_cython_function(frame).module.filename
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            lineno = self.get_cython_lineno(frame)
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if pygments:
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                lexer = pygments.lexers.CythonLexer(stripall=False)
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif self.is_python_function(frame):
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            pyframeobject = libpython.Frame(frame).get_pyop()
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if not pyframeobject:
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise gdb.GdbError(
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            'Unable to read information on python frame')
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            filename = pyframeobject.filename()
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            lineno = pyframeobject.current_line_num()
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if pygments:
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                lexer = pygments.lexers.PythonLexer(stripall=False)
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            symbol_and_line_obj = frame.find_sal()
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if not symbol_and_line_obj or not symbol_and_line_obj.symtab:
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                filename = None
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                lineno = 0
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                filename = symbol_and_line_obj.symtab.fullname()
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                lineno = symbol_and_line_obj.line
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if pygments:
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    lexer = pygments.lexers.CLexer(stripall=False)
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return SourceFileDescriptor(filename, lexer), lineno
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_source_line(self, frame):
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        source_desc, lineno = self.get_source_desc()
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return source_desc.get_source(lineno)
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame()
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def is_relevant_function(self, frame):
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        returns whether we care about a frame on the user-level when debugging
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Cython code
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        name = frame.name()
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        older_frame = frame.older()
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.is_cython_function(frame) or self.is_python_function(frame):
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return True
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif older_frame and self.is_cython_function(older_frame):
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # check for direct C function call from a Cython function
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cython_func = self.get_cython_function(older_frame)
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return name in cython_func.step_into_functions
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return False
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @default_selected_gdb_frame(err=False)
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def print_stackframe(self, frame, index, is_c=False):
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Print a C, Cython or Python stack frame and the line of source code
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if available.
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # do this to prevent the require_cython_frame decorator from
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # raising GdbError when calling self.cy.cy_cvalue.invoke()
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        selected_frame = gdb.selected_frame()
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        frame.select()
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            source_desc, lineno = self.get_source_desc(frame)
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except NoFunctionNameInFrameError:
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            print '#%-2d Unknown Frame (compile with -g)' % index
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not is_c and self.is_python_function(frame):
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            pyframe = libpython.Frame(frame).get_pyop()
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if pyframe is None or pyframe.is_optimized_out():
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                # print this python function as a C function
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return self.print_stackframe(frame, index, is_c=True)
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_name = pyframe.co_name
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_cname = 'PyEval_EvalFrameEx'
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_args = []
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif self.is_cython_function(frame):
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cyfunc = self.get_cython_function(frame)
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame)
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_name = cyfunc.name
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_cname = cyfunc.cname
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_args = [] # [(arg, f(arg)) for arg in cyfunc.arguments]
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            source_desc, lineno = self.get_source_desc(frame)
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_name = frame.name()
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_cname = func_name
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_args = []
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb_value = gdb.parse_and_eval(func_cname)
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except RuntimeError:
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_address = 0
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # Seriously? Why is the address not an int?
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func_address = int(str(gdb_value.address).split()[0], 0)
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        print '#%-2d 0x%016x in %s(%s)' % (index, func_address, func_name, a),
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if source_desc.filename is not None:
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            print 'at %s:%s' % (source_desc.filename, lineno),
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        print
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            print '    ' + source_desc.get_source(lineno)
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except gdb.GdbError:
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            pass
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        selected_frame.select()
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_remote_cython_globals_dict(self):
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        m = gdb.parse_and_eval('__pyx_m')
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            PyModuleObject = gdb.lookup_type('PyModuleObject')
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except RuntimeError:
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise gdb.GdbError(textwrap.dedent("""\
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                Unable to lookup type PyModuleObject, did you compile python
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                with debugging support (-g)?"""))
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        m = m.cast(PyModuleObject.pointer())
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return m['md_dict']
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_cython_globals_dict(self):
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Get the Cython globals dict where the remote names are turned into
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        local strings.
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        remote_dict = self.get_remote_cython_globals_dict()
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        pyobject_dict = libpython.PyObjectPtr.from_pyobject_ptr(remote_dict)
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result = {}
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        seen = set()
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for k, v in pyobject_dict.iteritems():
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            result[k.proxyval(seen)] = v
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return result
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def print_gdb_value(self, name, value, max_name_length=None, prefix=''):
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if libpython.pretty_printer_lookup(value):
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            typename = ''
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            typename = '(%s) ' % (value.type,)
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if max_name_length is None:
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            print '%s%s = %s%s' % (prefix, name, typename, value)
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            print '%s%-*s = %s%s' % (prefix, max_name_length, name, typename,
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     value)
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def is_initialized(self, cython_func, local_name):
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cyvar = cython_func.locals[local_name]
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cur_lineno = self.get_cython_lineno()
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if '->' in cyvar.cname:
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # Closed over free variable
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if cur_lineno > cython_func.lineno:
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if cyvar.type == PythonObject:
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    return long(gdb.parse_and_eval(cyvar.cname))
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return True
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return False
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return cur_lineno > cyvar.lineno
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class SourceFileDescriptor(object):
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, filename, lexer, formatter=None):
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.filename = filename
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.lexer = lexer
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.formatter = formatter
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def valid(self):
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return self.filename is not None
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def lex(self, code):
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if pygments and self.lexer and parameters.colorize_code:
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            bg = parameters.terminal_background.value
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.formatter is None:
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                formatter = pygments.formatters.TerminalFormatter(bg=bg)
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                formatter = self.formatter
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return pygments.highlight(code, self.lexer, formatter)
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return code
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def _get_source(self, start, stop, lex_source, mark_line, lex_entire):
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        with open(self.filename) as f:
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # to provide "correct" colouring, the entire code needs to be
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # lexed. However, this makes a lot of things terribly slow, so
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # we decide not to. Besides, it's unlikely to matter.
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if lex_source and lex_entire:
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                f = self.lex(f.read()).splitlines()
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            slice = itertools.islice(f, start - 1, stop - 1)
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            for idx, line in enumerate(slice):
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if start + idx == mark_line:
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    prefix = '>'
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                else:
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    prefix = ' '
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if lex_source and not lex_entire:
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    line = self.lex(line)
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                yield '%s %4d    %s' % (prefix, start + idx, line.rstrip())
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_source(self, start, stop=None, lex_source=True, mark_line=0,
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   lex_entire=False):
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        exc = gdb.GdbError('Unable to retrieve source code')
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not self.filename:
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise exc
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        start = max(start, 1)
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if stop is None:
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            stop = start + 1
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return '\n'.join(
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self._get_source(start, stop, lex_source, mark_line, lex_entire))
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except IOError:
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise exc
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Errors
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyGDBError(gdb.GdbError):
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Base class for Cython-command related erorrs
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, *args):
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        args = args or (self.msg,)
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        super(CyGDBError, self).__init__(*args)
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class NoCythonFunctionInFrameError(CyGDBError):
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    raised when the user requests the current cython function, which is
4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    unavailable
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    msg = "Current function is a function cygdb doesn't know about"
4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class NoFunctionNameInFrameError(NoCythonFunctionInFrameError):
4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    raised when the name of the C function could not be determined
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    in the current C stack frame
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    msg = ('C function name could not be determined in the current C stack '
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           'frame')
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Parameters
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonParameter(gdb.Parameter):
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Base class for cython parameters
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, name, command_class, parameter_class, default=None):
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.show_doc = self.set_doc = self.__class__.__doc__
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        super(CythonParameter, self).__init__(name, command_class,
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                              parameter_class)
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if default is not None:
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.value = default
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __nonzero__(self):
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return bool(self.value)
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    __bool__ = __nonzero__ # python 3
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CompleteUnqualifiedFunctionNames(CythonParameter):
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Have 'cy break' complete unqualified function or method names.
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ColorizeSourceCode(CythonParameter):
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Tell cygdb whether to colorize source code.
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TerminalBackground(CythonParameter):
5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Tell cygdb about the user's terminal background (light or dark).
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonParameters(object):
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Simple container class that might get more functionality in the distant
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    future (mostly to remind us that we're dealing with parameters).
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self):
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.complete_unqualified = CompleteUnqualifiedFunctionNames(
5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            'cy_complete_unqualified',
5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.COMMAND_BREAKPOINTS,
5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.PARAM_BOOLEAN,
5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            True)
5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.colorize_code = ColorizeSourceCode(
5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            'cy_colorize_code',
5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.COMMAND_FILES,
5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.PARAM_BOOLEAN,
5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            True)
5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.terminal_background = TerminalBackground(
5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            'cy_terminal_background_color',
5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.COMMAND_FILES,
5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.PARAM_STRING,
5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "dark")
5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)parameters = CythonParameters()
5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Commands
5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonCommand(gdb.Command, CythonBase):
5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Base class for Cython commands
5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_class = gdb.COMMAND_NONE
5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @classmethod
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def _register(cls, clsname, args, kwargs):
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not hasattr(cls, 'completer_class'):
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return cls(clsname, cls.command_class, *args, **kwargs)
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return cls(clsname, cls.command_class, cls.completer_class,
5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       *args, **kwargs)
5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @classmethod
5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def register(cls, *args, **kwargs):
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        alias = getattr(cls, 'alias', None)
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if alias:
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cls._register(cls.alias, args, kwargs)
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return cls._register(cls.name, args, kwargs)
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyCy(CythonCommand):
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Invoke a Cython command. Available commands are:
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy import
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy break
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy step
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy next
5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy run
5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy cont
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy finish
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy up
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy down
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy select
5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy bt / cy backtrace
5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy list
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy print
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy set
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy locals
5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy globals
5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy exec
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy'
6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_class = gdb.COMMAND_NONE
6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completer_class = gdb.COMPLETE_COMMAND
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, name, command_class, completer_class):
6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # keep the signature 2.5 compatible (i.e. do not use f(*a, k=v)
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        super(CythonCommand, self).__init__(name, command_class,
6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                            completer_class, prefix=True)
6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        commands = dict(
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # GDB commands
6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            import_ = CyImport.register(),
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            break_ = CyBreak.register(),
6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            step = CyStep.register(),
6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            next = CyNext.register(),
6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            run = CyRun.register(),
6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cont = CyCont.register(),
6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            finish = CyFinish.register(),
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            up = CyUp.register(),
6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            down = CyDown.register(),
6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            select = CySelect.register(),
6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            bt = CyBacktrace.register(),
6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            list = CyList.register(),
6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            print_ = CyPrint.register(),
6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            locals = CyLocals.register(),
6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            globals = CyGlobals.register(),
6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            exec_ = libpython.FixGdbCommand('cy exec', '-cy-exec'),
6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _exec = CyExec.register(),
6295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            set = CySet.register(),
6305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # GDB functions
6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cy_cname = CyCName('cy_cname'),
6335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cy_cvalue = CyCValue('cy_cvalue'),
6345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cy_lineno = CyLine('cy_lineno'),
6355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cy_eval = CyEval('cy_eval'),
6365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        )
6375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for command_name, command in commands.iteritems():
6395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            command.cy = self
6405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            setattr(self, command_name, command)
6415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.cy = self
6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # Cython module namespace
6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.cython_namespace = {}
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # maps (unique) qualified function names (e.g.
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # cythonmodule.ClassName.method_name) to the CythonFunction object
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.functions_by_qualified_name = {}
6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # unique cnames of Cython functions
6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.functions_by_cname = {}
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # map function names like method_name to a list of all such
6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # CythonFunction objects
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.functions_by_name = collections.defaultdict(list)
6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyImport(CythonCommand):
6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Import debug information outputted by the Cython compiler
6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Example: cy import FILE...
6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy import'
6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_class = gdb.COMMAND_STATUS
6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completer_class = gdb.COMPLETE_FILENAME
6685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def invoke(self, args, from_tty):
6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        args = args.encode(_filesystemencoding)
6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for arg in string_to_argv(args):
6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            try:
6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                f = open(arg)
6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            except OSError, e:
6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise gdb.GdbError('Unable to open file %r: %s' %
6765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                (args, e.args[1]))
6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            t = etree.parse(f)
6795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            for module in t.getroot():
6815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                cython_module = CythonModule(**module.attrib)
6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self.cy.cython_namespace[cython_module.name] = cython_module
6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                for variable in module.find('Globals'):
6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    d = variable.attrib
6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    cython_module.globals[d['name']] = CythonVariable(**d)
6875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                for function in module.find('Functions'):
6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    cython_function = CythonFunction(module=cython_module,
6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     **function.attrib)
6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    # update the global function mappings
6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    name = cython_function.name
6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    qname = cython_function.qualified_name
6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    self.cy.functions_by_name[name].append(cython_function)
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    self.cy.functions_by_qualified_name[
6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        cython_function.qualified_name] = cython_function
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    self.cy.functions_by_cname[
7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        cython_function.cname] = cython_function
7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    d = cython_module.functions[qname] = cython_function
7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    for local in function.find('Locals'):
7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        d = local.attrib
7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        cython_function.locals[d['name']] = CythonVariable(**d)
7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    for step_into_func in function.find('StepIntoFunctions'):
7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        d = step_into_func.attrib
7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        cython_function.step_into_functions.add(d['name'])
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    cython_function.arguments.extend(
7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        funcarg.tag for funcarg in function.find('Arguments'))
7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                for marker in module.find('LineNumberMapping'):
7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    cython_lineno = int(marker.attrib['cython_lineno'])
7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    c_linenos = map(int, marker.attrib['c_linenos'].split())
7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    cython_module.lineno_cy2c[cython_lineno] = min(c_linenos)
7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    for c_lineno in c_linenos:
7205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        cython_module.lineno_c2cy[c_lineno] = cython_lineno
7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyBreak(CythonCommand):
7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Set a breakpoint for Cython code using Cython qualified name notation, e.g.:
7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy break cython_modulename.ClassName.method_name...
7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    or normal notation:
7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy break function_or_method_name...
7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    or for a line number:
7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cy break cython_module:lineno...
7365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Set a Python breakpoint:
7385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Break on any function or method named 'func' in module 'modname'
7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cy break -p modname.func...
7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Break on any function or method named 'func'
7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cy break -p func...
7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy break'
7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_class = gdb.COMMAND_BREAKPOINTS
7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def _break_pyx(self, name):
7515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        modulename, _, lineno = name.partition(':')
7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        lineno = int(lineno)
7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if modulename:
7545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cython_module = self.cy.cython_namespace[modulename]
7555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
7565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cython_module = self.get_cython_function().module
7575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if lineno in cython_module.lineno_cy2c:
7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            c_lineno = cython_module.lineno_cy2c[lineno]
7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            breakpoint = '%s:%s' % (cython_module.c_filename, c_lineno)
7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.execute('break ' + breakpoint)
7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise gdb.GdbError("Not a valid line number. "
7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               "Does it contain actual code?")
7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def _break_funcname(self, funcname):
7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        func = self.cy.functions_by_qualified_name.get(funcname)
7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if func and func.is_initmodule_function:
7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            func = None
7715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        break_funcs = [func]
7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not func:
7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            funcs = self.cy.functions_by_name.get(funcname) or []
7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            funcs = [f for f in funcs if not f.is_initmodule_function]
7775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if not funcs:
7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gdb.execute('break ' + funcname)
7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return
7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if len(funcs) > 1:
7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                # multiple functions, let the user pick one
7845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                print 'There are multiple such functions:'
7855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                for idx, func in enumerate(funcs):
7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    print '%3d) %s' % (idx, func.qualified_name)
7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                while True:
7895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    try:
7905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        result = raw_input(
7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            "Select a function, press 'a' for all "
7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            "functions or press 'q' or '^D' to quit: ")
7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    except EOFError:
7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        return
7955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    else:
7965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        if result.lower() == 'q':
7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            return
7985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        elif result.lower() == 'a':
7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            break_funcs = funcs
8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            break
8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        elif (result.isdigit() and
8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            0 <= int(result) < len(funcs)):
8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            break_funcs = [funcs[int(result)]]
8045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            break
8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        else:
8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            print 'Not understood...'
8075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
8085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                break_funcs = [funcs[0]]
8095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for func in break_funcs:
8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.execute('break %s' % func.cname)
8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if func.pf_cname:
8135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gdb.execute('break %s' % func.pf_cname)
8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def invoke(self, function_names, from_tty):
8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        argv = string_to_argv(function_names.encode('UTF-8'))
8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if function_names.startswith('-p'):
8185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            argv = argv[1:]
8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            python_breakpoints = True
8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            python_breakpoints = False
8225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for funcname in argv:
8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if python_breakpoints:
8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gdb.execute('py-break %s' % funcname)
8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            elif ':' in funcname:
8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self._break_pyx(funcname)
8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self._break_funcname(funcname)
8305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @dont_suppress_errors
8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def complete(self, text, word):
8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # Filter init-module functions (breakpoints can be set using
8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # modulename:linenumber).
8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        names =  [n for n, L in self.cy.functions_by_name.iteritems()
8365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        if any(not f.is_initmodule_function for f in L)]
8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        qnames = [n for n, f in self.cy.functions_by_qualified_name.iteritems()
8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        if not f.is_initmodule_function]
8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if parameters.complete_unqualified:
8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            all_names = itertools.chain(qnames, names)
8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            all_names = qnames
8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        words = text.strip().split()
8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not words or '.' not in words[-1]:
8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # complete unqualified
8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            seen = set(text[:-len(word)].split())
8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return [n for n in all_names
8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          if n.startswith(word) and n not in seen]
8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # complete qualified name
8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        lastword = words[-1]
8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        compl = [n for n in qnames if n.startswith(lastword)]
8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if len(lastword) > len(word):
8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # readline sees something (e.g. a '.') as a word boundary, so don't
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # "recomplete" this prefix
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            strip_prefix_length = len(lastword) - len(word)
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            compl = [n[strip_prefix_length:] for n in compl]
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return compl
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonInfo(CythonBase, libpython.PythonInfo):
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Implementation of the interface dictated by libpython.LanguageInfo.
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def lineno(self, frame):
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # Take care of the Python and Cython levels. We need to care for both
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # as we can't simply dispath to 'py-step', since that would work for
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # stepping through Python code, but it would not step back into Cython-
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # related code. The C level should be dispatched to the 'step' command.
8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.is_cython_function(frame):
8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.get_cython_lineno(frame)
8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return super(CythonInfo, self).lineno(frame)
8785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def get_source_line(self, frame):
8805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            line = super(CythonInfo, self).get_source_line(frame)
8825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except gdb.GdbError:
8835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return None
8845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
8855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return line.strip() or None
8865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def exc_info(self, frame):
8885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.is_python_function:
8895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return super(CythonInfo, self).exc_info(frame)
8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def runtime_break_functions(self):
8925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.is_cython_function():
8935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.get_cython_function().step_into_functions
8945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return ()
8955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def static_break_functions(self):
8975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result = ['PyEval_EvalFrameEx']
8985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result.extend(self.cy.functions_by_cname)
8995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return result
9005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CythonExecutionControlCommand(CythonCommand,
9035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    libpython.ExecutionControlCommandBase):
9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @classmethod
9065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def register(cls):
9075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return cls(cls.name, cython_info)
9085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyStep(CythonExecutionControlCommand, libpython.PythonStepperMixin):
9115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Step through Cython, Python or C code."
9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy -step'
9145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stepinto = True
9155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def invoke(self, args, from_tty):
9175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.is_python_function():
9185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.python_step(self.stepinto)
9195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif not self.is_cython_function():
9205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.stepinto:
9215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                command = 'step'
9225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
9235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                command = 'next'
9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.finish_executing(gdb.execute(command, to_string=True))
9265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
9275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.step(stepinto=self.stepinto)
9285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyNext(CyStep):
9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Step-over Cython, Python or C code."
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy -next'
9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stepinto = False
9355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyRun(CythonExecutionControlCommand):
9385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Run a Cython program. This is like the 'run' command, except that it
9405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    displays Cython or Python source lines as well
9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy run'
9445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    invoke = CythonExecutionControlCommand.run
9465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyCont(CythonExecutionControlCommand):
9495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Continue a Cython program. This is like the 'run' command, except that it
9515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    displays Cython or Python source lines as well.
9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy cont'
9555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    invoke = CythonExecutionControlCommand.cont
9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyFinish(CythonExecutionControlCommand):
9595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Execute until the function returns.
9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy finish'
9635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    invoke = CythonExecutionControlCommand.finish
9655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CyUp(CythonCommand):
9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Go up a Cython, Python or relevant C frame.
9705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
9715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    name = 'cy up'
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    _command = 'up'
9735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def invoke(self, *args):
9755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
9765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            gdb.execute(self._command, to_string=True)
9775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            while not self.is_relevant_function(gdb.selected_frame()):
9785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                gdb.execute(self._command, to_string=True)
9795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except RuntimeError, e:
9805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise gdb.GdbError(*e.args)
9815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        frame = gdb.selected_frame()
9835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        index = 0
9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        while frame:
9855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            frame = frame.older()
9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            index += 1
9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.print_stackframe(index=index - 1)
9895f1c94371a64b3196d4be9466099bb892df9b88e