- (* Command line arguments. *)
- let filename = ref "Goalfile" in
-
- let argspec = [
- "-f", Arg.Set_string filename,
- "filename Set name of Goalfile";
- "--file", Arg.Set_string filename,
- "filename Set name of Goalfile";
- ] in
- let argspec = Arg.align argspec in
- let args = ref [] in
- let anon_fun s = args := s :: !args in
- Arg.parse argspec anon_fun usage;
-
- (*let args = List.rev !args in*)
- let filename = !filename in
-
- (* Parse the input file. *)
- let file = Parse.parse_goalfile filename in
-
- (* Parse the command line anon args. Each parameter has the
- * form "name=<expr>" to assign a value to a variable, or
- * "<expr>" to indicate a target to build.
- *)
- let assignments = ref [] in
- let targets = ref [] in
- List.iter (
- fun arg ->
- if Str.string_match var_regexp arg 0 then ( (* assignment *)
- let name = Str.matched_group 1 arg in
- let expr = Parse.parse_cli_expr (Str.matched_group 2 arg) in
- assignments := Ast.Let (name, expr) :: !assignments
- )
- else ( (* target *)
- let expr = Parse.parse_cli_expr arg in
- targets := expr :: !targets
- )
- ) !args;
-
- (* If no target was set on the command line, find
- * the first goal in the file.
- *)
- if !targets = [] then (
- try
- let first_goal =
- List.find (function Ast.Goal _ -> true | _ -> false) file in
- match first_goal with
- | Ast.Goal (name, [], _, _, _) ->
- targets := [Ast.ECall (name, [])]
- | Ast.Goal (name, _, _, _, _) ->
- failwithf "%s: first target ā%sā has parameters and so cannot be used as the default target"
- filename name
- | _ -> assert false
- with
- (* Actually this is fine. If there are no goals we'll do nothing. *)
- Not_found -> ()
- );
-
- let targets = List.rev !targets in
-
- (* Assignments are simply treated as statements added to the end of
- * the file (so they override earlier assignments to the same variable,
- * if any).
+ (* Handle the command line. *)
+ let anon_vars, targets = Cmdline.parse () in
+
+ (* Change directory (-C option). *)
+ Sys.chdir (Cmdline.directory ());
+
+ (* Create a temporary directory which is always cleaned up at exit. *)
+ let tmpdir =
+ let temp_dir = try Unix.getenv "TMPDIR" with Not_found -> "/var/tmp" in
+ let t = Filename.temp_file ~temp_dir "goals" ".d" in
+ Unix.unlink t;
+ Unix.mkdir t 0o700;
+ at_exit (
+ fun () ->
+ let cmd = sprintf "rm -rf %s" (Filename.quote t) in
+ ignore (Sys.command cmd)
+ );
+ t in
+
+ (* Create the initial environment, containing the system environment
+ * and a few other standard strings.