B
    ›³ëbM9  ã               @   s   d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 dd„ Zdej_eej_g ai aejadag add	„ Zd
d„ Zdd„ ZejjZdd„ ZG dd„ dƒZG dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZeaddd„Z dS )z4Operations on signature database files (.sconsign). é    N)ÚPICKLE_PROTOCOL)Ú
print_timec             C   s   t j t jjd|  ¡ d S )Nz#Ignoring corrupt .sconsign file: %s)ÚSConsÚWarningsÚwarnÚCorruptSConsignWarning)Úfilename© r	   ú-lib/python3.7/site-packages/SCons/SConsign.pyÚcorrupt_dblite_warning&   s    r   Tc              C   s4   t j ¡ } t j ¡ }| d kr(|dkr(dS d| S d S )NZmd5z	.sconsignz
.sconsign_)r   ZUtilZget_hash_formatZget_current_hash_algorithm_used)Zhash_formatZcurrent_hash_algorithmr	   r	   r
   Úcurrent_sconsign_filename=   s
    

r   c             C   s2  t d krtƒ a | jj}tj t ¡sÈ|jrÈd}xš|g|j D ]Š}|  |¡rÀyt	| |fS  t
k
r¾   | t ¡}yt ||¡ }t	|< W n ttfk
rž   Y nX |dkr²t |¡ ||fS Y nX d}q:W yt	| dfS  t
k
r   t t d¡ }t	|< t |¡ |dfS  tk
r,   tdt	ƒ ‚ Y nX d S )NÚcÚrz
DataBase =)ÚDB_Namer   ZfsZTopÚosÚpathÚisabsZrepositoriesZis_underÚDataBaseÚKeyErrorZentry_abspathÚ	DB_ModuleÚopenÚIOErrorÚOSErrorÚDB_sync_listÚappendÚ	TypeErrorÚprint)ÚdirÚtopÚmodeÚdr   Údbr	   r	   r
   ÚGet_DataBaseK   s8    

 


r"   c               C   s   g a g adS )zyReset global state.  Used by unit tests that end up using
    SConsign multiple times to get a clean slate for each test.N)Ú	sig_filesr   r	   r	   r	   r
   ÚResetm   s    r$   c           	   C   s¤   t ƒ rt ¡ } xtD ]}|jdd qW xXtD ]P}y
|j}W n tk
rP   Y nX |ƒ  y
|j}W n tk
rv   Y q.X |ƒ  q.W t ƒ r t ¡ |  }t	d| ƒ d S )Nr   )Úsyncz$Total SConsign sync time: %f seconds)
r   ÚtimeZperf_counterr#   Úwriter   r%   ÚAttributeErrorÚcloser   )Z
start_timeZsig_filer!   Ú
syncmethodZclosemethodÚelapsedr	   r	   r
   r'   w   s$    




r'   c               @   s@   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dS )ÚSConsignEntrya  
    Wrapper class for the generic entry in a .sconsign file.
    The Node subclass populates it with attributes as it pleases.

    XXX As coded below, we do expect a '.binfo' attribute to be added,
    but we'll probably generalize this in the next refactorings.
    )ÚbinfoÚninfoÚ__weakref__é   c             C   s   d S )Nr	   )Úselfr	   r	   r
   Ú__init__   s    zSConsignEntry.__init__c             C   s   | j  ¡  d S )N)r-   Úconvert_to_sconsign)r1   r	   r	   r
   r3   £   s    z!SConsignEntry.convert_to_sconsignc             C   s   | j  ||¡ d S )N)r-   Úconvert_from_sconsign)r1   r   Únamer	   r	   r
   r4   ¦   s    z#SConsignEntry.convert_from_sconsignc             C   s‚   t | di ƒ ¡ }xBt| ƒ ¡ D ]2}x,t |ddƒD ]}t| |ƒr0t | |ƒ||< q0W qW | j|d< y
|d= W n tk
r|   Y nX |S )NÚ__dict__Ú	__slots__r	   Ú_version_idr/   )ÚgetattrÚcopyÚtypeÚmroÚhasattrÚcurrent_version_idr   )r1   ÚstateÚobjr5   r	   r	   r
   Ú__getstate__©   s    


