o
    ?Di                    @   s  d Z d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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ddlZejd dksEJ edZdadd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd ZdZdd ZG dd de Z!G dd dZ"e"ddeeZ#e"ddeeZ$e"ddeeZ%e"ddeeZ&e"d d!ed"d# Z'e"d$d!ed%d# Z(e"d&d!eeZ)e"d'd!eeZ*e'e(e)e*d(Z+d)d*gZ,d+a-G d,d- d-Z.G d.d/ d/e.Z/G d0d1 d1e.Z0G d2d3 d3e.Z1G d4d5 d5e.Z2G d6d7 d7Z3G d8d9 d9e Z4G d:d; d;Z5G d<d= d=e5Z6G d>d? d?e5Z7e8d@\Z9Z:Z;Z<G dAdB dBZ=G dCdD dDZ>G dEdF dFe Z?G dGdH dHe5Z@G dIdJ dJe5ZAG dKdL dLe5ZBG dMdN dNe7ZCG dOdP dPe7ZDG dQdR dRe7ZEG dSdT dTe7ZFG dUdV dVe@ZGG dWdX dXe5ZHG dYdZ dZe5ZIG d[d\ d\ZJG d]d^ d^e7ZKG d_d` d`e7ZLeBeCeLeFe6eEeDeAeJeIeGeHeKdaZMG dbdc dcZNeNdddedfdgZOeNdhdediZPeNdjdkdiZQeNdldmdkdkdndldoZReNdpdqdrdsdkdkdndldtZSeOePeQeReSduZTdvdw ZUG dxdy dyZVdzd{ ZWejXd|d fd}d~ZYeZdkreY  dS dS )z:Generate a dot graph from the output of several profilers.zJose Fonseca et al    N      z%.7gc                 C   s   d| t f S )N%u%s)MULTIPLICATION_SIGNx r   B/var/www/Datamplify/venv/lib/python3.10/site-packages/gprof2dot.pytimes2      r
   c                 C   s   d| d f S )Nz%.02f%%      Y@r   )pr   r   r	   
percentage5      r   c                 C   s   t |  S N)
timeFormat)tr   r   r	   fmttime8      r   c                 C   s   | | S r   r   abr   r   r	   add;   r   r   c                 C   s   J r   r   r   r   r   r	   fail>      r   c                 C   s   t t | }t| |S r   )mathfloorlog10round)
difference	tolerancenr   r   r	   round_differenceC   s   
r"   c                 C   s   | | ||  S r   r   )r   min_valmax_valr   r   r	   rescale_differenceH      r%   c              	   C   s   dd t | jD }dd t |jD }g }tt|D ]!}z|t|| ||  d  W q ty=   |d Y qw t|t|fS )Nc                 S      g | ]\}}|t  qS r   TOTAL_TIME_RATIO).0_f1r   r   r	   
<listcomp>M       z&min_max_difference.<locals>.<listcomp>c                 S   r'   r   r(   )r*   r+   f2r   r   r	   r-   N   r.   d   r   )	sorted_iteritems	functionsrangelenappendabs
IndexErrorminmax)profile1profile2	f1_events	f2_eventsdifferencesir   r   r	   min_max_differenceL   s   "r@   g      >c                 C   s   z
t | t | }W n
 ty   Y dS w |dk r*|t k r(tjd| |f  dS |dkr@|dt kr>tjd| |f  dS |S )N      ?        z warning: negative ratio (%s/%s)
z(warning: ratio greater than one (%s/%s)
)floatZeroDivisionErrortolsysstderrwrite)	numeratordenominatorratior   r   r	   rK   [   s   
rK   c                   @       e Zd ZdZdd Zdd ZdS )UndefinedEventz:Raised when attempting to get an event which is undefined.c                 C      t |  || _d S r   )	Exception__init__eventselfrQ   r   r   r	   rP   o      

zUndefinedEvent.__init__c                 C   s   d| j j S )Nzunspecified event %s)rQ   namerS   r   r   r	   __str__s   r   zUndefinedEvent.__str__N__name__
__module____qualname____doc__rP   rW   r   r   r   r	   rM   l       rM   c                   @   s<   e Zd ZdZefddZdd Zdd Zdd	 Zd
d Z	dS )Eventz3Describe a kind of event, and its basic operations.c                 C   s   || _ || _|| _|| _d S r   )rU   _null_aggregator
_formatter)rS   rU   null
aggregator	formatterr   r   r	   rP   z   s   
zEvent.__init__c                 C      | j S r   rU   rV   r   r   r	   __repr__      zEvent.__repr__c                 C   re   r   )r_   rV   r   r   r	   rb      rh   z
Event.nullc                 C   s$   |dusJ |dusJ |  ||S )zAggregate two event values.N)r`   )rS   val1val2r   r   r	   	aggregate   s   zEvent.aggregatec                 C   s   |dusJ |  |S )zFormat an event value.N)ra   )rS   valr   r   r	   format   s   
zEvent.formatN)
rY   rZ   r[   r\   strrP   rg   rb   rk   rm   r   r   r   r	   r^   w   s    r^   CallsSamplesTimerB   c                 C      dt |  d S N())r   r   r   r   r	   <lambda>       rv   z
Time ratioc                 C   rr   rs   )r   r   r   r   r	   rv      rw   z
Total timezTotal time ratio)z	self-timeself-time-percentagez
total-timetotal-time-percentagery   rx   
callratiosc                   @   :   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )Objectz=Base class for all objects in profile which can store events.Nc                 C   s   |d u r	i | _ d S || _ d S r   events)rS   r~   r   r   r	   rP      s   

zObject.__init__c                 C   s   t | t |k S r   id)rS   otherr   r   r	   __lt__   r&   zObject.__lt__c                 C   s
   || j v S r   r}   rR   r   r   r	   __contains__      
zObject.__contains__c                 C   $   z| j | W S  ty   t|w r   )r~   KeyErrorrM   rR   r   r   r	   __getitem__   
   zObject.__getitem__c                 C   s0   |d u r|| j v r| j |= d S d S || j |< d S r   r}   )rS   rQ   valuer   r   r	   __setitem__   s
   
zObject.__setitem__r   )	rY   rZ   r[   r\   rP   r   r   r   r   r   r   r   r	   r|      s    
r|   c                   @   s   e Zd ZdZdd ZdS )CallzhA call between functions.

    There should be at most one call object for every pair of functions.
    c                 C   s    t |  || _d | _d | _d S r   )r|   rP   	callee_idrK   weight)rS   r   r   r   r	   rP         

zCall.__init__N)rY   rZ   r[   r\   rP   r   r   r   r	   r      s    r   c                   @   s`   e Zd ZdZdd Zdd Zdd ZedZ	ed	Z
ed
Zdd Zdd ZdddZdS )FunctionzA function.c                 C   sD   t |  || _|| _d | _d | _i | _d | _d | _d | _	d | _
d S r   )r|   rP   r   rU   moduleprocesscallscalledr   cyclefilename)rS   r   rU   r   r   r	   rP      s   

zFunction.__init__c                 C   s<   |j | jv rtjdt| jt|j f  || j|j < d S )Nz1warning: overwriting call from function %s to %s
)r   r   rF   rG   rH   rn   r   )rS   callr   r   r	   add_call   s    zFunction.add_callc                 C   s>   || j vrt|}d|t< d|t< d|t< || j |< | j | S Nr   )r   r   SAMPLESSAMPLES2CALLS)rS   r   r   r   r   r	   get_call   s   


zFunction.get_callz
\([^()]*\)z<[^<>]*>z	\s+const$c                 C   sP   | j }	 | jd|\}}|snq| jd|}	 | jd|\}}|s'	 |S q)z@Remove extraneous information from C++ demangled function names.T )rU   _parenthesis_resubn	_const_resub
_angles_re)rS   rU   r!   r   r   r	   stripped_name   s   zFunction.stripped_namec                 C   re   r   rf   rV   r   r   r	   rg     rh   zFunction.__repr__,
	:=
c                    s&   |  fddt| j D | S )z Returns as a string all information available in this Function object
            separators sep1:between entries
                       sep2:between attribute name and value,
                       sep3: inserted at end
        c                 3   s&    | ]\}}  |t|gV  qd S r   )joinrn   r*   kvsep2r   r	   	<genexpr>  s   $ z Function.dump.<locals>.<genexpr>)r   sorted__dict__items)rS   sep1r   sep3r   r   r	   dump  s   &zFunction.dumpN)r   r   r   )rY   rZ   r[   r\   rP   r   r   recompiler   r   r   r   rg   r   r   r   r   r	   r      s    
	

r   c                   @   rL   )Cyclez+A cycle made from recursive function calls.c                 C   s   t |  t | _d S r   )r|   rP   setr2   rV   r   r   r	   rP   "  s   
zCycle.__init__c                 C   sP   || j vsJ | j | |jd ur#|jj D ]}|| j vr"| | q| |_d S r   )r2   r   r   add_function)rS   functionr   r   r   r	   r   &  s   



zCycle.add_functionN)rY   rZ   r[   r\   rP   r   r   r   r   r	   r     r]   r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zd6ddZ	d6ddZ
dd Zdd ZdejfddZG dd dZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 ZdS )7ProfilezThe whole profile.c                 C   s   t |  i | _g | _d S r   )r|   rP   r2   cyclesrV   r   r   r	   rP   3     

