
    	^cq              
          d dl Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	mZm
Z
mZ ddlmZ i dd	d
dddddddddddddddddddddddd dd!d"d#d$d%d$d$d&d'd(d(d)d*d(d+Zh d,Zi Zd-d.hZ e ej        d/                    Z e ej         ej        e j                   ej        e j                  z   d0z                        e eej         ed1d2                              z  Ze e ej        d3                    z  Zd]d4Z e            Zd5 Z d6 Z!efd7Z"d8 Z#d9 Z$d: Z%eefd;Z&d< Z'd= Z(i Z)d> Z*d? Z+d@ Z,dA Z-dB Z.dC Z/dD Z0dE Z1dF Z2edGhz  Z3d^dHZ4 G dI dJe	j5                  Z6d_dKZ7dL Z8d_dMZ9dN Z:dO Z;dP Z<dQ Z=dR Z>e<e>dSZ?dT Z@dU ZAdV ZBdW ZCdX ZDdY ZEejF        G                    dZ          ZHd[ ZId\ ZJdS )`    N   )_)getattrhex)errorparserpycompatsmartsetutil)
stringutil   ()   N)   groupr      ))   funcr   r   N   [)r   NN)	   subscriptr      ]N   #)r   NN)   relationr   N   ##)   NN)   _concatr   N   ~)   NN)   ancestorr   N   ^)r   NN)   parentr   
   parentpost   -)   N)   negate   )   minusr"   N   ::)      dagrangeall)   dagrangeprer'   )   dagranger'      dagrangepost   ..   :)      rangeall)   rangeprer.   )   ranger.   	   rangepost   not)
   N)r3   r4   NN   !   and)r"   NN)r6   r"   N   &   %)r"   NN)   onlyr"      onlypost   or)   NN)r;   r<   N   |)   NN)   keyvaluer>   N)   NN)   listr@   N)r   NNNN)r      symbolNNN)r      stringNNN)   +   =   ,r   r   rB   rC      end>   r;   r6   r3      "   's   ()[]#:=,-|&+!~^%s   ._@      s   -/c              #     K   t          | t                    st          j        d| z            t	          j        |           } |t          }|t          }| rr|                     dd          }t          fd|D                       rr|d         rd|d         dfV  t          |          dk    r4t          |d                   }dd|fV  |d         rd|d         |dz   fV  ddt          |           fV  dS dt          |           }}||k     rd| |         }|                                rn:|dk    r| ||d	z            d
