a
    xd6                    @   s  d dl m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d dlZd dlZzd dlmZ W n ey   d dlmZ Y n0 d dlmZmZ d dlmZ d dlmZ d dlZd dlmZmZmZ d dlm Z  G dd de!Z"e# d	kZ$e$ Z%e$Z&d
Z'dZ(G dd de)Z*G dd de)Z+G dd de)Z,dVddZ-dd Z.dd Z/dd Z0dd Z1dd Z2dd Z3d d! Z4d"d# Z5d$d% Z6d&d' Z7d(d) Z8d*d+ Z9d,d- Z:d.d/ Z;d0d1 Z<d2d3 Z=d4d5 Z>d6d7 Z?d8d9 Z@dWd;d<ZAd=d> ZBeBd?d@ ZCG dAdB dBe)ZDG dCdD dDeDZEG dEdF dFeDZFi dfdGdHZGG dIdJ dJe)ZHG dKdL dLe)ZIg dMfdNdOZJg dMfdPdQZKdRdS ZLg g fdTdUZMdS )X    )absolute_importN)StringIO)GlobItemCommand)to_bytes	to_string
to_unicode)BooleanExpressionc                   @   s   e Zd Zdd ZdS )InternalShellErrorc                 C   s   || _ || _d S N)commandmessage)selfr   r    r   W/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/lit/TestRunner.py__init__   s    zInternalShellError.__init__N)__name__
__module____qualname__r   r   r   r   r   r
      s   r
   Windowsz	/dev/nullz%dbg\(([^)'"]*)\)(.*)c                   @   s    e Zd ZdZdd Zdd ZdS )ShellEnvironmentzMutable shell environment containing things like CWD and env vars.

    Environment variables are not implemented, but cwd tracking is. In addition,
    we maintain a dir stack for pushd/popd.
    c                 C   s   || _ t|| _g | _d S r   )cwddictenvdirStack)r   r   r   r   r   r   r   @   s    
zShellEnvironment.__init__c                 C   s2   t j|r|| _nt jt j| j|| _d S r   )ospathisabsr   realpathjoin)r   Znewdirr   r   r   
change_dirE   s    zShellEnvironment.change_dirN)r   r   r   __doc__r   r    r   r   r   r   r   8   s   r   c                   @   sP   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 Z
dd ZdS )TimeoutHelperz
        Object used to helper manage enforcing a timeout in
        _executeShCmd(). It is passed through recursive calls
        to collect processes that have been executed so that when
        the timeout happens they can be killed.
    c                 C   s(   || _ g | _d| _d| _d | _d | _d S NF)timeout_procs_timeoutReached_doneKillPass_lock_timer)r   r$   r   r   r   r   R   s    zTimeoutHelper.__init__c                 C   s   |   sd S | j  d S r   )activer)   cancelr   r   r   r   r+   \   s    zTimeoutHelper.cancelc                 C   s
   | j dkS Nr   r$   r,   r   r   r   r*   a   s    zTimeoutHelper.activec                 C   sd   |   sd S d}| j" | j| | j}W d    n1 s>0    Y  |r`|  sXJ |   d S r#   )r*   r(   r%   appendr'   timeoutReached_kill)r   procZneedToRunKillr   r   r   
addProcessd   s    $zTimeoutHelper.addProcessc                 C   s6   |   sd S t | _t| j| j| _| j  d S r   )	r*   	threadingLockr(   Timerr$   _handleTimeoutReachedr)   startr,   r   r   r   
startTimerw   s
    
zTimeoutHelper.startTimerc                 C   s   d| _ |   d S )NT)r&   r1   r,   r   r   r   r7      s    z#TimeoutHelper._handleTimeoutReachedc                 C   s   | j S r   )r&   r,   r   r   r   r0      s    zTimeoutHelper.timeoutReachedc                 C   sP   | j 6 | jD ]}tj|j qg | _d| _W d   n1 sB0    Y  dS )ab  
            This method may be called multiple times as we might get unlucky
            and be in the middle of creating a new process in _executeShCmd()
            which won't yet be in ``self._procs``. By locking here and in
            addProcess() we should be able to kill processes launched after
            the initial call to _kill()
        TN)r(   r%   litutilZkillProcessAndChildrenpidr'   )r   pr   r   r   r1      s
    
zTimeoutHelper._killN)r   r   r   r!   r   r+   r*   r3   r9   r7   r0   r1   r   r   r   r   r"   K   s   

r"   c                   @   s   e Zd ZdZg fddZdS )ShellCommandResultz-Captures the result of an individual command.c                 C   s,   || _ || _|| _|| _|| _t|| _d S r   )r   stdoutstderrexitCoder0   listoutputFiles)r   r   r?   r@   rA   r0   rC   r   r   r   r      s    zShellCommandResult.__init__N)r   r   r   r!   r   r   r   r   r   r>      s   r>   c                 C   sL   t |}|dkr|  t| |||}|  d}| rDd|}||fS )zG
        Wrapper around _executeShCmd that handles
        timeout
    r   NzReached timeout of {} seconds)r"   r9   _executeShCmdr+   r0   format)cmdshenvresultsr$   timeoutHelperZfinalExitCodetimeoutInfor   r   r   executeShCmd   s    
