3
!a_%                 @   s   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 ej	dZ
ej	dZG dd deZG dd	 d	eZd
d Zdd Zdd Zdd Zdd Zdd ZG dd dejZedkree dS )    N)PATCHES_DIR)HEADERSz(?:['\"])?([\w]+)z\s*#\s*define\s*([\w]+)c               @   s   e Zd ZdS )DirtyGitErrorN)__name__
__module____qualname__ r   r   H/home/aniruddha/Desktop/UnitTestSetup/test/cbmc/patches/compute_patch.pyr   (   s   r   c               @   s   e Zd ZdS )PatchCreationErrorN)r   r   r   r   r   r   r	   r
   +   s   r
   c               C   s
   t jdS )Nz        This script generates patch files for the header files used
        in the cbmc proof. These patches permit setting values of preprocessor
        macros as part of the proof configuration.
    )textwrapdedentr   r   r   r	   prolog.   s    r   c              C   s   t  } tjjtjjtdd}xtj|D ]\}}}d|krPtjj|d}d}nd|kr*tjj|d}d}nq*t|d`}djd	d
 |D }tj	|}	||	j
 krx.|	| D ]"}
tj|
}|r| j|jd qW W dQ R X q*W | S )zCollects all define values in Makefile.json.

       Some of the Makefiles use # in the json to make comments.
       As this is non standard json, we need to remove the comment
       lines before parsing. Then we extract all defines from the file.
    z..ZproofszMakefile.jsonDEFzMakefileCommon.jsonzDEF r c             S   s$   g | ]}|r|j  jd  r|qS )#)strip
startswith).0liner   r   r	   
<listcomp>K   s    z$find_all_defines.<locals>.<listcomp>   N)setospathabspathjoinr   walkopenjsonloadskeysDEFINE_REGEX_MAKEFILEmatchaddgroup)definesZ	proof_dirfldr_fylesfilekeysourcecontentmakefiledefineZmatchedr   r   r	   find_all_defines6   s&    

"r0   c       	      C   s   d}t |d}d}x|D ]}tj|}|r|jd| kr|j jd r|}x"|j jdrpt|}||7 }qPW |t	j
dj|jd|d7 }n||7 }|}qW W dQ R X t |d	}|j| W dQ R X dS )
z$Wraps all defines used in an ifndef.r   r   r   z#ifndef\zv                    #ifndef {target}
                        {original}                    #endif
                    )targetZoriginalNw)r   DEFINE_REGEX_HEADERr#   r%   lstripr   rstripendswithnextr   r   formatwrite)	r&   header_fileZmodified_contentr,   lastr   r#   Zfull_defoutputr   r   r	   manipulate_headerfileY   s$    

r>   c             C   s   t jddgt jt jdd}t jddgt jt jdd}|jrTttjdj|j|j	|jrtttjdj|j|j	x&| D ]}t
jj|d |jkrzdS qzW d	S )
z6Check that the header_file is not previously modified.gitstatusT)stdoutstderruniversal_newlinesz
diff-filesz`                Could not run git status. Exited: {}
                stderr: {}
                zd                Could not run git diff-files. Exited: {}
                stderr: {}
                
F)
subprocessrunDEVNULLPIPE
returncoder   r   r   r9   rB   r   r   basenamerA   )Zheader_filesr@   Z
diff_stater;   r   r   r	   header_dirtyw   s    
rK   c          	   C   s   t | | tjdd|gtjtjdd}tjddd|gtjtjdd}|jrdttjdj	|j|j
|jrttjdj	|j||j
|jtjd	}d
| d }tjjt|}|jrt|d}|j|j W dQ R X dS )zDComputes a patch enclosing defines used in CBMC proofs with #ifndef.r?   ZdiffT)rA   rB   rC   Zcheckoutz--z_                git diff exited with error code: {}
                stderr: {}
                z                git checkout for cleaning files failed with error code: {}
                on file {}
                stderr: {}
                r(   Zauto_patch_z.patchr3   N)r>   rE   rF   rH   rG   rI   r
   r   r   r9   rB   r   replacer   sepr   r   r   rA   r   r:   )r&   r;   patchcleanedZheader_path_partZ	path_nameZ
patch_filer   r   r	   create_patch   s&    
rP   c             C   s:   t  }t| s(x&| D ]}t|| qW nttjdd S )Nz                It seems like one of the header files is in dirty state.
                This script cannot patch files in dirty state.
                )r0   rK   rP   r   r   r   )headersr&   headerr   r   r	   create_patches   s    
rS   c               @   s   e Zd Zdd Zdd ZdS )TestDefineRegexesc             C   s   d}d}d}d}d}t j|}t j|}t j|}t j|}	t j|}
| j| | j| | j| | j|	 | j|
 | j|jdd | j|jdd | j|jdd | j|	jdd | j|
jdd d S )	Nz<ipconfigETHERNET_MINIMUM_PACKET_BYTES={MINIMUM_PACKET_BYTES}z(ipconfigETHERNET_MINIMUM_PACKET_BYTES=50z2'configASSERT(X)=__CPROVER_assert(x, "must hold")'z3"configASSERT (X)=__CPROVER_assert(x, "must hold")"z/configASSERT(X)=__CPROVER_assert(x,"must hold")r   Z%ipconfigETHERNET_MINIMUM_PACKET_BYTESconfigASSERT)r"   r#   assertIsNotNoneassertEqualr%   )selfinput1input2input3Zinput4Zinput5match1match2match3Zmatch4Zmatch5r   r   r	   test_makefile_regex   s,    









z%TestDefineRegexes.test_makefile_regexc             C   s   d	}d}d}t j|}t j|}t j|}| j| | j| | j| | j|jdd | j|jdd | j|jdd d S )
Nz-#define configASSERT( x )    if( ( x ) == 0 )z#vAssertCalled( __FILE__, __LINE__ )z7#define ipconfigMAX_ARP_RETRANSMISSIONS           ( 5 )z3#define ipconfigINCLUDE_FULL_INET_ADDR            1r   rU   ZipconfigMAX_ARP_RETRANSMISSIONSZipconfigINCLUDE_FULL_INET_ADDRzP#define configASSERT( x )    if( ( x ) == 0 )vAssertCalled( __FILE__, __LINE__ ))r4   r#   rV   rW   r%   )rX   rY   rZ   r[   r\   r]   r^   r   r   r	   test_header_regex   s     





z#TestDefineRegexes.test_header_regexN)r   r   r   r_   r`   r   r   r   r	   rT      s   rT   __main__)r   r   rerE   r   Zunittestpatches_constantsr   r   compiler"   r4   	Exceptionr   r
   r   r0   r>   rK   rP   rS   ZTestCaserT   r   r   r   r   r	   <module>   s(   

#/