Release coccinelle-0.2.0
[bpt/coccinelle.git] / tools / spp.ml
1 (*
2 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
3 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
4 * This file is part of Coccinelle.
5 *
6 * Coccinelle is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, according to version 2 of the License.
9 *
10 * Coccinelle is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * The authors reserve the right to distribute this or future versions of
19 * Coccinelle under other licenses.
20 *)
21
22
23 open Common
24
25 exception WrongArguments
26
27 (* could do via a List.filter because cpp flags are simple as it's
28 * "-I/usr/include" not ["-I";"/usr/include"] like in ocaml so no
29 * need to look multiple args.
30 *)
31 let rec cpp_flags_filter xs =
32 match xs with
33 | [] -> []
34 | x::xs ->
35 (match x with
36 | s when x =~ "-D.*" ->
37 s::cpp_flags_filter xs
38 | s when s =~ "-I.*" ->
39 s::cpp_flags_filter xs
40 | _ ->
41 cpp_flags_filter xs
42 )
43
44 let is_compile_command xs =
45 List.mem "-c" xs
46
47 let source_file xs =
48 xs +> List.filter (fun s -> s =~ ".*\\.c$")
49
50 let rec fix_args args file =
51 match args with
52 [] -> []
53 | hd::tail ->
54 if hd = file then
55 (hd^".i") :: tail
56 else
57 hd::fix_args tail file
58
59 let rec get_outputfile args =
60 match args with
61 [] -> ([],"")
62 | hd::tail ->
63 if hd = "-o" then
64 let (hd',tail') = match tail with
65 hd'::tail' -> (hd',tail')
66 | _ -> raise WrongArguments
67 in
68 (tail', hd')
69 else
70 let (ntail, out) = get_outputfile tail in
71 (hd::ntail, out)
72
73 let main () =
74 let args = List.tl (Array.to_list Sys.argv) in
75 (*args +> List.iter pr2;*)
76 if is_compile_command args
77 then begin
78 let file = source_file args in
79 (match file with
80 | [file] ->
81 let cpp_flags = cpp_flags_filter args in
82 let cmd2 =
83 (spf "cpp %s %s > %s.i"
84 (Common.join " " cpp_flags)
85 file
86 file)
87 in
88 pr2 cmd2;
89 let ret2 = Sys.command cmd2 in
90 if ret2 > 0 then exit ret2;
91 let sp_args = fix_args args file in
92 let cmd = "spatch " ^ (Common.join " " sp_args) in
93 pr2 cmd;
94 let ret = Sys.command cmd in
95 exit ret
96
97 | [] -> failwith "could not find name of source file"
98 | x::y::xs -> failwith "multiple source files"
99 );
100 end
101 else
102 begin
103 let (nargs, outfile) = get_outputfile args in
104 let cmd2 =
105 (spf "cat %s > %s"
106 (Common.join " " nargs)
107 outfile)
108 in
109 pr2 cmd2;
110 Sys.command cmd2
111 end
112
113 let _ = main ()