3333import os
3434import shutil
3535
36- from typing import List , Optional , TYPE_CHECKING
36+ from typing import List , Optional , Tuple , TYPE_CHECKING
3737
3838from chc .util .Config import Config
3939import chc .util .fileutil as UF
@@ -55,7 +55,7 @@ def __init__(
5555 unreachability : bool = False ,
5656 thirdpartysummaries : List [str ] = [],
5757 nofilter : bool = True ,
58- verbose : bool = True ,
58+ verbose : bool = False ,
5959 ) -> None :
6060 """Initialize the analyzer location and target file location.
6161
@@ -90,7 +90,7 @@ def capp(self) -> "CApplication":
9090
9191 @property
9292 def contractpath (self ) -> Optional [str ]:
93- return None
93+ return self . capp . contractpath
9494
9595 @property
9696 def config (self ) -> Config :
@@ -112,51 +112,59 @@ def projectpath(self) -> str:
112112 def targetpath (self ) -> str :
113113 return self .capp .targetpath
114114
115+ @property
116+ def projectname (self ) -> str :
117+ return self .capp .projectname
118+
115119 def reset (self ) -> None :
116120 """Remove all file- and function-level files produced by the analysis."""
117121
118122 def remove (f : str ) -> None :
119123 if os .path .isfile (f ):
120124 os .remove (f )
121125
122- def g (fi : "CFile" ) -> None :
123- cfiledir = UF .get_cfile_directory (self .path , fi .name )
124- if os .path .isdir (cfiledir ):
125- for f in os .listdir (cfiledir ):
126- if len (f ) > 10 and (
127- f [- 8 :- 4 ] in ["_api" , "_ppo" , "_spo" , "_pod" ]
128- or f [- 9 :- 4 ] in ["_invs" , "_vars" ]
129- ):
130- os .remove (os .path .join (cfiledir , f ))
131- remove (UF .get_cfile_predicate_dictionaryname (self .capp .path , fi .name ))
132- remove (UF .get_cfile_interface_dictionaryname (self .capp .path , fi .name ))
133- remove (UF .get_cfile_assignment_dictionaryname (self .capp .path , fi .name ))
134- remove (UF .get_cxreffile_filename (self .capp .path , fi .name ))
135- remove (UF .get_cfile_contexttablename (self .capp .path , fi .name ))
136-
137- self .capp .iter_files (g )
138- remove (UF .get_global_definitions_filename (self .capp .path ))
126+ for fi in self .capp .cfiles :
127+ for fn in fi .get_functions ():
128+ fnargs : Tuple [str , str , Optional [str ], str , str ] = (
129+ fn .targetpath , fn .projectname , fn .cfilepath , fn .cfilename , fn .name )
130+ remove (UF .get_api_filename (* fnargs ))
131+ remove (UF .get_ppo_filename (* fnargs ))
132+ remove (UF .get_spo_filename (* fnargs ))
133+ remove (UF .get_pod_filename (* fnargs ))
134+ remove (UF .get_invs_filename (* fnargs ))
135+ remove (UF .get_vars_filename (* fnargs ))
136+ fiargs : Tuple [str , str , Optional [str ], str ] = (
137+ fi .targetpath , fi .projectname , fi .cfilepath , fi .cfilename )
138+ remove (UF .get_cfile_contexttablename (* fiargs ))
139+ remove (UF .get_cfile_predicate_dictionaryname (* fiargs ))
140+ remove (UF .get_cfile_interface_dictionaryname (* fiargs ))
141+ remove (UF .get_cfile_assignment_dictionaryname (* fiargs ))
142+ remove (UF .get_cxreffile_filename (* fiargs ))
143+
144+ remove (UF .get_global_definitions_filename (
145+ self .capp .targetpath , self .capp .projectname ))
139146
140147 def reset_logfiles (self ) -> None :
141148 """Remove all log files from semantics directory."""
142149
143- def g (fi : "CFile" ) -> None :
144- logfiledir = UF .get_cfile_logfiles_directory (self .path , fi .name )
145- if os .path .isdir (logfiledir ):
146- for f in os .listdir (logfiledir ):
147- if (
148- f .endswith ("chlog" )
149- or f .endswith ("infolog" )
150- or f .endswith ("errorlog" )
151- ):
152- os .remove (os .path .join (logfiledir , f ))
150+ def remove (f : str ) -> None :
151+ if os .path .isfile (f ):
152+ os .remove (f )
153153
154- self .capp .iter_files (g )
154+ for fi in self .capp .cfiles :
155+ fiargs : Tuple [str , str , Optional [str ], str ] = (
156+ fi .targetpath , fi .projectname , fi .cfilepath , fi .cfilename )
157+ for kind in [
158+ "gencheck.chlog" , "gencheck.infolog" , "gencheck.errorlog" ,
159+ "primary.chlog" , "primary.infolog" , "primary.errorlog" ]:
160+ fkargs = fiargs + (kind , )
161+ remove (UF .get_cfile_logfile_name (* fkargs ))
155162
156- def reset_tables (self , cfilename : str ) -> None :
163+ def reset_tables (self , cfile : "CFile" ) -> None :
157164 """Reload dictionaries from file (to get updated data from analyzer)."""
158165
159- cfile = self .capp .get_file (cfilename )
166+ cfilename = cfile .name
167+ chklogger .logger .debug ("Reset tables for %s" , cfilename )
160168 cfile .reinitialize_tables ()
161169 cfile .reload_ppos ()
162170 cfile .reload_spos ()
@@ -189,64 +197,30 @@ def _create_file_primary_proofobligations_cmd_partial(self) -> List[str]:
189197 cmd .append ("-cfilename" )
190198 return cmd
191199
192- def rungui (self , name : str , outputpath : Optional [str ] = None ) -> None :
193- semdir = os .path .dirname (self .path )
194- analysisdir = os .path .dirname (semdir )
195- if outputpath is None :
196- outputpath = analysisdir
197- if self .gui is None :
198- print ("Gui has not been configured." )
199- exit (1 )
200- cmd : List [str ] = [
201- self .gui ,
202- "-summaries" ,
203- self .chsummaries ,
204- "-output" ,
205- outputpath ,
206- "-name" ,
207- name ,
208- "-xpm" ,
209- self .config .utildir ,
210- "-analysisdir" ,
211- analysisdir ,
212- "-contractpath" ,
213- self .contractpath ,
214- ]
215- print (cmd )
216- try :
217- result = subprocess .call (
218- cmd ,
219- cwd = self .path ,
220- stdout = open (os .devnull , "w" ),
221- stderr = subprocess .STDOUT ,
222- )
223- except subprocess .CalledProcessError as args :
224- print (args .output )
225- print (args )
226- exit (1 )
227-
228200 def create_file_primary_proofobligations (
229201 self , cfilename : str , cfilepath : Optional [str ] = None ) -> None :
230202 """Call analyzer to create primary proof obligations for a single file."""
231203
204+ chklogger .logger .info (
205+ "Create primiary proof obligations for %s" , cfilename )
232206 try :
233207 cmd = self ._create_file_primary_proofobligations_cmd_partial ()
234208 cmd .append (cfilename )
235209 if cfilepath is not None :
236210 cmd .extend (["-cfilepath" , cfilepath ])
211+ chklogger .logger .info (
212+ "Primary proof obligations are created for %s" , cfilename )
213+ chklogger .logger .info (
214+ "Ocaml analyzer is called with %s" , str (cmd ))
237215 if self .verbose :
238- chklogger .logger .info (
239- "Primary proof obligations are created for %s" , cfilename )
240- chklogger .logger .info (
241- "Ocaml analyzer is called with %s" , str (cmd ))
242216 result = subprocess .call (
243217 cmd , cwd = self .targetpath , stderr = subprocess .STDOUT )
244218 print ("\n Result: " + str (result ))
245219 # self.capp.get_file(cfilename).predicatedictionary.initialize()
246220 else :
247221 result = subprocess .call (
248222 cmd ,
249- cwd = self .path ,
223+ cwd = self .targetpath ,
250224 stdout = open (os .devnull , "w" ),
251225 stderr = subprocess .STDOUT ,
252226 )
@@ -267,18 +241,18 @@ def create_app_primary_proofobligations(self, processes: int = 1) -> None:
267241
268242 if processes > 1 :
269243
270- def f (cfile : str ) -> None :
244+ def f (cfile : "CFile" ) -> None :
271245 cmd = self ._create_file_primary_proofobligations_cmd_partial ()
272- cmd .append (cfile )
246+ cmd .append (cfile . name )
273247 self ._execute_cmd (cmd )
274248
275- self .capp .iter_filenames_parallel (f , processes )
249+ self .capp .iter_files_parallel (f , processes )
276250 else :
277251
278- def f (cfile : str ) -> None :
279- self .create_file_primary_proofobligations (cfile )
252+ def f (cfile : "CFile" ) -> None :
253+ self .create_file_primary_proofobligations (cfile . name )
280254
281- self .capp .iter_filenames (f )
255+ self .capp .iter_files (f )
282256
283257 def _generate_and_check_file_cmd_partial (self , domains : str ) -> List [str ]:
284258 cmd : List [str ] = [
@@ -314,19 +288,17 @@ def generate_and_check_file(self, cfilename: str, domains: str) -> None:
314288 try :
315289 cmd = self ._generate_and_check_file_cmd_partial (domains )
316290 cmd .append (cfilename )
291+ chklogger .logger .info (
292+ "Calling AI to generate invariants: %s" ,
293+ " " .join (cmd ))
317294 if self .verbose :
318- print (
319- "Generating invariants and checking proof obligations for "
320- + cfilename
321- )
322- print (cmd )
323295 result = subprocess .call (
324296 cmd , cwd = self .targetpath , stderr = subprocess .STDOUT )
325297 print ("\n Result: " + str (result ))
326298 else :
327299 result = subprocess .call (
328300 cmd ,
329- cwd = self .path ,
301+ cwd = self .targetpath ,
330302 stdout = open (os .devnull , "w" ),
331303 stderr = subprocess .STDOUT ,
332304 )
@@ -343,19 +315,19 @@ def generate_and_check_app(self, domains: str, processes: int = 1) -> None:
343315
344316 if processes > 1 :
345317
346- def f (cfile : str ) -> None :
318+ def f (cfile : "CFile" ) -> None :
347319 cmd = self ._generate_and_check_file_cmd_partial (domains )
348- cmd .append (cfile )
320+ cmd .append (cfile . name )
349321 self ._execute_cmd (cmd )
350322
351- self .capp .iter_filenames_parallel (f , processes )
323+ self .capp .iter_files_parallel (f , processes )
352324 else :
353325
354- def f (cfile : str ) -> None :
355- self .generate_and_check_file (cfile , domains )
326+ def f (cfile : "CFile" ) -> None :
327+ self .generate_and_check_file (cfile . name , domains )
356328
357- self .capp .iter_filenames (f )
358- self .capp .iter_filenames (self .reset_tables )
329+ self .capp .iter_files (f )
330+ self .capp .iter_files (self .reset_tables )
359331
360332
361333if __name__ == "__main__" :
0 commit comments