3
!a_e9                 @   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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ye W n ek
r   eZY nX ej jdZed  dkreed dkrejZnejZdd Zdd	 Zd
d Zd;ddZdd Zddddddddde	jddddddZeed Zded< eed< d d! Z d"d#gd$eee  ej!d%j"d&d'j#e d(d)d*d+gd,d-d.d/d0gd1d-d.gZ$d2d3 Z%d4d5 Z&d6d7 Z'd8d9 Z(e)d:kre(  dS )<    N.3      c               C   s
   t jdS )Na
          This script generates Makefiles that can be used either on Windows (with
        NMake) or Linux (with GNU Make). The Makefiles consist only of variable
        definitions; they are intended to be used with a common Makefile that
        defines the actual rules.

        The Makefiles are generated from JSON specifications. These are simple
        key-value dicts, but can contain variables and computation, as
        well as comments (lines whose first character is "#"). If the
        JSON file contains the following information:

                {
                    # 'T was brillig, and the slithy toves
                    "FOO": "BAR",
                    "BAZ": "{FOO}",

                    # Did gyre and gimble in the wabe;
                    "QUUX": 30
                    "XYZZY": "__eval 5 if {QUUZ} < 5 else min({QUUX}, 60)"
                }

        then the resulting Makefile will look like

                H_FOO = BAR
                H_BAZ = BAR
                H_QUUX = 30
                H_XYZZY = 30

        The language used for evaluation is highly restricted; arbitrary
        python is not allowed.  JSON values that are lists will be
        joined with whitespace:

                { "FOO": ["BAR", "BAZ", "QUX"] }

                ->

                H_FOO = BAR BAZ QUX

        As a special case, if a key is equal to "DEF", "INC" (and maybe more,
        read the code) the list of values is treated as a list of defines or
        include paths. Thus, they have -D or /D, or -I or /I, prepended to them
        as appropriate for the platform.


                { "DEF": ["DEBUG", "FOO=BAR"] }

                on Linux ->

                H_DEF = -DDEBUG -DFOO=BAR

        Pathnames are written with a forward slash in the JSON file. In
        each value, all slashes are replaced with backslashes if
        generating Makefiles for Windows. If you wish to generate a
        slash even on Windows, use two slashes---that will be changed
        into a single forward slash on both Windows and Linux.

                {
                    "INC": [ "my/cool/directory" ],
                    "DEF": [ "HALF=//2" ]
                }

                On Windows ->

                H_INC = /Imy\cool\directory
                H_DEF = /DHALF=/2

        When invoked, this script walks the directory tree looking for files
        called "Makefile.json". It reads that file and dumps a Makefile in that
        same directory. We assume that this script lives in the same directory
        as a Makefile called "Makefile.common", which contains the actual Make
        rules. The final line of each of the generated Makefiles will be an
        include statement, including Makefile.common.
    )textwrapdedent r   r   N/home/aniruddha/Desktop/UnitTestSetup/test/cbmc/proofs/make_proof_makefiles.pyprolog<   s    Hr
   c             C   s   t | }|j j }W d Q R X djdd |D }ytj|tjd}W n6 tjj	k
r~   t
j  tjd|  tjd Y nX |S )N
c             S   s$   g | ]}|r|j  jd  r|qS )#)lstrip
startswith).0liner   r   r	   
<listcomp>   s    z)load_json_config_file.<locals>.<listcomp>)object_pairs_hookzparsing file %sr   )openread
splitlinesjoinjsonloadscollectionsOrderedDictdecoderJSONDecodeError	traceback	print_excloggingerrorsysexit)filehandlelinesZno_commentsdatar   r   r	   load_json_config_file   s    
r'   c             C   s  t tjj| d}tj }d|kr8tjd|   td djdd |d D |d< tj }xl|j	 D ]`\}}t
|trg }x$|D ]}|jt||||| d	 qW dj|||< qft||||| ||< qfW d
|j kst|d
 j dkrd|d
< nt|d
 j dkrd|d
< dd |j	 D }dt| d  }	|	t| jtjjdd   }	ttjj| dd*}
|
jdjdj|t| d |	d W d Q R X d S )NzMakefile.jsonZOBJSz3Expected a list of object files in %s/Makefile.jsonr    c             s   s   | ]}|j d s|V  qdS )z_harness.gotoN)endswith)r   or   r   r	   	<genexpr>   s    z dump_makefile.<locals>.<genexpr>ZOBJS_EXCEPT_HARNESSTEXPECTEDtrueZ
SUCCESSFULfalseFAILUREc             S   s   g | ]\}}d ||f qS )z	H_%s = %sr   )r   kvr   r   r	   r      s    z!dump_makefile.<locals>.<listcomp>z..%szpath-sepMakefilewz6{contents}

{include} {common_dir_path}Makefile.commonr   zmakefile-inc)contentsincludecommon_dir_path)r'   ospathr   r   r   r   r    r"   items
isinstancelistappendcomputekeysstrlower_platform_choiceslensplitsepr   writeformat)Zdyrsystemr&   makefileso_farnamevalueZ	new_valueitemr6   r$   r   r   r	   dump_makefile   s<    




