B
    d                 @   s  d Z ddlmZ yeZW n ek
r,   Y nX ddlZddlZddlZddl	Z	ddl
Z
ddlZddlZyeZeZW n ek
r   eZeZY nX yddlmZ dZW n ek
r>   dZyddlmZ W nn ek
r8   yddlmZ W nF ek
r2   yddlZW n" ek
r,   ddlmZ Y nX Y nX Y nX Y nX yddlZddlZW n& ek
rz   dZejd	 Y nX eed
rddlm Z  nddl!m"Z  ddl#m$Z$ dZ%dZ&e'e%e&dZ(e) pdZ*dd Z+dpddZ,dd Z-dqddZ.dd Z/dd Z0G dd de1Z2G d d! d!e1Z3G d"d# d#e3Z4G d$d% d%e1Z5G d&d' d'e1Z6G d(d) d)ej7Z8G d*d+ d+e8Z9G d,d- d-e9Z:G d.d/ d/ej;Z<G d0d1 d1e<Z=G d2d3 d3e<Z>G d4d5 d5e<Z?G d6d7 d7e1Z@e@ ZAG d8d9 d9ejBe5ZCG d:d; d;eCZDG d<d= d=eCZEG d>d? d?eCZFG d@dA dAe5e$jGZHG dBdC dCeCe$jIZJG dDdE dEeJe$jKZLG dFdG dGeLZMG dHdI dIeJZNG dJdK dKeJZOG dLdM dMeJZPG dNdO dOeCZQG dPdQ dQeQZRG dRdS dSeCZSG dTdU dUeCZTG dVdW dWeCZUG dXdY dYeCZVdZd[ ZWG d\d] d]eCZXG d^d_ d_eXZYG d`da dae1ZZG dbdc dceCe$j[eZZ\G ddde deeCZ]G dfdg dgej^e5Z_G dhdi die_Z`G djdk dkej^e5ZaG dldm dmej^e5eZZbeH ZceDd Zeeeec_edndo Zfef  dS )rz)
GDB extension that adds Cython support.
    )print_functionN)etreeTF)cElementTree)ElementTreez,Install pygments for colorized source code.
string_to_argv)r   )split)	libpythonCObjectPythonObject)r	   r
   zUTF-8c                s   t   fdd}|S )z*sigh*, readlinec                 s.   y
 | |S  t k
r(   t   Y nX d S )N)	Exception	traceback	print_exc)argskwargs)function f/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/Cython/Debugger/libcython.pywrapperJ   s
    
z%dont_suppress_errors.<locals>.wrapper)	functoolswraps)r   r   r   )r   r   dont_suppress_errorsH   s    r   c                s    fdd}|S )Nc                s   t  d fdd	}|S )Nc                sX   y|pt  }W n tk
r.   t dY nX  rF| d krFt | |f||S )NzNo frame is currently selected.)gdbselected_frameRuntimeErrorGdbErrornameNoFunctionNameInFrameError)selfframer   r   )errr   r   r   r   W   s    z>default_selected_gdb_frame.<locals>.decorator.<locals>.wrapper)N)r   r   )r   r   )r   )r   r   	decoratorV   s    
z-default_selected_gdb_frame.<locals>.decoratorr   )r   r    r   )r   r   default_selected_gdb_frameU   s    r!   c                s   t  t fdd}|S )Nc                s6   | dpt }| |s&td | f||S )Nr   zHSelected frame does not correspond with a Cython function we know about.)getr   r   is_cython_functionr   )r   r   r   r   )r   r   r   r   g   s    

