7e161df289227af92e1d37fca18800c2cd9a37d8
2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
29 * Copyright 2012, INRIA
30 * Julia Lawall, Gilles Muller
31 * Copyright 2010-2011, INRIA, University of Copenhagen
32 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
33 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
34 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
35 * This file is part of Coccinelle.
37 * Coccinelle is free software: you can redistribute it and/or modify
38 * it under the terms of the GNU General Public License as published by
39 * the Free Software Foundation, according to version 2 of the License.
41 * Coccinelle is distributed in the hope that it will be useful,
42 * but WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 * GNU General Public License for more details.
46 * You should have received a copy of the GNU General Public License
47 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
49 * The authors reserve the right to distribute this or future versions of
50 * Coccinelle under other licenses.
55 (* The following finds out for each file, how it does deallocation for each
61 let l = input_line i
in
62 (if String.length
l > 2 && String.get
l 0 = '
+'
63 then info := (String.sub
l 1 (String.length
l - 1))::!info);
66 with End_of_file
-> List.rev
!info
69 let rec loop acc
= function
72 if String.get x
0 = '
+'
(* the start of a new file *)
74 (match Str.split (Str.regexp
" ") x
with
75 _
::x
::_
-> loop ((x
,[])::acc
) xs
76 | _
-> failwith
("no file: "^x
))
80 (file
,instances
)::rest
-> (file
,x
::instances
)::rest
81 | _
-> failwith
"not possible" in
83 let res = List.rev
(loop [] l) in
84 List.map
(function (x
,l) -> (x
,List.rev
l)) res
86 let detect_alloc_free str
l =
88 let (same
,diff
) = List.partition
(function (a1
,f1
) -> a
= a1
) l in
90 [(a1
,f1
)] -> if List.mem f f1
then l else (a1
,f
::f1
) :: diff
92 let rec loop acc = function
95 match Str.split (Str.regexp
(str^
"\", ")) x
with
101 (match Str.split (Str.regexp
"[, )]+") rest
with
102 alloc
::free
::_
-> try_add alloc free
acc
106 | _
-> loop acc xs
in
108 (List.map
(function (a
,f
) -> (a
,List.sort compare f
)) (loop [] l))
110 let rec iterate str
= function
117 List.partition
(function (x1
,l1
) -> l1
= info) rest
in
119 [(files
,info)] -> (x
::files
,info)::diff
120 | _
-> ([x
],info)::diff
)
121 (iterate str xs
) (detect_alloc_free str
l)
123 (* ------------------------------------------------------------------------ *)
124 (* The following prints that information *)
128 (function (files
,(a
,fs
)) ->
129 List.iter
(function x
-> Printf.printf
"%s\n" x
) files
;
130 Printf.printf
" alloc: %s, free: %s\n" a
(String.concat
", " fs
);
134 (* ------------------------------------------------------------------------ *)
135 (* The following makes a semantic patch for that information *)
137 let sedify o generic_file dir
l =
139 (function (files
,(a
,fs
)) ->
145 "sed s/ALLOC/%s/ %s | sed s/FREE/%s/ > %s/%s-%s.cocci\n"
146 a generic_file f dir a f
) in ()
150 (function (files
,(a
,fs
)) ->
152 [f
] -> Printf.fprintf o
"mono_spatch_linux %s-%s.cocci &\n" a f
156 let collect_allocs l =
159 (function rest
-> function x
->
160 if List.mem x rest
then rest
else x
::rest
) in
163 function (files
,(a
,fs
)) ->
165 List.partition
(function (a1
,fs1
) -> a
= a1
) rest
in
167 [(a1
,fs1
)] -> (a
,union fs fs1
)::diff
169 | _ -> failwith
"not possible")
172 let sedify_ors o generic_file dir
l =
173 let l = collect_allocs l in
180 Printf.sprintf
"\"\\\\\\(%s\\\\\\)\""
181 (String.concat
"\\\\\\|" fs
) in
185 "sed s/ALLOC/%s/ %s | sed s/FREE/%s/ > %s/%s-%s_et_al.cocci\n"
186 a generic_file
sfs dir a f
) in ())
193 Printf.fprintf o
"mono_spatch_linux %s-%s_et_al.cocci &\n" a f
)
196 (* ------------------------------------------------------------------------ *)
199 let gen = ref "generic2.cocci"
202 let str = ref "detected allocator"
204 let options = [ "-sed", Arg.Set
sed, "sed output";
205 "-sp", Arg.String
(function x
-> gen := x
),
207 "-str", Arg.String
(function x
-> str := x
),
208 "cocci file for use with sed";
209 "-dir", Arg.String
(function x
-> dir := x
),
210 "dir for sed output"; ]
214 Arg.parse
(Arg.align
options) (fun x
-> file := x
) usage;
215 let i = open_in
!file in
219 let l = iterate !str l in
223 let o = open_out
(Printf.sprintf
"%s/files" !dir) in
224 Printf.fprintf
o "#! /bin/sh\n\n";
225 sedify o !gen !dir l;
226 sedify_ors o !gen !dir l;
227 Printf.fprintf
o "\nwait\n/bin/rm tmp*out\n";
230 if not
!sed then print_output l