Summary: Reimplement command line options in preparation for uniformly passing options from the top-level infer driver that invokes a build command through the build system to the descendant infer processes. All command line options of all executables are collected into Config, and declared using a new CommandLineOption module that supports maintining backward compatibility with the current command line interface. Very few values representing command line options are mutable now, as they are set once during parsing but are constant thereafter. All ordering dependencies are contained within the implementation of Config, and the implementation of Config is careful to avoid unintended interactions and ordering dependencies between options. Reviewed By: jvillard Differential Revision: D3273345 fbshipit-source-id: 8e8c6famaster
parent
d73d4ea177
commit
3e2fa59262
@ -0,0 +1,378 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2016 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** Definition and parsing of command line arguments *)
|
||||||
|
|
||||||
|
open! Utils
|
||||||
|
|
||||||
|
module F = Format
|
||||||
|
|
||||||
|
|
||||||
|
(* 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 = A | C | J | L | P | T
|
||||||
|
|
||||||
|
let current_exe =
|
||||||
|
match Filename.basename Sys.executable_name with
|
||||||
|
| "InferAnalyze" -> A
|
||||||
|
| "InferClang" -> C
|
||||||
|
| "InferJava" -> J
|
||||||
|
| "InferLLVM" -> L
|
||||||
|
| "InferPrint" -> P
|
||||||
|
| _ -> T
|
||||||
|
|
||||||
|
|
||||||
|
type desc = { long: string; short: string; meta: string; doc: string; spec: Arg.spec }
|
||||||
|
|
||||||
|
let dashdash long =
|
||||||
|
match long with
|
||||||
|
| "" | "--" -> long
|
||||||
|
| _ -> "--" ^ long
|
||||||
|
|
||||||
|
let short_meta {short; meta; spec} =
|
||||||
|
String.concat " "
|
||||||
|
((if short = "" then [] else ["| -" ^ short]) @
|
||||||
|
(match spec with
|
||||||
|
| Arg.Symbol (symbols, _) ->
|
||||||
|
["{ " ^ (String.concat " | " symbols) ^ " }" ^ meta]
|
||||||
|
| _ ->
|
||||||
|
if meta = "" then [] else ["<" ^ meta ^ ">"]))
|
||||||
|
|
||||||
|
let left_length long short_meta =
|
||||||
|
(String.length (dashdash long)) + (String.length short_meta)
|
||||||
|
|
||||||
|
let max_left_length limit current ({long; spec} as desc) =
|
||||||
|
let short_meta =
|
||||||
|
match spec with
|
||||||
|
| Arg.Symbol _ -> short_meta {desc with spec = Arg.Unit (fun () -> ())}
|
||||||
|
| _ -> short_meta desc in
|
||||||
|
let length = left_length long short_meta in
|
||||||
|
if length > limit then current else max current length
|
||||||
|
|
||||||
|
let xdesc {long; short; spec; doc} =
|
||||||
|
let key long short =
|
||||||
|
match long, short with
|
||||||
|
| "", "" -> ""
|
||||||
|
| "--", _ -> "--"
|
||||||
|
| "", _ -> "-" ^ short
|
||||||
|
| _ -> "--" ^ long
|
||||||
|
in
|
||||||
|
let xspec long spec =
|
||||||
|
match spec with
|
||||||
|
(* translate Symbol to String for better formatting of --help messages *)
|
||||||
|
| Arg.Symbol (symbols, action) ->
|
||||||
|
Arg.String (fun arg ->
|
||||||
|
if IList.mem ( = ) arg symbols then
|
||||||
|
action arg
|
||||||
|
else
|
||||||
|
raise (Arg.Bad (F.sprintf "wrong argument '%s'; option '%s' expects one of: %s"
|
||||||
|
arg (dashdash long) (String.concat " | " symbols)))
|
||||||
|
)
|
||||||
|
| _ ->
|
||||||
|
spec
|
||||||
|
in
|
||||||
|
(key long short, xspec long spec, doc)
|
||||||
|
|
||||||
|
let pad_and_xform left_width desc =
|
||||||
|
match desc with
|
||||||
|
| {doc = ""} ->
|
||||||
|
xdesc desc
|
||||||
|
| {long; doc} ->
|
||||||
|
let short_meta = short_meta desc in
|
||||||
|
let gap = left_width - (left_length long short_meta) in
|
||||||
|
if gap < 0 then
|
||||||
|
xdesc {desc with doc = short_meta ^ "\n" ^ (String.make (4 + left_width) ' ') ^ doc}
|
||||||
|
else
|
||||||
|
xdesc {desc with doc = short_meta ^ (String.make (gap + 1) ' ') ^ doc}
|
||||||
|
|
||||||
|
let align ?(limit=max_int) desc_list =
|
||||||
|
let left_width = IList.fold_left (max_left_length limit) 0 desc_list in
|
||||||
|
(IList.map (pad_and_xform left_width) desc_list)
|
||||||
|
|
||||||
|
|
||||||
|
let check_no_duplicates desc_list =
|
||||||
|
let rec check_for_duplicates_ = function
|
||||||
|
| [] | [_] ->
|
||||||
|
true
|
||||||
|
| (x, _, _) :: (y, _, _) :: _ when x <> "" && x = y ->
|
||||||
|
failwith ("Multiple definitions of command line option: " ^ x)
|
||||||
|
| _ :: tl ->
|
||||||
|
check_for_duplicates_ tl
|
||||||
|
in
|
||||||
|
check_for_duplicates_ (IList.sort (fun (x, _, _) (y, _, _) -> String.compare x y) desc_list)
|
||||||
|
|
||||||
|
|
||||||
|
let full_desc_list = ref []
|
||||||
|
|
||||||
|
let exe_desc_lists = [(A, ref []); (C, ref []); (J, ref []); (L, ref []); (P, ref []); (T, ref [])]
|
||||||
|
|
||||||
|
(* add desc to all desc_lists for the purposes of parsing, include desc in --help only for exes *)
|
||||||
|
let add exes desc =
|
||||||
|
full_desc_list := desc :: !full_desc_list ;
|
||||||
|
IList.iter (fun (exe, desc_list) ->
|
||||||
|
let desc =
|
||||||
|
if IList.mem ( = ) exe exes then
|
||||||
|
desc
|
||||||
|
else
|
||||||
|
{desc with meta = ""; doc = ""} in
|
||||||
|
desc_list := desc :: !desc_list
|
||||||
|
) exe_desc_lists
|
||||||
|
|
||||||
|
let mk ?(deprecated=[]) ?(exes=[])
|
||||||
|
~long ?(short="") ~default ~meta doc ~default_to_string ~mk_setter ~mk_spec =
|
||||||
|
let variable = ref default in
|
||||||
|
let closure = mk_setter variable in
|
||||||
|
let setter str =
|
||||||
|
try closure str
|
||||||
|
with _ -> raise (Arg.Bad ("bad value " ^ str ^ " for flag " ^ long)) in
|
||||||
|
let spec = mk_spec setter in
|
||||||
|
let doc =
|
||||||
|
let default_string = default_to_string default in
|
||||||
|
if default_string = "" then doc
|
||||||
|
else doc ^ " (default: " ^ default_string ^ ")" in
|
||||||
|
let desc = {long; short; meta; doc; spec} in
|
||||||
|
(* add desc for long option, with documentation (which includes any short option) for exes *)
|
||||||
|
add exes desc ;
|
||||||
|
(* add desc for short option only for parsing, without documentation *)
|
||||||
|
if short <> "" then
|
||||||
|
add [] {desc with long = ""; meta = ""; doc = ""} ;
|
||||||
|
(* add desc for deprecated options only for parsing, without documentation *)
|
||||||
|
IList.iter (fun deprecated ->
|
||||||
|
add [] {desc with long = ""; short = deprecated; meta = ""; doc = ""}
|
||||||
|
) deprecated ;
|
||||||
|
variable
|
||||||
|
|
||||||
|
type 'a t =
|
||||||
|
?deprecated:string list -> long:Arg.key -> ?short:Arg.key ->
|
||||||
|
?exes:exe list -> ?meta:string -> Arg.doc ->
|
||||||
|
'a
|
||||||
|
|
||||||
|
let mk_set var value ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
let setter () = var := value in
|
||||||
|
ignore(
|
||||||
|
mk ~deprecated ~long ?short ~default:() ?exes ~meta doc
|
||||||
|
~default_to_string:(fun () -> "")
|
||||||
|
~mk_setter:(fun _ _ -> setter ())
|
||||||
|
~mk_spec:(fun _ -> Arg.Unit setter) )
|
||||||
|
|
||||||
|
let mk_option ?(default=None) ?(default_to_string=fun _ -> "") ~f
|
||||||
|
?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta doc
|
||||||
|
~default_to_string
|
||||||
|
~mk_setter:(fun var str -> var := f str)
|
||||||
|
~mk_spec:(fun set -> Arg.String set)
|
||||||
|
|
||||||
|
let mk_bool ?(deprecated_no=[]) ?(default=false) ?(f=fun b -> b)
|
||||||
|
?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
let nolong =
|
||||||
|
let len = String.length long in
|
||||||
|
if len > 3 && String.sub long 0 3 = "no-" then
|
||||||
|
String.sub long 3 (len - 3)
|
||||||
|
else
|
||||||
|
"no-" ^ long
|
||||||
|
and noshort =
|
||||||
|
Option.map (fun short ->
|
||||||
|
let len = String.length short in
|
||||||
|
if len > 1 && String.sub short 0 1 = "n" then
|
||||||
|
String.sub short 1 (len - 1)
|
||||||
|
else
|
||||||
|
"n" ^ short
|
||||||
|
) short
|
||||||
|
in
|
||||||
|
let doc nolong =
|
||||||
|
match noshort with
|
||||||
|
| Some noshort -> doc ^ " (Conversely: --" ^ nolong ^ " | -" ^ noshort ^ ")"
|
||||||
|
| None -> doc ^ " (Conversely: --" ^ nolong ^ ")"
|
||||||
|
in
|
||||||
|
let doc, nodoc =
|
||||||
|
if not default then
|
||||||
|
("Activates: " ^ doc nolong, "")
|
||||||
|
else
|
||||||
|
("", "Deactivates: " ^ doc long) in
|
||||||
|
let default_to_string _ = "" in
|
||||||
|
let mk_spec set = Arg.Unit (fun () -> set "") in
|
||||||
|
let var =
|
||||||
|
mk ~long ?short ~deprecated ~default ?exes
|
||||||
|
~meta doc ~default_to_string ~mk_setter:(fun var _ -> var := f true) ~mk_spec in
|
||||||
|
ignore(
|
||||||
|
mk ~long:nolong ?short:noshort ~deprecated:deprecated_no ~default:(not default) ?exes
|
||||||
|
~meta nodoc ~default_to_string ~mk_setter:(fun _ _ -> var := f false) ~mk_spec );
|
||||||
|
var
|
||||||
|
|
||||||
|
let mk_bool_group ?(deprecated_no=[]) ?(default=false)
|
||||||
|
?(deprecated=[]) ~long ?short ?exes ?(meta="") doc children =
|
||||||
|
let f b =
|
||||||
|
IList.iter (fun child -> child := b) children ;
|
||||||
|
b
|
||||||
|
in
|
||||||
|
mk_bool ~deprecated ~deprecated_no ~default ~long ?short ~f ?exes ~meta doc
|
||||||
|
|
||||||
|
let mk_int ~default ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta doc
|
||||||
|
~default_to_string:string_of_int
|
||||||
|
~mk_setter:(fun var str -> var := (int_of_string str))
|
||||||
|
~mk_spec:(fun set -> Arg.String set)
|
||||||
|
|
||||||
|
let mk_float ~default ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta doc
|
||||||
|
~default_to_string:string_of_float
|
||||||
|
~mk_setter:(fun var str -> var := (float_of_string str))
|
||||||
|
~mk_spec:(fun set -> Arg.String set)
|
||||||
|
|
||||||
|
let mk_string ~default ?(f=fun s -> s) ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta doc
|
||||||
|
~default_to_string:(fun s -> s)
|
||||||
|
~mk_setter:(fun var str -> var := f str)
|
||||||
|
~mk_spec:(fun set -> Arg.String set)
|
||||||
|
|
||||||
|
let mk_string_opt ?default ?(f=fun s -> s) ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
let default_to_string = function Some s -> s | None -> "" in
|
||||||
|
let f s = Some (f s) in
|
||||||
|
mk_option ~deprecated ~long ?short ~default ~default_to_string ~f ?exes ~meta doc
|
||||||
|
|
||||||
|
let mk_string_list ?(default=[]) ?(f=fun s -> s)
|
||||||
|
?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta doc
|
||||||
|
~default_to_string:(String.concat ", ")
|
||||||
|
~mk_setter:(fun var str -> var := (f str) :: !var)
|
||||||
|
~mk_spec:(fun set -> Arg.String set)
|
||||||
|
|
||||||
|
let mk_symbol ~default ~symbols ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
let strings = IList.map fst symbols in
|
||||||
|
let sym_to_str = IList.map (fun (x,y) -> (y,x)) symbols in
|
||||||
|
let of_string str = IList.assoc string_equal str symbols in
|
||||||
|
let to_string sym = IList.assoc ( = ) sym sym_to_str in
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta doc
|
||||||
|
~default_to_string:(fun s -> to_string s)
|
||||||
|
~mk_setter:(fun var str -> var := of_string str)
|
||||||
|
~mk_spec:(fun set -> Arg.Symbol (strings, set))
|
||||||
|
|
||||||
|
let mk_symbol_opt ~symbols ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
let strings = IList.map fst symbols in
|
||||||
|
let of_string str = IList.assoc string_equal str symbols in
|
||||||
|
mk ~deprecated ~long ?short ~default:None ?exes ~meta doc
|
||||||
|
~default_to_string:(fun _ -> "")
|
||||||
|
~mk_setter:(fun var str -> var := Some (of_string str))
|
||||||
|
~mk_spec:(fun set -> Arg.Symbol (strings, set))
|
||||||
|
|
||||||
|
let mk_symbol_seq ?(default=[]) ~symbols ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
|
||||||
|
let strings = IList.map fst symbols in
|
||||||
|
let sym_to_str = IList.map (fun (x,y) -> (y,x)) symbols in
|
||||||
|
let of_string str = IList.assoc string_equal str symbols in
|
||||||
|
let to_string sym = IList.assoc ( = ) sym sym_to_str in
|
||||||
|
mk ~deprecated ~long ?short ~default ?exes ~meta:(" ,-separated sequence" ^ meta) doc
|
||||||
|
~default_to_string:(fun syms -> String.concat " " (IList.map to_string syms))
|
||||||
|
~mk_setter:(fun var str_seq -> var := IList.map of_string (Str.split (Str.regexp ",") str_seq))
|
||||||
|
~mk_spec:(fun set -> Arg.Symbol (strings, set))
|
||||||
|
|
||||||
|
let anon_fun = ref (fun arg -> raise (Arg.Bad ("unexpected anonymous argument: " ^ arg)))
|
||||||
|
|
||||||
|
let mk_anon () =
|
||||||
|
let anon = ref [] in
|
||||||
|
anon_fun := (fun arg -> anon := arg :: !anon) ;
|
||||||
|
anon
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(** [sep_char] is used to separate elements of argv when encoded into environment variables *)
|
||||||
|
let sep_char = '^'
|
||||||
|
|
||||||
|
let encode_argv_to_env argv =
|
||||||
|
String.concat (String.make 1 sep_char)
|
||||||
|
(IList.filter (fun arg ->
|
||||||
|
not (String.contains arg sep_char)
|
||||||
|
|| (
|
||||||
|
F.eprintf "Ignoring unsupported option containing '%c' character: %s@\n" sep_char arg ;
|
||||||
|
false
|
||||||
|
)
|
||||||
|
) argv)
|
||||||
|
|
||||||
|
let decode_env_to_argv env =
|
||||||
|
Str.split (Str.regexp_string (String.make 1 sep_char)) env
|
||||||
|
|
||||||
|
let prepend_to_argv args =
|
||||||
|
let cl_args = match Array.to_list Sys.argv with _ :: tl -> tl | [] -> [] in
|
||||||
|
(Sys.executable_name, args @ cl_args)
|
||||||
|
|
||||||
|
(** [prefix_before_rest (prefix @ ["--" :: rest])] is [prefix] where "--" is not in [prefix]. *)
|
||||||
|
let prefix_before_rest args =
|
||||||
|
let rec prefix_before_rest_ rev_keep = function
|
||||||
|
| [] | "--" :: _ -> IList.rev rev_keep
|
||||||
|
| keep :: args -> prefix_before_rest_ (keep :: rev_keep) args in
|
||||||
|
prefix_before_rest_ [] args
|
||||||
|
|
||||||
|
|
||||||
|
let parse env_var exe_usage =
|
||||||
|
let curr_speclist = ref []
|
||||||
|
and full_speclist = ref []
|
||||||
|
in
|
||||||
|
let usage_msg = exe_usage current_exe
|
||||||
|
in
|
||||||
|
let curr_usage status =
|
||||||
|
Arg.usage !curr_speclist usage_msg ;
|
||||||
|
exit status
|
||||||
|
and full_usage status =
|
||||||
|
Arg.usage !full_speclist usage_msg ;
|
||||||
|
exit status
|
||||||
|
in
|
||||||
|
let help_desc_list =
|
||||||
|
[ { long = "help"; short = ""; meta = ""; spec = Arg.Unit (fun () -> curr_usage 0);
|
||||||
|
doc = "Display this list of options" }
|
||||||
|
; { long = "help-full"; short = ""; meta = ""; spec = Arg.Unit (fun () -> full_usage 0);
|
||||||
|
doc = "Display the full list of options, including internal and experimental options" }
|
||||||
|
] in
|
||||||
|
let section heading speclist =
|
||||||
|
let norm k =
|
||||||
|
let len = String.length k in
|
||||||
|
if len > 3 && String.sub k 0 3 = "no-" then String.sub k 3 (len - 3) else k in
|
||||||
|
let compare_specs {long = x} {long = y} =
|
||||||
|
match x, y with
|
||||||
|
| "--", "--" -> 0
|
||||||
|
| "--", _ -> 1
|
||||||
|
| _, "--" -> -1
|
||||||
|
| _ -> String.compare (norm x) (norm y) in
|
||||||
|
let sort speclist = IList.sort compare_specs speclist in
|
||||||
|
let add_heading speclist =
|
||||||
|
match heading with
|
||||||
|
| Some heading ->
|
||||||
|
let doc = "\n " ^ heading ^ "\n" in
|
||||||
|
{ doc; long = ""; short = ""; meta = ""; spec = Arg.Unit (fun () -> ()) } :: speclist
|
||||||
|
| None ->
|
||||||
|
speclist in
|
||||||
|
let suppress_help speclist =
|
||||||
|
("-help", Arg.Unit (fun () -> raise (Arg.Bad "unknown option '-help'")), "") :: speclist in
|
||||||
|
suppress_help (align ~limit:32 (add_heading (sort speclist)))
|
||||||
|
in
|
||||||
|
let curr_desc_list = IList.assoc ( = ) current_exe exe_desc_lists
|
||||||
|
in
|
||||||
|
(* curr_speclist includes args for current exe with docs, and all other args without docs, so
|
||||||
|
that all args can be parsed, but --help and parse failures only show external args for
|
||||||
|
current exe *)
|
||||||
|
curr_speclist := (section None (help_desc_list @ !curr_desc_list))
|
||||||
|
;
|
||||||
|
assert( check_no_duplicates !curr_speclist )
|
||||||
|
;
|
||||||
|
full_speclist := (section None (help_desc_list @ !full_desc_list))
|
||||||
|
;
|
||||||
|
let env_args = decode_env_to_argv (try Unix.getenv env_var with Not_found -> "") in
|
||||||
|
(* begin transitional support for INFERCLANG_ARGS *)
|
||||||
|
let c_args =
|
||||||
|
Str.split (Str.regexp_string (String.make 1 ':'))
|
||||||
|
(try Unix.getenv "INFERCLANG_ARGS" with Not_found -> "") in
|
||||||
|
let env_args = c_args @ env_args in
|
||||||
|
(* end transitional support for INFERCLANG_ARGS *)
|
||||||
|
let exe_name, env_cl_args = prepend_to_argv env_args in
|
||||||
|
Unix.putenv env_var (encode_argv_to_env (prefix_before_rest env_cl_args)) ;
|
||||||
|
(try
|
||||||
|
Arg.parse_argv (Array.of_list (exe_name :: env_cl_args)) !curr_speclist !anon_fun usage_msg
|
||||||
|
with
|
||||||
|
| Arg.Bad usage_msg -> Pervasives.prerr_string usage_msg; exit 2
|
||||||
|
| Arg.Help usage_msg -> Pervasives.print_string usage_msg; exit 0
|
||||||
|
);
|
||||||
|
curr_usage
|
@ -0,0 +1,96 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2016 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** Definition and parsing of command line arguments *)
|
||||||
|
|
||||||
|
open! Utils
|
||||||
|
|
||||||
|
type exe = A | C | J | L | P | T
|
||||||
|
|
||||||
|
val current_exe : exe
|
||||||
|
|
||||||
|
(** The [mk_*] functions declare command line options, while [parse] parses then according to the
|
||||||
|
declared options.
|
||||||
|
|
||||||
|
The arguments of the declaration functions are largely treated uniformly:
|
||||||
|
- [long] declares the option [--long]
|
||||||
|
- [short] declares the option [-short] as an alias
|
||||||
|
- [deprecated] declares the option [-key] as an alias, for each [key] in [deprecated]
|
||||||
|
- [default] specifies the default value
|
||||||
|
- [default_to_string] is used to document the default value
|
||||||
|
- [f] specifies a transformation to be performed on the parsed value before setting the config
|
||||||
|
variable
|
||||||
|
- [symbols] is an association list sometimes used in place of [f]
|
||||||
|
- [exes] declares that the option should be included in the external documentation (--help) for
|
||||||
|
each [exe] in [exes], otherwise it appears only in --help-full
|
||||||
|
- [meta] is a meta-variable naming the parsed value for documentation purposes
|
||||||
|
- a documentation string
|
||||||
|
*)
|
||||||
|
type 'a t =
|
||||||
|
?deprecated:string list -> long:string -> ?short:string ->
|
||||||
|
?exes:exe list -> ?meta:string -> string ->
|
||||||
|
'a
|
||||||
|
|
||||||
|
(** [mk_set variable value] defines a command line option which sets [variable] to [value]. *)
|
||||||
|
val mk_set : 'a ref -> 'a -> unit t
|
||||||
|
|
||||||
|
val mk_option :
|
||||||
|
?default:'a option -> ?default_to_string:('a option -> string) -> f:(string -> 'a option) ->
|
||||||
|
'a option ref t
|
||||||
|
|
||||||
|
(** [mk_bool long short doc] defines a [bool ref] set by the command line flag [--long] (and
|
||||||
|
[-short]), and cleared by the flag [--no-long] (and [-nshort]). If [long] already has a "no-",
|
||||||
|
or [short] nas an "n", prefix, then the existing prefixes will instead be removed. The default
|
||||||
|
value is [false] unless overridden by [~default:true]. The [doc] string will be prefixed with
|
||||||
|
either "Activates:" or "Deactivates:", so should be phrased accordingly. *)
|
||||||
|
val mk_bool : ?deprecated_no:string list -> ?default:bool -> ?f:(bool -> bool) -> bool ref t
|
||||||
|
|
||||||
|
(** [mk_bool_group children] behaves as [mk_bool] with the addition that all the [children] are also
|
||||||
|
set. A child can be unset by including "--no-child" later in the arguments. *)
|
||||||
|
val mk_bool_group : ?deprecated_no:string list -> ?default:bool -> (bool ref list -> bool ref) t
|
||||||
|
|
||||||
|
val mk_int : default:int -> int ref t
|
||||||
|
|
||||||
|
val mk_float : default:float -> float ref t
|
||||||
|
|
||||||
|
val mk_string : default:string -> ?f:(string -> string) -> string ref t
|
||||||
|
|
||||||
|
val mk_string_opt : ?default:string -> ?f:(string -> string) -> string option ref t
|
||||||
|
|
||||||
|
(** [mk_string_list] defines a [string list ref], initialized to [[]] unless overridden by
|
||||||
|
[~default]. Each argument of an occurrence of the option will be prepended to the list, so the
|
||||||
|
final value will be in the reverse order they appeared on the command line. *)
|
||||||
|
val mk_string_list :
|
||||||
|
?default:string list -> ?f:(string -> string) -> string list ref t
|
||||||
|
|
||||||
|
(** [mk_symbol long symbols] defines a command line flag [--long <symbol>] where [(<symbol>,_)] is
|
||||||
|
an element of [symbols]. *)
|
||||||
|
val mk_symbol : default:'a -> symbols:(string * 'a) list -> 'a ref t
|
||||||
|
|
||||||
|
(** [mk_symbol_opt] is similar to [mk_symbol] but defaults to [None]. *)
|
||||||
|
val mk_symbol_opt : symbols:(string * 'a) list -> 'a option ref t
|
||||||
|
|
||||||
|
(** [mk_symbol_seq long symbols] defines a command line flag [--long <symbol sequence>] where
|
||||||
|
[<symbol sequence>] is a comma-separated sequence of [<symbol>]s such that [(<symbol>,_)] is an
|
||||||
|
element of [symbols]. *)
|
||||||
|
val mk_symbol_seq : ?default:'a list -> symbols:(string * 'a) list -> 'a list ref t
|
||||||
|
|
||||||
|
(** [mk_anon ()] defines a [string list ref] of the anonymous command line arguments, in the reverse
|
||||||
|
order they appeared on the command line. *)
|
||||||
|
val mk_anon :
|
||||||
|
unit ->
|
||||||
|
string list ref
|
||||||
|
|
||||||
|
(** [parse env_var exe_usage] parses command line arguments as specified by preceding calls to the
|
||||||
|
[mk_*] functions, and returns a function that prints the usage message and help text then exits.
|
||||||
|
The decoded value of environment variable [env_var] is prepended to [Sys.argv] before parsing.
|
||||||
|
Therefore arguments passed on the command line supercede those specified in the environment
|
||||||
|
variable. WARNING: If an argument appears both in the environment variable and on the command
|
||||||
|
line, it will be interpreted twice. *)
|
||||||
|
val parse : string -> (exe -> Arg.usage_msg) -> (int -> 'a)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,222 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
||||||
|
* Copyright (c) 2013 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! Utils
|
||||||
|
|
||||||
|
(** Configuration values: either constant, determined at compile time, or set at startup
|
||||||
|
time by system calls, environment variables, or command line options *)
|
||||||
|
|
||||||
|
|
||||||
|
type language = Clang | Java
|
||||||
|
|
||||||
|
val string_of_language : language -> string
|
||||||
|
|
||||||
|
type clang_lang = C | CPP | OBJC | OBJCPP
|
||||||
|
|
||||||
|
type os_type = Unix | Win32 | Cygwin
|
||||||
|
|
||||||
|
type zip_library = {
|
||||||
|
zip_filename : string;
|
||||||
|
zip_channel : Zip.in_file Lazy.t;
|
||||||
|
models : bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
(** Configuration values *)
|
||||||
|
|
||||||
|
val allow_missing_index_in_proc_call : bool
|
||||||
|
val anonymous_block_num_sep : string
|
||||||
|
val anonymous_block_prefix : string
|
||||||
|
val assign : string
|
||||||
|
val attributes_dir_name : string
|
||||||
|
val backend_stats_dir_name : string
|
||||||
|
val bound_error_allowed_in_procedure_call : bool
|
||||||
|
val captured_dir_name : string
|
||||||
|
val default_failure_name : string
|
||||||
|
val default_in_zip_results_dir : string
|
||||||
|
val dotty_output : string
|
||||||
|
val filter_buckets : bool
|
||||||
|
val frontend_stats_dir_name : string
|
||||||
|
val global_tenv_filename : string
|
||||||
|
val idempotent_getters : bool
|
||||||
|
val incremental_procs : bool
|
||||||
|
val inferconfig_file : string
|
||||||
|
val initial_analysis_time : float
|
||||||
|
val ivar_attributes : string
|
||||||
|
val max_recursion : int
|
||||||
|
val meet_level : int
|
||||||
|
val models_dir : string
|
||||||
|
val nsnotification_center_checker_backend : bool
|
||||||
|
val objc_method_call_semantics : bool
|
||||||
|
val os_type : os_type
|
||||||
|
val perf_stats_prefix : string
|
||||||
|
val proc_stats_filename : string
|
||||||
|
val property_attributes : string
|
||||||
|
val report_nullable_inconsistency : bool
|
||||||
|
val reporting_stats_dir_name : string
|
||||||
|
val save_compact_summaries : bool
|
||||||
|
val save_time_in_summaries : bool
|
||||||
|
val smt_output : bool
|
||||||
|
val source_file_extentions : string list
|
||||||
|
val sources_dir_name : string
|
||||||
|
val specs_dir_name : string
|
||||||
|
val specs_files_suffix : string
|
||||||
|
val start_filename : string
|
||||||
|
val taint_analysis : bool
|
||||||
|
val trace_absarray : bool
|
||||||
|
val undo_join : bool
|
||||||
|
val unsafe_unret : string
|
||||||
|
val weak : string
|
||||||
|
|
||||||
|
|
||||||
|
(** Configuration values specified by environment variables *)
|
||||||
|
|
||||||
|
val from_env_variable : string -> bool
|
||||||
|
val get_env_variable : string -> string option
|
||||||
|
|
||||||
|
val analyze_models : bool
|
||||||
|
val lazy_dynamic_dispatch : bool
|
||||||
|
val report_custom_error : bool
|
||||||
|
val sound_dynamic_dispatch : bool
|
||||||
|
|
||||||
|
|
||||||
|
(** Configuration values specified by command-line options *)
|
||||||
|
|
||||||
|
val anon_args : string list
|
||||||
|
val abs_struct : int
|
||||||
|
val allow_specs_cleanup : bool
|
||||||
|
val analysis_stops : bool
|
||||||
|
val analyzer : analyzer option
|
||||||
|
val angelic_execution : bool
|
||||||
|
val array_level : int
|
||||||
|
val ast_file : string option
|
||||||
|
val bugs_csv : outfile option
|
||||||
|
val bugs_json : outfile option
|
||||||
|
val bugs_txt : outfile option
|
||||||
|
val bugs_xml : outfile option
|
||||||
|
val calls_csv : outfile option
|
||||||
|
val checkers : bool
|
||||||
|
val checkers_enabled : bool
|
||||||
|
val clang_lang : clang_lang
|
||||||
|
val cluster_cmdline : string option
|
||||||
|
val code_query : string option
|
||||||
|
val continue_capture : bool
|
||||||
|
val create_harness : bool
|
||||||
|
val cxx_experimental : bool
|
||||||
|
val debug_mode : bool
|
||||||
|
val dependency_mode : bool
|
||||||
|
val developer_mode : bool
|
||||||
|
val dotty_cfg_libs : bool
|
||||||
|
val eradicate : bool
|
||||||
|
val err_file_cmdline : string
|
||||||
|
val infer_cache : string option
|
||||||
|
val inferconfig_home : string option
|
||||||
|
val iterations : int
|
||||||
|
val javac_verbose_out : string
|
||||||
|
val join_cond : int
|
||||||
|
val latex : outfile option
|
||||||
|
val load_analysis_results : string option
|
||||||
|
val makefile_cmdline : string
|
||||||
|
val merge : bool
|
||||||
|
val ml_buckets :
|
||||||
|
[ `MLeak_all | `MLeak_arc | `MLeak_cf | `MLeak_cpp | `MLeak_no_arc | `MLeak_unknown ] list
|
||||||
|
val models_file : string option
|
||||||
|
val models_mode : bool
|
||||||
|
val modified_targets : string option
|
||||||
|
val monitor_prop_size : bool
|
||||||
|
val nelseg : bool
|
||||||
|
val no_static_final : bool
|
||||||
|
val no_translate_libs : bool
|
||||||
|
val nonstop : bool
|
||||||
|
val objc_memory_model_on : bool
|
||||||
|
val only_footprint : bool
|
||||||
|
val optimistic_cast : bool
|
||||||
|
val out_file_cmdline : string
|
||||||
|
val precondition_stats : bool
|
||||||
|
val print_builtins : bool
|
||||||
|
val print_types : bool
|
||||||
|
val print_using_diff : bool
|
||||||
|
val procs_csv : outfile option
|
||||||
|
val procs_xml : outfile option
|
||||||
|
val project_root : string option
|
||||||
|
val quiet : bool
|
||||||
|
val reactive_mode : bool
|
||||||
|
val report : outfile option
|
||||||
|
val report_runtime_exceptions : bool
|
||||||
|
val reports_include_ml_loc : bool
|
||||||
|
val results_dir : string
|
||||||
|
val save_analysis_results : string option
|
||||||
|
val seconds_per_iteration : float
|
||||||
|
val show_buckets : bool
|
||||||
|
val show_progress_bar : bool
|
||||||
|
val source_file : string option
|
||||||
|
val source_file_copy : string option
|
||||||
|
val spec_abs_level : int
|
||||||
|
val specs_library : string list
|
||||||
|
val stats_mode : bool
|
||||||
|
val subtype_multirange : bool
|
||||||
|
val suppress_warnings_annotations : string option
|
||||||
|
val svg : bool
|
||||||
|
val symops_per_iteration : int
|
||||||
|
val test : bool
|
||||||
|
val test_filtering : bool
|
||||||
|
val testing_mode : bool
|
||||||
|
val trace_error : bool
|
||||||
|
val trace_join : bool
|
||||||
|
val trace_rearrange : bool
|
||||||
|
val type_size : bool
|
||||||
|
val unit_test : bool
|
||||||
|
val whole_seconds : bool
|
||||||
|
val worklist_mode : int
|
||||||
|
val write_dotty : bool
|
||||||
|
val write_html : bool
|
||||||
|
val xml_specs : bool
|
||||||
|
val zip_libraries : zip_library list
|
||||||
|
|
||||||
|
|
||||||
|
(** Global variables *)
|
||||||
|
|
||||||
|
(** [set_reference_and_call_function ref val f x] calls f x with ref set to val.
|
||||||
|
Restore the initial value also in case of exception. *)
|
||||||
|
val set_reference_and_call_function : 'a ref -> 'a -> ('b -> 'c) -> 'b -> 'c
|
||||||
|
|
||||||
|
val footprint : bool ref
|
||||||
|
|
||||||
|
(** Call f x with footprint set to true.
|
||||||
|
Restore the initial value of footprint also in case of exception. *)
|
||||||
|
val run_in_footprint_mode : ('a -> 'b) -> 'a -> 'b
|
||||||
|
|
||||||
|
(** Call f x with footprint set to false.
|
||||||
|
Restore the initial value of footprint also in case of exception. *)
|
||||||
|
val run_in_re_execution_mode : ('a -> 'b) -> 'a -> 'b
|
||||||
|
|
||||||
|
val forcing_delayed_prints : bool ref
|
||||||
|
val nLOC : int ref
|
||||||
|
val pp_simple : bool ref
|
||||||
|
|
||||||
|
|
||||||
|
(** Global variables with initial values specified by command-line options *)
|
||||||
|
|
||||||
|
val abs_val : int ref
|
||||||
|
|
||||||
|
val reset_abs_val : unit -> unit
|
||||||
|
|
||||||
|
(** Call f x with abs_val set to zero.
|
||||||
|
Restore the initial value also in case of exception. *)
|
||||||
|
val run_with_abs_val_equal_zero : ('a -> 'b) -> 'a -> 'b
|
||||||
|
|
||||||
|
val allow_leak : bool ref
|
||||||
|
val arc_mode : bool ref
|
||||||
|
val curr_language : language ref
|
||||||
|
|
||||||
|
|
||||||
|
(** Command Line Interface Documentation *)
|
||||||
|
|
||||||
|
val print_usage_exit : unit -> 'a
|
@ -1,16 +0,0 @@
|
|||||||
(*
|
|
||||||
* Copyright (c) 2015 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*)
|
|
||||||
|
|
||||||
open! Utils
|
|
||||||
|
|
||||||
(** arguments for InferLLVM *)
|
|
||||||
|
|
||||||
let debug_mode = ref false
|
|
||||||
|
|
||||||
let source_filename : string option ref = ref None
|
|
@ -1,16 +0,0 @@
|
|||||||
(*
|
|
||||||
* Copyright (c) 2015 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*)
|
|
||||||
|
|
||||||
open! Utils
|
|
||||||
|
|
||||||
(** arguments for InferLLVM *)
|
|
||||||
|
|
||||||
val debug_mode : bool ref
|
|
||||||
|
|
||||||
val source_filename : string option ref
|
|
Loading…
Reference in new issue