z%require_cython_frame.<locals>.wrapper)r   r   require_running_program)r   r   r   )r   r   require_cython_framef   s    r%   c                s    fdd}|S )Nc                s   t   fdd}|S )Nc                s`   |   }|  }|s|r.s.| f|| n.|r>t n|  rRt  n
tdd S )NzFNot a function cygdb knows about. Use the normal GDB commands instead.)r#   is_python_functionr   executeis_relevant_functionr   )r   r   r   Zis_cyZis_py)	c_commandr   python_commandr   r   r   t   s    z5dispatch_on_frame.<locals>.decorator.<locals>.wrapper)r   r   )r   r   )r)   r*   )r   r   r    s   s    z$dispatch_on_frame.<locals>.decoratorr   )r)   r*   r    r   )r)   r*   r   dispatch_on_framer   s    r+   c                s   t   fdd}|S )Nc                 s6   yt   W n tk
r*   t dY nX  | |S )NzNo frame is currently selected.)r   r   r   r   )r   r   )r   r   r   r      s
    z(require_running_program.<locals>.wrapper)r   r   )r   r   r   )r   r   r$      s    r$   c                s   t   fdd}|S )Nc                s&   t |tjr| } | |f||S )N)
isinstancer   Valuestring)r   r.   r   r   )r   r   r   r      s    z.gdb_function_value_to_unicode.<locals>.wrapper)r   r   )r   r   r   )r   r   gdb_function_value_to_unicode   s    r/   c               @   s   e Zd Zdd ZdS )CythonModulec             C   s.   || _ || _|| _i | _i | _i | _i | _d S )N)r   filename
c_filenameglobalslineno_cy2clineno_c2cy	functions)r   module_namer1   r2   r   r   r   __init__   s    zCythonModule.__init__N)__name__
__module____qualname__r8   r   r   r   r   r0      s   r0   c               @   s   e Zd Zdd ZdS )CythonVariablec             C   s&   || _ || _|| _|| _t|| _d S )N)r   cnamequalified_nametypeintlineno)r   r   r=   r>   r?   rA   r   r   r   r8      s
    zCythonVariable.__init__N)r9   r:   r;   r8   r   r   r   r   r<      s   r<   c                   s"   e Zd Zedf fdd	Z  ZS )CythonFunctionFalsec	       	         sF   t t| ||||| || _|| _|dk| _i | _g | _t | _	d S )NTrue)
superrB   r8   modulepf_cnameis_initmodule_functionlocals	argumentssetstep_into_functions)	r   rF   r   r=   rG   r>   rA   r?   rH   )	__class__r   r   r8      s    	
zCythonFunction.__init__)r9   r:   r;   r	   r8   __classcell__r   r   )rM   r   rB      s   rB   c               @   s   e Zd Zedddd Zedddd Ze dd Ze d	d
 Ze dd Ze dd Z	e dd Z
e dd Ze dd Zeddd!ddZdd Zdd Zd"ddZdd  ZdS )#
CythonBaseF)r   c             C   s   |  | jjkS )N)r   cyfunctions_by_cname)r   r   r   r   r   r#      s    zCythonBase.is_cython_functionc             C   s,   |  dkr(t| }|o&|  S dS )z
        Tells if a frame is associated with a Python function.
        If we can't read the Python frame information, don't regard it as such.
        PyEval_EvalFrameExF)r   r   Frameget_pyopis_optimized_out)r   r   pyframer   r   r   r&      s    zCythonBase.is_python_functionc             C   s   |  S )N)r   )r   r   r   r   r   get_c_function_name   s    zCythonBase.get_c_function_namec             C   s
   |  jS )N)find_salline)r   r   r   r   r   get_c_lineno   s    zCythonBase.get_c_linenoc             C   s$   | j j| }|d kr t |S )N)rP   rQ   r"   r   NoCythonFunctionInFrameError)r   r   resultr   r   r   get_cython_function   s    zCythonBase.get_cython_functionc             C   s    |  |}|jj| |dS )z
        Get the current Cython line number. Returns 0 if there is no
        correspondence between the C and Cython code.
        r   )r]   rF   r5   r"   rZ   )r   r   cyfuncr   r   r   get_cython_lineno   s    
zCythonBase.get_cython_linenoc             C   s   d  } }}|  |rB| |jj}| |}trtjjdd}n| |rt	
| }|shtd| }| }trtjjdd}n>| }|r|jsd }d}n"|j }|j}trtjjdd}t|||fS )NF)stripallz*Unable to read information on python framer   )r#   r]   rF   r1   r_   pygmentslexersCythonLexerr&   r   rS   rT   r   r   Zcurrent_line_numPythonLexerrX   ZsymtabfullnamerY   CLexerSourceFileDescriptor)r   r   r1   rA   lexerZpyframeobjectZsymbol_and_line_objr   r   r   get_source_desc   s0    




zCythonBase.get_source_descc             C   s   |   \}}||S )N)ri   
get_source)r   r   source_descrA   r   r   r   get_source_line  s    zCythonBase.get_source_linec             C   sN   |  }| }| |s$| |r(dS |rJ| |rJ| |}||jkS dS )zl
        returns whether we care about a frame on the user-level when debugging
        Cython code
        TF)r   olderr#   r&   r]   rL   )r   r   r   Zolder_framecython_funcr   r   r   r(      s    

zCythonBase.is_relevant_functionc                s  t  }   y \}}W n  tk
rB   td|  dS X |s rt 	 }|dksp|
 rj |ddS |j}d}	g }
nR rĈ } fdd}|j}|j}	g }
n \}}  }|}	g }
yt |	}W n tk
r
   d}Y n>X |j}t|tsHt|ttfs6t|}t| d d}d	d
d |
D }tjd||||f  |jdk	rtjd|j|f  tjd ytjd||  W n t jk
r   Y nX |  dS )zk
        Print a C, Cython or Python stack frame and the line of source code
        if available.
        z%#%-2d Unknown Frame (compile with -g)NT)is_crR   c                s   j jj|  dS )N)r   )rP   	cy_cvalueinvoke)arg)r   r   r   r   <lambda>M      z-CythonBase.print_stackframe.<locals>.<lambda>r   z, c             s   s   | ]\}}d ||f V  qdS )z%s=%sNr   ).0r   valr   r   r   	<genexpr>d  s    z.CythonBase.print_stackframe.<locals>.<genexpr>z#%-2d 0x%016x in %s(%s)z	 at %s:%s
z    ) r   r   selectri   r   printr&   r   rS   rT   rU   print_stackframeco_namer#   r]   r   r=   parse_and_evalr   addressr,   r@   strbytesr   joinsysstdoutwriter1   rj   r   )r   r   indexro   r   rk   rA   rV   	func_nameZ
func_cnameZ	func_argsr^   fZ	gdb_valueZfunc_addressar   )r   r   r   r{   1  sV    


zCythonBase.print_stackframec             C   sT   t d}yt d}W n$ tk
r<   t tdY nX || }|d S )NZ__pyx_mPyModuleObjectzy                Unable to lookup type PyModuleObject, did you compile python
                with debugging support (-g)?Zmd_dict)	r   r}   Zlookup_typer   r   textwrapdedentcastZpointer)r   mr   r   r   r   get_remote_cython_globals_dicts  s    
z)CythonBase.get_remote_cython_globals_dictc             C   sF   |   }tj|}i }t }x"| D ]\}}||||< q(W |S )zk
        Get the Cython globals dict where the remote names are turned into
        local strings.
        )r   r   ZPyObjectPtrZfrom_pyobject_ptrrK   itemsZproxyval)r   Zremote_dictZpyobject_dictr\   seenkvr   r   r   get_cython_globals_dict  s    z"CythonBase.get_cython_globals_dictN c             C   sT   t |rd}nd|jf }|d kr:td||||f  ntd|||||f  d S )Nr   z(%s) z%s%s = %s%sz%s%-*s = %s%s)r   Zpretty_printer_lookupr?   rz   )r   r   valuemax_name_lengthprefixtypenamer   r   r   print_gdb_value  s    
zCythonBase.print_gdb_valuec             C   sR   |j | }|  }d|jkrH||jkrD|jtkr@tt|jS dS dS ||jkS )Nz->TF)	rI   r_   r=   rA   r?   r
   r@   r   r}   )r   rn   Z
local_namecyvarZ
cur_linenor   r   r   is_initialized  s    



zCythonBase.is_initialized)F)Nr   )r9   r:   r;   r!   r#   r&   rW   rZ   r]   r_   ri   rl   r(   r{   r   r   r   r   r   r   r   r   rO      s   	!A
rO   c               @   s8   e Zd ZdddZdd Zdd Zdd	 ZdddZdS )rg   Nc             C   s   || _ || _|| _d S )N)r1   rh   	formatter)r   r1   rh   r   r   r   r   r8     s    zSourceFileDescriptor.__init__c             C   s
   | j d k	S )N)r1   )r   r   r   r   valid  s    zSourceFileDescriptor.validc             C   sL   t rH| jrHtjrHtjj}| jd kr2t jj|d}n| j}t 	|| j|S |S )N)bg)
ra   rh   
parameterscolorize_codeterminal_backgroundr   r   
formattersZTerminalFormatter	highlight)r   coder   r   r   r   r   lex  s    
zSourceFileDescriptor.lexc          	   c   s   t | j}|r&|r&| |  }t||d |d }xTt|D ]H\}}	|| |kr`d}
nd}
|rv|sv| |	}	d|
|| |	 f V  qFW W d Q R X d S )N   > z%s %4d    %s)	openr1   r   read
splitlines	itertoolsislice	enumeraterstrip)r   startstop
lex_source	mark_line
lex_entirer   sliceidxrY   r   r   r   r   _get_source  s    
z SourceFileDescriptor._get_sourceTr   Fc          	   C   sd   t d}| js|t|d}|d kr.|d }yd| |||||S  tk
r^   |Y nX d S )NzUnable to retrieve source coder   rx   )r   r   r1   maxr   r   IOError)r   r   r   r   r   r   excr   r   r   rj     s    