k    rd
d|fV  |dz  }n|dk    r| ||d	z            dk    rdd|fV  |dz  }n|dk    r| ||d	z            dk    rdd|fV  |dz  }n|t          v r	|d|fV  n|t          v s|dk    r| ||d	z            dv r|dk    r|dz  }| |         }d }	nt          j        }	|dz  }|}||k     r>| |         }
|
dk    r|d	z  }|
|k    rd |	| ||                   |fV  n-|dz  }||k     >t          j        t#          d          |          n	||v r|}|dz  }||k     r3| |         }
|
|vrn&|
dk    r| |dz
           dk    r|dz  }n|dz  }||k     3| ||         }|t$          v r|d|fV  nd|v rtr |          rd||fV  nf|                    d          }|dd         D ])}|rd||fV  |t          |          z  }dd|fV  |dz  }*|d         rd|d         |fV  nd||fV  |dz  }n%t          j        t#          d          | z  |          |dz  }||k     ddd|fV  dS )a  
    Parse a revset statement into a stream of tokens

    ``syminitletters`` is the set of valid characters for the initial
    letter of symbols.

    By default, character ``c`` is recognized as valid for initial
    letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``.

    ``symletters`` is the set of valid characters for non-initial
    letters of symbols.

    By default, character ``c`` is recognized as valid for non-initial
    letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.

    Check that @ is a valid unquoted token character (issue3686):
    >>> list(tokenize(b"@::"))
    [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]

    s&   revset statement must be bytes, got %rNr-   r   c              3   2   K   | ]}| |          V  d S N ).0symlookups     6/usr/lib/python3/dist-packages/mercurial/revsetlang.py	<genexpr>ztokenize.<locals>.<genexpr>w   s0      33ss3vvc{{333333    r   rB   rG   r@   r&      .r,   r   r      r)s   r's   r"c                     | S rN   rO   xs    rS   <lambda>ztokenize.<locals>.<lambda>   s    1 rU      \rC   s   unterminated stringr!   s   syntax error in revset '%s')
isinstancebytesr   ProgrammingErrorr
   bytestr_syminitletters_symletterssplitalllenisspace_simpleopletters_quotelettersr	   unescapestr
ParseErrorr   keywords)programrR   syminitletters
symletterspartssposlcdecodedrQ   ps    `           rS   tokenizerx   T   s,     * gu%% 
$5?
 
 	
 w''G( 
 6  dA&&3333e33333 		Qx / %(A....5zzA~~aMMT1o%%%8 7$eAhA66664W....FGC
''CL99;; R	II'#a-0E99$$$$$1HCCII'#a-0E99$$$$$1HCCII'#a-0E99$$$$$1HCC"""dC.    DyycAg&.88DyyqCL$+1HCA''CL::1HC66$ffWQsU^&<&<a@@@@q '' &q)?'@'@!DDD 
 .  A1HC''CLJ&&II'#'"2d":":1HCq '' !C%.ChD!n$$$$ 8ffSkk 8$c1-----  IIdOOE"3B3Z   4#,a"3333SVV#T1o---QRy 8(%)Q7777 #q))))1HCC"011G;S   	qk ''l 4
rU   c                 p    | r| d         dk    r| d         S t          j        t          d                    )Nr   rB   r   s   not a symbol)r   rk   r   rY   s    rS   	getsymbolrz      s:     QqTYt

1_--
.
..rU   c                 n    | r | d         dk    s| d         dk    r| d         S t          j        |          )Nr   rC   rB   r   r   rk   )rZ   errs     rS   	getstringr~      s@     adi1Q49#4#4t

3

rU   c                     | s|t           ur|S 	 t          t          | |                    S # t          $ r t	          j        |          w xY wrN   )_notsetintr~   
ValueErrorr   rk   )rZ   r}   defaults      rS   
getintegerr      sb     ''$9Q$$%%% $ $ $s###$s	   , Ac                 t    t          j        t          |                     }||S t          j        |          rN   )r   	parseboolrz   r   rk   )rZ   r}   values      rS   
getbooleanr      s4     1..E

3

rU   c                 V    | sg S | d         dk    rt          | dd                    S | gS )Nr   rA   r   )listrY   s    rS   getlistr      s7     	twAabbE{{3JrU   c                     | st          j        |          | d         }|dk    r| d         | d         fS |dk    r
d | d         fS |dk    r
| d         d fS |dk    rdS t          j        |          )	Nr   r1   r   r@   r0   r2   r/   NNr|   )rZ   r}   ops      rS   getranger     s     $s###	
1B	X~~tQqTz	{		QqTz	|		tTz	{		z

3

rU   c                     | r,| d         dk    s| d         dk    rt          | |          }||fS t          | |          \  }}t          |||          t          |||          fS )zGet [first, last] integer range (both inclusive) from a parsed tree

    If any of the sides omitted, and if no default provided, ParseError will
    be raised.
    r   rC   rB   )r   r   )rZ   err1err2deffirstdeflastnabs           rS   getintranger     sv     	 adi1Q49#4#4q$!tAtDAqax((*Qg*F*FFFrU   c                     t          |           }t          |          |k     s|dk    r't          |          |k    rt          j        |          |S )Nr   )r   rf   r   rk   )rZ   minmaxr}   rs   s        rS   getargsr   !  sH    

A
1vv||qSVVc\\s###HrU   c                 r    t          j        t          |           |t          j        |          dd          S )Nr?   rB   )keyvaluenodekeynode)r	   buildargsdictr   splitargspec)rZ   funcnamekeyss      rS   getargsdictr   (  s<    

D!!    rU   c                 p    t                               |           }|t          |           xt           | <   }|S rN   )
_treecachegetparse)spectrees     rS   _cachedtreer   6  s2    >>$D|"'++-
44KrU   c                 F    t          |           }t          j        |dg|R  S )zCreate raw parsed tree from a template revset statement

    >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2'))
    ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2'))
    rB      _)r   r	   	buildtree)tmplspecreplstemplates      rS   _buildr   >  s-     8$$HH&7@%@@@@rU   c                 R    t          |           }t          j        ||dddh          S )a  Test if a tree matches the given pattern statement; return the matches

    >>> _match(b'f(_)', parse(b'f()'))
    >>> _match(b'f(_)', parse(b'f(1)'))
    [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')]
    >>> _match(b'f(_)', parse(b'f(1, 2)'))
    r   r?   rA   )r   r	   	matchtree)patspecr   patterns      rS   _matchr   H  s5     '""G(;*@  rU   c                 (    t          dd| |f          S )Ns!   ancestors(_) and not ancestors(_)r6   )r   )revsbasess     rS   
_matchonlyr   V  s    6u8MNNNrU   c                    t          | t                    s| S | d         }|dk    rd| d         f}| d         d         dk    rt          d|| d         d         f          S | d         d         dk    rt          d	|f          S | d         d         d
k    rt          d|| d         d         f          S | d         d         dk    rt          d|f          S nk|dk    r|t          d| dd         z             fS |dk    rC| d         d         dk    r1t          d| d         d         | d         d         | d         f          S |ft          d | dd         D                       z   S )zrRewrite raw parsed tree to resolve ambiguous syntax which cannot be
    handled well by our simple top-down parserr   r   r    r   r@   r)   r*   r(   r+   r0   r1   r/   r2   r;   rA   Nr   r      relsubscriptc              3   4   K   | ]}t          |          V  d S rN   )_fixopsrP   ys     rS   rT   z_fixops.<locals>.<genexpr>u  s(      33333333rU   )r^   tupler   )rZ   r   posts      rS   r   r   Z  s    a 	
1B	Y qt$Q47n$$KqtAw7888qT!W&&OT2333qT!W##HdAaDG4555qT!W##L$/000 $	u GJ122.//00	|		!Q; 6 61a!A$q'1Q4@AAA5533QqrrU3333333rU   c                 
   | | S | d         }|dk    r"t          t          dg| dd          R            S |dk    r"t          t          dg| dd          R            S |dk    r#t          t          d| d                             S |d	k    r!t          j        t	          d
                    |dk    r#t          t          d| d                             S |dk    r#t          t          d| d                             S |dk    r7t          | d         t	          d                    }t          dd|z   f          S |dv r| S |dk    r|d fS |dv r|t          | d                   fS |dk    rt          | d                   S |dv r/t          | d                   }t          | d                   }|||fS |dk    rEt          | d                   }t          | d                   }t          | d                   }||||fS |dk    r%|ft          d | dd          D                       z   S |dk    r|| d         t          | d                   fS |dk    r|| d         t          | d                   fS t          d|z            ) Nr   r%   s   _ and not _r   r9   
   only(_, _)r:   s   only(_)r(   s   can't use '::' in this contextr)   s   ancestors(_)r+   s   descendants(_)r#   s   can't negate thatrC   r!   rC   rB      smartsetr/   >   r;   r3   r0   r2   r    r   >   r6   r1   r   r   r*   r   r   r@   r   r>   rA   c              3   4   K   | ]}t          |          V  d S rN   _analyzer   s     rS   rT   z_analyze.<locals>.<genexpr>  s(      88QXa[[888888rU   r?   r      invalid operator %r)r   r   r   rk   r   r~   r   r   )rZ   r   rq   tatbtcs         rS   r   r   x  s   y	
1B	X~~~6!""666777	w}5qu555666	{		z1Q400111	~		q!BCCDDD	~		!55666			0!A$77888	yadA23344D1H-...	2	2	2	{		Dz	H	H	HHQqTNN##	x!~~	  
 
 ad^^ad^^B|			ad^^ad^^ad^^BB	wuu88!ABB%8888888	{		AaD(1Q4..))	wAaD(1Q4..))
+b0
1
11rU   c                      t          |           S )zTransform raw parsed tree to evaluatable tree which can be fed to
    optimize() or getset()

    All pseudo operations should be mapped to real operations or functions
    defined in methods or symbols table respectively.
    r   rY   s    rS   analyzer     s     A;;rU   c                    | d| fS | d         }|dv rd| fS |dk    rt          | d                   \  }}t          | d                   \  }}t          ||          }t          dd||f          }|r6t          |d                   dv r|t	          d	|d         |d                   fS t          ||          pt          ||          }|r|t	          d
g|dd          R  fS t          d|          }|r|d||d         ffS ||k    rd}||||ffS |dk    rg g g cfd}t          | d                   D ]z}	t          |	          \  }}
|
0|
d         dk    s|
d         dk    r                    ||
f           F |                                 |                               |
           { |             t                    dk    rd         d         fS t                    |dt                    z   ffS |dk    rit          d| d                   r,t          t	          d                    }|d         |d         fS t          | d                   }|d         ||d         ffS |dk    rd| fS |dv r't          | d                   }|d         ||d         ffS |dv r:t          | d                   \  }}t          | d                   \  }}||z   |||ffS |dv r%t          | d                   \  }}
|||
| d         ffS |dk    r,t          | d                   \  }}
|||
| d         | d         ffS |dk    r3t          d | dd          D              \  t                    |fz   fS |dk    r%t          | d                   \  }}
||| d         |
ffS |dk    rt          | d                   }t          | d                   \  }}t          t                              |          d d          }t          d!|          }|d"k    r|r||z   t	          d#|d                   fS ||z   || d         |ffS t!          d$|z            )%Nr   r   g      ?r6   r   r@   s   _() & ancestors(_)>      draft   secret
   _notpublics   _phaseandancestors(_, _)r   s   not _s
   differences	   andsmallyr;   c                  2   sd S t                    dk    rd         \  } }nCd                    d D                       }t          dd|f          }t          |          \  } }                    |                                |           d d = d S )Nr   r       c              3   ,   K   | ]\  }}|d          V  dS )r   NrO   )rP   wts      rS   rT   z-_optimize.<locals>.flushss.<locals>.<genexpr>  s*      331qt333333rU   s   _list(_)rC   )rf   joinr   	_optimizeappend)r   r   rq   r   sstswss       rS   flushssz_optimize.<locals>.flushss  s     2ww!||!u11JJ3333333;A77 ||1IIaLLLIIaLLL111rU   rC   rB   r   r3   s   public()s   _notpublic()r/   )r0   r2   r    )r*   r1   )r   r   r   r   r   r>   rA   c              3   4   K   | ]}t          |          V  d S rN   r   r   s     rS   rT   z_optimize.<locals>.<genexpr>
  s(      33y||333333rU   r?   r   _weights   commonancestors(_)s   headss   _commonancestorheads(_)r   )r   r   r   rz   r   r   r   r   rf   r   r   zipsumr   symbolsr   r   )rZ   r   war   wbr   r   mr   r   r   ofr   r   r   s                @@@rS   r   r     s   y!t	
1B	000Av	v1Q4B1Q4BBKK (62r*:;; 	F1Q4$HHHf8!A$!EEEE r24*R"4"4 	4f]3QqrrU333338R   	1r1Q400077B2r2,	u R
B	 	 	 	 	 	 	 1 	 	AQ<<DAq}!A$)"3"3qty7H7H		1a&!!!GIIIIIaLLLIIaLLLL			r77a<<a5"Q%<2wwZ%))3444	v+qt$$ 	$&1122AQ41:!A$AQ4"ad##	{		!t	9	9	9adOOtb!A$Z	&	&	&1Q4B1Q4BBwR$$	B	B	B112q!A$-			112q!A$!%%%	w33QqrrU3334B2ww
""	{		112qtQ-	wadOO1Q4BGKKNNIq11("-- ==Q=r66"<adCCCC2vAaD"~%%
+b0
1
11rU   c                 *    t          |           \  }}|S )z[Optimize evaluatable tree

    All pseudo operations should be transformed beforehand.
    r   )r   r   newtrees      rS   optimizer     s    
 !GWNrU      $c                    |r,|                      d          r|                     d          rd}t          j        t                    }|                    t          | ||                    \  }}|t          |           k    r"t          j        t          d          |          t          t          j        |d                    S )aQ  Generate a parse tree of given spec with given tokenizing options

    >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters)
    ('func', ('symbol', 'foo'), ('symbol', '$1'))
    >>> from . import error
    >>> from . import pycompat
    >>> try:
    ...   _parsewith(b'$1')
    ... except error.ParseError as e:
    ...   pycompat.sysstr(e.message)
    ...   e.location
    "syntax error in revset '$1'"
    0
    >>> try:
    ...   _parsewith(b'foo bar')
    ... except error.ParseError as e:
    ...   pycompat.sysstr(e.message)
    ...   e.location
    'invalid token'
    4
    s   revset(r   N)rR   rn   s   invalid token)rA   r;   )
startswithendswithr	   elementsr   rx   rf   r   rk   r   r   simplifyinfixops)r   rR   rn   rw   r   rr   s         rS   
_parsewithr   +  s    ,  $//*-- $--2E2E hAf^DDD ID# c$iiq!122C8886*41ABBCCCrU   c                   T    e Zd ZdZ ed          Zed             Zed             ZdS )_aliasrulesz0Parsing and expansion rule set of revset aliasess   revset aliasc                 .    t          | t                    S )a  Parse alias declaration/definition ``spec``

        This allows symbol names to use also ``$`` as an initial letter
        (for backward compatibility), and callers of this function should
        examine whether ``$`` is used also for unexpected symbols or not.
        rn   )r   _aliassyminitletters)r   s    rS   _parsez_aliasrules._parseQ  s     $/CDDDDrU   c                     | d         dk    r5| d         d         dk    r%| d         d         t          | d                   fS d S d S )Nr   r   r   rB   r@   )r   r   s    rS   _trygetfuncz_aliasrules._trygetfunc[  sP    7g$q'!*	"9"971:wtAw//// "9"9rU   N)	__name__
__module____qualname____doc__r   _sectionstaticmethodr   r   rO   rU   rS   r   r   L  s`        ::q!!HE E \E 0 0 \0 0 0rU   r   c                 ,   t                               |          }t                               ||           } |\t          |                                          D ]:\  }}|j        r.|j        s' |t          d          |j        z             d|_        ;| S )zCExpand aliases in a tree, aliases is a list of (name, value) tuplesNs   warning: %s
T)r   buildmapexpandsorteditemsr   warnedr   )r   aliaseswarnnamealiass        rS   expandaliasesr  a  s    ""7++Ggt,,D!'--//22 	$ 	$KD%{ $5< $Q'((EK8999#KrU   c                    t          | t                    r
| d         dv r| S | d         dk    r| g}g }|r|                                }|d         dk    r+|                    t	          |dd                              nR|d         dv r|                    |d                    n,t          d          |d         z  }t          j        |          |dd		                    |          fS t          d
 | D                       S )z(Fold elements to be concatenated by `##`r   r   r   r   NrC   rB   s#   "##" can't concatenate "%s" elementrC   rU   c              3   4   K   | ]}t          |          V  d S rN   )
foldconcat)rP   r   s     rS   rT   zfoldconcat.<locals>.<genexpr>  s(      11qZ]]111111rU   )
r^   r   popextendreversedr   r   r   rk   r   )r   pendingrs   emsgs        rS   r  r  n  s   dE"" d1g 2 ' '
 Aw*& 	,Atz!!x!""////1///1BCCqtL&s+++  	, 388A;;''11D111111rU   c                     	 t          | |          S # t          j        $ rP}|j        C|j        }|                     dd          } | dz   d|dz   z  z   dz   t          d          z   |_         d }~ww xY w)N)rR      
    r   s   ^ s   here)r   r   rk   locationreplacer   hint)r   rR   instlocs       rS   r   r     s    $v.... 
 
 