zProfile.__init__c                 C   s8   |j | jv rtjd|jt|j f  || j|j < d S )Nz)warning: overwriting function %s (id %s)
)r   r2   rF   rG   rH   rU   rn   )rS   r   r   r   r	   r   8  s   zProfile.add_functionc                 C      | j | d S r   )r   r5   )rS   r   r   r   r	   	add_cycle=  r&   zProfile.add_cyclec                 C   sh   | j  D ],}t|j D ]"}|j| j|ksJ || j vr0tjdt	||j
f  |j|= qqdS )zValidate the edges.z8warning: call to undefined function %s from function %s
N)r2   valueslistr   keysr   rF   rG   rH   rn   rU   )rS   r   r   r   r   r	   validate@  s   
zProfile.validatec                 C   sj   g }i }d}| j  D ]
}| ||||}qg }| j  D ]}|jdur/|j|vr/||j q|| _dS )zCFind cycles using Tarjan's strongly connected components algorithm.r   N)
r2   r   _tarjanr   r5   r   rF   rG   rH   rU   )rS   stackdataorderr   r   r   memberr   r   r	   find_cyclesJ  s   zProfile.find_cyclesc                    s   t  }t  fdd|D }t|dkrD| \}|| dkr$q| j| }t |j | }|fdd|D }t|dksi }|D ]#}	| j|	 }i }
|j D ]}||v rc|j| |
|< qV|
|_|||	< qH|| _d S )Nc                       g | ]}| fqS r   r   )r*   	root_nodedepthr   r	   r-   `      z&Profile.prune_root.<locals>.<listcomp>r   c                       h | ]}| d  fqS    r   r*   new_node
node_depthr   r	   	<setcomp>h  r.   z%Profile.prune_root.<locals>.<setcomp>)r   r4   popr   r2   r   r   union)rS   rootsr   visitedfrontiernodefnewNodessubtreeFunctionsr!   newCallscr   r   r   r	   
prune_root^  s,   




zProfile.prune_rootc                    s,  t t}| j D ]}| j| j D ]	}|| | qq
t }t fdd|D }t|dkr[| \}|| dkrCq-|| | }	|	fdd|	D }t|dks3t| j }
|}|

|}i }|D ]#}| j| }i }|j D ]}||v r|j| ||< q{||_|||< qm|| _d S )Nc                    r   r   r   )r*   	leaf_noder   r   r	   r-   {  r   z&Profile.prune_leaf.<locals>.<listcomp>r   c                    r   r   r   r   r   r   r	   r     r.   z%Profile.prune_leaf.<locals>.<setcomp>)collectionsdefaultdictr   r2   r   r   r   r4   r   r   intersection)rS   leafsr   edgesUpr   r!   r   r   r   r   downTreeupTreepathpathFunctionsr   r   r   r   r	   
prune_leaft  s:   





zProfile.prune_leafc                    s2   dd | j  D   fddt  |D S )Nc                 S   s   i | ]\}}|j |qS r   rf   r   r   r   r	   
<dictcomp>  r.   z*Profile.getFunctionIds.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   )r*   rU   function_namesr   r	   r-     r   z*Profile.getFunctionIds.<locals>.<listcomp>)r2   r   fnmatchfilterr   )rS   funcNamer   r   r	   getFunctionIds  s   zProfile.getFunctionIdsc                 C   s(   | j D ]}| j | j|kr|  S qdS NFr2   rU   )rS   r   r   r   r   r	   getFunctionId  s
   
zProfile.getFunctionIdNc                    s    du s dv rd fddj D }n= d dkr= dd   fd	d
j D }d dd | D }ndd j D }d dd t| D }||d  |  dS )a   Print to file function entries selected by fnmatch.fnmatch like in
            method getFunctionIds, with following extensions:
             - selector starts with "%": dump all information available
             - selector is '+' or '-': select all function entries
        N)+*z,
c                 3   s$    | ]}d | j | jf V  qdS )z%s:	%sNr   )r*   kfrV   r   r	   r     s    z+Profile.printFunctionIds.<locals>.<genexpr>r   %r   c                    s$   i | ]\}}t  |j r||qS r   )r   rU   r   selectorr   r	   r     s    z,Profile.printFunctionIds.<locals>.<dictcomp>c                 s   s,    | ]\}}d |j t|| f V  qdS )z%s	({k})	(%s)::
	%sN)rU   typer   r   r   r   r	   r     s     c                 s   s    | ]}|j V  qd S r   rf   )r*   r   r   r   r	   r     s    c                 s   s    | ]}|V  qd S r   r   )r*   nmr   r   r	   r     s    r   )	r   r2   r   r   r   r   r   rH   flush)rS   r   filer   function_infor   r   )r   rS   r	   printFunctionIds  s    



zProfile.printFunctionIdsc                   @   s   e Zd Zdd ZdS )zProfile._TarjanDatac                 C   s   || _ || _d| _d S r   )r   lowlinkonstack)rS   r   r   r   r	   rP     s   
zProfile._TarjanData.__init__N)rY   rZ   r[   rP   r   r   r   r	   _TarjanData  s    r  c              
   C   sF  z||j  }|W S  ty   | |}|||j < Y nw |d7 }t|}|| d|_|j D ]8}z||j }|jrDt	|j
|j|_
W q1 tyi   | j|j }	| |	|||}||j }t	|j
|j
|_
Y q1w |j
|jkr||d }
||d= t|
dkrt }|
D ]}|| d||j  _q|S |
D ]}d||j  _q|S )zTarjan's strongly connected components algorithm.

        See also:
        - http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm
        r   TNF)r   r   r  r4   r5   r  r   r   r   r8   r  r   r2   r   r   r   )rS   r   r   r   r   	func_dataposr   callee_datacalleemembersr   r   r   r   r	   r     sF   






zProfile._tarjanc           	      C   sn  i }| j D ]}d||< qi }| j D ]}d||< q| j D ]L}|j D ]D}|j|jkrj| j|j }||jv rZ||  || 7  < |jd urY|j|jurY||j  || 7  < q&tj	
d|j d |j d  q&q| j D ]C}|j D ];}|jd u sJ |j|jkr| j|j }||jv r|jd ur|j|jur||j }n|| }t|| ||_qxd|_qxqqd S )NrB   zcall_ratios: No data for z	 call to r   )r   r2   r   r   r   r   r~   r   rF   rG   rH   rU   rK   )	rS   rQ   cycle_totalsr   function_totalsr   r   r  totalr   r   r	   call_ratios  s@   



 
zProfile.call_ratiosc                 C   s   || vsJ | j  D ])}||vsJ ||v sJ |j D ]}||vs&J |j|jkr3|jdus3J qq| jD ]}| }| j  D ]
}|||| }qC|| |< q8| }| j  D ]}|||| }| 	||| q\|| |< dS )zPropagate function time ratio along the function calls.

        Must be called after finding the cycles.

        See also:
        - http://citeseer.ist.psu.edu/graham82gprof.html
        N)
r2   r   r   r   r   rK   r   rb   rk   _integrate_function)rS   outeventineventr   r   r   r  r   r   r	   	integrate  s(   


zProfile.integratec                 C   sh   |j d ur| |j ||S ||vr0|| }|j D ]}|j|jkr+|| |||7 }q|||< || S r   )r   _integrate_cycler   r   r   r   _integrate_call)rS   r   r  r  r  r   r   r   r	   r  .  s   
zProfile._integrate_functionc                 C   sF   ||vsJ |j d usJ | j|j }|j | ||| }|||< |S r   )rK   r2   r   r  )rS   r   r  r  r  subtotalr   r   r	   r  :  s   zProfile._integrate_callc                 C   s  ||vr|  }|jD ]&}|| }|j D ]}| j|j }|j|ur,|| |||7 }q||7 }q|||< i }	| j D ]4}
|
j|urq|
j D ]'}| j|j }|j|u rpz|	|  |j7  < W qI tyo   |j|	|< Y qIw qIq=|jD ]}|  ||< qu|		 D ]I\}}i }i }i }| 
||| | ||||t  | ||||||||}t| }t|| d| ksJ t|| | d| | ksJ q|| S )NgHz>MbP?)rb   r2   r   r   r   r   r  rK   r   r   _rank_cycle_function_call_ratios_cycler   _integrate_cycle_functionr9   r6   )rS   r   r  r  r  r   r  r   r  calleesr   
call_ratioranksr  partialspartialmax_partialr   r   r	   r  B  sJ   





"zProfile._integrate_cyclec                 C   s  ddl }g }i }i }t|g}d||< |j D ](}	|	j|jkr@| j|	j }
|
j|u r@d||
< ||
 ||
g}||| |||
< q|r|	|\}}}||vr|||< |
| |j D ]\}	|	j|jkr| j|	j }
|
j|u r|| }||
}|dur|d| krd| }|||
< ||
 }||d< ||d< ||d|| q]d| }|||
< |||
g}||| |||
< q]|sCdS dS )z|Dijkstra's shortest paths algorithm.

        See also:
        - http://en.wikipedia.org/wiki/Dijkstra's_algorithm
        r   Nr   )heapqr   r   r   r   r   r2   r   heappushheappopr   get	_siftdownindex)rS   r   r   r  r"  QQdr   r   r   r  itemcostparentr   member_rankrank	Qd_calleer   r   r	   r  o  sT   





zProfile._rank_cycle_functionc                 C   s   ||vr>| | |j D ]1}|j|jkr=| j|j }|j|u r=|| || kr=||d|j ||< | 	||||| qd S d S )NrB   )
r   r   r   r   r   r2   r   r%  rK   r  )rS   r   r   r  r  r   r   r  r   r   r	   r    s   

zProfile._call_ratios_cyclec	                 C   s(  ||vr|||  }	|j  D ]^}
|
j|jkrm| j|
j }|j|ur1||
v s(J |	||
|  7 }	q|| || krm| ||||||||}t|
j|| }|| }z
|
|  |7  < W n tyh   ||
|< Y nw |	|7 }	q|	||< z||  |	7  < W || S  ty   |	||< Y || S w || S r   )	r   r   r   r   r2   r   r  rK   rM   )rS   r   r   partial_ratior  r  r  r  r  r   r   r  callee_partialr  call_partialr   r   r	   r    s8   

z!Profile._integrate_cycle_functionc              	   C   sN   |  }| j D ]}z
|||| }W q	 ty    Y  dS w || |< dS )z)Aggregate an event for the whole profile.N)rb   r2   r   rk   rM   )rS   rQ   r  r   r   r   r	   rk     s   zProfile.aggregatec                 C   s   || vsJ || v sJ | j  D ]6}||vsJ ||v sJ t|| | | ||< |j D ]}||vs7J ||v rFt|| | | ||< q/qd| |< d S )NrA   )r2   r   rK   r   )rS   r  r  r   r   r   r   r	   rK     s   zProfile.ratioc              
      s  | j  D ]@ z t  _W n	 ty   Y nw  j D ]'}| j |j }t|v r/|t |_qzt t |t |_W q tyD   Y qw qt| j 	 D ]}| j |   jdurb j|k rb| j |= qMt| j 	 D ]0}| j |  |r j
rt fdd|D s| j |= qj|r jrt fdd|D s| j |= qj| j  D ]$ t j	 D ]} j| }|| j vs|jdur|j|k rÈ j|= qq|rg }	| j  D ] z	|	 t  W q ty   Y qw t|	pdg}
| j  D ] z	 t |
  _W q ttfy   Y qw dS dS )zPrune the profileNc                 3   s    | ]	} j |V  qd S r   )r   
startswithr*   r   r   r   r	   r     s    z Profile.prune.<locals>.<genexpr>c                 3   s     | ]} j |d kV  qdS )r   N)r   findr4  r5  r   r	   r      s    r   )r2   r   r)   r   rM   r   r   r8   r   r   r   anyr   r5   
TIME_RATIOr9   rD   )rS   
node_thres
edge_threspathscolor_nodes_by_selftimer   r  function_idr   weights	max_ratior   r5  r	   prune  sj   



 
 

zProfile.prunec                 C   s   | j  D ]0}tjd|jf  | |j |j D ]}| j |j	 }tjd|jf  | |j qq| j
D ]}tjd | |j |j D ]}tjd|jf  qJq9d S )NzFunction %s:
z  Call %s:
zCycle:
z  Function %s
)r2   r   rF   rG   rH   rU   _dump_eventsr~   r   r   r   )rS   r   r   r  r   r   r   r	   r     s   

zProfile.dumpc                 C   s2   |  D ]\}}tjd|j||f  qd S )Nz    %s: %s
)r   rF   rG   rH   rU   rm   )rS   r~   rQ   r   r   r   r	   rA  (  s   zProfile._dump_events)r   )rY   rZ   r[   r\   rP   r   r   r   r   r   r   r   r   rF   rG   r  r  r   r  r  r  r  r  r  r  r  rk   rK   r@  r   rA  r   r   r   r	   r   0  s6    


))!-1=r   c                   @   r{   )Structz7Masquerade a dictionary with a structure-like behavior.Nc                 C   s   |d u ri }|| j d< d S )N_attrs)r   )rS   attrsr   r   r	   rP   5  s   zStruct.__init__c                 C   r   r   )rC  r   AttributeErrorrS   rU   r   r   r	   __getattr__:  r   zStruct.__getattr__c                 C   s   || j |< d S r   )rC  )rS   rU   r   r   r   r	   __setattr__@  r   zStruct.__setattr__c                 C   
   t | jS r   )rn   rC  rV   r   r   r	   rW   C  r   zStruct.__str__c                 C   rI  r   )reprrC  rV   r   r   r	   rg   F  r   zStruct.__repr__r   )	rY   rZ   r[   r\   rP   rG  rH  rW   rg   r   r   r   r	   rB  2  s    
rB  c                   @   rL   )
ParseErrorz)Raised when parsing to signal mismatches.c                 C      t |  || _|| _d S r   )rO   rP   msgline)rS   rM  rN  r   r   r	   rP   M  s   

zParseError.__init__c                 C   s   d| j | jf S )Nz%s: %r)rM  rN  rV   r   r   r	   rW   S  r&   zParseError.__str__NrX   r   r   r   r	   rK  J  s    rK  c                   @   s(   e Zd ZdZdZdZdd Zdd ZdS )	ParserzParser interface.TFc                 C   s   d S r   r   rV   r   r   r	   rP   ]  r   zParser.__init__c                 C   s   t r   )NotImplementedErrorrV   r   r   r	   parse`  r   zParser.parseN)rY   rZ   r[   r\   
stdinInputmultipleInputrP   rQ  r   r   r   r	   rO  W  s    rO  c                   @   rL   )
JsonParserz_Parser for a custom JSON representation of profile data.

    See schema.json for details.
    c                 C   rN   r   )rO  rP   streamrS   rU  r   r   r	   rP   k  rT   zJsonParser.__init__c              
   C   s  t | j}|d dksJ t }d|t< |d }tt|D ];}|| }t||d }z|d |_W n	 t	y<   Y nw z|d |_