zSourceFileDescriptor.get_source)N)NTr   F)r9   r:   r;   r8   r   r   r   rj   r   r   r   r   rg     s   
 rg   c                   s    e Zd ZdZ fddZ  ZS )
CyGDBErrorz6
    Base class for Cython-command related errors
    c                s    |p
| j f}tt| j|  d S )N)msgrE   r   r8   )r   r   )rM   r   r   r8     s    zCyGDBError.__init__)r9   r:   r;   __doc__r8   rN   r   r   )rM   r   r     s   r   c               @   s   e Zd ZdZdZdS )r[   z]
    raised when the user requests the current cython function, which is
    unavailable
    z7Current function is a function cygdb doesn't know aboutN)r9   r:   r;   r   r   r   r   r   r   r[     s   r[   c               @   s   e Zd ZdZdZdS )r   zi
    raised when the name of the C function could not be determined
    in the current C stack frame
    zDC function name could not be determined in the current C stack frameN)r9   r:   r;   r   r   r   r   r   r   r     s   r   c                   s.   e Zd ZdZd fdd	Zdd ZeZ  ZS )CythonParameterz*
    Base class for cython parameters
    Nc                s6   | j j | _| _tt| ||| |d k	r2|| _d S )N)rM   r   Zshow_docZset_docrE   r   r8   r   )r   r   command_classZparameter_classdefault)rM   r   r   r8     s
    zCythonParameter.__init__c             C   s
   t | jS )N)boolr   )r   r   r   r   __bool__  s    zCythonParameter.__bool__)N)r9   r:   r;   r   r8   r   __nonzero__rN   r   r   )rM   r   r     s   r   c               @   s   e Zd ZdZdS ) CompleteUnqualifiedFunctionNameszH
    Have 'cy break' complete unqualified function or method names.
    N)r9   r:   r;   r   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdS )ColorizeSourceCodez5
    Tell cygdb whether to colorize source code.
    N)r9   r:   r;   r   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdS )TerminalBackgroundzJ
    Tell cygdb about the user's terminal background (light or dark).
    N)r9   r:   r;   r   r   r   r   r   r   %  s   r   c               @   s   e Zd ZdZdd ZdS )CythonParametersz
    Simple container class that might get more functionality in the distant
    future (mostly to remind us that we're dealing with parameters).
    c             C   s@   t dtjtjd| _tdtjtjd| _tdtjtj	d| _
d S )NZcy_complete_unqualifiedTZcy_colorize_codeZcy_terminal_background_colorZdark)r   r   COMMAND_BREAKPOINTSZPARAM_BOOLEANcomplete_unqualifiedr   COMMAND_FILESr   r   ZPARAM_STRINGr   )r   r   r   r   r8   1  s    zCythonParameters.__init__N)r9   r:   r;   r   r8   r   r   r   r   r   +  s   r   c               @   s.   e Zd ZdZejZedd Zedd Z	dS )CythonCommandz(
    Base class for Cython commands
    c             C   s:   t | ds| || jf||S | || j| jf||S d S )Ncompleter_class)hasattrr   r   )clsclsnamer   r   r   r   r   	_registerN  s    
