o ]Lb;@sdZddlmZmZddlZddlZddlmZddlm Z e dZ Gdd d e Z ejGd d d eZejGd d d eZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZddZGdddeZdS)alinelog 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. )absolute_importprint_functionN)attr)pycompats>IIc@seZdZdZdS) LineLogErrorz>Error raised when something bad happens internally in linelog.N)__name__ __module__ __qualname____doc__r r 3/usr/lib/python3/dist-packages/mercurial/linelog.pyr src@s$eZdZeZeZeZdS)lineinfoN)rr r ribrevlinenum_offsetr r r r r$s rc@s,eZdZeZeZeZddZdS)annotateresultcCs t|jSN)iterlinesselfr r r __iter__4 zannotateresult.__iter__N) rr r rrrr_eofrr r r r r.s  rc@s`eZdZejZejddZejddZddZ ejddZ ejd d Z ejd d Z d S)_llinstructioncCdSrr rop1op2r r r __init__<z_llinstruction.__init__cCrrr rr r r __str__@r"z_llinstruction.__str__cCst|Sr)strrr r r __repr__Dsz_llinstruction.__repr__cCrrr rotherr r r __eq__Gr"z_llinstruction.__eq__cCdS)z5Encode this instruction to the binary linelog format.Nr rr r r encodeKz_llinstruction.encodecCr))agExecute 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 rrpcemitr r r executeOr+z_llinstruction.executeN) rr r abcABCMeta __metaclass__abstractmethodr!r#r%r(r*r/r r r r r8s    rc@8eZdZdZddZddZddZdd Zd d Zd S) _jgez@If the current rev is greater than or equal to op1, jump to op2.cC||_||_dSr_cmprev_targetrr r r r!a z _jge.__init__cCd|j|jfS)Nz JGE %d %dr7rr r r r#ez _jge.__str__cC(t|t|ko|j|jko|j|jkSrtyper8r9r&r r r r(h   z _jge.__eq__cCst|jd>|jSN_llentrypackr8r9rr r r r*osz _jge.encodecCs||jkr|jS|dSNrr7r,r r r r/r z _jge.executeN rr r r r!r#r(r*r/r r r r r5^ r5c@r4) _jumpz=Unconditional jumps are expressed as a JGE with op1 set to 0.cCs|dkr td|||_dS)Nrs%malformed JUMP, op1 must be 0, got %d)rr9rr r r r!{s  z_jump.__init__cCs d|jS)NzJUMP %dr9rr r r r#rz _jump.__str__cCst|t|ko |j|jkSr)r?r9r&r r r r(sz _jump.__eq__cCstd|jSNr)rDrEr9rr r r r*z _jump.encodecC|jSrrKr,r r r r/sz _jump.executeNrHr r r r rJxs rJc@r4) rz1EOF is expressed as a JGE that always jumps to 0.cCs,|dkr td||dkrtd|dS)Nrs$malformed EOF, op1 must be 0, got %ds$malformed EOF, op2 must be 0, got %d)rrr r r r!s   z _eof.__init__cCr))NEOFr rr r r r#z _eof.__str__cCst|t|kSr)r?r&r r r r(r<z _eof.__eq__cCs tddSrL)rDrErr r r r*s z _eof.encodecCrrr r,r r r r/rPz _eof.executeNrHr r r r rs rc@r4) _jlz1If the current rev is less than op1, jump to op2.cCr6rr7rr r r r!r:z _jl.__init__cCr;)NzJL %d %dr7rr r r r#r<z _jl.__str__cCr=rr>r&r r r r(r@z _jl.__eq__cCstd|jd>B|jS)NrrBrCrr r r r*z _jl.encodecCs||jkr|jS|dSrFr7r,r r r r/rGz _jl.executeNrHr r r r rQrIrQc@r4) _linez Emit a line.cCr6r_rev _origlinenorr r r r!s z_line.__init__cCr;)Nz LINE %d %drTrr r r r#r<z _line.__str__cCr=r)r?rUrVr&r r r r(r@z _line.__eq__cCstd|jd>B|jSrA)rDrErUrVrr r r r*rRz _line.encodecCs|t|j|j||dSrF)rrUrVr,r r r r/sz _line.executeNrHr r r r rSs rSc Csz t||\}}Wntjy}ztd|d}~ww|d@}|d?}|dkrA|dkr<|dkr7t||St||St||S|dkrJt||S|dkrSt ||St d|)z?Decode a single linelog instruction from an offset in a buffer.s!reading an instruction failed: %rNrBrrsUnimplemented opcode %r) rD unpack_fromstructerrorrrrJr5rQrSNotImplementedError)dataoffsetrr eopcoder r r _decodeones&       r`c@seZdZdZd ddZddZdd Zd d Zed d Z ddZ ddZ ddZ d!ddZ ddZeddZeddZddZd"ddZdS)#linelogz1Efficient cache for per-line history information.NrcCs2|durtddtddg}||_d|_||_dSrL)r_program _lastannotate_maxrev)rprogrammaxrevr r r r!s  zlinelog.__init__cCr=r)r?rbrdr&r r r r(r@zlinelog.__eq__cCsdtt||jt|jfS)Nz")hexidrdlenrbrr r r r%s  zlinelog.__repr__csDdttt|jtdfddt|jdddDS)Nz %%%dd %%s c3s |] \}}||fVqdSrr ).0idxifmtr r s z#linelog.debugstr..r)rir$rbrsysstrjoin enumeraterr rnr debugstrszlinelog.debugstrcCst|tjdkrtdt|tjft|tj}t|d}t|tr(d}nt|ttfr3|j }n tdt |j t|tttfsFJ|j }||krUtd||ft ddg}td|D] }|t||tjqa|||dS)Nrs9invalid linelog buffer size %d (must be a multiple of %d)z,Expected one of _jump, _jge, or _jl. Got %s.sFcorrupt linelog data: claimed %d entries but given data for %d entriesr)rf)rirDsizerr` isinstancerJr5rQr8r?rr9rrxrangeappend)clsbufexpectedfakejgerf numentries instructionsr]r r r fromdatas:     zlinelog.fromdatacCs8t|jt|j}|ddd|jddDS)Ncss|]}|VqdSr)r*)rkrmr r r rp/sz!linelog.encode..r)r5rdrirbr*rr)rhdrr r r r*-s"zlinelog.encodecCsg|_d|_d|_dSrL)rbrdrcrr r r clear1s z linelog.clearcCs|j|||dt||dS)Nr)_internal_blines) replacelinesri)rra1a2blinesr r r replacelines_vec6szlinelog.replacelines_veccCsf|jr|j}n||}|t|jkrtd|t|j|f|t|jkr3tdd}tdd|j} n |j|} |j| j}|jj } | } |jj } g} | j }||kr| ||d}| t ||t ||D]-}|dur~|t||| | t||qg||\}}|t||| | t||qg||kr|t|jkrtd|t|j|f|t|jkr|j}n|j|j}|dkr||jkr|j|djd}| t||| }| |t|ttfs| td| jdtd| |j| j<t|jj|kr ||jj|_n t|tsJ||j_| |jj||<t|jj||j_||jkr1||_dSdS)z+Replace lines [a1, a2) with lines [b1, b2).s-%d contains %d lines, tried to access line %drrN)rcannotaterirrrrrbr__len__rxrQrrwrSrdr5rvrJmaxr)rrrrb1b2rara1insta1info programlen oldproglen appendinst blineinfosbappendtgtrnewrev newlinenumendaddra1instpcr r r r;sp        zlinelog.replacelinescCsd}g}d}|dur/|t|jkr/|j|}|}||||j}|d7}|dur/|t|jks|dur;td|t|||}||_|S)Nrrz4Probably hit an infinite loop in linelog. Program:\n)rirbr/rxrrtrrc)rrr-rexecutedinstlastpcrr r r rs$  zlinelog.annotatecCrNr)rdrr r r rfszlinelog.maxrevcCsdd|jjDS)z?Return the last annotation result. C linelog code exposed this.cSsg|]}|j|jfqSr )rr)rklr r r sz*linelog.annotateresult..)rcrrr r r rszlinelog.annotateresultcCs|jj|jSr)rcrr)rliner r r getoffsetrMzlinelog.getoffsetcCs|pd}g}tt|jD]D}|j|}|d}t|tr"|j}n&t|tr+|St|tt fr3nt|t rB| |j |j fntd|||krP|S|}qtd)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. rsIllegal instruction %rsFailed to perform getalllines)rrwrirbrvrJr9rrQr5rSrxrUrVr)rstartendr-rsteprnextpcr r r getallliness$     zlinelog.getalllinesrLr)rr)rr r r r!r(r%rt classmethodrr*rrrrpropertyrfrrrr r r r ras&    X  ra)r __future__rrr0rY thirdpartyrrStructrD Exceptionrsobjectrrrr5rJrrQrSr`rar r r r s(     &