=$-C<<t,,D
 utsQw'77%?!G**LDI
s    A2AA--A2c                 T    dt          j        t          j        |                     z  S )zQuote a value in order to make it safe for the revset engine.

    >>> _quote(b'asdf')
    "'asdf'"
    >>> _quote(b"asdf'\"")
    '\'asdf\\\'"\''
    >>> _quote(b'asdf\'')
    "'asdf\\''"
    >>> _quote(1)
    "'1'"
    s   '%s')r   	escapestrr
   ra   )rq   s    rS   _quoter&    s%     Z)(*:1*=*=>>>>rU   c                    | dk    rdt          |          z  S | dk    rt          |          S | dk    r0t          |t                    st          t          |           d|z  S | dk    rt          t          |                    S | dk    r7	 t          |                                          S # t          $ r t          w xY wt          j
        t          d          | z            )	N   ds   _rev(%d)   srW   s   (%s)   n   bs&   unexpected revspec format character %s)r   r&  r^   r_   	TypeErrorr   r   branchAttributeErrorr   rk   r   )rt   args     rS   _formatargtyper0    s    DyySXX%%	
dc{{	
d#u%% 	Oc


}	
dc#hh	
d	#**,,''' 	 	 	O	

1FGG!K
L
LLs    B. .C c                 $   t          |           }|dk    rdS |dk    rt          || d                   S |dk    rt          |           S |dk    r%dt          d                    |                     z  S |dk    r"d	d                    d
 | D                       z  S |dk    r8	 dd                    d | D                       z  S # t
          $ r t          w xY w|dz  }dt          | d |         |          t          | |d          |          fz  S )Nr   	   _list('')r   r(  r)  s	   _list(%s)r   r*  s   _hexlist('%s')c              3   4   K   | ]}t          |          V  d S rN   r   rP   r   s     rS   rT   z!_formatlistexp.<locals>.<genexpr>  s(      -@-@c!ff-@-@-@-@-@-@rU   r+  s   _list('%s')c              3   >   K   | ]}|                                 V  d S rN   )r-  r4  s     rS   rT   z!_formatlistexp.<locals>.<genexpr>  s*      .E.Eaqxxzz.E.E.E.E.E.ErU   r@   s
   (%s or %s))rf   r0  _formatintlistr&  r   r.  r,  _formatlistexp)rq   r   rs   r   s       rS   r7  r7    s7   AAAvv|	
