diff --git a/infer/bin/inferlib.py b/infer/bin/inferlib.py index 3465000d5..91823e0d6 100644 --- a/infer/bin/inferlib.py +++ b/infer/bin/inferlib.py @@ -164,6 +164,9 @@ infer_group.add_argument('-nt', '--notest', action='store_true', dest='notest', help='Prints output of symbolic execution') +infer_group.add_argument('-npb', '--no-progress-bar', action='store_true', + help='Do not show a progress bar in the analysis') + infer_group.add_argument('--specs-dir', metavar='', action='append', @@ -521,6 +524,9 @@ class Infer: if self.args.notest: infer_options += ['-notest'] + if self.args.no_progress_bar: + infer_options += ['-no_progress_bar'] + if self.args.debug: infer_options += [ '-developer_mode', diff --git a/infer/src/backend/clusterMakefile.ml b/infer/src/backend/clusterMakefile.ml index 325c80a82..4dcab01c1 100644 --- a/infer/src/backend/clusterMakefile.ml +++ b/infer/src/backend/clusterMakefile.ml @@ -47,7 +47,9 @@ let pp_prolog fmt clusters = if filter cl then F.fprintf fmt "%a " Cluster.pp_cl (i+1)) clusters; F.fprintf fmt "@.@.default: test@.@.all: test@.@."; - F.fprintf fmt "test: $(OBJECTS)@.\techo \"Analysis done\"@.@." + F.fprintf fmt "test: $(OBJECTS)@."; + if !Config.show_progress_bar then F.fprintf fmt "\techo \"\\n\"@."; + F.fprintf fmt "\techo \"Analysis done\"@.@." let pp_epilog fmt () = F.fprintf fmt "@.clean:@.\trm -f $(OBJECTS)@." diff --git a/infer/src/backend/config.ml b/infer/src/backend/config.ml index c1c34862f..228142c61 100644 --- a/infer/src/backend/config.ml +++ b/infer/src/backend/config.ml @@ -400,3 +400,5 @@ let curr_language = ref C_CPP let string_of_language = function | Java -> "Java" | C_CPP -> "C_CPP" + +let show_progress_bar = ref true diff --git a/infer/src/backend/inferanalyze.ml b/infer/src/backend/inferanalyze.ml index b3fbe1a2e..6cf36d967 100644 --- a/infer/src/backend/inferanalyze.ml +++ b/infer/src/backend/inferanalyze.ml @@ -145,6 +145,7 @@ let arg_desc = "-version", Arg.Unit print_version, None, "print version information and exit"; "-version_json", Arg.Unit print_version_json, None, "print version json formatted"; "-objcm", Arg.Set Config.objc_memory_model_on, None, "Use ObjC memory model"; + "-no_progress_bar", Arg.Unit (fun () -> Config.show_progress_bar := false), None, "Do not show a progress bar"; "-ml_buckets", Arg.Set_string ml_buckets_arg, Some "ml_buckets", "memory leak buckets to be checked, separated by commas. The possible buckets are cf (Core Foundation), arc, narc (No arc), cpp"; ] in @@ -238,6 +239,7 @@ end let analyze exe_env = let init_time = Unix.gettimeofday () in + L.log_progress_simple "."; Specs.clear_spec_tbl (); Random.self_init (); let line_reader = Printer.LineReader.create () in @@ -344,7 +346,10 @@ let create_minimal_clusters file_cg exe_env to_analyze_map : Cluster.t list = let total_files = ref 0 in let total_procs = ref 0 in let total_LOC = ref 0 in + let total = Procname.Map.cardinal to_analyze_map in + let analyzed_map_done = ref 0 in let create_cluster_elem (file_pname, changed_procs) = (* create a Cluster.elem for the file *) + L.log_progress "Creating clusters..." analyzed_map_done total; let source_file = ClusterMakefile.source_file_from_pname file_pname in if !Cluster.trace_clusters then L.err " [create_minimal_clusters] %s@." (DB.source_file_to_string source_file); @@ -477,7 +482,10 @@ let compute_clusters exe_env files_changed : Cluster.t list = let global_cg = Exe_env.get_cg exe_env in let nodes, edges = Cg.get_nodes_and_edges global_cg in let defined_procs = Cg.get_defined_nodes global_cg in + let total_nodes = IList.length nodes in + let computed_nodes = ref 0 in let do_node (n, defined, restricted) = + L.log_progress "Computing dependencies..." computed_nodes total_nodes; if defined then Cg.add_defined_node file_cg (ClusterMakefile.source_file_to_pname (Exe_env.get_source exe_env n)) in @@ -498,6 +506,7 @@ let compute_clusters exe_env files_changed : Cluster.t list = end end in IList.iter do_node nodes; + L.log_progress_simple "\n"; if not !Config.intraprocedural then IList.iter do_edge edges; if !save_file_dependency then Cg.save_call_graph_dotty (Some (DB.filename_from_string "file_dependency.dot")) Specs.get_specs file_cg; @@ -527,6 +536,8 @@ let compute_clusters exe_env files_changed : Cluster.t list = Cluster.combine_split_clusters clusters max_cluster_size desired_cluster_size in L.err "@.Combined clusters with max size %d@." max_cluster_size; Cluster.print_clusters_stats clusters'; + let number_of_clusters = IList.length clusters' in + L.log_progress_simple ("\nAnalyzing "^(string_of_int number_of_clusters)^" clusters"); ClusterMakefile.create_cluster_makefile_and_exit clusters' file_cg !makefile_cmdline false end; let clusters' = @@ -534,6 +545,8 @@ let compute_clusters exe_env files_changed : Cluster.t list = clusters !Config.max_cluster_size !Config.max_cluster_size in L.err "@.Combined clusters with max size %d@." !Config.max_cluster_size; Cluster.print_clusters_stats clusters'; + let number_of_clusters = IList.length clusters' in + L.log_progress_simple ("\nAnalyzing "^(string_of_int number_of_clusters)^" clusters"); clusters' (** compute the set of procedures in [cg] changed since the last analysis *) diff --git a/infer/src/backend/logging.ml b/infer/src/backend/logging.ml index 7d8484962..d6c03fadb 100644 --- a/infer/src/backend/logging.ml +++ b/infer/src/backend/logging.ml @@ -163,3 +163,14 @@ let d_increase_indent (indent: int) = (** dump command to decrease the indentation level *) let d_decrease_indent (indent: int) = add_print_action (PTdecrease_indent, Obj.repr indent) + +let log_progress text counter total = + if !Config.show_progress_bar then + (counter := !counter + 1; + let percentage = (100 * !counter) / total in + F.fprintf Format.err_formatter "%s %d%s" text percentage "%\r"; + F.fprintf Format.err_formatter "@?") + +let log_progress_simple text = + if !Config.show_progress_bar then + F.fprintf Format.err_formatter "%s@?" text diff --git a/infer/src/backend/logging.mli b/infer/src/backend/logging.mli index 806f44d96..d145f8314 100644 --- a/infer/src/backend/logging.mli +++ b/infer/src/backend/logging.mli @@ -131,3 +131,7 @@ val d_increase_indent : int -> unit (** dump command to decrease the indentation level *) val d_decrease_indent : int -> unit + +val log_progress : string -> int ref -> int -> unit + +val log_progress_simple : string -> unit