zSConsignEntry.__getstate__c             C   s.   x(|  ¡ D ]\}}|dkr
t| ||ƒ q
W d S )N)r8   r/   )ÚitemsÚsetattr)r1   r?   ÚkeyÚvaluer	   r	   r
   Ú__setstate__·   s    zSConsignEntry.__setstate__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r7   r>   r2   r3   r4   rA   rF   r	   r	   r	   r
   r,   ’   s   r,   c               @   sH   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S )ÚBasea  
    This is the controlling class for the signatures for the collection of
    entries associated with a specific directory.  The actual directory
    association will be maintained by a subclass that is specific to
    the underlying storage method.  This class provides a common set of
    methods for fetching and storing the individual bits of information
    that make up signature entry.
    c             C   s   i | _ d| _i | _d S )NF)ÚentriesÚdirtyÚto_be_merged)r1   r	   r	   r
   r2   Æ   s    zBase.__init__c             C   s
   | j | S )z6
        Fetch the specified entry attribute.
        )rL   )r1   r   r	   r	   r
   Ú	get_entryË   s    zBase.get_entryc             C   s   || j |< d| _dS )z 
        Set the entry.
        TN)rL   rM   )r1   r   r@   r	   r	   r
   Ú	set_entryÑ   s    
zBase.set_entryc             C   s   d S )Nr	   )r1   r   r@   r	   r	   r
   Údo_not_set_entryØ   s    zBase.do_not_set_entryc             C   s,   |  ¡ }|j | ¡ ¡ || j|< d| _d S )NT)Úget_stored_infor-   ÚmergeZ	get_binforN   rM   )r1   r   ÚnodeÚentryr	   r	   r
   Ú
store_infoÛ   s    
zBase.store_infoc             C   s   d S )Nr	   )r1   r   rT   r	   r	   r
   Údo_not_store_infoá   s    zBase.do_not_store_infoc          	   C   sb   xV| j  ¡ D ]H\}}| ¡ }y
|j}W n tk
r:   Y nX | | ¡ ¡ || j|< qW i | _ d S )N)rN   rB   rR   r.   r(   rS   Z	get_ninforL   )r1   rD   rT   rU   r.   r	   r	   r
   rS   ä   s    
z
Base.mergeN)rG   rH   rI   rJ   r2   rO   rP   rQ   rV   rW   rS   r	   r	   r	   r
   rK   ½   s   rK   c                   s*   e Zd ZdZ‡ fdd„Zddd„Z‡  ZS )ÚDBz¬
    A Base subclass that reads and writes signature information
    from a global .sconsign.db* file--the actual file suffix is
    determined by the database module.
    c       	   
      s  t ƒ  ¡  || _t|ƒ\}}t| ¡ ƒ}y|| }W n tk
rH   Y n¤X y&t |¡| _	t
| j	tƒsni | _	t‚W nV tk
r†   ‚ Y nB tk
rÆ } z$tj tjjd| j ¡ |f ¡ W d d }~X Y nX x"| j	 ¡ D ]\}}| ||¡ qÔW |dkr| j| _| j| _t | ¡ d S )Nz*Ignoring corrupt sconsign entry : %s (%s)
r   )Úsuperr2   r   r"   ÚnormcaseZ	get_tpathr   ÚpickleÚloadsrL   Ú
isinstanceÚdictr   ÚKeyboardInterruptÚ	Exceptionr   r   r   r   rB   r4   rQ   rP   rW   rV   r#   r   )	r1   r   r!   r   r   Z
rawentriesÚerD   rU   )Ú	__class__r	   r
   r2   ú   s0    
&
zDB.__init__é   c             C   sŽ   | j s
d S |  ¡  t| jƒ\}}t| j ¡ ƒ}x| j ¡ D ]\}}| ¡  q:W t	 
| jt¡||< |rŠy
|j}W n tk
r‚   Y nX |ƒ  d S )N)rM   rS   r"   r   rZ   Úget_internal_pathrL   rB   r3   r[   Údumpsr   r%   r(   )r1   r%   r!   r   r   rD   rU   r*   r	   r	   r
   r'   "  s    