rK   c                 C   s   t | trt| |S | gS r   )
isinstancer   sortedresolve)argr   r   r   r   expand_glob   s    
rP   c                 C   s0   | d g}| dd  D ]}| t|| q|S )Nr      )extendrP   )argsr   resultrO   r   r   r   expand_glob_expressions   s    
rU   c                 C   s   g }d}| D ]}g }|r"| d d|v pNd|v pNd|v pNd|v pNd|v pN| }|r^| d |D ]b}|dkrz| | qb|dkr| dt| d  g }| d	 qb|r|| g }| | qb|r|| |r|| | d qd
|S )a  
    Reimplement Python's private subprocess.list2cmdline for MSys compatibility

    Based on CPython implementation here:
      https://hg.python.org/cpython/file/849826a900d2/Lib/subprocess.py#l422

    Some core util distributions (MSys) don't tokenize command line arguments
    the same way that MSVC CRT does. Lit rolls its own quoting logic similar to
    the stock CPython logic to paper over these quoting and tokenization rule
    differences.

    We use the same algorithm from MSDN as CPython
    (http://msdn.microsoft.com/en-us/library/17w5ykft.aspx), but we treat more
    characters as needing quoting, such as double quotes themselves, and square
    brackets.

    For MSys based tools, this is very brittle though, because quoting an
    argument makes the MSys based tool unescape backslashes where it shouldn't
    (e.g. "a\c\\d" becomes "a\c\d" where it should stay as it was,
    according to regular win32 command line parsing rules).
    F 	"[;\   z\" )r/   lenrR   r   )seqrT   	needquoterO   bs_bufcr   r   r   quote_windows_command   s4    
.



rc   c           	      C   s   t |}d}t|dd  D ]`\}}|dkr2d}q|rNd}|| jv r| j|= q|d\}}}|dkrr|d } q~|| j|< q||d  S )NFrQ   z-uT=r]   )r^   	enumerater   	partition)	r   rS   Zarg_idx_nextZunset_next_env_varZarg_idxrO   keyeqvalr   r   r   	updateEnv  s"    
rj   c                 C   s8   t | jdkrt| d|| jd  t| ddddS )z0executeBuiltinCd - Change the current directory.r\   z'cd' supports only one argumentrQ   r]   r   F)r^   rS   r
   r    r>   rF   rG   r   r   r   executeBuiltinCd  s    
rl   c                 C   sF   t | jdkrt| d|j|j || jd  t| ddddS )z>executeBuiltinPushd - Change the current dir and save the old.r\   z"'pushd' supports only one argumentrQ   r]   r   F)r^   rS   r
   r   r/   r   r    r>   rk   r   r   r   executeBuiltinPushd%  s
    
rm   c                 C   sD   t | jdkrt| d|js(t| d|j |_t| ddddS )zBexecuteBuiltinPopd - Restore a previously saved working directory.rQ   z!'popd' does not support argumentszpopd: directory stack emptyr]   r   F)r^   rS   r
   r   popr   r>   rk   r   r   r   executeBuiltinPopd-  s    

ro   c                 C   s2   t | jdkrtdt|| j t| ddddS )z3executeBuiltinExport - Set an environment variable.r\   z#'export' supports only one argumentr]   r   F)r^   rS   r
   rj   r>   rk   r   r   r   executeBuiltinExport6  s    rp   c                    s  g }t | tj||\}}}|tjks.|tjkr8t| dd}dd }|tjkrZd}t }n0trtjj}t	|j
|jd }|dd|df | jdd }d d}	t|dkr|d	 d
v r|d	 }
|dd }|
dkrd q|
dkrd}	q fdd}|rD|dd D ]&}|||| ||d q||||d  |	rX||d |D ]\}}}}|  q\|r~dn| }t| |dd	dS )z#Interpret a redirected echo commandz1stdin and stderr redirects not supported for echoTc                 S   s   | S r   r   xr   r   r   <lambda>I      z$executeBuiltinEcho.<locals>.<lambda>FbNrQ   r   )-e-nrv   rw   c                    s0    s| S t j| } tjdk r"dnd}| |S )N   r   Zstring_escapeunicode_escape)r:   r;   r   sysversion_infodecode)rO   codecZinterpret_escapesr   r   maybeUnescapee  s
    z)executeBuiltinEcho.<locals>.maybeUnescaperV   
r]   )processRedirects
subprocessPIPEr
   r   
kIsWindowsr:   r;   r   opennamemoder/   rS   r^   writeclosegetvaluer>   )rF   rG   opened_filesstdinr?   r@   Zis_redirectedencoderS   Zwrite_newlineflagr   rO   r   r   fr   outputr   r   r   executeBuiltinEcho=  sN    


r   c                 C   s  t | j|jdd }zt|d\}}W n8 tjyb } zt| dt| W Y d}~n
d}~0 0 d}|D ]"\}}|dkrd}qldslJ dqlt|d	krt| d
t	 }d	}	|D ]}
|j}t
rt|
nt|
}
t
rt|nt|}tj|
s
tjtj||
}
|rtj|
 qztj|
 W q tyj } z"|dt|  d}	W Y d}~qd}~0 0 qt| d| |	dS )z-executeBuiltinMkdir - Create new directories.rQ   Nr=   zUnsupported: 'mkdir':  %sFz-pTunhandled optionr   z$Error: 'mkdir' is missing an operandz"Error: 'mkdir' command failed, %s
r]   )rU   rS   r   getopt
gnu_getoptGetoptErrorr
   strr^   r   r   r   r   r   r   r   r   r   r:   r;   mkdir_pmkdirOSErrorr   r>   r   )rF   	cmd_shenvrS   optserrparentoar@   rA   dirr   r   r   r   executeBuiltinMkdir{  s8    (
r   c           #         sP  t | j|jdd }zt|ddg\}}W n8 tjyf } zt| dt| W Y d}~n
d}~0 0 d}d}|D ]0\}}|dkrd}qt|d	v rd}qtdstJ d
qtt|dkrt| ddd }	t	 }
d}|D ]f}|j}t
rt|nt|}t
rt|nt|}tj|s*tjtj||}|r@tj|s@qҐztj|r|sj|
d|  d}t dkrddlm mmmm ddlm}m}m m!} ddlm"} ddlm#}m$}m%} G  fddd|}t&dd\}}}}d}d}d}d}||B |B |B }|j'j(}||g|_)tj*|}||t|d } d | t|< | t|d < |||| |d}!|||!}"|"r||"nt+j,||r|	ndd n@|rt-|tj.st/|t01t0|j2t0j3B  t4| W q t5y8 } z"|
d t|  d}W Y d}~qd}~0 0 qt6| d!|
7 |dS )"z:executeBuiltinRm - Removes (deletes) files or directories.rQ   NZfrR--recursivezUnsupported: 'rm':  %sFz-fT)z-rz-Rr   r   r   z!Error: 'rm' is missing an operandc                 S   s.   t |tt |jtjB  t | d S r   )r   chmodstatS_IMODEst_modeS_IWRITEremove)funcr   exc_infor   r   r   on_rm_error  s     z%executeBuiltinRm.<locals>.on_rm_errorzError: %s is a directory
r   )BOOLHWNDLPCWSTRUINTWORD)	addressofbyrefc_void_pcreate_unicode_buffer)	Structure)windllWinErrorPOINTERc                	       s@   e Zd Zdfdfdfdfdfd fdfdfgZd	S )
z)executeBuiltinRm.<locals>.SHFILEOPSTRUCTWZhWndwFuncpFromZpTofFlagsZfAnyOperationsAbortedZhNameMappingsZlpszProgressTitleN)r   r   r   _fields_r   r   r   r   r   r   r   r   r   SHFILEOPSTRUCTW  s   r            i      r\    )r   r   r   )onerrorzError: 'rm' command failed, %sr]   )8rU   rS   r   r   r   r   r
   r   r^   r   r   r   r   r   r   r   r   r   existsisdirr   platformsystemZctypes.wintypesr   r   r   r   r   ctypesr   r   r   r   r   r   r   r   rangeshell32SHFileOperationWargtypesabspathshutilrmtreeaccessW_OKr   r   r   r   r   r   r   r>   r   )#rF   r   rS   r   r   force	recursiver   r   r   r@   rA   r   r   r   r   r   r   r   r   r   r   ZFO_MOVEZFO_COPYZ	FO_DELETEZ	FO_RENAMEZ
FOF_SILENTZFOF_NOCONFIRMATIONZFOF_NOCONFIRMMKDIRZFOF_NOERRORUIZ	FOF_NO_UIr   r   Z	operationrT   r   r   r   executeBuiltinRm  s    (



r   c                 C   s   t | ddddS )z?executeBuiltinColon - Discard arguments and exit with status 0.r]   r   F)r>   )rF   r   r   r   r   executeBuiltinColon   s    r   c                 C   s  g d}| j D ]\}}|dkr.|ddg|d< q|dkrF|ddg|d< q|dkrh|d	v rh|t| |d< q|d
ksx|dkr|ddg |d< |d< q|dkr|ddg|d< q|dkr|ddg|d< q|dkr|ddg|d< qt| d||ff qg d}t|D ]\}}	t|	tr|	dkr$|}
nj|	dkr^|dkrDt| dn|dkrVtj}
ntj}
n0|	dkr|dkr|t| dtj}
n
t| d|
||< q|	\}}}
|
dur|
||< qd}t	||j
}t|dkrt| d|d }tr|tkrtj|d}
nLtr |dkr td|}
n0tj|j
|}tr>t|nt|}t||}
|dkrf|
dd |
|	d< ||||
f|f  |
||< q|S )zReturn the standard fds for cmd after applying redirects

    Returns the three standard file descriptors for the new child process.  Each
    fd may be an open, writable file object or a sentinel value from the
    subprocess module.
    )r   rQ   r\   )>r\   wNr\   )>>r\   r   )>&r\   Z012)r   )z&>rQ   )r   )r   )<rr   zUnsupported redirect: %r)NNNr   r   zUnsupported redirect for stdinr   zUnsupported redirect on stdoutzBad redirectz8Unsupported: glob in redirect expanded to multiple filesr   z/dev/ttyCON)	redirectsintr
   re   rL   tupler   r   STDOUTrP   r   r^   kAvoidDevNullkDevNulltempfileTemporaryFiler   r   r   r   r   r   r   seekr/   )rF   Zstdin_sourcer   r   r   opfilenameZstd_fdsindexr   fdr   Zredir_filenamer   r   r   r   r     sx    













r   c           *      C   s  |  rd S t| tjr| jdkrBt| j|||}t| j|||S | jdkrVt| d| jdkrt| j|||}|dkrt| j|||}|S | jdkrt| j|||}|d u r|S |dkrt| j|||}|S t	d| j t| tj
sJ g }g }tj}g }g }	g }
tdd	g}tjtjtjtd
}ttttttttd}t| jD ]\}}|}t|j}g }d}d}|d dkr||u rt |j!|j"}t#||}|sRt|dn|d dkr|$|%d |d7 }|r|d dkr|$|%d d}|sRt|dn<|d dkrV|$|%d |d7 }|sRt|dnqVqt|&|d d }|r.|d dkst'| jdkr.||urt|d(|d |rt|d(|d t'| jdkrt|d(|d |t)||j*|}|d rt+|j, |_,|j|j-_|$| |j,  S |d |v r~|.dt/j0 tjtjt|j"d< tj||d d |d< |r|| }d}ng }t1||||	\}}}|tj2kr|tjkrtj}d}n:d}|tjkr|| jd krt3j4dd}|$||f d }|d 5d rBtj|j!|d }tj6|rB|}|s`t7j89|d |j"d! }|sxt|d"|d  t:rzt;}W n t<y   t=}Y n0 t|D ]R\}}t||rt>|v rt3j?dd#}|@  |
$|jA |Bt>|jA||< qtC||j!}tDrtE|}zD|$tjF||j!|||||j"tGdd$d%
 |$| |H|d  W n8 tIy }  zt|d&(|| W Y d } ~ n