zCythonCommand._registerc             O   s0   t | dd }|r | | j|| | | j||S )Nalias)getattrr   r   r   )r   r   r   r   r   r   r   registerV  s    zCythonCommand.registerN)
r9   r:   r;   r   r   COMMAND_NONEr   classmethodr   r   r   r   r   r   r   G  s   r   c                   s0   e Zd ZdZdZejZejZ	 fddZ
  ZS )CyCyaa  
    Invoke a Cython command. Available commands are:

        cy import
        cy break
        cy step
        cy next
        cy run
        cy cont
        cy finish
        cy up
        cy down
        cy select
        cy bt / cy backtrace
        cy list
        cy print
        cy set
        cy locals
        cy globals
        cy exec
    rP   c                s   t t| j|||dd tt t t t t	 t
 t t t t t t t t t tddt t tdtdtdtdd	}x&| D ]\}}| |_t| || qW | | _i | _i | _ i | _!t"#t$| _%d S )
NT)r   zcy execz-cy-execcy_cnamerp   	cy_linenocy_eval)import_Zbreak_stepnextruncontfinishupdownry   Zbtlistprint_rI   r3   exec__execrK   r   rp   r   r   )&rE   r   r8   dictCyImportr   CyBreakCyStepCyNextCyRunCyContCyFinishCyUpCyDownCySelectCyBacktraceCyListCyPrintCyLocals	CyGlobalsr   ZFixGdbCommandCyExecCySetCyCNameCyCValueCyLineCyEvalr   rP   setattrcython_namespacefunctions_by_qualified_namerQ   collectionsdefaultdictr   functions_by_name)r   r   r   r   commandscommand_namecommand)rM   r   r   r8   z  sB    

zCyCy.__init__)r9   r:   r;   r   r   r   r   r   ZCOMPLETE_COMMANDr   r8   rN   r   r   )rM   r   r   _  s
   r   c               @   s(   e Zd ZdZdZejZejZ	dd Z
dS )r   zb
    Import debug information outputted by the Cython compiler
    Example: cy import FILE...
    z	cy importc             C   s*  t |tr|t}xt|D ] }yt|}W n: tk
rl } ztd||j	d f W d d }~X Y nX t
|}x| D ]}tf |j}|| jj|j< x,|dD ]}	|	j}
tf |
|j|
d < qW x|dD ]}tf d|i|j}|j}|j}| jj| | || jj|j< || jj|j< | }
|j|< x.|dD ] }|j}
tf |
|j|
d < qJW x*|dD ]}|j}
|j|
d  qzW |j !d	d
 |dD  qW xb|dD ]T}t"|jd }t#t$t"|jd % }t&||j'|< x|D ]}||j(|< qW qW qW q W d S )NzUnable to open file %r: %sr   ZGlobalsr   Z	FunctionsrF   ZLocalsZStepIntoFunctionsc             s   s   | ]}|j V  qd S )N)tag)ru   Zfuncargr   r   r   rw     s    z"CyImport.invoke.<locals>.<genexpr>	ArgumentsZLineNumberMappingcython_lineno	c_linenos))r,   BYTESdecode_filesystemencodingr   r   OSErrorr   r   r   r   parseZgetrootr0   attribrP   r   r   findr<   r3   rB   r>   r  appendr   rQ   r=   r6   rI   rL   addrJ   extendr@   r   mapr   minr4   r5   )r   r   from_ttyrr   r   etrF   cython_modulevariabledr   cython_functionr   qnamelocalZstep_into_funcmarkerr  r  c_linenor   r   r   rq     sJ    

