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