zDB.write)rc   )rG   rH   rI   rJ   r2   r'   Ú__classcell__r	   r	   )rb   r
   rX   ô   s   (rX   c                   s   e Zd Zd‡ fdd„	Z‡  ZS )ÚDirNc                s`   t ƒ  ¡  |sdS t |¡| _t| jtƒs4i | _t‚|r\x"| j ¡ D ]\}}| 	||¡ qDW dS )z8
        fp - file pointer to read entries from
        N)
rY   r2   r[   ÚloadrL   r]   r^   r   rB   r4   )r1   Úfpr   rD   rU   )rb   r	   r
   r2   >  s    
zDir.__init__)NN)rG   rH   rI   r2   rf   r	   r	   )rb   r
   rg   =  s   rg   c                   s*   e Zd ZdZ‡ fdd„Zddd„Z‡  ZS )ÚDirFilezJ
    Encapsulates reading and writing a per-directory .sconsign file.
    c                sÊ   || _ tj | ¡ tƒ ¡| _yt| jdƒ}W n tk
rD   d}Y nX yt	ƒ  
||¡ W n@ tk
rn   ‚ Y n, tk
r˜   tj tjjd| j ¡ Y nX y| ¡  W n tk
rº   Y nX t | ¡ dS )z2
        dir - the directory for the file
        ÚrbNz#Ignoring corrupt .sconsign file: %s)r   r   r   Újoinrd   r   Úsconsignr   r   rY   r2   r_   r`   r   r   r   r   r)   r(   r#   r   )r1   r   ri   )rb   r	   r
   r2   U  s$    
zDirFile.__init__rc   c       
      C   s²  | j s
dS |  ¡  tj | j ¡ dt ¡  ¡}yt|dƒ}|}W n@ t	k
r€   yt| j
dƒ}| j
}W n t	k
rz   dS X Y nX x| j ¡ D ]\}}| ¡  qŽW t | j|t¡ | ¡  || j
kr„y.t | j
¡d }t | j
d¡ t | j
¡ W n t	tfk
r   Y nX yt || j
¡ W n` tk
r‚   t| j
dƒ*}t|dƒ}	| |	 ¡ ¡ W dQ R X W dQ R X t | j
|¡ Y nX yt |¡ W n t	tfk
r¬   Y nX dS )a)  
        Write the .sconsign file to disk.

        Try to write to a temporary file first, and rename it if we
        succeed.  If we can't write to the temporary file, it's
        probably because the directory isn't writable (and if so,
        how did we build anything in this directory, anyway?), so
        try to write directly to the .sconsign file as a backup.
        If we can't rename, try to copy the temporary contents back
        to the .sconsign file.  Either way, always try to remove
        the temporary file at the end.
        Nz.scons%dÚwbr   i¶  rk   )rM   rS   r   r   rl   r   rd   Úgetpidr   r   rm   rL   rB   r3   r[   Údumpr   r)   ÚstatÚchmodÚunlinkr   Úrenamer'   Úread)
r1   r%   ZtempÚfileÚfnamerD   rU   r   ÚfÚf2r	   r	   r
   r'   r  sD    

"zDirFile.write)rc   )rG   rH   rI   rJ   r2   r'   rf   r	   r	   )rb   r
   rj   Q  s   rj   c             C   s*   | dkrt adanta| a|dk	r&|adS )zU
    Arrange for all signatures to be stored in a global .sconsign.db*
    file.
    N)rj   ÚForDirectoryr   rX   r   )r5   Z
dbm_moduler	   r	   r
   ÚFile²  s    r{   )N)!rJ   ZSCons.compatr   r   r[   r&   ZSCons.dbliteZSCons.Warningsr   Z
SCons.Utilr   r   ZdbliteZIGNORE_CORRUPT_DBFILESZcorruption_warningr#   r   r   r   r   r   r"   r$   r   rZ   r'   r,   rK   rX   rg   rj   rz   r{   r	   r	   r	   r
   Ú<module>   s8   "+7I^