*



zCyImport.invokeN)r9   r:   r;   r   r   r   ZCOMMAND_STATUSr   ZCOMPLETE_FILENAMEr   rq   r   r   r   r   r     s
   r   c               @   s>   e Zd ZdZdZejZdd Zdd Z	dd Z
ed	d
 ZdS )r   a  
    Set a breakpoint for Cython code using Cython qualified name notation, e.g.:

        cy break cython_modulename.ClassName.method_name...

    or normal notation:

        cy break function_or_method_name...

    or for a line number:

        cy break cython_module:lineno...

    Set a Python breakpoint:
        Break on any function or method named 'func' in module 'modname'

            cy break -p modname.func...

        Break on any function or method named 'func'

            cy break -p func...
    zcy breakc             C   st   | d\}}}t|}|r*| jj| }n
|  j}||jkrf|j| }d|j|f }t	d|  n
t
dd S )N:z%s:%szbreak z5Not a valid line number. Does it contain actual code?)	partitionr@   rP   r   r]   rF   r4   r2   r   r'   r   )r   r   
modulename_rA   r  r  
breakpointr   r   r   
_break_pyx  s    


zCyBreak._break_pyxc             C   sx  | j j|}|r|jrd }|g}|s<| j j|p8g }dd |D }|s^td|  d S t|dkr2td x&t	|D ]\}}td||j
f  q~W xytd}W n tk
r   d S X | dkrd S | d	kr|}P q| r$d
t|  krt|k r$n n|t| g}P qtd qW n
|d
 g}x6|D ].}td|j  |jrBtd|j  qBW d S )Nc             S   s   g | ]}|j s|qS r   )rH   )ru   r   r   r   r   
<listcomp>%  s    z+CyBreak._break_funcname.<locals>.<listcomp>zbreak r   z"There are multiple such functions:z%3d) %szMSelect a function, press 'a' for all functions or press 'q' or '^D' to quit: qr   r   zNot understood...zbreak %s)rP   r   r"   rH   r  r   r'   lenrz   r   r>   inputEOFErrorlowerisdigitr@   r=   rG   )r   funcnamefuncZbreak_funcsfuncsr   r\   r   r   r   _break_funcname  sF    


$

zCyBreak._break_funcnamec             C   s   t |tr|t}t|}|dr8|dd  }d}nd}x>|D ]6}|rZtd|  qBd|krn| | qB| 	| qBW d S )Nz-pr   TFzpy-break %sr   )
r,   r	  r
  r  r   
startswithr   r'   r%  r0  )r   Zfunction_namesr  argvZpython_breakpointsr-  r   r   r   rq   L  s    



