6131e079c1af15e35d1a4c22a2541e3015e9a052
[bpt/coccinelle.git] / bundles / menhirLib / menhir-20120123 / demos / ocamldep.wrapper
1 #!/usr/bin/env ocaml
2
3 (* ocamldep.wrapper <filename> ... <filename> - <ocamldep command>
4 runs the <ocamldep command> in an environment where all of the
5 <filenames> listed appear to exist. The files are created, if
6 required, before the command is run, and destroyed afterwards. *)
7
8 (* An earlier version of this script acquired a lock, so as to prevent
9 multiple instances of this script from interfering with one another.
10 However, this did not prevent interference between this script and
11 some other process (e.g., the ocaml compiler) which creates files.
12 So, the lock has been removed. My suggestion is to never use this
13 script in a concurrent setting. If you wish to use parallel make,
14 then you might be able to use a two-level Makefile approach: first,
15 compute all dependencies in a sequential manner; then, construct all
16 targets in a parallel manner. *)
17
18 #load "unix.cma"
19 open Printf
20
21 (* Parse the command line. The arguments that precede "-" are understood
22 as file names and stored in the list [xs]. The arguments that follow
23 "-" are understood as a command and stored in [command]. *)
24
25 let xs =
26 ref []
27
28 let command =
29 ref ""
30
31 let verbose =
32 ref false
33
34 let rec loop accumulating i =
35 if i = Array.length Sys.argv then
36 ()
37 else if accumulating then
38 (* [accumulating] is [true] as long as we have not found the "-" marker *)
39 match Sys.argv.(i) with
40 | "-v" ->
41 verbose := true;
42 loop true (i+1)
43 | "-" ->
44 (* We have found the marker. The next parameter should be the name of
45 the raw [ocamldep] command. Copy it to the command (unquoted --
46 apparently some shells do not permit quoting a command name). *)
47 let i = i + 1 in
48 assert (i < Array.length Sys.argv);
49 command := Sys.argv.(i);
50 (* Stop accumulating file names. Copy the remaining arguments into
51 the command. *)
52 loop false (i+1)
53 | _ ->
54 (* Continue accumulating file names in [xs]. *)
55 xs := Sys.argv.(i) :: !xs;
56 loop true (i+1)
57 else begin
58 (* After we have found the "-" marker, the remaining arguments are
59 copied (quoted) into the command. *)
60 command := sprintf "%s %s" !command (Filename.quote Sys.argv.(i));
61 loop false (i+1)
62 end
63
64 let () =
65 loop true 1
66
67 (* Create the required files if they don't exist, run the command,
68 then destroy any files that we have created. *)
69
70 let rec loop = function
71 | [] ->
72 if !verbose then
73 fprintf stderr "ocamldep.wrapper: running %s\n" !command;
74 Sys.command !command
75 | x :: xs ->
76 if Sys.file_exists x then
77 loop xs
78 else begin
79 if !verbose then
80 fprintf stderr "ocamldep.wrapper: creating fake %s\n" x;
81 let c = open_out x in
82 close_out c;
83 let exitcode = loop xs in
84 if Sys.file_exists x then begin
85 try
86 if !verbose then
87 fprintf stderr "ocamldep.wrapper: removing fake %s..." x;
88 Sys.remove x;
89 if !verbose then
90 fprintf stderr " ok\n"
91 with Sys_error _ ->
92 if !verbose then
93 fprintf stderr " failed\n"
94 end;
95 exitcode
96 end
97
98 let () =
99 exit (loop !xs)