d } ~ 0 0 |tjkr|d jJ@  d |d _J|tjkr|d jK}n|r|d jL}ntj}qP|	D ]\}!}"}}#|@  qd gt'| }$|d M |$d< tNt'|d D ]Z}|| jKd urZ|| jKO }%nd'}%|| jLd ur~|| jLO }&nd'}&|%|&f|$|< q6|D ]6\}}|Pdd |$| d |O f|$|< |@  qd }'t|$D ]\}\}%}&|| Q }|tRjS krtT|| d r| }n || dkr<|dkr8dnd}z&|%d u rNd'}%ntU|%jVd(d$d)}%W n   t=|%}%Y n0 z&|&d u rd'}&ntU|&jVd(d$d)}&W n   t=|&}&Y n0 g }(|dkrRtW|	D ]\}!}"}}#|#d ur|"d*v rz8tX|#d+}|O })W d    n1 s0    Y  W n   d })Y n0 |)d ur|($|!|#|)f q|$tY| j| |%|&||  |( | jZr|'r|dkr|}'n|}'q|
D ]*}zt[| W n tIy   Y n0 q| j\r|' }'|'S ),NrZ   &zunsupported shell operator: '&'z||r   &&zUnknown shell command: %rcatdiffbuiltin_commands)Zcdexportechor   ZpopdZpushdZrm:Fr   z"Error: 'env' requires a subcommandnotrQ   z--crashTz"Error: 'not' requires a subcommand!z Error: '!' requires a subcommandr   zError: 'env' cannot call '{}'z%Error: 'not --crash' cannot call '{}'z.Unsupported: '{}' cannot be part of a pipeliner\   
PYTHONPATHz.pyr   zw+br   .PATHz%r: command not found)deletereplace)	r   
executabler   r?   r@   r   	close_fdsuniversal_newlineserrorsz'Could not create process ({}) due to {}r]   utf-8r  )r   r   rb)]r0   rL   ShUtilSeqr   rD   lhsrhsr
   