W n	 t	yM   Y nw d|t< d|_|| q|d D ]q}g }|d D ]}|j| }|| qg|j|d d  }|jd	 |_|d
 d }	|d }
|
t  |	7  < |t  |	7  < |d	d  D ],}z|j|
j }W n t	y   t|
j}|	|t< || Y n	w |t  |	7  < |}
qq_	 |  |  |tt |t |tt |S )Nversionr   r2   rU   r   r   r~   	callchainr   r+  )jsonloadrU  r   r   r3   r4   r   r   r   r   r   r   r2   r5   r   r   r   r   r   r   r   r   rK   r8  r  r  r)   )rS   objprofilefnsfunctionIndexfnr   rQ   rX  r+  r  callerr   r   r   r	   rQ  o  sd   


zJsonParser.parseN)rY   rZ   r[   r\   rP   rQ  r   r   r   r	   rT  d  s    rT  c                   @   8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )
LineParserz4Base class for parsers that read line-based formats.c                 C   s&   t |  || _d | _d| _d| _d S )NFr   )rO  rP   _stream_LineParser__line_LineParser__eofline_norV  r   r   r	   rP     s
   

zLineParser.__init__c                 C   s>   | j  }|sd| _d| _n|  jd7  _|d}|| _d S )Nr   Tr   
)rc  readlinerd  re  rf  rstriprS   rN  r   r   r	   rh    s   


zLineParser.readlinec                 C   s   | j d usJ | j S r   )rd  rV   r   r   r	   	lookahead     zLineParser.lookaheadc                 C   s    | j d usJ | j }|   |S r   )rd  rh  rj  r   r   r	   consume  s   zLineParser.consumec                 C   s   | j d usJ | jS r   )rd  re  rV   r   r   r	   eof  rl  zLineParser.eofN)	rY   rZ   r[   r\   rP   rh  rk  rm  rn  r   r   r   r	   rb    s    
rb     c                   @   s   e Zd ZdddZdd ZdS )XmlTokenNc                 C   s6   |t tttfv s
J || _|| _|| _|| _|| _d S r   )	XML_ELEMENT_STARTXML_ELEMENT_ENDXML_CHARACTER_DATAXML_EOFr   name_or_datarD  rN  column)rS   r   ru  rD  rN  rv  r   r   r	   rP     s   
zXmlToken.__init__c                 C   sR   | j tkrd| j d S | j tkrd| j d S | j tkr | jS | j tkr'dS J )N<z ...>z</>zend of file)r   rq  ru  rr  rs  rt  rV   r   r   r	   rW     s   



zXmlToken.__str__)NNNrY   rZ   r[   rP   rW   r   r   r   r	   rp    s    
rp  c                   @   sJ   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )XmlTokenizerzExpat based XML tokenizer.Tc                 C   sZ   || _ g | _d| _d| _|| _d| _d| _tjj	
 | _| j| j_| j| j_| j| j_d S )Nr   Fr   r   r   )fptokensr'  finalskip_wscharacter_poscharacter_dataxmlparsersexpatParserCreateparserhandle_element_startStartElementHandlerhandle_element_endEndElementHandlerhandle_character_dataCharacterDataHandler)rS   r|  r  r   r   r	   rP     s   

zXmlTokenizer.__init__c                 C   s4   |    |  \}}tt||||}| j| d S r   )finish_character_datar	  rp  rq  r}  r5   )rS   rU   
attributesrN  rv  tokenr   r   r	   r       z!XmlTokenizer.handle_element_startc                 C   s4   |    |  \}}tt|d ||}| j| d S r   )r  r	  rp  rr  r}  r5   )rS   rU   rN  rv  r  r   r   r	   r    r  zXmlTokenizer.handle_element_endc                 C   s"   | j s|  | _|  j |7  _ d S r   )r  r	  r  )rS   r   r   r   r	   r    s   
z"XmlTokenizer.handle_character_datac                 C   sL   | j r$| jr| j  s| j\}}tt| j d ||}| j| d| _ d S d S Nr   )r  r  isspacer  rp  rs  r}  r5   )rS   rN  rv  r  r   r   r	   r    s   

z"XmlTokenizer.finish_character_datac                 C   s   d}| j t| jkr3| js3g | _d| _ | j|}t||k | _| j|| j | j t| jkr3| jr| j t| jkrK|  \}}t	t
d d ||}|S | j| j  }|  j d7  _ |S )Ni @  r   r   )r'  r4   r}  r~  r|  readr  Parser	  rp  rt  )rS   sizer   rN  rv  r  r   r   r	   next  s   zXmlTokenizer.nextc                 C   s   | j j| j jfS r   )r  CurrentLineNumberCurrentColumnNumberrV   r   r   r	   r	  *  r&   zXmlTokenizer.posNT)rY   rZ   r[   r\   rP   r  r  r  r  r  r	  r   r   r   r	   rz    s    
rz  c                   @   s   e Zd Zdd Zdd ZdS )XmlTokenMismatchc                 C   rL  r   )rO   rP   expectedfound)rS   r  r  r   r   r	   rP   0  r   zXmlTokenMismatch.__init__c                 C   s$   d| j j| j jt| jt| j f S )Nz%u:%u: %s expected, %s found)r  rN  rv  rn   r  rV   r   r   r	   rW   5  s   $zXmlTokenMismatch.__str__Nry  r   r   r   r	   r  .  s    r  c                   @   sJ   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dddZ
dS )	XmlParserzBase XML document parser.c                 C   s    t |  t|| _|   d S r   )rO  rP   rz  	tokenizerrm  rS   r|  r   r   r	   rP   <  s   

zXmlParser.__init__c                 C   s   | j  | _d S r   )r  r  r  rV   r   r   r	   rm  A  r&   zXmlParser.consumec                 C      | j jtko| j j|kS r   )r  r   rq  ru  rF  r   r   r	   match_element_startD     zXmlParser.match_element_startc                 C   r  r   )r  r   rr  ru  rF  r   r   r	   match_element_endG  r  zXmlParser.match_element_endc                 C   sp   | j jtkr|   | j jtks| j jtkrttt|| j | j j|kr.ttt|| j | j j}|   |S r   )	r  r   rs  rm  rq  r  rp  ru  rD  )rS   rU   rD  r   r   r	   element_startJ  s   zXmlParser.element_startc                 C   sh   | j jtkr|   | j jtks| j jtkrttt|| j | j j|kr.ttt|| j |   d S r   )r  r   rs  rm  rr  r  rp  ru  rF  r   r   r	   element_endU  s   zXmlParser.element_endTc                 C   s@   d}| j jtkr|| j j7 }|   | j jtks|r| }|S r  )r  r   rs  ru  rm  strip)rS   r  r   r   r   r	   r  ^  s   zXmlParser.character_dataNr  )rY   rZ   r[   r\   rP   rm  r  r  r  r  r  r   r   r   r	   r  9  s    	r  c                   @   s   e Zd ZdZdd Zdd ZedZedZ	dd	 Z
ed
ZedZedZedZeZedZedZedZdd Zdd Zdd Zdd Zdd ZdS )GprofParseraa  Parser for GNU gprof output.

    See also:
    - Chapter "Interpreting gprof's Output" from the GNU gprof manual
      http://sourceware.org/binutils/docs-2.18/gprof/Call-Graph.html#Call-Graph
    - File "cg_print.c" from the GNU gprof source code
      http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/gprof/cg_print.c?rev=1.12&cvsroot=src
    c                 C       t |  || _i | _i | _d S r   rO  rP   r|  r2   r   r  r   r   r	   rP   r  r   zGprofParser.__init__c                 C   2   | j  }|stjd td |d}|S Nzerror: unexpected end of file
r   rg  r|  rh  rF   rG   rH   exitri  rj  r   r   r	   rh  x     


zGprofParser.readline^\d+$
^\d+\.\d+$c                 C   f   i }|  }| D ]$\}}|du rd}n| j|r t|}n
| j|r*t|}|||< q
t|S zTExtract a structure from a match object, while translating the types in the process.N	groupdictr   _int_rematchint	_float_rerC   rB  rS   morD  r  rU   r   r   r   r	   	translate     

zGprofParser.translatez^\s+called/total\s+parents\s*$|^index\s+%time\s+self\s+descendents\s+called\+self\s+name\s+index\s*$|^\s+called/total\s+children\s*$|^index\s+%\s+(time\s+)?self\s+children\s+called\s+name\s*$z#^\s+<spontaneous>\s*$|^.*\((\d+)\)$z^\[(?P<index>\d+)\]?\s+(?P<percentage_time>\d+\.\d+)\s+(?P<self>\d+\.\d+)\s+(?P<descendants>\d+\.\d+)\s+(?:(?P<called>\d+)(?:\+(?P<called_self>\d+))?)?\s+(?P<name>\S.*?)(?:\s+<cycle\s(?P<cycle>\d+)>)?\s\[(\d+)\]$z^\s+(?P<self>\d+\.\d+)?\s+(?P<descendants>\d+\.\d+)?\s+(?P<called>\d+)(?:/(?P<called_total>\d+))?\s+(?P<name>\S.*?)(?:\s+<cycle\s(?P<cycle>\d+)>)?\s\[(?P<index>\d+)\]$z^\[(?P<index>\d+)\]?\s+(?P<percentage_time>\d+\.\d+)\s+(?P<self>\d+\.\d+)\s+(?P<descendants>\d+\.\d+)\s+(?:(?P<called>\d+)(?:\+(?P<called_self>\d+))?)?\s+<cycle\s(?P<cycle>\d+)\sas\sa\swhole>\s\[(\d+)\]$z^\s+(?P<self>\d+\.\d+)?\s+(?P<descendants>\d+\.\d+)?\s+(?P<called>\d+)(?:\+(?P<called_self>\d+))?\s+(?P<name>\S.*?)(?:\s+<cycle\s(?P<cycle>\d+)>)?\s\[(?P<index>\d+)\]$z^--+$c           	      C   s  g }g }	 |st jd |d}|drn#| j|}|s0| j|r'qt jd|  n
| |}|	| q| j
|}|sMt jd|  d S | |}|r}|d}| j|}|sq| j|rhqRt jd|  n
| |}|	| |sT||_||_|| j|j< d S )NT!warning: unexpected end of entry
r   [+warning: unrecognized call graph entry: %r
)rF   rG   rH   r   r3  _cg_parent_rer  _cg_ignore_rer  r5   _cg_primary_re_cg_child_reparentschildrenr2   r'  	rS   linesr  r  rN  r  r,  r   childr   r   r	   parse_function_entry  sD   







