
    	^cQ;                        d Z ddlZddlZddlmZ ddlmZ  ej        d          Z G d de	          Z
ej         G d	 d
                      Zej         G d d                      Z G d d          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Zd Z G d d          ZdS )a  linelog is an efficient cache for annotate data inspired by SCCS Weaves.

SCCS Weaves are an implementation of
https://en.wikipedia.org/wiki/Interleaved_deltas. See
mercurial/helptext/internals/linelog.txt for an exploration of SCCS weaves
and how linelog works in detail.

Here's a hacker's summary: a linelog is a program which is executed in
the context of a revision. Executing the program emits information
about lines, including the revision that introduced them and the line
number in the file at the introducing revision. When an insertion or
deletion is performed on the file, a jump instruction is used to patch
in a new body of annotate information.
    N   )attr)pycompats   >IIc                       e Zd ZdZdS )LineLogErrorz>Error raised when something bad happens internally in linelog.N)__name__
__module____qualname____doc__     3/usr/lib/python3/dist-packages/mercurial/linelog.pyr   r      s        HHHHr   r   c                   h    e Zd Z ej                    Z ej                    Z ej                    ZdS )lineinfoN)r   r	   r
   r   ibrevlinenum_offsetr   r   r   r   r   #   s7         $'))CdgiiGdgiiGGGr   r   c                   n    e Zd Z ej                    Z ej                    Z ej                    Zd ZdS )annotateresultc                 *    t          | j                  S N)iterlinesselfs    r   __iter__zannotateresult.__iter__3   s    DJr   N)	r   r	   r
   r   r   r   r   _eofr   r   r   r   r   r   -   sJ        