ValueErrorZPipeliner   r   setr   r   r   dirnamer   __file__rl   rp   r   r   ro   rm   r   r   re   commandsrB   rS   r   r   r   rj   r/   rn   getr^   rE   r   r   r   rA   r   insertr{   r   r   r   r   r   
startswithisfiler:   r;   whichr   
basestring	NameErrorr   r   NamedTemporaryFiler   r   r   rU   r   rc   PopenkUseCloseFDsr3   r   r   r?   r@   communicater   readr   waitsignalSIGINTKeyboardInterruptr   r}   rM   r   r>   Zpipe_errr   negate)*rF   rG   rH   rI   resZprocsZproc_not_countsZdefault_stdinZstderrTempFilesr   Znamed_temp_filesr   Zbuiltin_commands_dirZinproc_builtinsijr   rS   Znot_argsZ	not_countZ	not_crashZinproc_builtinrT   r   r?   r@   ZstderrIsStdoutr   Z
exe_in_cwdZstr_typerO   r   er   r   r   ZprocDataoutr   rA   Zoutput_filesdatar   r   r   rD   a  s   







	$






	
(




,


rD   c                 C   s  g }t |D ]\}}tt|}|rH|d}	||	r:dnd }||< z"|t||j	| j
j  W q   tjtjd|  Y   S 0 q|d }
|dd  D ]}t|
d|}
qg }d }z(t|| j
j}t|
|||jd\}}W n> ty(   t d }d	}|t|jd
|j|d Y n0 d
 }}t |D ]\}}|dddd |jjD f 7 }|jdkr|jdkr|j  s|j!  sq:|j"D ]r\}}}|  r|d|f 7 }t#|j$ddd}t%|dkr ||d d d 7 }|d7 }n||7 }|d7 }q|j  r0|d|jf 7 }|j!  rL|d|j!f 7 }|j  sl|j!  sl|d7 }|jdkr|j	r|jdk s|jdkrt&t'|jd@ (d}n
t)|j}|d|f 7 }|jdkr:|j*r:|dt)|j*f 7 }q:||||fS ) Nr\   
: '\1'; \2: '\1'zshell parser error on: %rr   rQ   r   r.      r]   Fz$ %s
rV   c                 s   s   | ]}d | V  qdS )z"%s"Nr   .0sr   r   r   	<genexpr>  s   z(executeScriptInternal.<locals>.<genexpr>z# redirected output from %r:
r  r   r  r   z
...
znote: data was truncated
r   z# command output:
%s
z# command stderr:
%s
z0note: command had no output on stdout or stderr
   l    Lz+error: command failed with exit status: %s
z#error: command reached timeout: %s
)+re   rematch
kPdbgRegexgroupexpandr/   r  ZShParser	isWindowsconfigpipefailparser:   TestResultFAILr  r   environmentrK   maxIndividualTestTimer
   r{   r   r>   r   r   r   rS   rA   r?   stripr@   rC   r   r}   r^   hexr   rstripr   r0   )test	litConfigtmpBaser  r   Zcmdsr"  lnr1  r   rF   rb   rH   rJ   rG   rA   r$  r%  r   rT   r   r   r&  ZcodeStrr   r   r   executeScriptInternal  s    

 


 
rE  c              
   C   s~  |  }|jo| }|d }|r(|d7 }d}i }	|jrD|sD|d7 }ntjdkrVd|	d< t||fi |	}
|rt|D ]8\}}tt|}|rt|	d}|
|rd	nd
||< qt|jr|
d n
|
d |
d| nt|D ]:\}}tt|}|r|	d}|
|rdnd||< q| jjrB|
|dkr<dnd |jrb|
|dkr\dnd tjdkr|dkr|
tdd| d d n|
dd| d  |
|dkrdnd |
  |rdd|g}n*|r||g}nd|g}|jr|j| }z.tjj||| jj|jd\}}}|||d fW S  tjjyx } z |j|j|j|jfW  Y d }~S d }~0 0 d S )Nz.scriptz.batr   ru   rx   r  encodingr\   zecho '\1' > nul && zecho '\1' > nulz	@echo on
z
@echo off
z
@if %ERRORLEVEL% NEQ 0 EXIT
r'  r(  wbs   set -o pipefail;zset -o pipefail;s   set -x;zset -x;z{ z	; } &&
{ z; }   
r   rF   z/cz/bin/sh)r   r   r$   )ZgetBashPathr5  r{   r|   r   re   r0  r1  r2  r3  r4  Zecho_all_commandsr   r   r6  r7  bytesr   ZuseValgrindZvalgrindArgsr:   r;   ZexecuteCommandr<  r=  ZExecuteCommandTimeoutExceptionr%  r   rA   msg)rA  rB  rC  r  r   ZbashPathZisWin32CMDEXEscriptr   Zopen_kwargsr   r"  rD  r1  r   r%  r   rA   r$  r   r   r   executeScript  sp    







 


rL  c                 c   s   t tdddd |D f }t| d}z| }|tdsR|td }d}d}||D ]X}| }||	td||7 }|}|
 \}	}
|t|	d	t|
d	d
fV  qdW |  n
|  0 dS )z
    parseIntegratedTestScriptCommands(source_path) -> commands

    Parse the commands in an integrated test script file into a list of
    (line_number, command_type, line).
    z	(%s)(.*)
|c                 s   s   | ]}t |V  qd S r   )r0  escape)r+  kr   r   r   r-  A  rt   z4parseIntegratedTestScriptCommands.<locals>.<genexpr>r  r   rQ   r   r  N)r0  compiler   r   r   r  endswithfinditerr8   countgroupsr   r}   r@  r   )source_pathkeywordsZkeywords_rer   r&  line_numberZlast_match_positionr1  Zmatch_positionkeywordrD  r   r   r   !parseIntegratedTestScriptCommands-  s*    