z GprofParser.parse_function_entryc                 C   s   |d }| j |}|stjd|  d S | |}g |_|dd  D ]}| j|}|s7tjd|  q$| |}|j| q$|| j	|j
< d S )Nr   r  r   )_cg_cycle_header_rer  rF   rG   rH   r  r2   _cg_cycle_member_rer5   r   r   )rS   r  rN  r  r   r   r   r   r	   parse_cycle_entry  s   

zGprofParser.parse_cycle_entryc                 C   s*   |d  dr| | d S | | d S )Nr   r  )r3  r  r  rS   r  r   r   r	   parse_cg_entry  s   zGprofParser.parse_cg_entryc                 C   s   | j |  s	 | j |  r|  }| j |r%|  }| j |sg }|dkrN|rD| sD| j|r?| | g }n|| |  }|dks+dS dS )Parse the call graph.N)_cg_header_rer  rh  r  
_cg_sep_rer  r5   rS   rN  entry_linesr   r   r	   parse_cg  s    

zGprofParser.parse_cgc           
   	   C   s  |    | j  t }d|t< i }| jD ]}t ||< q| j D ]}t	|j
|j}|j|t< |jd ur9|j|_|jd urPt|j
}|j|t< | j|j7  _|jD ]1}t|j
}|jd usaJ |j|t< |j
| jvrt	|j
|j}d|t< d|_|| || qS|| |jd urz||j }	W n ty   tjd|j  t }	|	||j< Y nw |	| |t |t  |t< q"| D ]}	||	 q|  |tt |t |tt |t t |S )NrB   r   -warning: <cycle %u as a whole> entry missing
)!r  r|  closer   TIMEr   r   r2   r   r   r'  rU   rS   r   called_selfr   r   r  r   r   r   r   rF   rG   rH   r   r   rK   r8  r  r  
TOTAL_TIMEr)   )
rS   r\  r   r'  entryr   r   r  missingr   r   r   r	   rQ  ,  sZ   














zGprofParser.parseN)rY   rZ   r[   r\   rP   rh  r   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rQ  r   r   r   r	   r  h  s@    	

		

	/r  c                   @   s   e Zd ZdZdd Zdd ZedZedZ	dd	 Z
ed
ZedZedZedZeZedZedZdd Zdd Zdd Zdd Zdd ZdS )	AXEParserz:Parser for VTune Amplifier XE 2013 gprof-cc report output.c                 C   r  r   r  r  r   r   r	   rP     r   zAXEParser.__init__c                 C   r  r  r  rj  r   r   r	   rh    r  zAXEParser.readliner  r  c                 C   r  r  r  r  r   r   r	   r    r  zAXEParser.translatez^Index |^-----+ z^Index\s+Function\s*$z^\[(?P<index>\d+)\]?\s+(?P<percentage_time>\d+\.\d+)\s+(?P<self>\d+\.\d+)\s+(?P<descendants>\d+\.\d+)\s+(?P<name>\S.*?)(?:\s+<cycle\s(?P<cycle>\d+)>)?\s+\[(\d+)\]\s*$z^\s+(?P<self>\d+\.\d+)?\s+(?P<descendants>\d+\.\d+)?\s+(?P<name>\S.*?)(?:\s+<cycle\s(?P<cycle>\d+)>)?(?:\s+\[(?P<index>\d+)\]\s*)?\s*$z^\[(?P<index>\d+)\]?\s+(?P<percentage_time>\d+\.\d+)\s+(?P<self>\d+\.\d+)\s+(?P<descendants>\d+\.\d+)\s+<cycle\s(?P<cycle>\d+)\sas\sa\swhole>\s+\[(\d+)\]\s*$z~^\s+(?P<self>\d+\.\d+)?\s+(?P<descendants>\d+\.\d+)?\s+(?P<name>\S.*?)(?:\s+<cycle\s(?P<cycle>\d+)>)?\s+\[(?P<index>\d+)\]\s*$c           	      C   s   g }g }	 |st jd d S |d}|drn!| j|}|s+t jd|  n| |}|jdkr:|	| q| j
|}|sMt jd|  d S | |}|r{|d}| j|}|sjt jd|  n| |}|jdkry|	| |sT|jdkr||_||_|| j|j< d S d S )	NTr  r   r  z/warning: unrecognized call graph entry (1): %r
<spontaneous>z/warning: unrecognized call graph entry (2): %r
z/warning: unrecognized call graph entry (3): %r
)rF   rG   rH   r   r3  r  r  r  rU   r5   r  r  r  r  r2   r'  r  r   r   r	   r    sF   










zAXEParser.parse_function_entryc                 C   s  g }	 |st jd d S |d}|drn!| j|}|s)t jd|  n| |}|jdkr8|	| q| j
|}|sKt jd|  d S | |}g |_|dd  D ]}| j|}|slt jd	|  qY| |}|j	| qY||_|| j|j< d S )
NTz'warning: unexpected end of cycle entry
r   r  z/warning: unrecognized call graph entry (6): %r
r  z/warning: unrecognized call graph entry (4): %r
r   z/warning: unrecognized call graph entry (5): %r
)rF   rG   rH   r   r3  r  r  r  rU   r5   r  r2   r  r  r   r   )rS   r  r  rN  r  r,  r   r   r   r   r	   r    s<   






zAXEParser.parse_cycle_entryc                 C   s.   t dd |D r| | d S | | d S )Nc                 s   s    | ]}d |v V  qdS )z
as a wholeNr   )r*   
linelooperr   r   r	   r   )  s    z+AXEParser.parse_cg_entry.<locals>.<genexpr>)r7  r  r  r  r   r   r	   r  (  s   zAXEParser.parse_cg_entryc                 C   sv   |   }| j|r|   }| j|s
g }| j|s9| r(| | g }n|| |   }| j|rdS dS )r  N)rh  r  r  _cg_footer_rer  r  r5   r  r   r   r	   r  .  s   

zAXEParser.parse_cgc              	   C   s  t jd |   | j  t }d|t< i }| jD ]}t	 ||< q| j
 D ]|}t|j|j}|j|t< |jd |t< |jD ](}t|j}|t |t< |j| j
vrct|j|j}d|t< || || q@|| |jd urz||j }	W n ty   t jd|j  t	 }	|	||j< Y nw |	| |t |t  |t< q(| D ]}	||	 q|  |tt |t |j
 D ]}|j D ]}|jd ur|j
|j }
|j|
t  |t< qq|S )Nzbwarning: for axe format, edge weights are unreliable estimates derived from function total times.
rB   r   r  )rF   rG   rH   r  r|  r  r   r  r   r   r2   r   r   r'  rU   rS   percentage_timer)   r  r   r   r   r   r   r   r   rK   r8  r  r   r   )rS   r\  r   r'  r  r   r  r   r  r   r  r   r   r	   rQ  A  sX   










zAXEParser.parseN)rY   rZ   r[   r\   rP   rh  r   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  rQ  r   r   r   r	   r    s:    


	
	/'r  c                   @   s>  e Zd ZdZedZdd Zdd Zdd Z	d	d
 Z
edZdd Zdd Zdd Zdd Zdd Zdd ZdZede d e d d d Zd?dd Zd!d" Zed#Zd$d%d%d%d&d$d%d%d%d&d%d'Zd$d%d%d%d&d(d)d)d)d*d+d'Zd,d- Zd.d/ Zd0d1 Zed2Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"d=d> Z#dS )@CallgrindParserzoParser for valgrind's callgrind tool.

    See also:
    - https://valgrind.org/docs/manual/cl-format.html
    z,^calls=\s*(\d+)\s+((\d+|\+\d+|-\d+|\*)\s+)+$c                 C   sP   t | | i | _i | _d| _dg| _dg| _d| _g | _t	 | _
d| j
t< d S )Nr   rN  r   )rb  rP   position_ids	positionsnum_positionscost_positionslast_positions
num_eventscost_eventsr   r\  r   rS   infiler   r   r	   rP     s   zCallgrindParser.__init__c                 C   s   |    | d | d |  r	 |  s|  s.tjd| j  tjd|    | j	
  | j	  | j	tt | j	t | j	tt | j	S )NrW  creatorz"warning: line %u: unexpected line
z%s
)rh  	parse_key
parse_partrn  rF   rG   rH   rf  rk  r\  r   r   rK   r8  r   r  r   r  r)   rV   r   r   r	   rQ    s   



zCallgrindParser.parsec                 C   s@   |   sdS |   r	 |   s
|  sdS |  r	 |  sdS NFT)parse_header_lineparse_body_linerV   r   r   r	   r    s   zCallgrindParser.parse_partc                 C   s8   |   p|  p|  p|  p|  p|  p|  S r   )parse_emptyparse_commentparse_part_detailparse_descriptionparse_event_specificationparse_cost_line_defparse_cost_summaryrV   r   r   r	   r    s   z!CallgrindParser.parse_header_line)cmdpidthreadpartc                 C   s   |  | jS r   )
parse_keys_detail_keysrV   r   r   r	   r    r   z!CallgrindParser.parse_part_detailc                 C   s   |  dd uS )Ndescr  rV   r   r   r	   r    r   z!CallgrindParser.parse_descriptionc                 C      |  d}|d u rdS dS )NrQ   FTr   rR   r   r   r	   r       
z)CallgrindParser.parse_event_specificationc                 C   sh   |  d}|d u rdS |\}}| }|dkrt|| _|| _|dkr2t|| _|| _dg| j | _dS )N)r~   r  Fr~   r  r   T)r  splitr4   r  r  r  r  r  )rS   pairkeyr   r   r   r   r	   r    s   


z#CallgrindParser.parse_cost_line_defc                 C   r  )N)summarytotalsFTr  )rS   r  r   r   r	   r    r  z"CallgrindParser.parse_cost_summaryc                 C   s(   |   p|  p|  p|  p|  S r   )r  r  parse_cost_lineparse_position_specparse_association_specrV   r   r   r	   r    s   zCallgrindParser.parse_body_linez"(0x[0-9a-fA-F]+|\d+|\+\d+|-\d+|\*)^z( +z)*z( +\d+)*$Nc                 C   s  |    }| j|}|sdS |  }|d u r,z
| jd | jd< W n	 ty+   Y nw | }t|| j	| j
 ks<J |d| j	 }|| j	d  }|dg| j
t|  7 }t| j	D ]4}|| }	|	dkrk| j| }	n|	d dv r{| j| t|	 }	n|	drt|	d	}	nt|	}	|	| j|< q[d
d |D }|d u r|t  |d 7  < | jt  |d 7  < nC|  }
|
 j|7  _z|j|
