|
|
|
@ -873,93 +873,33 @@ let process_summary filters formats_by_report_kind linereader stats summary issu
|
|
|
|
|
issues_acc'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module AnalysisResults = struct
|
|
|
|
|
type t = (string * Specs.summary) list
|
|
|
|
|
|
|
|
|
|
let spec_files_from_cmdline () =
|
|
|
|
|
if CLOpt.is_originator then (
|
|
|
|
|
(* Find spec files specified by command-line arguments. Not run at init time since the specs
|
|
|
|
|
let spec_files_from_cmdline () =
|
|
|
|
|
if CLOpt.is_originator then (
|
|
|
|
|
(* Find spec files specified by command-line arguments. Not run at init time since the specs
|
|
|
|
|
files may be generated between init and report time. *)
|
|
|
|
|
List.iter
|
|
|
|
|
~f:(fun arg ->
|
|
|
|
|
if not (Filename.check_suffix arg Config.specs_files_suffix) && arg <> "." then
|
|
|
|
|
print_usage_exit ("file " ^ arg ^ ": arguments must be .specs files") )
|
|
|
|
|
Config.anon_args ;
|
|
|
|
|
if Config.test_filtering then ( Inferconfig.test () ; L.exit 0 ) ;
|
|
|
|
|
if List.is_empty Config.anon_args then load_specfiles () else List.rev Config.anon_args )
|
|
|
|
|
else load_specfiles ()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Load .specs files in memory and return list of summaries *)
|
|
|
|
|
let load_summaries_in_memory () : t =
|
|
|
|
|
let summaries = ref [] in
|
|
|
|
|
let load_file fname =
|
|
|
|
|
match Specs.load_summary (DB.filename_from_string fname) with
|
|
|
|
|
| None ->
|
|
|
|
|
L.(die UserError) "Error: cannot open file %s@." fname
|
|
|
|
|
| Some summary ->
|
|
|
|
|
summaries := (fname, summary) :: !summaries
|
|
|
|
|
in
|
|
|
|
|
let do_load () = spec_files_from_cmdline () |> List.iter ~f:load_file in
|
|
|
|
|
Utils.without_gc ~f:do_load ;
|
|
|
|
|
let summ_cmp (_, summ1) (_, summ2) =
|
|
|
|
|
let loc1 = Specs.get_loc summ1 and loc2 = Specs.get_loc summ2 in
|
|
|
|
|
let n = SourceFile.compare loc1.Location.file loc2.Location.file in
|
|
|
|
|
if n <> 0 then n else Int.compare loc1.Location.line loc2.Location.line
|
|
|
|
|
in
|
|
|
|
|
List.sort ~cmp:summ_cmp !summaries
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Create an iterator which loads spec files one at a time *)
|
|
|
|
|
let iterator_of_spec_files () =
|
|
|
|
|
let sorted_spec_files = List.sort ~cmp:String.compare (spec_files_from_cmdline ()) in
|
|
|
|
|
let do_spec f fname =
|
|
|
|
|
match Specs.load_summary (DB.filename_from_string fname) with
|
|
|
|
|
| None ->
|
|
|
|
|
L.(die UserError) "Error: cannot open file %s@." fname
|
|
|
|
|
| Some summary ->
|
|
|
|
|
f (fname, summary)
|
|
|
|
|
in
|
|
|
|
|
let iterate f = List.iter ~f:(do_spec f) sorted_spec_files in
|
|
|
|
|
iterate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Serializer for analysis results *)
|
|
|
|
|
let analysis_results_serializer : t Serialization.serializer =
|
|
|
|
|
Serialization.create_serializer Serialization.Key.analysis_results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Load analysis_results from a file *)
|
|
|
|
|
let load_analysis_results_from_file (filename: DB.filename) : t option =
|
|
|
|
|
Serialization.read_from_file analysis_results_serializer filename
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Save analysis_results into a file *)
|
|
|
|
|
let store_analysis_results_to_file (filename: DB.filename) (analysis_results: t) =
|
|
|
|
|
Serialization.write_to_file analysis_results_serializer filename ~data:analysis_results
|
|
|
|
|
|
|
|
|
|
List.iter
|
|
|
|
|
~f:(fun arg ->
|
|
|
|
|
if not (Filename.check_suffix arg Config.specs_files_suffix) && arg <> "." then
|
|
|
|
|
print_usage_exit ("file " ^ arg ^ ": arguments must be .specs files") )
|
|
|
|
|
Config.anon_args ;
|
|
|
|
|
if Config.test_filtering then ( Inferconfig.test () ; L.exit 0 ) ;
|
|
|
|
|
if List.is_empty Config.anon_args then load_specfiles () else List.rev Config.anon_args )
|
|
|
|
|
else load_specfiles ()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Create an iterator which loads spec files one at a time *)
|
|
|
|
|
let get_summary_iterator () =
|
|
|
|
|
let sorted_spec_files = List.sort ~cmp:String.compare (spec_files_from_cmdline ()) in
|
|
|
|
|
let do_spec f fname =
|
|
|
|
|
match Specs.load_summary (DB.filename_from_string fname) with
|
|
|
|
|
| None ->
|
|
|
|
|
L.(die UserError) "Error: cannot open file %s@." fname
|
|
|
|
|
| Some summary ->
|
|
|
|
|
f summary
|
|
|
|
|
in
|
|
|
|
|
let iterate f = List.iter ~f:(do_spec f) sorted_spec_files in
|
|
|
|
|
iterate
|
|
|
|
|
|
|
|
|
|
(** Return an iterator over all the summaries.
|
|
|
|
|
If options - load_results or - save_results are used,
|
|
|
|
|
all the summaries are loaded in memory *)
|
|
|
|
|
let get_summary_iterator () =
|
|
|
|
|
let iterator_of_summary_list r f = List.iter ~f r in
|
|
|
|
|
match Config.load_analysis_results with
|
|
|
|
|
| None -> (
|
|
|
|
|
match Config.save_analysis_results with
|
|
|
|
|
| None ->
|
|
|
|
|
iterator_of_spec_files ()
|
|
|
|
|
| Some s ->
|
|
|
|
|
let r = load_summaries_in_memory () in
|
|
|
|
|
store_analysis_results_to_file (DB.filename_from_string s) r ;
|
|
|
|
|
iterator_of_summary_list r )
|
|
|
|
|
| Some fname ->
|
|
|
|
|
match load_analysis_results_from_file (DB.filename_from_string fname) with
|
|
|
|
|
| Some r ->
|
|
|
|
|
iterator_of_summary_list r
|
|
|
|
|
| None ->
|
|
|
|
|
L.(die UserError) "Error: cannot open analysis results file %s@." fname
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
let register_perf_stats_report () =
|
|
|
|
|
let stats_dir = Filename.concat Config.results_dir Config.reporting_stats_dir_name in
|
|
|
|
@ -1051,9 +991,9 @@ let pp_summary_and_issues formats_by_report_kind issue_formats =
|
|
|
|
|
let stats = Stats.create () in
|
|
|
|
|
let linereader = Printer.LineReader.create () in
|
|
|
|
|
let filters = Inferconfig.create_filters Config.analyzer in
|
|
|
|
|
let iterate_summaries = AnalysisResults.get_summary_iterator () in
|
|
|
|
|
let iterate_summaries = get_summary_iterator () in
|
|
|
|
|
let all_issues = ref [] in
|
|
|
|
|
iterate_summaries (fun (_, summary) ->
|
|
|
|
|
iterate_summaries (fun summary ->
|
|
|
|
|
all_issues
|
|
|
|
|
:= process_summary filters formats_by_report_kind linereader stats summary !all_issues ) ;
|
|
|
|
|
List.iter
|
|
|
|
|