rZ  c                 C   s<   |   }tj|\}}tj|d}tj||}||fS )zeGet the temporary location, this is always relative to the test suite
    root, not test source root.ZOutput)getExecPathr   r   splitr   )rA  ZexecpathexecdirZexecbasetmpDirrC  r   r   r   getTempPathse  s
    r_  c                 C   s:   t rtdd| ddS | d dks*J | dd  S d S )Nz^(.):z\1r[   /r   rQ   )r   r0  subr   )r   r   r   r   colonNormalizePathn  s    rb  Fc           
      C   s  |   }tj|}|rH|dd}|dd}|dd}|dd}g }|| jj |d }tj|}|d|fd|fd|fdtj	fd|fd	|fd
|fg |dt
|jfdt
|jfdtjjfg |d|ddfd|ddfd|ddfd|ddd fd|ddfd|ddfg dd }	|d|	|ddfd|	|ddfd|	|ddfd|	|ddd fd|	|ddfg |dt|fdt|fdt|fdt|d fd t|fg |S )!Nr[   r`  z.tmpz%sz%Sz%pz
%{pathsep}z%tz%basename_tz%Tz%{fs-src-root}z%{fs-tmp-root}z	%{fs-sep}z%/sz%/Sz%/pz%/tz%/Tz%/etz\\\\\\\\c                 S   s   |  dd} |  dd} | S )N@z\@r   z\&)r   )r,  r   r   r   regex_escape  s    z-getDefaultSubstitutions.<locals>.regex_escapez%{/s:regex_replacement}z%{/S:regex_replacement}z%{/p:regex_replacement}z%{/t:regex_replacement}z%{/T:regex_replacement}z%:sz%:Sz%:pz%:tz%:T)getSourcePathr   r   r  r   rR   r6  substitutionsbasenamepathseppathlibPathanchorseprb  )
rA  r^  rC  normalize_slashes
sourcepathZ	sourcedirrf  ZtmpNamebaseNamerd  r   r   r   getDefaultSubstitutionsu  st    





rp  c                    s   i   fdd}|S )Nc                    s   |  vr|  | <  |  S r   r   rq   cacher   r   r   memoized  s    z_memoize.<locals>.memoizedr   )r   rs  r   rq  r   _memoize  s    rt  c                 C   s
   t | S r   )r0  rQ  )r   r   r   r   _caching_re_compile  s    ru  c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ExpandableScriptDirectiveaZ  
    Common interface for lit directives for which any lit substitutions must be
    expanded to produce the shell script.  It includes directives (e.g., 'RUN:')
    specifying shell commands that might have lit substitutions to be expanded.
    It also includes lit directives (e.g., 'DEFINE:') that adjust substitutions.

    start_line_number: The directive's starting line number.
    end_line_number: The directive's ending line number, which is
        start_line_number if the directive has no line continuations.
    keyword: The keyword that specifies the directive.  For example, 'RUN:'.
    c                 C   s   || _ || _|| _d S r   )start_line_numberend_line_numberrY  )r   rw  rx  rY  r   r   r   r     s    z"ExpandableScriptDirective.__init__c                 C   s   dsJ ddS )a  
        Add a continuation line to this directive and return True, or do nothing
        and return False if the specified line is not a continuation for this
        directive (e.g., previous line does not end in '', or keywords do not
        match).

        line_number: The line number for the continuation line.
        keyword: The keyword that specifies the continuation line.  For example,
            'RUN:'.
        line: The content of the continuation line after the keyword.
        F-expected method to be called on derived classNr   r   rX  rY  liner   r   r   add_continuation  s    z*ExpandableScriptDirective.add_continuationc                 C   s   dsJ ddS )a  
        Does this directive require a continuation line?

        '' is documented as indicating a line continuation even if whitespace
        separates it from the newline.  It looks like a line continuation, and
        it would be confusing if it didn't behave as one.
        Fry  Nr   r,   r   r   r   needs_continuation  s    z,ExpandableScriptDirective.needs_continuationc                 C   s,   | j | jkrd| j  S d| j  d| j S )z
        Get a phrase describing the line or range of lines so far included by
        this directive and any line continuations.
        zat line z
from line z to )rw  rx  r,   r   r   r   get_location  s    z&ExpandableScriptDirective.get_locationN)r   r   r   r!   r   r|  r}  r~  r   r   r   r   rv    s
   
rv  c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )CommandDirectivez
    A lit directive taking a shell command line.  For example,
    'RUN: echo hello world'.

    command: The content accumulated so far from the directive and its
        continuation lines.
    c                    s   t  ||| | | _d S r   )superr   r@  r   )r   rw  rx  rY  r{  	__class__r   r   r     s    zCommandDirective.__init__c                 C   s8   || j ks|  sdS | jd d |  | _|| _dS )NFr   T)rY  r}  r   r@  rx  rz  r   r   r   r|  	  s
    z!CommandDirective.add_continuationc                 C   s   | j d dkS Nr   r[   )r   r,   r   r   r   r}    s    z#CommandDirective.needs_continuation)r   r   r   r!   r   r|  r}  __classcell__r   r   r  r   r    s   r  c                       s@   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Z  Z	S )SubstDirectivea#  
    A lit directive taking a substitution definition or redefinition.  For
    example, 'DEFINE: %{name} = value'.

    new_subst: True if this directive defines a new substitution.  False if it
        redefines an existing substitution.
    body: The unparsed content accumulated so far from the directive and its
        continuation lines.
    name: The substitution's name, or None if more continuation lines are still
        required.
    value: The substitution's value, or None if more continuation lines are
        still required.
    c                    s4   t  ||| || _|| _d | _d | _|   d S r   )r  r   	new_substbodyr   value_parse_body)r   rw  rx  rY  r  r{  r  r   r   r   $  s    zSubstDirective.__init__c                 C   s\   || j ks|  sdS | s&td| j d d  d |  | _|| _|   dS )NFz$Substitution's continuation is emptyr   rV   T)	rY  r}  r>  r  r  r@  lstriprx  r  rz  r   r   r   r|  -  s    $zSubstDirective.add_continuationc                 C   s   | j  dd  dkS r  )r  r@  r,   r   r   r   r}  9  s    z!SubstDirective.needs_continuationc                 C   sn   |   rdS | jdd}t|dkr.td|d  | _|d  | _t	d| jsjtd| j ddS )	z
        If no more line continuations are required, parse all the directive's
        accumulated lines in order to identify the substitution's name and full
        value, and raise an exception if invalid.
        Nrd   rQ   z.Substitution's definition does not contain '='r   z%{[_a-zA-Z][-_:0-9a-zA-Z]*}zSubstitution name 'z' is malformed as it must start with '%{', it must end with '}', and the rest must start with a letter or underscore and contain only alphanumeric characters, hyphens, underscores, and colons)
r}  r  r\  r^   r  r>  r   r  r0  	fullmatch)r   partsr   r   r   r  <  s    zSubstDirective._parse_bodyc              
      sF     rJ d jdd} fddtD }dfdd|D } jr|r|td	 j d
 j d 	  | 
d j|f dS t|dkrtd j d j d 	  | |std j d j d 	  |d  d  jkr0td j d j d 	  d j | 	 j|f|d < dS )zX
        Modify the specified substitution list as specified by this directive.
        z=expected directive continuations to be parsed before applyingr[   \\c                    s"   g | ]\}} j |d  v r|qS r   )r   )r+  r"  substr,   r   r   
<listcomp>j  s   z7SubstDirective.adjust_substitutions.<locals>.<listcomp>r]   c                 3   s   | ]}d  | d  V  qdS )z
Existing pattern: r   Nr   )r+  r"  )rf  r   r   r-  l  s   z6SubstDirective.adjust_substitutions.<locals>.<genexpr>z%Substitution whose pattern contains 'z' is already defined before 'z' directive r   NrQ   z/Multiple substitutions whose patterns contain 'z' are defined before 'zNo substitution for 'z' is defined before 'z.Existing substitution whose pattern contains 'z*' does not have the pattern specified by 'z
Expected pattern: )r}  r  r   re   r   r  r  r   rY  r~  r  r^   )r   rf  Z
value_replexistingZexisting_resr   )r   rf  r   adjust_substitutionsc  sh    




z#SubstDirective.adjust_substitutions)
r   r   r   r!   r   r|  r}  r  r  r  r   r   r  r   r    s   	'r  c           
         s   dd dd } fddfddfd	d
}du rFn|}g }| D ]P}t |trl| qRt |tr~|j}	nt |tsJ |}	||||	 qR|S )a!  
    Apply substitutions to the script.  Allow full regular expression syntax.
    Replace each matching occurrence of regular expression pattern a with
    substitution b in line ln.

    If a substitution expands into another substitution, it is expanded
    recursively until the line has no more expandable substitutions. If
    the line can still can be substituted after being substituted
    `recursion_limit` times, it is an error. If the `recursion_limit` is
    `None` (the default), no recursive substitution is performed at all.
    c                 S   s   t dd| S )Nz%%
#_MARKER_#ru  ra  rD  r   r   r   escapePercents  s    z*applySubstitutions.<locals>.escapePercentsc                 S   s   t dd| S )Nr  %r  r  r   r   r   unescapePercents  s    z,applySubstitutions.<locals>.unescapePercentsc                    sl   |  ddkr| S dd dd dd d	d
  fdd  | dd\}} t| dkshJ |S )N%if r   c                 S   s`   |  dsd | fS | dd  } td| }|s8td| d |  }| | d  } || fS )Nr  r   z%{z$'%{' is missing for %if substitution)r  ru  searchr  r8   end)rD  r1  condr   r   r   tryParseIfCond  s    