j }W n ty   t|
j}||t< |d |t< || Y nw |t  |7  < |t  |d 7  < |   dS )NFobcobr   0r   z-+0x   c                 S   s   g | ]}t |qS r   )rC   )r*   rQ   r   r   r	   r-      r   z3CallgrindParser.parse_cost_line.<locals>.<listcomp>T)rk  ri  _cost_rer  get_functionr  r   r  r4   r  r  r3   r  r  r3  r   r\  
get_calleer   r   r   r   r   r   r   rm  )rS   r   rN  r  r   r   r  r~   r?   positionr  r   r   r   r	   r	    sX   

zCallgrindParser.parse_cost_linec                 C   s`   |   }|dsdS |dd\}}|  }t|d }|dd  }|   | | dS )Nzcalls=F=r   r   T)rk  r3  r  r  r  rm  r	  )rS   rN  r+   r   r   call_positionr   r   r	   r  7  s   

z&CallgrindParser.parse_association_speczR^(?P<position>[cj]?(?:ob|fl|fi|fe|fn))=\s*(?:\((?P<id>\d+)\))?(?:\s*(?P<name>.+))?r  flr_  )r  r  fifer_  r  cflcficfecfnjfir  r  r  r   c                 C   s   |   }|ds|dr|   dS | j|}|sdS | \}}}|r?| j| }|r6|| j||f< n	| j||fd}|| j	| j
| < |   dS )Nzjump=zjcnd=TFr   )rk  r3  rm  _position_rer  groups_position_table_mapr  r%  r  _position_map)rS   rN  r  r  r   rU   tabler   r   r	   r
  d  s    
z#CallgrindParser.parse_position_specc                 C   s,   |   rdS |  }| rdS |   dS r  )rn  rk  r  rm  rj  r   r   r	   r  {  s   zCallgrindParser.parse_emptyc                 C   s"   |   }|dsdS |   dS )N#FT)rk  r3  rm  rj  r   r   r	   r    s
   
zCallgrindParser.parse_commentz^(\w+):c                 C   s    |  |f}|s
d S |\}}|S r   r  )rS   r  r  r   r   r   r	   r    s
   zCallgrindParser.parse_keyc                 C   sP   |   }| j|}|sd S |dd\}}||vrd S | }|   ||fS )N:r   )rk  _key_rer  r  r  rm  )rS   r   rN  r  r  r   r   r   r	   r    s   zCallgrindParser.parse_keysc                 C   sb   |}z	| j j| }W |S  ty0   t||}|r tj||_d|t< d|_	| j 
| Y |S w r   )r\  r2   r   r   osr   basenamer   r   r   r   )rS   r   r   rU   r   r   r   r   r	   make_function  s   
zCallgrindParser.make_functionc                 C   8   | j dd}| j dd}| j dd}| |||S )Nr  r   r  r_  r  r%  r+  rS   r   r   r   r   r   r	   r       zCallgrindParser.get_functionc                 C   r,  )Nr  r   r  r  r-  r.  r   r   r	   r    r/  zCallgrindParser.get_calleec                 C   (   	 t |  |  s|  dsd S qNTr&  rb  rh  rn  rk  r3  rV   r   r   r	   rh    
   
zCallgrindParser.readliner   )$rY   rZ   r[   r\   r   r   _call_rerP   rQ  r  r  r   r  r  r  r  r  r  r  _CallgrindParser__subpos_rer  r	  r  r!  r#  r$  r
  r  r  r(  r  r  r+  r  r  rh  r   r   r   r	   r    s    


;
	
r  c                   @   T   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	
dZe	
dZdd ZdS )
PerfParserzParser for linux perf callgraph output.

    It expects output generated with

        perf record -g
        perf script | gprof2dot.py --format=perf
    c                 C      t | | t | _d S r   rb  rP   r   r\  r  r   r   r	   rP        zPerfParser.__init__c                 C   r0  r1  r2  rV   r   r   r	   rh    r3  zPerfParser.readlinec                 C      |    | j}d|t< |  s|   |  r|  |  |tt |	t
 tdkr6|tt |S tdkrl|t |t< |tt |j D ]}|j D ]}|jd urh|j|j }|j|t  |t< qRqK|S J Nr   rz   
callstacksrh  r\  r   rn  parse_eventr   r   rK   r8  r  r   totalMethodr  r)   TOTAL_SAMPLESr2   r   r   r   rS   r\  r   r   r  r   r   r	   rQ    2   

zPerfParser.parsec              	   C   s   |   rd S |  }|sJ |  }|sd S |d }|t  d7  < | jt  d7  < |dd  D ],}z|j|j }W n tyR   t|j}d|t	< |
| Y n	w |t	  d7  < |}q1t|}|D ]
}|t  d7  < qdd S Nr   r   )rn  rm  parse_callchainr   r\  r   r   r   r   r   r   r   rA  )rS   rN  rX  r  r`  r   r   r   r   r   r	   r?    s0   
zPerfParser.parse_eventc                 C   sH   g }|   r|  }|d u rn	|| |   s|   dkr"|   |S r  )rk  
parse_callr5   rm  )rS   rX  r   r   r   r	   rE    s   
zPerfParser.parse_callchainzD^\s+(?P<address>[0-9a-fA-F]+)\s+(?P<symbol>.*)\s+\((?P<module>.*)\)$\+0x[0-9a-fA-F]+$c                 C   s   |   }| j|}|sJ |sd S |d}|r!t| jd|}|r'|dkr,|d}|d}|d | }z	| jj| }W |S  t	yd   t
||}tj||_d|t< d|t< | j| Y |S w )Nsymbolr   z	[unknown]addressr   r'  r   )rm  call_rer  groupr   r   addr2_rer\  r2   r   r   r)  r   r*  r   r   rA  r   rS   rN  r  function_namer   r=  r   r   r   r	   rF  %  s.   



zPerfParser.parse_callNrY   rZ   r[   r\   rP   rh  rQ  r?  rE  r   r   rJ  rL  rF  r   r   r   r	   r7    s      

r7  c                   @   s   e Zd ZdZdddddddZd	d
 Zdd Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#S )$OprofileParserzParser for oprofile callgraph output.

    See also:
    - http://oprofile.sourceforge.net/doc/opreport.html#opreport-callgraph
    z(\d+)z(\S+)z/(?P<source>\(no location information\)|\S+:\d+)z#(?P<image>\S+(?:\s\(tgid:[^)]*\))?)z(?P<application>\S+)z(?P<symbol>\(no symbols\)|.+?))samplesr   zlinenr infoz
image namezapp namezsymbol namec                 C   s   t | | i | _d | _d S r   )rb  rP   entriesentry_rer  r   r   r	   rP   U     
zOprofileParser.__init__c                 C   sn   z| j |j }W n ty   |||f| j |j< Y d S w |\}}}| || | j|j7  _| || d S r   )rR  r   r   update_subentries_dictrQ  )rS   callersr   r  r  callers_totalfunction_totalcallees_totalr   r   r	   	add_entryZ  s   
zOprofileParser.add_entryc              	   C   sN   |  D ] }z||j }W n ty   |||j< Y qw | j|j7  _qd S r   )r   r   r   rQ  )rS   r  r  r   r  r   r   r	   rU  e  s   z%OprofileParser.update_subentries_dictc           
      C   s4  |    |   |  r|   |  st }i }d|t< | j D ]\\}}}t|j	|j
}|j|t< || |t  |j7  < |jrLtj|j|_|jrWtj|j|_d}| D ]}||j7 }q]| D ]}|js}t|j	}	|j|	t< ||	 qiq"|  |  |tt |t |tt |S r   )rh  parse_headerrk  parse_entryr   r   rR  r   r   r   rU   rQ  r   applicationr)  r   r*  r   imager   rS   r   r   r   r   r   rK   r8  r  r  r)   )
rS   r\  reverse_call_samples_callers	_function_calleesr   total_callee_samples_calleer   r   r   r	   rQ  n  sB   





zOprofileParser.parsec                    sd      s      r  }td|}dd fdd|D  d }t| _   d S )Nz\s\s+z^\s*z\s+c                       g | ]} j | qS r   )
_fields_re)r*   fieldrV   r   r	   r-         z/OprofileParser.parse_header.<locals>.<listcomp>z(?P<self>\s+\[self\])?$)	match_headerrm  rk  r   r  r   r   rS  skip_separator)rS   rN  fieldsrS  r   rV   r	   r[    s    zOprofileParser.parse_headerc                 C   sB   |   }|  r|  }|d ur|   }| ||| |   d S r   )parse_subentriesmatch_primaryparse_subentryrZ  rj  )rS   rV  r   r  r   r   r	   r\    s   zOprofileParser.parse_entryc                 C   s*   i }|   r|  }|||j< |   s|S r   )match_secondaryrn  r   )rS   
subentriessubentryr   r   r	   rl    s   
zOprofileParser.parse_subentriesc                 C   sT  t  }|  }| j|}|std|| }t|d|_d|v r>|d dkr>|d }|	d\}}||_
t||_nd}d |_
d |_|dd|_|dd|_d	|v rd|d	 d
krd|d	 |_nd|_|jdr{|jdr{|jdd |_d|j|j||jf|_|dd d k|_|jr| jd7  _|jr|j|_|S |j|_|S )Nzfailed to parser   sourcez(no location information)r'  r   r^  r]  rH  z(no symbols)"r   rS   z:self)rB  rm  rS  r  rK  r  r  rK  rQ  r  r   linenor%  r^  r]  rH  r3  endswithr   r   rS   rU   )rS   r  rN  r  rk  rr  r   rt  r   r   r	   rn    s>   
zOprofileParser.parse_subentryc                 C   s$   |   s|   |   r|   d S r   )match_separatorrm  rV   r   r   r	   rj    s   zOprofileParser.skip_separatorc                 C   s   |   }|dS )NrQ  )rk  r3  rj  r   r   r	   ri    s   
zOprofileParser.match_headerc                 C   s   |   }|dt| kS )N-)rk  r4   rj  r   r   r	   rv       zOprofileParser.match_separatorc                 C   s   |   }|d d   S Nr   rk  r  rj  r   r   r	   rm    s   zOprofileParser.match_primaryc                 C   s   |   }|d d  S ry  rz  rj  r   r   r	   ro    rx  zOprofileParser.match_secondaryN)rY   rZ   r[   r\   rf  rP   rZ  rU  rQ  r[  r\  rl  rn  rj  ri  rv  rm  ro  r   r   r   r	   rP  E  s,    		,		#rP  c                   @   sL   e Zd ZdZedZedZdd Zdd Z	dd	 Z
d
d Zdd ZdS )HProfParserz}Parser for java hprof output

    See also:
    - http://java.sun.com/developer/technicalArticles/Programming/HPROF.html
    z\t(.*)\((.*):(.*)\)z^TRACE (\d+):$c                 C   s   t | | i | _i | _d S r   )rb  rP   tracesrQ  r  r   r   r	   rP     rT  zHProfParser.__init__c                 C   s  |    |  ds|   |  dr|  ds(|   |  dr|   |  ds>|   |  dr3|   t }d|t< i }| j	 D ]W\}}|| j
vrZqP| j
| d }d }|D ]A\}}}	||vrt||}
d|
t< ||
 |