$'))CDGIIE4799D         r   r   c                       e Zd Zej        Zej        d             Zej        d             Zd Z	ej        d             Z
ej        d             Zej        d             ZdS )_llinstructionc                     d S r   r   r   op1op2s      r   __init__z_llinstruction.__init__;       r   c                     d S r   r   r   s    r   __str__z_llinstruction.__str__?   r&   r   c                      t          |           S r   )strr   s    r   __repr__z_llinstruction.__repr__C   s    4yyr   c                     d S r   r   r   others     r   __eq__z_llinstruction.__eq__F   r&   r   c                     dS )z5Encode this instruction to the binary linelog format.Nr   r   s    r   encodez_llinstruction.encodeJ         r   c                     dS )ag  Execute this instruction.

        Args:
          rev: The revision we're annotating.
          pc: The current offset in the linelog program.
          emit: A function that accepts a single lineinfo object.

        Returns:
          The new value of pc. Returns None if exeuction should stop
          (that is, we've found the end of the file.)
        Nr   r   r   pcemits       r   executez_llinstruction.executeN   r2   r   N)r   r	   r
   abcABCMeta__metaclass__abstractmethodr%   r(   r+   r/   r1   r7   r   r   r   r    r    7   s        KM   	     	   	D D D 	    r   r    c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )_jgez@If the current rev is greater than or equal to op1, jump to op2.c                 "    || _         || _        d S r   _cmprev_targetr"   s      r   r%   z_jge.__init__`       r   c                 $    d| j         | j        fz  S )Nz	JGE %d %dr?   r   s    r   r(   z_jge.__str__d   s    dlDL999r   c                     t          |           t          |          k    o| j        |j        k    o| j        |j        k    S r   typer@   rA   r-   s     r   r/   z_jge.__eq__g   =    JJ$u++% .-.-	
r   c                 R    t                               | j        dz  | j                  S N   _llentrypackr@   rA   r   s    r   r1   z_jge.encoden   s    }}T\Q.===r   c                 0    || j         k    r| j        S |dz   S Nr   r?   r4   s       r   r7   z_jge.executeq   s     $,<Avr   N	r   r	   r
   r   r%   r(   r/   r1   r7   r   r   r   r=   r=   ]   se        JJ  : : :
 
 
> > >    r   r=   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )_jumpz=Unconditional jumps are expressed as a JGE with op1 set to 0.c                 D    |dk    rt          d|z            || _        d S )Nr   s%   malformed JUMP, op1 must be 0, got %d)r   rA   r"   s      r   r%   z_jump.__init__z   s*    !88G#MNNNr   c                     d| j         z  S )NzJUMP %drA   r   s    r   r(   z_jump.__str__   s    DL))r   c                 b    t          |           t          |          k    o| j        |j        k    S r   )rF   rA   r-   s     r   r/   z_jump.__eq__   s'    DzzT%[[(JT\U]-JJr   c                 B    t                               d| j                  S Nr   )rL   rM   rA   r   s    r   r1   z_jump.encode   s    }}Q---r   c                     | j         S r   rU   r4   s       r   r7   z_jump.execute   s
    |r   NrP   r   r   r   rR   rR   w   sh        GG  
* * *K K K. . .    r   rR   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )r   z1EOF is expressed as a JGE that always jumps to 0.c                 f    |dk    rt          d|z            |dk    rt          d|z            d S )Nr   s$   malformed EOF, op1 must be 0, got %ds$   malformed EOF, op2 must be 0, got %d)r   r"   s      r   r%   z_eof.__init__   sC    !88FLMMM!88FLMMM 8r   c                     dS )NEOFr   r   s    r   r(   z_eof.__str__   s    vr   c                 B    t          |           t          |          k    S r   )rF   r-   s     r   r/   z_eof.__eq__   s    DzzT%[[((r   c                 8    t                               dd          S rX   )rL   rM   r   s    r   r1   z_eof.encode   s    }}Q"""r   c                     d S r   r   r4   s       r   r7   z_eof.execute   s    tr   NrP   r   r   r   r   r      sh        ;;N N N  ) ) )# # #    r   r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )_jlz1If the current rev is less than op1, jump to op2.c                 "    || _         || _        d S r   r?   r"   s      r   r%   z_jl.__init__   rB   r   c                 $    d| j         | j        fz  S )NzJL %d %dr?   r   s    r   r(   z_jl.__str__   s    T\4<888r   c                     t          |           t          |          k    o| j        |j        k    o| j        |j        k    S r   rE   r-   s     r   r/   z
_jl.__eq__   rG   r   c                 X    t                               d| j        dz  z  | j                  S )Nr   rJ   rK   r   s    r   r1   z
_jl.encode   s$    }}Q$,!"34dlCCCr   c                 0    || j         k     r| j        S |dz   S rO   r?   r4   s       r   r7   z_jl.execute   s     <Avr   NrP   r   r   r   rb   rb      sh        ;;  9 9 9
 
 
D D D    r   rb   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )_linezEmit a line.c                 "    || _         || _        d S r   _rev_origlinenor"   s      r   r%   z_line.__init__   s    	r   c                 $    d| j         | j        fz  S )Nz
LINE %d %drk   r   s    r   r(   z_line.__str__   s    ty$*:;;;r   c                     t          |           t          |          k    o| j        |j        k    o| j        |j        k    S r   )rF   rl   rm   r-   s     r   r/   z_line.__eq__   s?    JJ$u++% 6	UZ'6 E$55	
r   c                 X    t                               d| j        dz  z  | j                  S rI   )rL   rM   rl   rm   r   s    r   r1   z_line.encode   s$    }}Q$)q.143CDDDr   c                 T     |t          | j        | j        |                     |dz   S rO   )r   rl   rm   r4   s       r   r7   z_line.execute   s,    Xdi!1266777Avr   NrP   r   r   r   ri   ri      sh          < < <
 
 
E E E    r   ri   c                    	 t                               | |          \  }}n)# t          j        $ r}t	          d|z            d}~ww xY w|dz  }|dz	  }|dk    r<|dk    r&|dk    rt          ||          S t          ||          S t          ||          S |dk    rt          ||          S |dk    rt          ||          S t          d|z            )z?Decode a single linelog instruction from an offset in a buffer.s!   reading an instruction failed: %rN   rJ   r   r   s   Unimplemented opcode %r)rL   unpack_fromstructerrorr   r   rR   r=   rb   ri   NotImplementedError)dataoffsetr#   r$   eopcodes         r   
_decodeoner|      s    E''f55SS< E E E?!CDDDE4ZF
(C{{!88axxC~~%c??"C~~	13}}	1S#
86A
B
BBs   ! AAAc                       e Zd ZdZddZd Zd Zd Zed             Z	d	 Z
d
 Zd ZddZd Zed             Zed             Zd ZddZdS )linelogz1Efficient cache for per-line history information.Nr   c                 t    | t          dd          t          dd          g}|| _        d | _        || _        d S rX   )r   _program_lastannotate_maxrev)r   programmaxrevs      r   r%   zlinelog.__init__   s=    ? Aqzz41::.G!r   c                     t          |           t          |          k    o| j        |j        k    o| j        |j        k    S r   )rF   r   r   r-   s     r   r/   zlinelog.__eq__   s=    JJ$u++% ./.-	
r   c                 t    dt          t          |                     | j        t          | j                  fz  S )Nz"<linelog at %s: maxrev=%d size=%d>)hexidr   lenr   r   s    r   r+   zlinelog.__repr__   s5    34MML7
 
 	
r   c                    dt          t          t          | j                                      z  t          j        d                              fdt          | j        dd          d          D                       S )Nz	%%%dd %%s   
c              3   ,   K   | ]\  }}||fz  V  d S r   r   ).0idxifmts      r   	<genexpr>z#linelog.debugstr.<locals>.<genexpr>	  s@       +
 +
%sAC3(N+
 +
 +
 +
 +
 +
r   r   )r   r*   r   r   sysstrjoin	enumerate)r   r   s    @r   debugstrzlinelog.debugstr  s    CC$6$6 7 7888u%%** +
 +
 +
 +
)24=3Da)H)H+
 +
 +
 
 
 	
r   c                    t          |          t          j        z  dk    r+t          dt          |          t          j        fz            t          |          t          j        z  }t	          |d          }t          |t                    rd}nHt          |t          t          f          r|j	        }n$t          dt          |          j        z            t          |t          t          t          f          sJ |j        }||k    rt          d||fz            t          dd          g}t          d|          D ]2}|                    t	          ||t          j        z                       3 | ||          S )Nr   s9   invalid linelog buffer size %d (must be a multiple of %d)z,Expected one of _jump, _jge, or _jl. Got %s.sF   corrupt linelog data: claimed %d entries but given data for %d entriesr   )r   )r   rL   sizer   r|   
isinstancerR   r=   rb   r@   rF   r   rA   r   rangeappend)clsbufexpectedfakejger   
numentriesinstructionsry   s           r   fromdatazlinelog.fromdata  s   s88hm#q((Ls88X]+,   s88hm+S!$$gu%% 	FF$-- 	_FF>w--()   'E4#566666_
z!!=Z()  
 Q

|Az** 	I 	IF
30F G GHHHHs<////r   c                     t          | j        t          | j                                                            }|d                    d | j        dd          D                       z   S )Nr   c              3   >   K   | ]}|                                 V  d S r   )r1   )r   r   s     r   r   z!linelog.encode.<locals>.<genexpr>.  s*      DDQahhjjDDDDDDr   r   )r=   r   r   r   r1   r   )r   hdrs     r   r1   zlinelog.encode,  sZ    4<T]!3!344;;==SXXDD$-2CDDDDDDDr   c                 0    g | _         d| _        d | _        d S rX   )r   r   r   r   s    r   clearzlinelog.clear0  s    !r   c           	      R    |                      |||dt          |          |          S )Nr   )_internal_blines)replacelinesr   )r   r   a1a2bliness        r   replacelines_veczlinelog.replacelines_vec5  s2      RCKK& ! 
 
 	
r   c           	         | j         r| j         }n|                     |          }|t          |j                  k    r't	          d|t          |j                  |fz            |t          |j                  k    r't          dd          }t          dd|j                  }	n|j        |         }	| j        |	j                 }| j        j	        }
 |
            }| j        j
        }g }|j
        }||k     r|||z
  dz   z   } |t          ||                     t          ||          D ]}|< |t          || |
                                  |t          ||                     @||         \  }} |t          || |
                                  |t          ||                     ||k     r|t          |j                  k    r't	          d|t          |j                  |fz            |t          |j                  k    r|j        }n|j        |         j        }|dk    r#|| j        k     r|j        |dz
           j        dz   } |t          ||                      |
            } ||           t!          |t"          t
          f          s! |t#          d|	j        dz                        t#          d|          | j        |	j        <   t          | j         j                  |k    r|| j         j        |         _        n#t!          |t
                    sJ || j         _        || j         j        ||<   t%          | j         j        |          | j         _        || j        k    r	|| _        dS dS )z+Replace lines [a1, a2) with lines [b1, b2).s-   %d contains %d lines, tried to access line %dr   r   N)r   annotater   r   r   r   r   r   r   __len__r   rb   r   ri   r   r=   r   rR   maxr   )r   r   r   r   b1b2r   ara1insta1info
programlen
oldproglen
appendinst
blineinfosbappendtgtr   newrev
newlinenumendaddra1instpcs                        r   r   zlinelog.replacelines:  s    	$ #BBs##BBH@BHr*+   3rx==   !QZZFaBG,,FFXb\F]6>2F]*
Z\\
])
 
#77 R!,CJs3}}%%% R== : :#+GHS'::<<@@AAAJuS'223333)9')B&FJGHVZFFGGGJuVZ88999977CMM!!"DCMM2./   s28}}$$'(2,.Avv#,,
 (26*2Q6JtC))***:<<
6 &5$-00 	5JuQ 233444(-a(<(<fn%
 t!'((2--3;D$R(00fd+++++&.D#*4 B'!$T%7%;S!A!ADLLL r   c                 V   d}g }d}|b|t          | j                  k     rJ| j        |         }|}|                    |||j                  }|dz  }||t          | j                  k     J|$t	          d|                                 z             t          |||          }|| _        |S )Nr   r   z4Probably hit an infinite loop in linelog. Program:\n)r   r   r7   r   r   r   r   r   )r   r   r5   r   executedinstlastpcr   s           r   r   zlinelog.annotate  s     nC,>,>!>!>=$DFc2u|44BMH	 nC,>,>!>!>
 >G--//"   C//	r   c                     | j         S r   )r   r   s    r   r   zlinelog.maxrev  s
    |r   c                 .    d | j         j        D             S )z?Return the last annotation result. C linelog code exposed this.c                 *    g | ]}|j         |j        fS r   )r   r   )r   ls     r   
<listcomp>z*linelog.annotateresult.<locals>.<listcomp>  s!    EEEq	"EEEr   )r   r   r   s    r   r   zlinelog.annotateresult  s     FED,>,DEEEEr   c                 0    | j         j        |         j        S r   )r   r   r   )r   lines     r   	getoffsetzlinelog.getoffset  s    !'-55r   c                    |pd}g }t          t          | j                            D ]}| j        |         }|dz   }t          |t                    r|j        }nt          |t                    r|c S t          |t          t          f          rnIt          |t                    r"|
                    |j        |j        f           nt          d|z            ||k    r|c S |}t          d          )zGet all lines that ever occurred in [start, end).

        Passing start == end == 0 means "all lines ever".

        This works in terms of *internal* program offsets, not line numbers.
        r   s   Illegal instruction %rs   Failed to perform getalllines)r   r   r   r   rR   rA   r   rb   r=   ri   r   rl   rm   r   )r   startendr5   r   stepr   nextpcs           r   getalllineszlinelog.getalllines  s
    Za #dm,,-- 	 	D=$D!VF$&& 	ED$'' ED3+.. ED%(( Edi)9:;;;;"#<t#CDDD}}BB;<<<r   rX   r   )r   r   )r   r	   r
   r   r%   r/   r+   r   classmethodr   r1   r   r   r   r   propertyr   r   r   r   r   r   r   r~   r~      s*       ;;   
 
 

 
 

 
 
 0 0 [0<E E E" " "

 
 

V V V Vp  *   X F F XF6 6 6= = = = = =r   r~   )r   r8   ru   
thirdpartyr    r   StructrL   	Exceptionr   sr   r   r    r=   rR   r   rb   ri   r|   r~   r   r   r   <module>r      s?    


             6=  I I I I I9 I I I                        # # # # # # # #L    >   4    N   *    >   ,    .   4    N   6C C C*f= f= f= f= f= f= f= f= f= f=r   