move CLOpt.exe to Config and restrict its API, remove Interactive fake exe

Summary:
Clients should use `Config.parse_action` instead to figure in what mode they
are operating.

In particular, the biggest change is in logging. Take the `parse_action` into
account instead of the exe, and change the log/ subdirectories to be "capture",
"driver", "analyze", and "print", corresponding to the various phases of an
infer run.

Reviewed By: jberdine

Differential Revision: D4474943

fbshipit-source-id: 6d33ad3
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 744edc10ec
commit 4584bf9a4c

@ -28,7 +28,7 @@ let register_perf_stats_report () => {
let () = {
Logging.set_log_file_identifier
CommandLineOption.Analyze (Option.map f::Filename.basename Config.cluster_cmdline);
CommandLineOption.(Infer Analysis) (Option.map f::Filename.basename Config.cluster_cmdline);
if Config.print_builtins {
Builtin.print_and_exit ()
};

@ -1199,7 +1199,7 @@ let process_summary filters formats_by_report_kind linereader stats top_proc_set
let module AnalysisResults = {
type t = list (string, Specs.summary);
let spec_files_from_cmdline () =>
if (CLOpt.equal_exe Config.current_exe CLOpt.Print) {
if CLOpt.is_originator {
/* 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. */
IList.iter

@ -43,7 +43,7 @@ let pp_prolog fmt clusters =
IList.map (F.sprintf "--clang-compilation-db-files '%s'") !Config.clang_compilation_db_files
|> String.concat ~sep:" " |> escape in
F.fprintf fmt "INFERANALYZE= %s --results-dir '%s' %s \n@."
(Config.bin_dir ^/ (CLOpt.exe_name Analyze))
(Config.bin_dir ^/ (Config.exe_name Analyze))
(escape Config.results_dir)
compilation_dbs_cmd;
F.fprintf fmt "CLUSTERS=";

@ -392,7 +392,7 @@ let () =
remove_results_dir () ;
create_results_dir () ;
(* re-set log files, as default files were in results_dir removed above *)
L.set_log_file_identifier Config.current_exe None ;
L.set_log_file_identifier CLOpt.(Infer Driver) None ;
if Config.print_builtins then Builtin.print_and_exit () ;
if CLOpt.is_originator then L.do_out "%s@\n" Config.version_string ;
if Config.debug_mode || Config.stats_mode then log_infer_args driver_mode ;

@ -37,29 +37,6 @@ let to_arg_speclist = List.map ~f:to_arg_spec_triple
let is_env_var_set v =
Option.value (Option.map (Sys.getenv v) ~f:((=) "1")) ~default:false
(** Each command line option may appear in the --help list of any executable, these tags are used to
specify which executables for which an option will be documented. *)
type exe = Analyze | Clang | Driver | Interactive | Print [@@deriving compare]
let equal_exe = [%compare.equal : exe]
(** Association list of executable (base)names to their [exe]s. *)
let exes = [
("InferAnalyze", Analyze);
("InferClang", Clang);
("infer", Driver);
("InferPrint", Print);
("interactive", Interactive);
]
let exe_name =
let exe_to_name = IList.map (fun (n,a) -> (a,n)) exes in
fun exe -> IList.assoc equal_exe exe exe_to_name
let frontend_exes = [Clang]
(** The working directory of the initial invocation of infer, to which paths passed as command line
options are relative. *)
let init_work_dir, is_originator =
@ -335,6 +312,9 @@ let anon_fun arg = match !unknown_args_action with
| `Reject ->
raise (Arg.Bad ("unexpected anonymous argument: " ^ arg))
(* keep track of the final parse action to drive the remainder of the program *)
let final_parse_action = ref (Infer Driver)
(* end parsing state *)
type 'a t =
@ -674,6 +654,7 @@ let set_curr_speclist_for_parse_action ~incomplete ~usage parse_action =
let select_parse_action ~incomplete ~usage action =
let usage = set_curr_speclist_for_parse_action ~incomplete ~usage action in
unknown_args_action := if accept_unknown_args action then `Add else `Reject;
final_parse_action := action;
usage
let mk_rest_actions ?(parse_mode=Infer []) doc ~usage decode_action =
@ -804,4 +785,4 @@ let parse ?(incomplete=false) ?config_file ~usage action =
if not incomplete then add_parsed_args_to_args_to_export ();
curr_usage in
if not incomplete then Unix.putenv ~key:args_env_var ~data:!args_to_export;
curr_usage
!final_parse_action, curr_usage

@ -11,17 +11,6 @@
open! IStd
type exe = Analyze | Clang | Driver | Interactive | Print [@@ deriving compare]
val equal_exe : exe -> exe -> bool
(** Association list of executable (base)names to their [exe]s. *)
val exes : (string * exe) list
val exe_name : exe -> string
val frontend_exes: exe list
(** a section is a part of infer that can be affected by an infer option *)
type section = Analysis | Clang | Driver | Java | Print [@@deriving compare]
@ -174,7 +163,7 @@ val extend_env_args : string list -> unit
the environment variable, and the command line. The [args_env_var] is set to the set of options
parsed in [args_env_var] and on the command line. *)
val parse : ?incomplete:bool -> ?config_file:string ->
usage:Arg.usage_msg -> parse_action -> (int -> 'a)
usage:Arg.usage_msg -> parse_action -> parse_action * (int -> 'a)
(** [is_env_var_set var] is true if $[var]=1 *)
val is_env_var_set : string -> bool

@ -17,6 +17,23 @@ open! PVariant
module CLOpt = CommandLineOption
module F = Format
type exe = Analyze | Clang | Driver | Print [@@deriving compare]
let equal_exe = [%compare.equal : exe]
(** Association list of executable (base)names to their [exe]s. *)
let exes = [
("InferAnalyze", Analyze);
("InferClang", Clang);
("infer", Driver);
("InferPrint", Print);
]
let exe_name =
let exe_to_name = IList.map (fun (n,a) -> (a,n)) exes in
fun exe -> IList.assoc equal_exe exe exe_to_name
let frontend_parse_modes = CLOpt.(Infer [Clang])
type analyzer =
Capture | Compile | Infer | Eradicate | Checkers | Tracing | Crashcontext | Linters | Quandary
@ -245,9 +262,8 @@ let real_exe_name =
Utils.realpath Sys.executable_name
let current_exe =
if !Sys.interactive then CLOpt.Interactive
else try IList.assoc String.equal (Filename.basename real_exe_name) CLOpt.exes
with Not_found -> ((CLOpt.Driver) : CLOpt.exe)
try IList.assoc String.equal (Filename.basename real_exe_name) exes
with Not_found -> Driver
let bin_dir =
Filename.dirname real_exe_name
@ -314,15 +330,15 @@ let infer_is_javac = maven
let startup_action =
let open CLOpt in
if infer_is_javac then Javac
else if !Sys.interactive then NoParse
else match current_exe with
| Analyze -> Infer Analysis
| Clang -> NoParse
| Driver -> Infer Driver
| Interactive -> NoParse
| Print -> Infer Print
let exe_usage = match (current_exe : CLOpt.exe) with
let exe_usage = match current_exe with
| Analyze ->
version_string ^ "\n" ^
"Usage: InferAnalyze [options]\n\
@ -331,8 +347,6 @@ let exe_usage = match (current_exe : CLOpt.exe) with
| Clang ->
"Usage: internal script to capture compilation commands from clang and clang++. \n\
You shouldn't need to call this directly."
| Interactive ->
"Usage: interactive ocaml toplevel. To pass infer config options use env variable"
| Print ->
"Usage: InferPrint [options] name1.specs ... namen.specs\n\
Read, convert, and print .specs files. \
@ -358,7 +372,7 @@ and project_root =
(* Parse the phase 1 options, ignoring the rest *)
let _ : int -> 'a = CLOpt.parse ~incomplete:true startup_action ~usage:""
let _ : CLOpt.parse_action * (int -> 'a) = CLOpt.parse ~incomplete:true startup_action ~usage:""
(* Define the values that depend on phase 1 options *)
@ -688,7 +702,7 @@ and (
) =
let developer_mode =
CLOpt.mk_bool ~long:"developer-mode"
~default:CLOpt.(equal_exe current_exe Print)
~default:(equal_exe current_exe Print)
"Show internal exceptions"
and filtering =
@ -703,7 +717,7 @@ and (
and print_types =
CLOpt.mk_bool ~long:"print-types"
~default:CLOpt.(equal_exe current_exe Clang)
~default:(equal_exe current_exe Clang)
"Print types in symbolic heaps"
and reports_include_ml_loc =
@ -1055,7 +1069,7 @@ and quandary_sinks =
CLOpt.mk_json ~long:"quandary-sinks" "Specify custom sinks for Quandary"
and quiet =
CLOpt.mk_bool ~long:"quiet" ~short:"q" ~default:(current_exe <> (CLOpt.Print : CLOpt.exe))
CLOpt.mk_bool ~long:"quiet" ~short:"q" ~default:(current_exe <> Print)
~parse_mode:CLOpt.(Infer [Print])
"Do not print specs on standard output"
@ -1392,11 +1406,11 @@ let post_parsing_initialization () =
| Some (Capture | Compile | Infer | Linters) | None -> ()
let parse_args_and_return_usage_exit =
let usage_exit =
let parse_action, parse_args_and_return_usage_exit =
let parse_action, usage_exit =
CLOpt.parse ~config_file:inferconfig_path ~usage:exe_usage startup_action in
post_parsing_initialization () ;
usage_exit
parse_action, usage_exit
let print_usage_exit () =
parse_args_and_return_usage_exit 1

@ -13,6 +13,9 @@ open! IStd
(** Configuration values: either constant, determined at compile time, or set at startup
time by system calls, environment variables, or command line options *)
type exe = Analyze | Clang | Driver | Print [@@deriving compare]
val exe_name : exe -> string
(** Various kind of analyzers *)
type analyzer =
@ -68,7 +71,6 @@ val classpath : string option
val cpp_extra_include_dir : string
val relative_cpp_models_dir : string
val csl_analysis : bool
val current_exe : CommandLineOption.exe
val default_failure_name : string
val default_in_zip_results_dir : string
val dotty_output : string
@ -235,6 +237,7 @@ val no_translate_libs : bool
val objc_memory_model_on : bool
val only_footprint : bool
val out_file_cmdline : string
val parse_action : CommandLineOption.parse_action
val pmd_xml : bool
val precondition_stats : bool
val print_logs : bool

@ -29,13 +29,14 @@ let dup_formatter fmt1 fmt2 =
Format.pp_set_formatter_output_functions fmt1 out_string flush
(** Name of dir for logging the output in the specific executable *)
let log_dir_of_exe (exe : CLOpt.exe) =
match exe with
| Analyze -> "analyze"
| Clang -> "clang"
| Driver -> "driver"
| Interactive -> "interactive"
| Print -> "print"
let log_dir_of_action (action : CLOpt.parse_action) = match action with
| Infer Analysis -> "analyze"
| Infer Driver -> "driver"
| Infer Clang
| Infer Java
| NoParse
| Javac -> "capture"
| Infer Print -> "print"
let stdout_err_log_files =
(((lazy F.std_formatter), (lazy Pervasives.stdout),
@ -52,8 +53,8 @@ let close_log_file fmt chan file =
Out_channel.close c
)
let create_log_file exe name_prefix outerr =
let log_dir = Config.results_dir ^/ Config.log_dir_name ^/ log_dir_of_exe exe in
let create_log_file action name_prefix outerr =
let log_dir = Config.results_dir ^/ Config.log_dir_name ^/ log_dir_of_action action in
let config_name = match outerr with
| `Out -> Config.out_file_cmdline
| `Err -> Config.err_file_cmdline in
@ -81,10 +82,10 @@ let create_log_file exe name_prefix outerr =
"log files flushing";
(file_fmt, chan, file)
let should_setup_log_files (exe : CLOpt.exe) = match exe with
| Analyze
| Clang -> Config.debug_mode || Config.stats_mode
| Driver -> true
let should_setup_log_files (action : CLOpt.parse_action) = match action with
| Infer Analysis
| Infer Clang -> Config.debug_mode || Config.stats_mode
| Infer Driver -> true
| _ -> false
let create_outerr_log_files exe prefix_opt =
@ -103,7 +104,7 @@ let create_outerr_log_files exe prefix_opt =
let ((out_formatter, out_chan, out_file),
(err_formatter, err_chan, err_file)) =
let (o_fmt, o_c, o_f), (e_fmt, e_c, e_f) =
create_outerr_log_files Config.current_exe None in
create_outerr_log_files Config.parse_action None in
((ref o_fmt, ref o_c, ref o_f),
(ref e_fmt, ref e_c, ref e_f))

@ -73,7 +73,7 @@ val set_delayed_prints : print_action list -> unit
val reset_delayed_prints : unit -> unit
(** Set a custom identifier to be part of the filename of the current logfiles. *)
val set_log_file_identifier : CommandLineOption.exe -> string option -> unit
val set_log_file_identifier : CommandLineOption.parse_action -> string option -> unit
(** print to the current out stream, as specified in set_log_file_identifier
(note: only prints in debug or in stats mode) *)

@ -44,7 +44,7 @@ let register_perf_stats_report source_file => {
let init_global_state_for_capture_and_linters source_file => {
Logging.set_log_file_identifier
CommandLineOption.Clang (Some (Filename.basename (SourceFile.to_abs_path source_file)));
CLOpt.(Infer Clang) (Some (Filename.basename (SourceFile.to_abs_path source_file)));
register_perf_stats_report source_file;
Config.curr_language := Config.Clang;
DB.Results_dir.init source_file;
@ -173,7 +173,7 @@ let cc1_capture clang_cmd => {
source_path (fun chan_in => run_and_validate_clang_frontend (`Pipe chan_in)) clang_cmd
};
/* reset logging to stop capturing log output into the source file's log */
Logging.set_log_file_identifier CommandLineOption.Clang None;
Logging.set_log_file_identifier CLOpt.(Infer Clang) None;
()
}
};

Loading…
Cancel
Save