||< || }
|s|
t  |7  < |t  |7  < n|
|}|t  |7  < |}qeqP|  |  |tt |t |tt |S )Nz------TRACE CPUr   )rh  rk  r3  rm  parse_tracesparse_samplesr   r   r|  r   rQ  r   r   r   r   r   r   rK   r8  r  r  r)   )rS   r\  r2   r   tracemtimelastfuncr  rN  r   r   r   r   r	   rQ    sF   $$



zHProfParser.parsec                 C   s,   |   dr|   |   dsd S d S )Nr}  )rk  r3  parse_tracerV   r   r   r	   r  0	  s   zHProfParser.parse_tracesc           
      C   s   |   }| j|}|d}d }g }|  dr=|   }| j|}|s'n| \}}}	||||	fg7 }|  ds|| j	t
|< d S )Nr   	)rm  trace_id_rer  rK  rk  r3  trace_researchr"  r|  r  )
rS   lr  tidr  r  r  rN  r  rN  r   r   r	   r  4	  s   

zHProfParser.parse_tracec                 C   sj   |    |    |  ds3|   \}}}}}}t||f| jt|< |    |  drd S d S )Nr~  )rm  rk  r3  r  r  rQ  )rS   r.  percent_selfpercent_accumcounttraceidmethodr   r   r	   r  G	  s   zHProfParser.parse_samplesN)rY   rZ   r[   r\   r   r   r  r  rP   rQ  r  r  r  r   r   r   r	   r{    s    

5r{  c                   @   sD   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dS )SysprofParserc                 C   s   t | | d S r   )r  rP   rV  r   r   r	   rP   S	  r&   zSysprofParser.__init__c                 C   s   i }i }|  d | jjtkr<| jjdkr|rJ | d}n| jjdkr/|r)J | d}n| | jj | jjtks| d | ||S )Nr\  objectsnodes)	r  r  r   rq  ru  parse_itemsparse_valuer  build_profile)rS   r  r  r   r   r	   rQ  V	  s   

	zSysprofParser.parsec                 C   sn   |d dksJ i }|  | | jjtkr0| |d d \}}||vs&J |||< | jjtks| | |S )Nr   s)r  r  r   rq  
parse_itemr  )rS   rU   r   r   r   r   r   r	   r  h	  s   

zSysprofParser.parse_itemsc                 C   s0   |  |}t|d }|  }| | ||fS )Nr   )r  r  parse_valuesr  )rS   rU   rD  r   r   r   r   r	   r  s	  s
   

zSysprofParser.parse_itemc                 C   sF   i }| j jtkr!| j j}| |}||vsJ |||< | j jtks|S r   )r  r   rq  ru  r  )rS   r   rU   r   r   r   r	   r  z	  s   
zSysprofParser.parse_valuesc                 C   sP   |  | |  }| | | rt|S |dr&|dr&|dd S |S )Nrs  r   r   )r  r  r  isdigitr  r3  ru  )rS   tagr   r   r   r	   r  	  s   

zSysprofParser.parse_valuec              	   C   s  t  }d|t< | D ]'\}}|d dkrqt||d }|d |t< || |t  |t 7  < q| D ]t\}}|d dkrBq7|d }|dkrc|| }	|	d }
||
 d dkr[n|	d }|dksJ|dkrhq7|d }||
 d stJ || d s|J |j|
 }|d }z|j| }W n ty   t|}||t	< |
| Y q7w |t	  |7  < q7|  |  |tt |t	 |tt |S )Nr   rS   rU   r,  object)r   r   r   r   r   r2   r   r   r   r   r   r   r   rK   r8  r  r  r)   )rS   r  r  r\  r   r  r   r   	parent_idr,  	caller_idr   rQ  r   r   r   r	   r  	  sR   


zSysprofParser.build_profileN)
rY   rZ   r[   rP   rQ  r  r  r  r  r  r   r   r   r	   r  Q	  s    	
r  c                   @   ra  )XPerfParserzRParser for CSVs generated by XPerf, from Microsoft Windows Performance Tools.
    c                 C   s,   t |  || _t | _d| jt< i | _d S r   )rO  rP   rU  r   r\  r   rv  rV  r   r   r	   rP   	  s
   


zXPerfParser.__init__c              
   C   s   dd l }|j| jdd d ddd|jd}d}|D ]}|r#| | d}q| | q| j  | j  | j	t
t | jt | jtt
 | jS )Nr   ,FTrg  )	delimiter	quotechar
escapechardoublequoteskipinitialspacelineterminatorquoting)csvreaderrU  
QUOTE_NONEr[  	parse_rowr\  r   r   rK   r8  r   r  r   r  r)   )rS   r  r  headerrowr   r   r	   rQ  	  s.   	


zXPerfParser.parsec                 C   s6   t t|D ]}|| }|| jvsJ || j|< qd S r   )r3   r4   rv  )rS   r  rv  rU   r   r   r	   r[  	  s
   zXPerfParser.parse_headerc              
   C   s  i }| j  D ]#\}}|| }ttfD ]}z||}W n	 ty$   Y qw  |||< q|d }|d d |d  }|d }	|d }
|dkrGd S | ||}|t  |	|
 7  < | jt  |	|
 7  < |d }|d	kr|d
}|d dkswJ |d |kr|	| d }|dd  D ]8}| ||}|d urz|j
|j }W n ty   t|j}|
|t< || Y n	w |t  |
7  < |}qd S d S )NzProcess NameModule!r   WeightCountIdleStack?/r   z[Root]r   r   )rv  r   r  rC   
ValueErrorr  r   r\  r  r5   r   r   r   r   r   r   )rS   r  rk  rU   rv  r   factoryr   rH  r   r  r   r   r`  r  r   r   r   r	   r  	  sR   



zXPerfParser.parse_rowc                 C   sn   |d | }z	| j j| }W |S  ty6   |dd\}}t||}||_||_d|t< | j | Y |S w )Nr  r   r   )	r\  r2   r   r  r   r   r   r   r   )rS   r   rH  r=  r   r   rU   r   r   r	   r  !
  s   	
zXPerfParser.get_functionN)	rY   rZ   r[   r\   rP   rQ  r[  r  r  r   r   r   r	   r  	  s    .r  c                   @   sF   e Zd ZdZdZdd ZedZdd Z	dd	 Z
d
d Zdd ZdS )SleepyParserzParser for GNU gprof output.

    See also:
    - http://www.codersnotes.com/sleepy/
    - http://sleepygraph.sourceforge.net/
    Fc                 C   s8   t |  ddlm} ||| _i | _i | _t | _d S )Nr   )ZipFile)	rO  rP   zipfiler  databasesymbolsr   r   r\  )rS   r   r  r   r   r	   rP   ;
  s   

zSleepyParser.__init__zk^(?P<id>\w+)\s+"(?P<module>[^"]*)"\s+"(?P<procname>[^"]*)"\s+"(?P<sourcefile>[^"]*)"\s+(?P<sourceline>\d+)$c                 C   s6   | j  D ]}| | kr|} nq| j |dS )Nr)r  namelistloweropen)rS   rU   database_namer   r   r	   	openEntryO
  s   zSleepyParser.openEntryc           
   	   C   s   |  dD ]K}|dd}| j|}|rP| \}}}}}d||g}z| jj| }	W n t	yJ   t
||}	||	_d|	t< | j|	 Y nw |	| j|< qd S )NzSymbols.txtUTF-8rg  r'  r   )r  decoderi  
_symbol_rer  r"  r   r\  r2   r   r   r   r   r   r  )
rS   rN  r  	symbol_idr   procname
sourcefile
sourceliner=  r   r   r   r	   parse_symbolsX
  s"   

zSleepyParser.parse_symbolsc              
      s     dD ]k}|dd}| }t|d }|dd  } fdd|D }|d }|t  |7  <  jt  |7  < |dd  D ],}z|j|j }W n t	yd   t
|j}||t< || Y n	w |t  |7  < |}qCqd S )NzCallstacks.txtr  rg  r   r   c                    re  r   )r  )r*   r  rV   r   r	   r-   t
  rh  z1SleepyParser.parse_callstacks.<locals>.<listcomp>)r  r  ri  r  rC   r   r\  r   r   r   r   r   r   )rS   rN  rk  rQ  	callstackr  r`  r   r   rV   r	   parse_callstacksl
  s*   
zSleepyParser.parse_callstacksc                 C   sT   | j }d|t< |   |   |  |  |tt |t	 |
tt |S r   )r\  r   r  r  r   r   rK   r8  r  r   r  r)   )rS   r\  r   r   r	   rQ  
  s   
zSleepyParser.parseN)rY   rZ   r[   r\   rR  rP   r   r   r  r  r  r  rQ  r   r   r   r	   r  1
  s    	r  c                   @   s8   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dS )PstatsParserz?Parser python profiling statistics saved with te pstats module.FTc              	   G   s^   dd l }z|j| | _W n ty%   tjdd|  td Y nw t	 | _
i | _d S )Nr   zPerror: failed to load %s, maybe they are generated by different python version?
, r   )pstatsStatsstatsr  rF   rG   rH   r   r  r   r\  function_ids)rS   r   r  r   r   r	   rP   
  s   
zPstatsParser.__init__c                 C   s4   |\}}}t j|d }t j|}d|||f S )Nr   z%s:%d:%s)r)  r   splitextr*  )rS   r  r   rN  rU   r   r   r   r	   get_function_name
  s   
zPstatsParser.get_function_namec                 C   sr   z| j | }W n) ty0   t| j }| |}t||}|d |_|| jj|< || j |< Y |S w | jj| }|S r   )r  r   r4   r  r   r   r\  r2   )rS   r  r   rU   r   r   r   r	   r  
  s   



zPstatsParser.get_functionc                 C   sv  d| j t< | jj| j t< | jj D ]\}\}}}}}| |}||_||t< ||t< | j t  |7  < t| j t || j t< | D ]_\}}| |}	t	|j
}
t|trtdt|dD ]0}|||d  \}}}}t|
v ry|
t  |7  < n||
t< t|
v r|
t  |7  < q^||
t< q^n||
t< t||| |
t< |	|
 qCq	 | j   | j tt | j tt | j S )NrB   r   ro  )r\  r  r  total_ttr  r   r  r   r9   r   r   