zCyBreak.invokec                s   dd | j j D }dd | j j D }tjr@t||}n|}| 	 }|r`d|d krt
|d t  	 fdd|D S |d   fdd|D }t tkrt t fdd|D }|S )	Nc             S   s&   g | ]\}}t d d |D r|qS )c             s   s   | ]}|j  V  qd S )N)rH   )ru   r   r   r   r   rw   c  s    z.CyBreak.complete.<locals>.<listcomp>.<genexpr>)any)ru   nLr   r   r   r&  b  s    z$CyBreak.complete.<locals>.<listcomp>c             S   s   g | ]\}}|j s|qS r   )rH   )ru   r4  r   r   r   r   r&  d  s    .c                s"   g | ]}| r| kr|qS r   )r1  )ru   r4  )r   wordr   r   r&  p  s    c                s   g | ]}|  r|qS r   )r1  )ru   r4  )lastwordr   r   r&  u  s    c                s   g | ]}| d  qS )Nr   )ru   r4  )strip_prefix_lengthr   r   r&  {  s    )rP   r  r   r   r   r   r   chainstripr   rK   r(  )r   textr8  namesZqnamesZ	all_nameswordsZcomplr   )r9  r   r:  r8  r   complete^  s    zCyBreak.completeN)r9   r:   r;   r   r   r   r   r   r%  r0  rq   r   r@  r   r   r   r   r     s   1r   c                   sH   e Zd ZdZ fddZ fddZ fddZdd	 Zd
d Z  Z	S )
CythonInfozM
    Implementation of the interface dictated by libpython.LanguageInfo.
    c                s$   |  |r| |S tt| |S )N)r#   r_   rE   rA  rA   )r   r   )rM   r   r   rA     s    

zCythonInfo.linenoc                s<   yt t| |}W n tjk
r*   d S X | p6d S d S )N)rE   rA  rl   r   r   r<  )r   r   rY   )rM   r   r   rl     s
    zCythonInfo.get_source_linec                s   | j rtt| |S d S )N)r&   rE   rA  exc_info)r   r   )rM   r   r   rB    s    zCythonInfo.exc_infoc             C   s   |   r|  jS dS )Nr   )r#   r]   rL   )r   r   r   r   runtime_break_functions  s    
z"CythonInfo.runtime_break_functionsc             C   s   dg}| | jj |S )NrR   )r  rP   rQ   )r   r\   r   r   r   static_break_functions  s    z!CythonInfo.static_break_functions)
r9   r:   r;   r   rA   rl   rB  rC  rD  rN   r   r   )rM   r   rA    s   	rA  c               @   s   e Zd Zedd ZdS )CythonExecutionControlCommandc             C   s   | | j tS )N)r   cython_info)r   r   r   r   r     s    z&CythonExecutionControlCommand.registerN)r9   r:   r;   r   r   r   r   r   r   rE    s   rE  c               @   s    e Zd ZdZdZdZdd ZdS )r   z&Step through Cython, Python or C code.zcy -stepTc             C   sV   |   r| | j n<|  sD| jr*d}nd}| tj|dd n| j| jd d S )Nr   r   T)	to_string)stepinto)r&   Zpython_steprH  r#   Zfinish_executingr   r'   r   )r   r   r  r  r   r   r   rq     s    zCyStep.invokeN)r9   r:   r;   r   r   rH  rq   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdZdS )r   z#Step-over Cython, Python or C code.zcy -nextFN)r9   r:   r;   r   r   rH  r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZejZdS )r   z
    Run a Cython program. This is like the 'run' command, except that it
    displays Cython or Python source lines as well
    zcy runN)r9   r:   r;   r   r   rE  r   rq   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZejZdS )r   z
    Continue a Cython program. This is like the 'run' command, except that it
    displays Cython or Python source lines as well.
    zcy contN)r9   r:   r;   r   r   rE  r   rq   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZejZdS )r   z-
    Execute until the function returns.
    z	cy finishN)r9   r:   r;   r   r   rE  r   rq   r   r   r   r   r     s   r   c               @   s    e Zd ZdZdZdZdd ZdS )r   z5
    Go up a Cython, Python or relevant C frame.
    zcy upr   c          
   G   s   y8t j| jdd x"| t  s4t j| jdd qW W n. tk
rf } zt j|j W d d }~X Y nX t  }d}x|r| }|d7 }qvW | j	|d d d S )NT)rG  r   r   )r   )
r   r'   _commandr(   r   r   r   r   rm   r{   )r   r   r  r   r   r   r   r   rq     s    zCyUp.invokeN)r9   r:   r;   r   r   rI  rq   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdZdS )r   z7
    Go down a Cython, Python or relevant C frame.
    zcy downr   N)r9   r:   r;   r   r   rI  r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdd ZdS )r   z
    Select a frame. Use frame numbers as listed in `cy backtrace`.
    This command is useful because `cy backtrace` prints a reversed backtrace.
    z	cy selectc          
   C   s   yt |}W n$ tk
r0   td|f Y nX t }x| rN| }q<W t|}ytd|| d f  W n. t	k
r } ztj|j
 W d d }~X Y nX d S )NzNot a valid number: %rz	select %dr   )r@   
ValueErrorr   r   r   newerr   
stackdepthr'   r   r   )r   Zstacknor  r   rL  r  r   r   r   rq     s    

zCySelect.invokeN)r9   r:   r;   r   r   rq   r   r   r   r   r     s   r   c               @   s0   e Zd ZdZdZdZejZej	Z
edd ZdS )r   zPrint the Cython stackzcy btzcy backtracec             C   s   t  }x| r| }q
W |dk}d}xT|r~y| |}W n tk
rV   d}Y nX |s`|rl| || |d7 }| }q,W d S )Nz-ar   Fr   )r   r   rm   r(   r   r{   rK  )r   r   r  r   Z	print_allr   Zis_relevantr   r   r   rq   )  s    

zCyBacktrace.invokeN)r9   r:   r;   r   r   r   r   COMMAND_STACKr   COMPLETE_NONEr   r$   rq   r   r   r   r   r   !  s   r   c               @   s(   e Zd ZdZdZejZejZ	dd Z
dS )r   za
    List Cython source code. To disable to customize colouring see the cy_*
    parameters.
    zcy listc             C   s2   |   \}}|j|d |d |dd}t| d S )N   T)r   r   )ri   rj   rz   )r   r#  r  sdrA   sourcer   r   r   rq   K  s    zCyList.invokeN)r9   r:   r;   r   r   r   r   r   rN  r   rq   r   r   r   r   r   @  s
   r   c               @   s,   e Zd ZdZdZejZdddZdd Z	dS )	r   zT
    Print a Cython variable using 'cy-print x' or 'cy-print module.function.x'
    zcy printNc             C   sv   |   rtd| S |  rd| jj|d}x |D ]}|dkrN| }q8P q8W | 	||| ntd|  d S )Nz	py-print *zprint )