zDapplySubstitutions.<locals>.substituteIfElse.<locals>.tryParseIfCondc                 S   s@   t d| }|sd| fS |ds,tdd| | d  fS )Nz^\s*%else\s*(%{)?FrQ   z&'%{' is missing for %else substitutionT)ru  r  r3  r  r  )rD  r1  r   r   r   tryParseElse  s    
zBapplySubstitutions.<locals>.substituteIfElse.<locals>.tryParseElsec                 S   s"   |  drd| dd  fS d| fS )Nz%}Tr\   F)r  r  r   r   r   tryParseEnd  s    
zAapplySubstitutions.<locals>.substituteIfElse.<locals>.tryParseEndc                 S   sD   t |r
dnd| }|s"| dfS |d}| d | | |d  fS )Nz(.*?)(?:%if|%})z(.*?)(?:%if)r]   rQ   )ru  r  r  )rD  isNestedr1  Ztext_endr   r   r   	parseText  s    

z?applySubstitutions.<locals>.substituteIfElse.<locals>.parseTextc           
         s   d}t | r|r"| \}}|r"qΈ| \}} |r| dd\}} | \}} |sZtdd}| \}} |r| dd\}} | \}} |stdt| r||7 }q||7 }q| |\}	} ||	7 }q|| fS )Nr]   Tr  z$'%}' is missing for %if substitutionz&'%}' is missing for %else substitution)r^   r  r	   evaluate)
rD  r  rT   Z	found_end_r  Z	branch_ifZbranch_elseZ
found_elsetext)
conditionsparseRecursiver  r  r  r  r   r   r    s4    

zDapplySubstitutions.<locals>.substituteIfElse.<locals>.parseRecursiveFr  r   )findr^   )rD  rT   )r  )r  r  r  r  r  r   substituteIfElse  s    $z,applySubstitutions.<locals>.substituteIfElsec                    sJ    | } D ]0\}}t r(|dd}t|t| | } q|  S )Nr[   r  )r   r   ru  ra  r   r>  )rD  r   ru   )r  r  rf  r   r   processLine  s    z'applySubstitutions.<locals>.processLinec                    sh   t trdksJ | }d} | }|| krL|k rL|}  | }|d7 }q&|| krdtd|f |S )Nr   rQ   zTRecursive substitution of '%s' did not complete in the provided recursion limit (%s))rL   r   r  )rD  ZorigLineZsteps	processed)r  recursion_limitr   r   processLineToFixedPoint
  s    
z3applySubstitutions.<locals>.processLineToFixedPointN)rL   r  r  r  r   r   r/   )
rK  rf  r  r  r  r  processr   	directiver{  r   )r  r  r  r  r  rf  r   applySubstitutions  s     X

r  c                   @   sH   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zed
d Zedd ZdS )
ParserKinda  
    An enumeration representing the style of an integrated test keyword or
    command.

    TAG: A keyword taking no value. Ex 'END.'
    COMMAND: A keyword taking a list of shell commands. Ex 'RUN:'
    LIST: A keyword taking a comma-separated list of values.
    BOOLEAN_EXPR: A keyword taking a comma-separated list of
        boolean expressions. Ex 'XFAIL:'
    INTEGER: A keyword taking a single integer. Ex 'ALLOW_RETRIES:'
    CUSTOM: A keyword with custom parsing semantics.
    DEFINE: A keyword taking a new lit substitution definition. Ex
        'DEFINE: %{name}=value'
    REDEFINE: A keyword taking a lit substitution redefinition. Ex
        'REDEFINE: %{name}=value'
    r   rQ   r\   ry   r   r         c                 C   sJ   t jdgt jdgt jdgt jdgt jdgt jddgt jdgt jdgi|  S )Nr   r   	r  TAGCOMMANDLISTBOOLEAN_EXPRINTEGERCUSTOMDEFINEREDEFINEr  r   r   r   allowedKeywordSuffixesF  s    