isinstancetupler3   r4   r   rK   r   print_statsprint_calleesr   r8  r)   )rS   r_  ccncttctrV  r  r   r`  r   r?   r   r   r	   rQ  
  s>   






zPstatsParser.parseN)
rY   rZ   r[   r\   rR  rS  rP   r  r  rQ  r   r   r   r	   r  
  s    
r  c                   @   r6  )DtraceParsera<  Parser for linux perf callgraph output.

    It expects output generated with

        # Refer to https://github.com/brendangregg/FlameGraph#dtrace
        # 60 seconds of user-level stacks, including time spent in-kernel, for PID 12345 at 97 Hertz
        sudo dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345/ { @[ustack()] = count(); } tick-60s { exit(0); }' -o out.user_stacks

        # The dtrace output
        gprof2dot.py -f dtrace out.user_stacks

        # Notice: sometimes, the dtrace outputs format may be latin-1, and gprof2dot will fail to parse it.
        # To solve this problem, you should use iconv to convert to UTF-8 explicitly.
        # TODO: add an encoding flag to tell gprof2dot how to decode the profile file.
        iconv -f ISO-8859-1 -t UTF-8 out.user_stacks | gprof2dot.py -f dtrace
    c                 C   r8  r   r9  r  r   r   r	   rP   
  r:  zDtraceParser.__init__c                 C   sH   	 t |  |  rd S |   }|drt |  n|dks#d S q)NTr~  r   )rb  rh  rn  rk  r  r3  rj  r   r   r	   rh  
  s   

zDtraceParser.readlinec                 C   r;  r<  r>  rB  r   r   r	   rQ    rC  zDtraceParser.parsec              	   C   s   |   rd S |  \}}|sd S |d }|t  |7  < | jt  |7  < |dd  D ],}z|j|j }W n tyL   t|j}||t< |	| Y n	w |t  |7  < |}q+t
|}|D ]
}|t  |7  < q^d S rD  )rn  rE  r   r\  r   r   r   r   r   r   r   rA  )rS   rX  r  r  r`  r   r   r   r   r   r	   r?  /  s,   
zDtraceParser.parse_eventc                 C   sH   g }d}|   r |  \}}|d u r	 ||fS || |   s||fS r   )rk  rF  r5   )rS   rX  r  r   r   r   r	   rE  M  s   
zDtraceParser.parse_callchainz!^\s+(?P<module>.*)`(?P<symbol>.*)rG  c                 C   s   |   }| j|}|sd t| fS |d}|r#t| jd|}|d}|d | }z| j	j
| }W |d fS  ty_   t||}tj||_d|t< d|t< | j	| Y |d fS w )NrH  r   r   r'  r   )rm  rJ  r  r  r  rK  r   r   rL  r\  r2   r   r   r)  r   r*  r   r   rA  r   rM  r   r   r	   rF  Z  s(   


zDtraceParser.parse_callNrO  r   r   r   r	   r  
  s     


r  c                   @   s:   e Zd ZdZdd Zdd Zdd ZedZ	d	d
 Z
dS )CollapseParserzbParser for the output of stackcollapse

    (from https://github.com/brendangregg/FlameGraph)
    c                 C   r8  r   r9  r  r   r   r	   rP     r:  zCollapseParser.__init__c                 C   s   | j }d|t< |   |  s|   |  r|  |  |tt |	t
 tdkr6|tt |S tdkrl|t |t< |tt t|jD ]}t|jD ]}|jd urh|j|j }|j|t  |t< qRqK|S J r<  )r\  r   rh  rn  r?  r   r   rK   r8  r  r   r@  r  r)   rA  compat_itervaluesr2   r   r   rB  r   r   r	   rQ    s2   

zCollapseParser.parsec           
         s      }|jddd\}}t|} jt  |7  < |d} fdd|D }|d t  |7  < t|D ]
}|t  |7  < q6|d }t|d d D ]%}|j	
|j}	|	d u rht|j}	d|	t< ||	 |	t  |7  < |}qMd S )	N r   )maxsplit;c                    s   g | ]}  |qS r   )_make_function)r*   r   rV   r   r	   r-     rh  z.CollapseParser.parse_event.<locals>.<listcomp>r   r   )rm  rsplitr  r\  r   r  r   rA  reversedr   r%  r   r   r   r   )
rS   rN  r   r  r   r2   r  r  r`  r   r   rV   r	   r?    s&   


zCollapseParser.parse_eventz3^(?P<func>[^ ]+) \((?P<file>.*):(?P<line>[0-9]+)\)$c                 C   s~   | j |}|r| \}}}d||f }n| }}d}| jj|}|du r=t||}||_d|t< d|t	< | j
| |S )zturn a call str into a Function

        takes a call site, as found between semicolons in the input, and returns
        a Function definition corresponding to that call site.
        z%s:%sNr   )rJ  r  r"  r\  r2   r%  r   r   r   rA  r   )rS   r   r  rU   r   rN  func_idr  r   r   r	   r    s   
zCollapseParser._make_functionN)rY   rZ   r[   r\   rP   rQ  r?  r   r   rJ  r  r   r   r   r	   r  z  s    
r  )axe	callgrindcollapsehprofrY  oprofileperfprofr  sleepysysprofxperfdtracec                   @   s   e Zd Z													
d,ddZdd Zdd Zdd Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+S )-ThemerB   rB   rA   rB   rB   rB   Arialwhitefilled      $@      ?      @皙@rA   c                 C   sL   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
|| _d S r   )bgcolormincolormaxcolorfontname	fontcolor	nodestyleminfontsizemaxfontsizeminpenwidthmaxpenwidthgammaskew)rS   r  r  r  r   r  r  r  r  r  r  r  r  r   r   r	   rP     s   
zTheme.__init__c                 C   s   | j | j S r   )
hsl_to_rgbr  rV   r   r   r	   graph_bgcolor	  r   zTheme.graph_bgcolorc                 C   re   r   r   rV   r   r   r	   graph_fontname  rh   zTheme.graph_fontnamec                 C   re   r   )r  rV   r   r   r	   graph_fontcolor  rh   zTheme.graph_fontcolorc                 C   
   |  |S r   colorrS   r   r   r   r	   node_bgcolor  r   zTheme.node_bgcolorc                 C   s   | j dkr	|  S | |S )Nr  )r  r
  r  r  r   r   r	   node_fgcolor  s   

zTheme.node_fgcolorc                 C   r  r   fontsizer  r   r   r	   node_fontsize  r   zTheme.node_fontsizec                 C   re   r   )r  rV   r   r   r	   
node_style  rh   zTheme.node_stylec                 C   r  r   r  r  r   r   r	   
edge_color!  r   zTheme.edge_colorc                 C   r  r   r  r  r   r   r	   edge_fontsize$  r   zTheme.edge_fontsizec                 C   s   t || j | jS r   )r9   r  r  r  r   r   r	   edge_penwidth'  s   zTheme.edge_penwidthc                 C   s   dt | | S )Nr  )r   sqrtr  r  r   r   r	   edge_arrowsize*  s   zTheme.edge_arrowsizec                 C   s   t |d | j | jS )N   )r9   r  r  r  r   r   r	   r  -  s   zTheme.fontsizec                 C   s   t t|dd}| j\}}}| j\}}}| jdk rtd| jdkr;||||   }||||   }	||||   }
n3| j}||| d||   |d   }||| d||   |d   }	||| d||   |d   }
| ||	|
S )NrB   rA   r   zSkew must be greater than 0g      )r8   r9   r  r  r  r  r	  )rS   r   hminsminlminhmaxsmaxlmaxhr  r  baser   r   r	   r  0  s   

   zTheme.colorc           	      C   s   |d }t t|dd}t t|dd}|dkr||d  }n|| ||  }|d | }| |||d }| |||}| |||d }|| jC }|| jC }|| jC }|||fS )z}Convert a color from HSL color-model to RGB.

        See also:
        - http://www.w3.org/TR/css3-color/#hsl-color
        rA   rB   r         @gUUUUUU?)r8   r9   _hue_to_rgbr  )	rS   r$  r  r  m2m1r  gr   r   r   r	   r	  D  s   



zTheme.hsl_to_rgbc                 C   sz   |dk r	|d7 }n|dkr|d8 }|d dk r!||| | d  S |d dk r)|S |d dk r;||| d|  d  S |S )	NrB   rA      g      @r  r   r&  UUUUUU?r   )rS   r)  r(  r$  r   r   r	   r'  _  s   
zTheme._hue_to_rgbN)r  r  r  r  r  r  r  r  r  r  r  rA   )rY   rZ   r[   rP   r
  r  r  r  r  r  r  r  r  r  r  r  r  r	  r'  r   r   r   r	   r    s:    
r  )r,  g?      ?)rB   rA   r  rA   )r  r  r  )rB   rA   g?)r  r  )rB   rB   g333333?r  g       @g      8@皙?)r  r  r  r  r  r  g      2@g      >@blacksolid)r  r  r  r  r  r  r  r  )r  pinkgraybwprintc                 c   s6    t |  }|  |D ]}| | }||fV  qd S r   )r   r   sort)dr   r  r   r   r   r	   r1     s   r1   c                   @   s   e Zd ZdZdZdZdd Zdd Zee	gZ
eegZdd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!S )"	DotWriterzWriter for the DOT language.

    See also:
    - "The DOT Language" specification
      http://www.graphviz.org/doc/info/lang.html
    Fc                 C   s
   || _ d S r   )r|  r  r   r   r	   rP     r   zDotWriter.__init__c                 C   sx   t |dkr(d}ttt |d|  d d}tt || d}tj||dd}|dd	}|d
d}|d
d}|S )z*Split the function name on multiple lines.    r,  rA   r  r   F)break_long_wordsr  r  z> >z>>)r4   r9   r  textwrapfillreplace)rS   rU   rK   heightwidthr   r   r	   wrap_function_name  s   zDotWriter.wrap_function_namec           &      C   s  |    | }| }| }|j|j|j|jf\}}	}
}| jd|ddd | jd|||ddd | jd|d	 d
d t	|j
D }t	|j
D ]y\}}g }|j}z|| }| jr_| |}|rht||\}}|| d}d}d}| jD ]}||jv r,|| }|| }t|| d }|tkr|}||kr||kr|
sd}|| dt|| d}n`||k r|	sd}d}|| dt|| d}nGd}||| }n=d}||| }n3||kr||kr|| dt|| d}n||k r|| dt|| d}n||| }|| |jd ur,||j dt d|j dt  qvW n ty   d}d}d}|jd urH||j |jd urT||j | jr]| }n|j}|rgd\}}d}t||krtj dt||d d d f  |d |d  t!d }| jr| |}|| | jD ]}||jv r||| }|| q|jd ur|d|jtf  Y nw |r|rt"|||}n|j#d ur|s|j#}nd}d$|}| j%|j&||| '|(||| '|)|d |*| |j+d! d"d t	|j,D }d#d t	|j
D } t	|j,D ]\}}!g }z6|!j-}"| |" j}#||# j&}$||$ }%| j.D ]}||!jv r[||!|  d$||%|  }|| q=W n$ ty   | j.D ]}||!jv r~||!|  }|| qiY nw |rdn|!j#}d$|}| j/|j&|!j-|| '|0|| '|0|d%|1| d%|2| d%|2| d%|3| d&	 q"qH| 4  d S )'Ngraphr-        ?r   ranksepnodesepr   r   )r   styler  r>  r=  edger  c                 S      i | ]\}}|j |qS r   rf   r*   r+   r   r   r   r	   r     r.   z,DotWriter.graphs_compare.<locals>.<dictcomp>boxr  r0   cdsz + r   90z - r  z/ r{     5warning: truncating function name with %u chars (%s)
r8  ...r   &   r   rB   r   z%f)labelorientationr  shaper  r  tooltipc                 S   rG  r   )r   )r*   r+   r   r   r   r	   r   E  r.   c                 S   rG  r   r   rH  r   r   r	   r   F  r.   z / %.2frP  r  r  r  penwidthlabeldistance	arrowsize)5begin_graphr  r  r  r    only_sloweronly_fastercolor_by_differenceattrr1   r2   rU   wrapr?  r@   r5   show_function_eventsr~   r6   r)   rm   r"   r   r   r   r   r   r  r   r4   rF   rG   rH   chrr%   r   r   r   r   r  r  r  r  r   r   r   show_edge_eventsrF  r  r  r  r  	end_graph)&rS   r:   r;   themeoptionsr   r  r  r    rZ  r[  r\  
functions2r+   	function1labelsrU   	function2min_diffmax_diffweight_differencerR  rQ  rQ   event1event2r   rP  rN  MAX_FUNCTION_NAMEr   calls2functions_by_id1call1call_id1	call_namecall_id2call2r   r   r	   graphs_compare  s  








$)
$



#




"




zDotWriter.graphs_comparec                 C   s  |    | }| }| }| jd|ddd | jd|d||ddd | jd	|d
 t|jD ]#\}}g }|jd urC||j |j	d urN||j	 | j
rV| }	n|j}	d}
t|	|
krtjdt|	|	d d d f  |	d |
d  td }	| jr| |	}	||	 | jD ]}||jv r||| }|| q|jd ur|d|jtf  |jd ur|j}nd}d|}| j|j|| ||| ||d| | |j!d t|j"D ]o\}}|j|j# }g }| j$D ]}||jv r||| }|| q|jd ur|j}n|jd ur|j}nd}d|}| j%|j|j#|| |&|| |&|d|'| d|(| d|(| d|)| d	 qq1| *  d S )Nr@  r-  rA  rB  r   rI  r   )r   rR  rE  r  r>  r=  rF  r  rL  rM  r8  rN  r   rO  r   rB   r   rT  )rP  r  r  r  rS  rU  )+rY  r  r  r  r]  r1   r2   r   r5   r   r  r   rU   r4   rF   rG   rH   r`  r^  r?  r_  r~   rm   r   r   r   r   r   r   r  r  r  r  r   r   r   ra  rF  r  r  r  r  rb  )rS   r\  rc  r   r  r  r+   r   rg  rN  rn  rQ   rP  r   r   r  r   r   r	   r@  g  s   