rM   Fc             C   s  t | tttfsDtjtdtjj	|d|t
| t
t|  td t
| } y| jf |}W nN tk
r } z2tjtdtjj	|d|| t
| td W Y d d }~X nX |d td dkrtjdd|}tjdt| d	 |}tjdd|}	n8|tdd  j }
tjd
|
 t|
tjj	|d|| }	|dkrLdt| d |	f }n$|dkrldt| d |	f }n|	}|ryd|| |f ||< W n tk
r   |||< Y nX tjd|| n|||< tjd|| |S )Nzx                        in file %s, the key '%s' has value '%s',
                        which is of the wrong type (%s)zMakefile.jsonr   z                        in file %s, the key '%s' has value '%s', which
                        contains the variable %s, but that variable has
                        not previously been set in the fileZ__evalz//Z__DOUBLE_SLASH__/zpath-sep-rezAbout to evaluate '%s'DEFz%s%sdefineINCr5   z%s %sz&Appending final value '%s' to key '%s'z Key '%s' set to final value '%s')r:   
basestringfloatintr   r    wrapr7   r8   r   r?   typer"   rF   KeyErrorrB   resubrA   stripdebug	eval_exprinfo)rK   rI   rG   keyharnessZ	appendingZ
var_subbedeZtmpZ	evaluatedZto_evalZfinal_valuer   r   r	   r=      sR    




r=   c                sh   yt j| ddj}W n: tk
rN   tj  tjtd||  t	d Y nX  fdd  |S )z:
    Safe evaluation of purely arithmetic expressions
    eval)modezw            in file %s at key '%s', value '%s' contained the expression
            '%s' which is an invalid expressionr   c                s  t j|  t| tr| jS t| tjrr | j}|dk	rZ|dk	rZt jt	d t
d |rh | jS  | jS t| tjr | j} | jd } | jd }|||S t| tjr | j} | j} | j}|||S t| tjrVttd}| jj|kr(t jt	d| jj t
d  | jd } | jd }|| jj ||S y\tjtjtjtjtjtj tj!tj"tj#tj$tj%tj&tj'tj(tj)tj*tj+tj,tj-tj.i
t/|  S  t0k
r   t jt	d t
d Y nX d S )	NTFzo                    in file %s at key '%s', there was an invalid guard
                    for an if statement.r   r   )maxminza                    in file %s at key '%s', there was an invalid
                    call to %s()zl                in file %s at key '%s', there was expression that
                was impossible to evaluate)1r   r[   r:   ast_numnastZIfExpZtestr    rU   r"   bodyZorelseZCompareleftZcomparatorsZopsZBinOprightopZCallrc   rd   funcidargsZEqoperatoreqZNotEqneZLtltZLtEleZGtgtZGtEgeZAddaddZSubrY   ZMultmulZDivfloordivrV   rW   )ZnodeZguardri   rj   rk   Zvalid_calls)eval_single_noder_   r^   r   r	   ry   	  s`    












z#eval_expr.<locals>.eval_single_node)
rg   parserh   SyntaxErrorr   r   r   r    rU   r"   )Zexpr_stringr_   r^   rK   Ztreer   )ry   r_   r^   r	   r\      s    ?r\   linuxrN   z-Dz-Ir5   )platformzpath-sepzpath-sep-rerP   r5   zmakefile-incwin32\z/Dz/Iz!INCLUDE)r|   windowsdarwinr}   macosc              C   s,   x&t j D ]\} }tj|d kr
| S q
W dS )Nr}   r|   )rA   r9   r!   r}   )
arg_stringZos_datar   r   r	   default_platformc  s    r   z-sz--systemOSz                which operating system to generate makefiles for.
                Defaults to the current platform (%(default)s);
                choices are {choices}z[%s]z, )choices)flagsmetavarr   defaulthelpz-vz	--verbosezverbose output
store_true)r   r   actionz-wz--very-verbosezvery verbose outputc              C   s>   t jt t jd} x"tD ]}|jd}| j|| qW | j S )N)descriptionformatter_classr   )argparseArgumentParserr
   RawDescriptionHelpFormatter_argspopadd_argument
parse_args)Zparsargr   r   r   r	   get_args  s    


r   c             C   sX   dj tjjtd}| jr,tj|tjd n(| j	rDtj|tj
d ntj|tjd d S )Nz#{script}: %(levelname)s %(message)s)script)rF   level)rF   r7   r8   basename__file__Zvery_verboser   basicConfigDEBUGverboseINFOWARNING)rn   fmtr   r   r	   set_up_logging  s    r   c             C   s   t jddt jdd| S )Nz\s+r(   r   )rX   rY   )stringr   r   r	   rU     s    rU   c              C   s@   t  } t|  x,tjdD ]\}}}d|krt|| j qW d S )Nr   zMakefile.json)r   r   r7   walkrM   rG   )rn   root_fylesr   r   r	   main  s
    r   __main__)F)*r   rg   r   r   r   ro   r7   Zos.pathr}   rX   r!   r   r   rR   	NameErrorr?   Zpython_versionrC   Z_platrT   ZConstantre   ZNumr
   r'   rM   r=   r\   escaperA   dictZ_mac_osr   r   rF   r   r   r   r   rU   r   __name__r   r   r   r	   <module>   sx   
K-
8R


	