z!ParserKind.allowedKeywordSuffixesc                 C   s8   t jdt jdt jdt jdt jdt jdt jdt jdi|  S )	Nr  r  r  r  r  r  r  r  r  r  r   r   r   r   R  s    zParserKind.strN)r   r   r   r!   r  r  r  r  r  r  r  r  staticmethodr  r   r   r   r   r   r  ,  s   
r  c                   @   s~   e Zd ZdZdddZdd Zdd Zed	d
 Zedd Z	e
dd Zedd Zedd Zedd Ze
dd ZdS )IntegratedTestKeywordParsera	  A parser for LLVM/Clang style integrated test scripts.

    keyword: The keyword to parse for. It must end in either '.' or ':'.
    kind: An value of ParserKind.
    parser: A custom parser. This value may only be specified with
            ParserKind.CUSTOM.
    Nc                    s|  t |}t|dks"|d |vrjt|dkrLtd|t ||d f ntd|t |d|f |d ur|t jkrtd| _| _g  _	| _
| _|t jkr fdd	 _n|t jkrЈ j _n|t jkr j _n|t jkr j _n|t jkr j _nj|t jkr4|d u r,td
| _nD|t jkrP fdd	 _n(|t jkrl fdd	 _ntd| d S )Nr   r   rQ   z*Keyword '%s' of kind '%s' must end in '%s'z2Keyword '%s' of kind '%s' must end in  one of '%s'rV   z;custom parsers can only be specified with ParserKind.CUSTOMc                    s     | || jS r   )_handleCommandrY  rX  r{  r   r,   r   r   rs   ~  s    
z6IntegratedTestKeywordParser.__init__.<locals>.<lambda>z*ParserKind.CUSTOM requires a custom parserc                    s    j | || jddS )NTr  _handleSubstrY  r  r,   r   r   rs     s    
c                    s    j | || jddS )NFr  r  r  r,   r   r   rs     s    
zUnknown kind '%s')r  r  r^   r  r   r   r  rY  kindparsed_linesr  parserr  r  _handleListr  _handleBooleanExprr  _handleSingleIntegerr  
_handleTagr  r  )r   rY  r  r  initial_valueZallowedSuffixesr   r,   r   r   g  sN    











z$IntegratedTestKeywordParser.__init__c              
   C   sn   z*|  j ||fg7  _ | ||| j| _W n> tyh } z&tt|d| j|f  W Y d }~n
d }~0 0 d S )Nz 
in %s directive on test line %d)r  r  r  r  r   rY  )r   rX  r{  r$  r   r   r   	parseLine  s    
z%IntegratedTestKeywordParser.parseLinec                 C   s   | j S r   r  r,   r   r   r   getValue  s    z$IntegratedTestKeywordParser.getValuec                 C   s   |   p|S )z&A helper for parsing TAG type keywordsr>  r  r   r   r   r    s    z&IntegratedTestKeywordParser._handleTagc                    s,   t dt |} fdd}t d||S )Nz	%\(line\)c                    sL   |  ddkr$t t|  d S |  ddkrHt t|  d S d S )NrQ   +r\   -)r3  r   r   )r1  rX  r   r   replace_line_number  s    zOIntegratedTestKeywordParser._substituteLineNumbers.<locals>.replace_line_numberz%\(line *([\+-]) *(\d+)\))r0  ra  r   )rX  r{  r  r   r  r   _substituteLineNumbers  s    z2IntegratedTestKeywordParser._substituteLineNumbersc                 C   sz   |  ||}|r"|d |||sv|du r.g }dj||d}ttd |sTJ ddj||d}|t|||| |S )	z*A helper for parsing COMMAND type keywordsr   Nz%%dbg({keyword} at line {line_number}))rY  rX  $z.kPdbgRegex expected to match actual %dbg usagez{pdbg} {real_command})pdbgZreal_command)r  r|  rE   r0  r1  r2  r/   r  )clsrX  r{  r   rY  r  r   r   r   r    s*    z*IntegratedTestKeywordParser._handleCommandc                 C   s*   |du rg }| dd |dD  |S )zA parser for LIST type keywordsNc                 S   s   g | ]}|  qS r   r  r*  r   r   r   r    rt   z;IntegratedTestKeywordParser._handleList.<locals>.<listcomp>,)rR   r\  r  r   r   r   r    s    z'IntegratedTestKeywordParser._handleListc                 C   sH   |du rg }zt |}W n  ty8   td|Y n0 || |S )z"A parser for INTEGER type keywordsNz;INTEGER parser requires the input to be an integer (got {}))r   r  rE   r/   )rX  r{  r   nr   r   r   r    s    
z0IntegratedTestKeywordParser._handleSingleIntegerc                 C   s   dd | dD }|rJ|d d dkrJ|d dd |d  |d< |d= |du rVg }|| |D ]"}|dkrd|dsdt|g  qd|S )	z'A parser for BOOLEAN_EXPR type keywordsc                 S   s    g | ]}|  d kr|  qS )r]   r  r*  r   r   r   r    rt   zBIntegratedTestKeywordParser._handleBooleanExpr.<locals>.<listcomp>r  r   r[   Nr   *)r\  rR   rR  r	   r  )rX  r{  r   r  r,  r   r   r   r    s    
z.IntegratedTestKeywordParser._handleBooleanExprc                 C   sL   |  ||}|r&|d |||r&|S |du r2g }|t||||| |S )z.A parser for DEFINE and REDEFINE type keywordsr   N)r  r|  r/   r  )r  rX  r{  r   rY  r  r   r   r   r    s    z(IntegratedTestKeywordParser._handleSubst)NN)r   r   r   r!   r   r  r  r  r  r  classmethodr  r  r  r  r  r   r   r   r   r  _  s$   
2

	