$










zDotWriter.graphc                 C   s   |  d |  d d S )Nz
digraph {
z	tooltip=" "
rH   rV   r   r   r	   rY    s   
zDotWriter.begin_graphc                 C   s   |  d d S )Nz}
rw  rV   r   r   r	   rb    r   zDotWriter.end_graphc                 K   s,   |  d |  | | | |  d d S Nr  ;
)rH   	attr_list)rS   whatrD  r   r   r	   r]       


zDotWriter.attrc                 K   s,   |  d | | | | |  d d S rx  rH   node_idrz  )rS   r   rD  r   r   r	   r     r|  zDotWriter.nodec                 K   s@   |  d | | |  d | | | | |  d d S )Nr  z -> ry  r}  )rS   srcdstrD  r   r   r	   rF    s   




zDotWriter.edgec                 C   s   |sd S |  d d}t|D ]/\}}|d u rq|rd}n|  d t|ts)J | s/J |  | |  d | | q|  d d S )Nz [TFr  r  ])rH   r1   r  rn   isidentifierr   )rS   rD  firstrU   r   r   r   r	   rz    s    



zDotWriter.attr_listc                 C   s@   t |trt|dkrdtj|ddd  }| | d S )Ni   r+   utf-8F)usedforsecurity)r  rn   r4   hashlibsha1encode	hexdigestr   )rS   r   r   r   r	   r~    s   zDotWriter.node_idc                 C   sX   t |ttfrt|}nt |tr#| r|ds|}n| |}nt| | d S )Nr  )	r  r  rC   rn   isalnumr3  escape	TypeErrorrH   )rS   r   r  r   r   r	   r     s   

zDotWriter.idc                    s4   |\}}}dd  dd  fdd|||fD  S )Nc                 S   s(   | dkrdS | dkrdS t d|  d S )NrB   r   rA      g     o@r  )r  )r   r   r   r	   	float2int  s
   z"DotWriter.color.<locals>.float2intr&  r   c                    s   g | ]}d  | qS )z%02xr   )r*   r   r  r   r	   r-     r.   z#DotWriter.color.<locals>.<listcomp>)r   )rS   rgbr  r*  r   r   r  r	   r    s   
"zDotWriter.colorc                 C   s<   | dd}| dd}| dd}| dd}d| d S )	N\z\\r   z\nr  z\trs  z\")r<  rS   r  r   r   r	   r    s
   zDotWriter.escapec                 C   r   r   )r|  rH   r  r   r   r	   rH     r&   zDotWriter.writeN)rY   rZ   r[   r\   r  r^  rP   r?  r)   r8  r_  r   ra  rv  r@  rY  rb  r]  r   rF  rz  r~  r   r  r  rH   r   r   r   r	   r7    s,     !V	r7  c                 C   s4   t | dkrd| d d d | d  S d| S )Nr  r  r   z or r   )r4   r   )r   r   r   r	   naturalJoin   s   
r  r   c                 C   s^  t t }|  t t }|  t t }|  tjdd}|jddddddd	 |jd
ddddddd |jdddddddd |jddd|dddt	| d |jdddd t
d!d |jd"d#d|d$d%d&t	| d |jd'd(d)d*d+d,d- |jd.d)d/d+d0d- |jd1d)d/tjd2 |jd3d4d)d5d+d6d- |jd7d)d8d+d9d- |jd:td;d< |jd=d>d|d?d@dAt	|dBtf dC |jdDddEdFdGdH |jdIdJddKdLdMdH |jdNdOddPdLdQdH |jdRdSdTdUdVdH |jdWddXdYdZdH |jd[d\d?dd]d^d_ |jd`d)dad+dbd- |jdcddddedfdH |jdgd)dhd+did- |jdjd)dkd+dld- |jdmd)dnd+dod- || \}}t|dpkrQ|jdqkrQ|jsQ|dr zt|j }W n tyj   |ds|j  Y nw |jrs|j|_|j
a
|jazt|j }W n ty   |dt|j  Y nw |jr|stj}	||	}
n|jrt|du dvdwdx}t|dp dvdwdx}||}||}nbt|du dy}	|	dz}|tjkrd{}nd|}|	 du t!j"|	|dx}	||	}
n:|j#r|s|d}|j  |jr	||d~ }||dU }n|| }
nt|dpkr|d|j  ||du }
|jr0|$ }|$ }n|
$ }|j%dFu rFttj&' ddwd+d}nt|j%ddwdx}t(|}|j)|_)|j*|_*|j+p_t}dd |D |_,|j-rr|j,.t/ |jr|0|j1d |j2d |j3|j4 |0|j1d |j2d |j3|j4 |j5r|6|7|j5|j8 |6|7|j5|j8 n4|0|j1d |j2d |j3|j4 |j5r|7|j5}|stj9:d|j5 d  t;dp |6||j8 |j<r|j=|j<d t;du |j>r|7|j>}|stj9:d|j> d  t;dp |?||j8 |jr'|@|||| dFS |A|| dFS )zMain program.z
	%prog [options] [file] ...)usagez-oz--outputFILEstringoutputzoutput filename [stdout])metavarr   desthelpz-nz--node-thres
PERCENTAGErC   r9  r  z8eliminate nodes below this threshold [default: %default])r  r   r  defaultr  z-ez--edge-thresr:  r.  z8eliminate edges below this threshold [default: %default]z-fz--formatchoicerm   r  z'profile format: %s [default: %%default])r   choicesr  r  r  z--total)rz   r=  r@  z}preferred method of calculating total time: callratios or callstacks (currently affects only perf format) [default: %default]z-cz
--colormaprc  r  z"color map: %s [default: %%default]z-sz--strip
store_truer  Fzestrip function parameters, template parameters, and const modifiers from demangled C++ function names)actionr  r  r  z--color-nodes-by-selftimer<  zQcolor nodes by self time, rather than by total time (sum of self and descendants)z--colour-nodes-by-selftime)r  r  r  z-wz--wrapr^  zwrap function namesz--show-samplesshow_sampleszshow function samplesz--time-formatz9format to use for showing time values [default: %default])r  r  z--node-labelMEASUREr5   node_labelszTmeasurements to on show the node (can be specified multiple times): %s [default: %s]r  )r  r   r  r  r  r  z--list-functionslist_functionsNa  list functions available for selection in -z or -l, requires selector argument
( use '+' to select all).
Recall that the selector argument is used with Unix/Bash globbing/pattern matching,
and that entries are formatted '<pkg>:<linenum>:<function>'. When argument starts
with '%', a dump of all available information is performed for selected entries,
 after removal of leading '%'.
)r   r  r  r  z-zz--rootrootr   zDprune call graph to show only descendants of specified root functionz-lz--leafleafzBprune call graph to show only ancestors of specified leaf functionz--depthr  r   r   zLprune call graph to show only descendants or ancestors until specified depthz--skew
theme_skewrA   zskew the colorization curve.  Values < 1.0 give more variety to lower percentages.  Values > 1.0 give less variety to lower percentagesz-pz--pathfilter_pathsz*Filter all modules not in a specified path)r  r   r  r  z	--comparecomparezCompare two graphs with almost identical structure. With this option two files should be provided.gprof2dot.py [options] --compare [file1] [file2] ...z--compare-tolerancer    r  zTolerance threshold for node difference (default=0.001%).If the difference is below this value the nodes are considered identical.z--compare-only-slowerrZ  zFDisplay comparison only for function which are slower in second graph.z--compare-only-fasterr[  zFDisplay comparison only for function which are faster in second graph.z--compare-color-by-differencer\  zmColor nodes based on the value of the difference. Nodes with the largest differences represent the hot spots.r   r  zincorrect number of argumentszinvalid colormap '%s'zinvalid format '%s'r   rtr  )encodingrbr  zutf-16ler  z.at least a file must be specified for %s inputz/exactly one file must be specified for %s inputwt)moder  closefdc                 S   s   g | ]}t | qS r   )rg  )r*   r  r   r   r	   r-      r   zmain.<locals>.<listcomp>r   z
root node z9 not found (might already be pruned : try -e0 -n0 flags)
r   z
leaf node z6 not found (maybe already pruned : try -e0 -n0 flags)
)Br   formatsr   r5  themesrg  optparseOptionParser
add_optionr  r@  SUPPRESS_HELPr   r   defaultLabelNames
parse_argsr4   rm   r  errorrc  r   r  r  time_formatrR  rF   stdinr  r  codecsBOM_UTF16_LEseekioTextIOWrapperrS  rQ  r  stdoutfilenor7  r  r^  r  r_  r  r5   r   r@  r9  r:  r  r<  r  r   r   r   rG   rH   r  r  r  r  r   rv  r@  )argvformatNames
themeNames
labelNames	optparserrd  argsrc  Formatr|  r  fp1fp2parser1parser2bomr  r:   r;   r\  r  dotrootIdsleafIdsr   r   r	   main(  s  

"










r  __main__)[r\   
__author__rF   r   os.pathr)  r   r:  r  xml.parsers.expatr  r   localerY  r   r  r  r  version_infor`  r   r   r
   r   r   r   r   r"   r%   r@   rE   rK   rO   rM   r^   r   r   r   rA  r  r8  r  r)   rg  r  r@  r|   r   r   r   r   rB  rK  rO  rT  rb  r3   rq  rr  rs  rt  rp  rz  r  r  r  r  r  r7  rP  r{  r  r  r  r  r  r  r  r  TEMPERATURE_COLORMAPPINK_COLORMAPGRAY_COLORMAPBW_COLORMAPPRINT_COLORMAPr  r1   r7  r  r  r  rY   r   r   r   r	   <module>   s,  
E    O#?/      @  (eukgO _ 			  }  