r&   r   r'   r#   rP   rp   rq   lstripdereferencer   )r   r   r  r   r   cr   r   r   rq   Z  s    

zCyPrint.invokec             C   s,   |   r$|  }tt|j|jS g S d S )N)r#   r]   r   r   r;  rI   r3   )r   r   r   r   r   r@  i  s    zCyPrint.complete)N)
r9   r:   r;   r   r   r   COMMAND_DATAr   rq   r@  r   r   r   r   r   R  s
   
r   c             C   s   | d   S )Nr   )r+  )itemr   r   r   rs   q  rt   rs   c               @   s4   e Zd ZdZdZejZejZ	e
ddddd ZdS )	r   z8
    List the locals from the current Cython frame.
    z	cy localszinfo localsz	py-locals)r)   r*   c       	      C   s   |   }|jr"| jj|| d S |j}tt|td}xRt|	 t
dD ]>\}}| |   |jrJt|j}|jsJ| |j||d qJW d S )N)keyr   )r]   rH   rP   r3   rq   rI   r(  r   sortedr   sortkeyr   r   r   r}   r=   rU   r   )	r   r   r  r  Zlocal_cython_varsr   r   r   r   r   r   r   rq   }  s    
zCyLocals.invokeN)r9   r:   r;   r   r   r   rM  r   rN  r   r+   rq   r   r   r   r   r   t  s
   r   c               @   s4   e Zd ZdZdZejZejZ	e
ddddd ZdS )	r   z:
    List the globals from the current Cython module.
    z
cy globalszinfo variablesz
py-globals)r)   r*   c          	   C   s  |   }|  jj}d}d}|r0tt|td}|r@tt|}t||}t }td xDt|	 t
dD ]0\}	}
|
tj}
||	 td||	|
f  qjW td xbt|	 t
dD ]N\}}||kryt|j}W n tk
r   Y qX |js| |j||d qW d S )Nr   )rX  zPython globals:z    %-*s = %sz
C globals:z    )r   r]   rF   r3   r(  r   rK   rz   rY  r   rZ  Zget_truncated_reprr   ZMAX_OUTPUT_LENr  r   r}   r=   r   rU   r   r   )r   r   r  Zglobal_python_dictmodule_globalsZmax_globals_lenZmax_globals_dict_lenr   r   r   r   r   r   r   r   r   r   rq     s2    


zCyGlobals.invokeN)r9   r:   r;   r   r   r   rM  r   rN  r   r+   rq   r   r   r   r   r     s
   r   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )EvaluateOrExecuteCodeMixinz
    Evaluate or execute Python code in a Cython or Python frame. The 'evalcode'
    method evaluations Python code, prints a traceback if an exception went
    uncaught, and returns any return value as a gdb.Value (NULL on exception).
    c       	   
   C   s   |   }x|j D ]\}}|jtkr| ||ryt|j}W n t	k
rX   wY n
X |j
rbq||}d|||jf }z&t|dk rtd tdW d|| X qW dS )zBFill a remotely allocated dict with values from the Cython C stackz
                    (PyObject *) PyDict_SetItem(
                        (PyObject *) %d,
                        (PyObject *) %d,
                        (PyObject *) %s)
                r   zPyErr_Print()zUnable to execute Python code.N)r]   rI   r   r?   r
   r   r   r}   r=   r   rU   Zalloc_pystringr   xdecref)	r   executorZlocal_dict_pointerrn   r   r   rv   Z	pystringpr   r   r   r   _fill_locals_dict  s     

z,EvaluateOrExecuteCodeMixin._fill_locals_dictc             C   sH   t  }x0|r8| |s"| |r.|  |S | }q
W t dd S )Nz0There is no Cython or Python frame on the stack.)r   r   r#   r&   ry   rm   r   )r   r   r   r   r   "_find_first_cython_or_python_frame  s    

z=EvaluateOrExecuteCodeMixin._find_first_cython_or_python_framec             C   sf   t  T td}td}z&| |t | |||||}W d |t | X W d Q R X |S )Nz&(PyObject *) PyModule_GetDict(__pyx_m)z(PyObject *) PyDict_New())r   ZFetchAndRestoreErrorr   r}   r_  Zpointervalueevalcoder]  )r   r^  r   
input_typeZglobal_dictZ
local_dictr\   r   r   r   _evalcode_cython  s    