r  Tc                 C   s  g }t dtj|dt dtjt dtjt dtjt dtjt dtjt dtj|dt d	tj|dg}d
d |D }|D ]8}t|t st	d|j
|v rt	d|j
 |||j
< qvt| | D ]6\}}}	|| }|||	 |dkr| du r qq|rtdd |D st	d|D ]*}
|
 rt	d|
j
 d|
  q|D ]P}|| }|jtjkrjqL| }|rL|d d dkrLt	dj|dqL|d  }|rt|dkrt	ddd | D S )a~  _parseKeywords

    Scan an LLVM/Clang style integrated test script and extract all the lines
    pertaining to a special parser. This includes 'RUN', 'XFAIL', 'REQUIRES',
    'UNSUPPORTED', 'ALLOW_RETRIES', 'END', 'DEFINE', 'REDEFINE', as well as
    other specified custom parsers.

    Returns a dictionary mapping each custom parser to its value after
    parsing the test.
    RUN:)r  XFAIL:	REQUIRES:UNSUPPORTED:ALLOW_RETRIES:zEND.DEFINE:	REDEFINE:c                 S   s   i | ]}|j |qS r   )rY  r+  r=   r   r   r   
<dictcomp>  rt   z"_parseKeywords.<locals>.<dictcomp>zDAdditional parser must be an instance of IntegratedTestKeywordParserz&Parser for keyword '%s' already existsTc                 s   s   | ]}t |tV  qd S r   )rL   r  )r+  r  r   r   r   r-  -  s   z!_parseKeywords.<locals>.<genexpr>zTest has no 'RUN:' linezTest has unterminated 'z' directive (with '\') r   r[   z.Test has unterminated '{key}' lines (with '\'))rg   rQ   z*Test has more than one ALLOW_RETRIES linesc                 S   s   i | ]}|j | qS r   )rY  r  r  r   r   r   r  L  rt   )r  r  r  r  r  r  r  r  rL   r  rY  rZ  keysr  r  anyr}  r~  r  rE   r^   values)rn  additional_parsersrequire_scriptrK  Zbuiltin_parsersZkeyword_parsersr  rX  Zcommand_typerD  r  rg   Zkpr  allowed_retriesr   r   r   _parseKeywords  sj    








r  c           	   
   C   sZ  zt |  ||}W n8 tyL } z tjtjt|W  Y d}~S d}~0 0 |d pXg }|d |ksjJ |d |kszJ |  j|d pg 7  _|  j	|d pg 7  _	|  j
|d pg 7  _
|d r|d d	 | _|  }| rd
|}tjtjd| S |  }|r*d
|}tjtjd| S |  sVd
| jj}tjtjd| S |S )a  parseIntegratedTestScript - Scan an LLVM/Clang style integrated test
    script and extract the lines to 'RUN' as well as 'XFAIL', 'REQUIRES',
    'UNSUPPORTED' and 'ALLOW_RETRIES' information into the given test.

    If additional parsers are specified then the test is also scanned for the
    keywords they specify and all matches are passed to the custom parser.

    If 'require_script' is False an empty script
    may be returned. This can be used for test formats where the actual script
    is optional or ignored.
    Nr  r  r  r  r  r  r  r   z, z4Test requires the following unavailable features: %sz?Test does not support the following features and/or targets: %szLTest does not require any of the features specified in limit_to_features: %s)r  re  r  r:   r9  r:  Z
UNRESOLVEDr   Zxfailsrequiresunsupportedr  ZgetMissingRequiredFeaturesr   UNSUPPORTEDZgetUnsupportedFeaturesZisWithinFeatureLimitsr6  Zlimit_to_features)	rA  r  r  parsedr$  rK  Zmissing_required_featuresrJ  Zunsupported_featuresr   r   r   parseIntegratedTestScriptO  sN    
*




r  c                    s   fdd}t jtj tj }jd }t|D ]>}||}	t	|	t j
jrl|	  S |	\}
}}}}|t
jkrJ qqJ|dkr|t
jkrt
j}dd|f }|d ur|d|f 7 }|d7 }|
r|d|
f 7 }|r|d	|f 7 }t j
||S )
Nc                    sx   rt  | }nt | }t|tjjr8|S |\}}}}|dkrTtj}n|d u rdtj}ntj}|||||fS r-   )	rL  rE  rL   r:   r9  r:  PASSr;  TIMEOUT)r]  r!  r%  r   rA   rJ   statusrB  rK  rA  rC  useExternalShr   r   runOnce  s    z_runShTest.<locals>.runOncerQ   r   zScript:
--
%s
--
Exit Code: %d
r   zTimeout: %s
z"Command Output (stdout):
--
%s
--
z"Command Output (stderr):
--
%s
--
)r:   r;   r   r   r   r  r[  r  r   rL   r9  r:  r;  r  Z	FLAKYPASSr   )rA  rB  r  rK  rC  r  r]  attemptsr"  r!  r%  r   rA   rJ   r  r   r   r  r   
_runShTest  s0    


r  c                 C   s   | j jrtjtjdS t|}t| | d}t|tjjr@|S ||7 }|j	r\tjtj
S t| \}}t|}	|	t| |||d7 }	dd | j jD }
t||	|
| j jd}t| ||||S )NzTest is unsupported)r  )rm  c                 S   s   i | ]
}|d qS )Tr   )r+  featurer   r   r   r    rt   z!executeShTest.<locals>.<dictcomp>)r  )r6  r  r:   r9  r:  r  rB   r  rL   Z	noExecuter  r_  rp  Zavailable_featuresr  ZrecursiveExpansionLimitr  )rA  rB  r  Zextra_substitutionsZpreamble_commandsrK  r  r^  rC  rf  r  r   r   r   executeShTest  s&    
r  )r   )F)N
__future__r   errnoio	itertoolsr   r   r  r   r{   r0  r   ri  r   r   r   r4   r   ImportErrorZlit.ShCommandsr   r   Z
lit.ShUtilr  Zlit.Testr9  Zlit.utilr:   r   r   r   Zlit.BooleanExpressionr	   	Exceptionr
   r   r   r  r   r   r2  objectr   r"   r>   rK   rP   rU   rc   rj   rl   rm   ro   rp   r   r   r   r   r   rD   rE  rL  rZ  r_  rb  rp  rt  ru  rv  r  r  r  r  r  r  r  r  r  r   r   r   r   <module>   s    L
B
	>$a]  >NB8	
E
6v
 "3 
R
79