aa1&&&	
da   	
dfUZZ]]3333	
d 5::-@-@a-@-@-@#@#@@@	
d	!EJJ.E.E1.E.E.E$E$EEE 	 	 	O	 	
QAN1RaR5!44nQqrrUA6N6NOOOs   #!C Cc                    	 t          |           }|dk    rdS |dk    rt          d| d                   S dd                    d | D                       z  S # t          t          f$ r" t          j        t          d                    w xY w)	Nr   r2  r   r(  s   _intlist('%s')r   c              3   :   K   | ]}d t          |          z  V  dS )s   %dN)r   r4  s     rS   rT   z!_formatintlist.<locals>.<genexpr>  s,      -K-Kec!ffn-K-K-K-K-K-KrU      invalid argument for revspec)rf   r0  r   r,  r   r   rk   r   )datars   s     rS   r6  r6    s    CII66<!VV!$Q000 5::-K-Kd-K-K-K#K#KKKz" C C Cq!@AABBBCs   A A !A 3B
c                 F    d                     fd| D                       S )Ns   , c              3   8   K   | ]}t          |          V  d S rN   )r0  )rP   r   r   s     rS   rT   z"_formatparamexp.<locals>.<genexpr>  s-      99qnQ**999999rU   )r   )argsr   s    `rS   _formatparamexpr?    s*    ::9999D999999rU   )   l   pc                 p   t          | |          }g }|D ]\  }}||                    |           |dk    rTt          |t                    rt	          |          }|                    t          t          |                               wt          j        d|z            d	                    |          S )a;  
    This is a convenience function for using revsets internally, and
    escapes arguments appropriately. Aliases are intentionally ignored
    so that intended expression behavior isn't accidentally subverted.

    Supported arguments:

    %r = revset expression, parenthesized
    %d = rev(int(arg)), no quoting
    %s = string(arg), escaped and single-quoted
    %b = arg.branch(), escaped and single-quoted
    %n = hex(arg), single-quoted
    %% = a literal '%'

    Prefixing the type with 'l' specifies a parenthesized list of that type,
    and 'p' specifies a list of function parameters of that type.

    >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()"))
    '(10 or 11):: and ((this()) or (that()))'
    >>> formatspec(b'%d:: and not %d::', 10, 20)
    '_rev(10):: and not _rev(20)::'
    >>> formatspec(b'%ld or %ld', [], [1])
    "_list('') or _rev(1)"
    >>> formatspec(b'keyword(%s)', b'foo\xe9')
    "keyword('foo\\xe9')"
    >>> b = lambda: b'default'
    >>> b.branch = b
    >>> formatspec(b'branch(%b)', b)
    "branch('default')"
    >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd'])
    "root(_list('a\\x00b\\x00c\\x00d'))"
    >>> formatspec(b'sort(%r, %ps)', b':', [b'desc', b'user'])
    "sort((:), 'desc', 'user')"
    >>> formatspec(b'%ls', [b'a', b"'"])
    "_list('a\\x00\\'')"
    N   baseset   unknown revspec item type: %rrU   )