z+EvaluateOrExecuteCodeMixin._evalcode_cythonc             C   s6   |   }t }| |r(t|||S | |||S )zi
        Evaluate `code` in a Python or Cython stack frame using the given
        `input_type`.
        )r`  r   PythonCodeExecutorr&   Z_evalcode_pythonrc  )r   r   rb  r   r^  r   r   r   ra    s
    
z#EvaluateOrExecuteCodeMixin.evalcodeN)r9   r:   r;   r   r_  r`  rc  ra  r   r   r   r   r\    s
   r\  c               @   s(   e Zd ZdZdZejZejZ	dd Z
dS )r   zD
    Execute Python code in the nearest Python or Cython frame.
    z-cy-execc             C   s.   |  |\}}t }|| ||j d S )N)Zreadcoder   rd  r]  ra  ZPy_single_input)r   exprr  rb  r^  r   r   r   rq     s    zCyExec.invokeN)r9   r:   r;   r   r   r   rM  r   rN  r   rq   r   r   r   r   r   	  s
   r   c               @   s,   e Zd ZdZdZejZejZ	e
dd ZdS )r   z
    Set a Cython variable to a certain value

        cy set my_cython_c_variable = 10
        cy set my_cython_py_variable = $cy_eval("{'doner': 'kebab'}")

    This is equivalent to

        set $cy_value("my_cython_variable") = 10
    zcy setc             C   sR   | dd}t|dkr"td|\}}| jj| }td||f  d S )N=r      z,Invalid expression. Use 'cy set var = expr'.zset %s = %s)	r   r(  r   r   rP   r   rq   r<  r'   )r   re  r  Zname_and_exprvarnamer=   r   r   r   rq   (  s    
zCySet.invokeN)r9   r:   r;   r   r   r   rV  r   rN  r   r%   rq   r   r   r   r   r     s
   
r   c               @   s"   e Zd ZdZeedddZdS )r   z
    Get the C name of a Cython variable in the current context.
    Examples:

        print $cy_cname("function")
        print $cy_cname("Class.method")
        print $cy_cname("module.function")
    Nc             C   s   |p
t  }d }| |r| |}||jkr<|j| j}nF||jjkrX|jj| j}n*d|jj|f }||jj	kr|jj	| j}|s| j
j|}|st d| |S )Nz%s.%szNo such Cython variable: %s)r   r   r#   r]   rI   r=   rF   r3   r   r6   rP   r   r"   r   )r   cynamer   r=   r  r  r   r   r   rq   ?  s     


zCyCName.invoke)N)r9   r:   r;   r   r%   r/   rq   r   r   r   r   r   5  s   r   c                   s*   e Zd ZdZeed fdd	Z  ZS )r   z-
    Get the value of a Cython variable.
    Nc                s`   |   }| |}| ||r<tt| j||d}t|S ||krN|| jS t	d| d S )N)r   zVariable %s is not initialized.)
r   r]   r   rE   r   rq   r   r}   Z_gdbvalr   )r   ri  r   Zglobals_dictr  r=   )rM   r   r   rq   ^  s    


zCyCValue.invoke)N)r9   r:   r;   r   r%   r/   rq   rN   r   r   )rM   r   r   Y  s   r   c               @   s   e Zd ZdZedd ZdS )r   z&
    Get the current Cython line.
    c             C   s   |   S )N)r_   )r   r   r   r   rq   r  s    zCyLine.invokeN)r9   r:   r;   r   r%   rq   r   r   r   r   r   m  s   r   c               @   s   e Zd ZdZedd ZdS )r   zO
    Evaluate Python code in the nearest Python or Cython frame and return
    c             C   s   t jj}| ||S )N)r   rd  ZPy_eval_inputra  )r   Zpython_expressionrb  r   r   r   rq   |  s    zCyEval.invokeN)r9   r:   r;   r   r/   rq   r   r   r   r   r   w  s   r   c               C   s    t tdtjtjf  d S )Nz        define cy step
        cy -step
        end

        define cy next
        cy -next
        end

        document cy step
        %s
        end

        document cy next
        %s
        end
    )r   Zsource_gdb_scriptr   r   r   r   r   r   r   r   r   register_defines  s    rj  )T)N)gr   
__future__r   	raw_inputr)  	NameErrorr   r   r   r   r   r   r   unicodeUNICODEr   r	  r   Zlxmlr   Z	have_lxmlImportErrorZ	xml.etreer   r   Zelementtree.ElementTreeZpygments.lexersra   Zpygments.formattersstderrr   r   r   shlexr   ZCython.Debuggerr   r	   r
   r   Z_data_typesgetfilesystemencodingr  r   r!   r%   r+   r$   r/   objectr0   r<   rB   rO   rg   r   r   r[   r   	Parameterr   r   r   r   r   r   Commandr   r   r   r   Z
PythonInforA  ZExecutionControlCommandBaserE  ZPythonStepperMixinr   r   r   r   r   r   r   r   r   r   r   rZ  r   r   r\  ZPyExecr   r   Functionr   r   r   r   rF  r   rP   rj  r   r   r   r   <module>   s   
$


 [?
Q@ %
		+O$
