Skip to content

Commit

Permalink
Refactor feature loading
Browse files Browse the repository at this point in the history
  • Loading branch information
kerneis committed Jun 30, 2014
1 parent f50c7b5 commit e1f9baf
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 41 deletions.
21 changes: 1 addition & 20 deletions src/feature.ml
Expand Up @@ -130,25 +130,6 @@ let add_plugin path =

(** Look for plugin and depencies and add them *)
let loadWithDeps s =
init ();
let paths = find_plugin s in
List.iter add_plugin paths

(** Parse only {switch} command-line option, ignoring every error raised by other, unparsed
* options. Return the list of plugins to load. *)
let loadFromArgv switch =
let spec = [
switch, Arg.String loadWithDeps, "";
(* ignore --help at this stage *)
"--help", Arg.Unit ignore, ""; "-help", Arg.Unit ignore, "" ] in
let idx = ref 0 in
let rec aux () =
try
Arg.parse_argv ~current:idx Sys.argv spec ignore ""
with Arg.Bad _ | Arg.Help _ -> aux ()
in init (); aux ()

let loadFromEnv name default =
let plugins =
try Str.split (Str.regexp "[ ,]+") (Sys.getenv name)
with Not_found -> default in
List.iter loadWithDeps plugins
13 changes: 0 additions & 13 deletions src/feature.mli
Expand Up @@ -82,22 +82,9 @@ val enabled : string -> bool

(**/**)

(** Initialize the module. This needs to be called before {!loadWithDeps} is
* used. Called automatically by {!loadFromArgv}. *)
val init : unit -> unit

(** Find and dynamically links a module. The name should be either a path to a
* cmo, cma or cmxs file, or the name of a findlib package. In the latter case,
* package dependencies are loaded automatically. Each file is loaded at most
* one. The loaded module must call {!registerFeature} to make its features
* available to CIL. *)
val loadWithDeps : string -> unit

(** {!loadFromArgv switch} searches {!Sys.argv} for the command-line option
* {!switch}, and loads the modules passed as parameters. Ignores every other
* {!Sys.argv} element. *)
val loadFromArgv : string -> unit

(** {!loadFromEnv name default} loads coma-separated module names stored in the
* environment variable {!name}, or {!default} if it is not defined. *)
val loadFromEnv : string -> string list -> unit
19 changes: 11 additions & 8 deletions src/main.ml
Expand Up @@ -60,7 +60,7 @@ let parseOneFile (fname: string) : C.file =
if !Cilutil.printStages then ignore (E.log "Parsing %s\n" fname);
let cil = F.parse fname () in

if (not (Feature.enabled "epicenter")) then (
if (not (Fe.enabled "epicenter")) then (
(* sm: remove unused temps to cut down on gcc warnings *)
(* (Stats.time "usedVar" Rmtmps.removeUnusedTemps cil); *)
(* (trace "sm" (dprintf "removing unused temporaries\n")); *)
Expand Down Expand Up @@ -101,7 +101,7 @@ let rec processOneFile (cil: C.file) =
end
end
end)
(Feature.list_registered ());
(Fe.list_registered ());


(match !outChannel with
Expand Down Expand Up @@ -133,10 +133,13 @@ let theMain () =
* wants these suppressed *)
C.print_CIL_Input := true;

(* Load plugins. This needs to be done before command-line arguments are
* built. *)
Feature.loadFromEnv "CIL_FEATURES" ["cil.default-features"];
Feature.loadFromArgv "--load";
(* Load plugins from environment and command-line. This needs to be
* done before command-line arguments are built. *)
let env_plugins =
try Str.split (Str.regexp "[ ,]+") (Sys.getenv "CIL_FEATURES")
with Not_found -> ["cil.default-features"] in
List.iter Fe.loadWithDeps env_plugins;
Util.parse_argv_skip_unknown ["--load", Arg.String Fe.loadWithDeps, ""] ignore;


(*********** COMMAND LINE ARGUMENTS *****************)
Expand All @@ -158,11 +161,11 @@ let theMain () =
" Enable " ^ fdesc.Fe.fd_description) ::
fdesc.Fe.fd_extraopt @ acc
)
(Feature.list_registered ())
(Fe.list_registered ())
[blankLine]
in
let featureArgs =
if Feature.list_registered () = [] then [] else
if Fe.list_registered () = [] then [] else
("", Arg.Unit (fun () -> ()), " \n\t\tCIL Features") :: featureArgs
in

Expand Down
8 changes: 8 additions & 0 deletions src/ocamlutil/util.ml
Expand Up @@ -65,3 +65,11 @@ let make_counter () =
let c = ref 0 in
(fun () -> incr c; !c),
(fun () -> c := 0)

let parse_argv_skip_unknown speclist anon_fun =
let idx = ref 0 in
let rec parse () =
try
Arg.parse_argv ~current:idx Sys.argv speclist anon_fun ""
with Arg.Bad _ | Arg.Help _ -> parse ()
in parse ()
5 changes: 5 additions & 0 deletions src/ocamlutil/util.mli
Expand Up @@ -25,3 +25,8 @@ val equals: 'a -> 'a -> bool
* counter (initialized to 0) and returns its new value; the second one
* resets the counter to 0. *)
val make_counter : unit -> (unit -> int) * (unit -> unit)

(** Same as {!Arg.parse} except it skips every unknown option, and
* disables [-help] and [--help]. *)
val parse_argv_skip_unknown : (Arg.key * Arg.spec * Arg.doc) list ->
Arg.anon_fun -> unit

0 comments on commit e1f9baf

Please sign in to comment.