_parseargsr   r^   setr
  r6  r   r   r`   r   )exprr>  parsedretr   r/  s         rS   
formatspecrJ    s    J d##F
C O O39JJsOOOO*__#s## "SkkJJ~d3ii001111()IA)MNNN88C==rU   c                    t          | |          }g }g }|D ]z\  }}||                    |           |dk    rAdt          j        |          f}|                    |           |                    d           dt	          j        d|z            d                    |          } t          | t                    }t          j
        |dg|R  }t          |          }t          |          }t          |          }|S )	z<similar to formatspec but return a parsed and optimized treeNrC  r   r   rD  rU   r   )rB   r   )rE  r   r   basesetr   r`   r   r   r   r	   r   r  r   r   )	rG  r>  rH  rI  inputsr   r/  r   r   s	            rS   spectreerN    s   d##F
CF O O39JJsOOOO*__"H$4S$9$9:GMM'"""JJt()IA)MNNN88C==Dd+?@@@DD"3=f===DdD4==DD>>DKrU   c                    t          j        |           } t          |          }g }d}|t          |           k     ra|                     d|          }|dk     r!|                    d| |d         f           n$|                    d| ||         f           |dz   }	 | |         }n/# t          $ r" t          j        t          d                    w xY w|dk    r|                    d|f           |dz  }	 t          |          }n/# t          $ r" t          j        t          d                    w xY wt                              |          }|r|dz  }|dk    }		 | |         }n/# t          $ r" t          j        t          d                    w xY w|	r&|dk    r |r|                    d	|f           |dz  }	 |                    d |t          |          |          f           n# t          t           f$ r" t          j        t          d
                    w xY w	 |                    dt#          ||          f           n6# t          t           f$ r" t          j        t          d
                    w xY w|dz  }|t          |           k     a	 t          |           t          j        t          d                    # t          $ r Y nw xY w|S )zparse the expression and replace all inexpensive args

    return a list of tuple [(arg-type, arg-value)]

    Arg-type can be:
    * None:      a string ready to be concatenated into a final spec
    * 'baseset': an iterable of revisions
    r   r8   Nr   s#   incomplete revspec format characters   missing argument for revspecr@  r(  rC  r:  s$   too many revspec arguments specified)r
   ra   iterrf   findr   
IndexErrorr   rk   r   nextStopIteration_formatlistfuncsr   r   r,  r   r0  )
rG  r>  argiterrI  rr   qrv   r/  r   islists
             rS   rE  rE  0  sU    D!!D4jjG
C
C
D		//IIdC  q55JJd344j)***

D$s1u+&'''!e	NS	AA 	N 	N 	N"1%K#L#LMMM	N99JJay!!!1HC	Gw--CC 	G 	G 	G"1%D#E#EFFF	G  ## 	K1HC$YFI   &<==    !t))) 

J,---qK

D!!DIIq//23333z* K K K&q)H'I'IJJJKK

D.C"8"89::::z* K K K&q)H'I'IJJJKqa D		//dWq!HIIJJJ   JsN   B' ',C:D
 
,D6!E* *,F.G1 13H$(%I 3J0K 
KKc                 ,    t          j        | d          S )Nr  )r	   prettyformatr   s    rS   rZ  rZ  w  s    t%;<<<rU   c                 z    t          | t                    r%t          t          t          |                     dz   S dS )Nr   r   )r^   r   r   mapdepthr   s    rS   r]  r]  {  s6    $ 3ud##$$q((qrU   c                    t          | t                    r
| d         dv rt                      S t                      }| dd          D ]}|t          |          z  }| d         dk    r!|                    | d         d                    |S )Nr   r  r   r   )r^   r   rF  	funcsusedadd)r   funcsrq   s      rS   r_  r_    s    dE"" d1g1G&G&Guuabb 	" 	"AYq\\!EE7gIId1gaj!!!rU   s   [0-9a-fA-F]{1,40}$c                 6    t                               |           S )z,returns true if the symbol looks like a hash)_hashrematch)symbols    rS   _ishashlikesymbolrf    s    ==   rU   c                     | sg S | d         dk    rt          | d                   r	| d         gS n6t          |           dk    r#g }| dd         D ]}|t          |          z  }|S g S )a7  returns the list of symbols of the tree that look like hashes

    >>> gethashlikesymbols(parse(b'3::abe3ff'))
    ['3', 'abe3ff']
    >>> gethashlikesymbols(parse(b'precursors(.)'))
    []
    >>> gethashlikesymbols(parse(b'precursors(34)'))
    ['34']
    >>> gethashlikesymbols(parse(b'abe3ffZ'))
    []
    r   rB   r   r>   N)rf  rf   gethashlikesymbols)r   resultssubtrees      rS   rh  rh    s      	Aw)T!W%% 	G9		TaABBx 	3 	3G)'222GGIrU   )NNNr   rN   )Kstringi18nr   r
   r   noder    r   r	   r   r   utilsr   r   rl   r   ri   rF  iterbytestrrh   sysbytesascii_lettersdigitsr\  bytechrrangerb   rc   rx   objectr   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   basealiasrulesr   r  r  r   r&  r0  r7  r6  r?  rU  rJ  rN  rE  rZ  r]  r_  recompilerc  rf  rh  rO   rU   rS   <module>rz     s                                        '
C' 	
9' 	
3	'
 
3' 	
3' 	
:' 	
9' 
 '  
 !'. 	
L/'0 01'2 	
.3'4 .5'6 	
,7'8 	
49': 
,;'< 	
+='> ,
1
-
%
%//'M' ' 'R #""
t3+x+,?@@AA  #H&.//
(
FM
*
*	+
	   CHeeCoo..//0 $8H$8$?$? @ @@E E E ET &((/ / /       ' $ $ $ $             )0 
G 
G 
G 
G     
  A A A  O O O4 4 4<32 32 32l  b2 b2 b2J   '$/ D D D DB0 0 0 0 0&' 0 0 0*
 
 
 
2 2 22    ? ? ?M M M(P P P,	C 	C 	C: : :
 
  0 0 0f  .D D DN= = =  	 	 	 '///
0
0! ! !
    rU   