865e0a16069d31581e141e92ebbf1ceb564a71fe
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
25 (* The following finds out for each file, how it does deallocation for each
31 let l = input_line i
in
32 (if String.length
l > 2 && String.get
l 0 = '
+'
33 then info := (String.sub
l 1 (String.length
l - 1))::!info);
36 with End_of_file
-> List.rev
!info
39 let rec loop acc
= function
42 if String.get x
0 = '
+'
(* the start of a new file *)
44 (match Str.split (Str.regexp
" ") x
with
45 _
::x
::_
-> loop ((x
,[])::acc
) xs
46 | _
-> failwith
("no file: "^x
))
50 (file
,instances
)::rest
-> (file
,x
::instances
)::rest
51 | _
-> failwith
"not possible" in
53 let res = List.rev
(loop [] l) in
54 List.map
(function (x
,l) -> (x
,List.rev
l)) res
56 let detect_alloc_free str
l =
58 let (same
,diff
) = List.partition
(function (a1
,f1
) -> a
= a1
) l in
60 [(a1
,f1
)] -> if List.mem f f1
then l else (a1
,f
::f1
) :: diff
62 let rec loop acc = function
65 match Str.split (Str.regexp
(str^
"\", ")) x
with
71 (match Str.split (Str.regexp
"[, )]+") rest
with
72 alloc
::free
::_
-> try_add alloc free
acc
78 (List.map
(function (a
,f
) -> (a
,List.sort compare f
)) (loop [] l))
80 let rec iterate str
= function
87 List.partition
(function (x1
,l1
) -> l1
= info) rest
in
89 [(files
,info)] -> (x
::files
,info)::diff
90 | _
-> ([x
],info)::diff
)
91 (iterate str xs
) (detect_alloc_free str
l)
93 (* ------------------------------------------------------------------------ *)
94 (* The following prints that information *)
98 (function (files
,(a
,fs
)) ->
99 List.iter
(function x
-> Printf.printf
"%s\n" x
) files
;
100 Printf.printf
" alloc: %s, free: %s\n" a
(String.concat
", " fs
);
104 (* ------------------------------------------------------------------------ *)
105 (* The following makes a semantic patch for that information *)
107 let sedify o generic_file dir
l =
109 (function (files
,(a
,fs
)) ->
115 "sed s/ALLOC/%s/ %s | sed s/FREE/%s/ > %s/%s-%s.cocci\n"
116 a generic_file f dir a f
) in ()
120 (function (files
,(a
,fs
)) ->
122 [f
] -> Printf.fprintf o
"mono_spatch_linux %s-%s.cocci &\n" a f
126 let collect_allocs l =
129 (function rest
-> function x
->
130 if List.mem x rest
then rest
else x
::rest
) in
133 function (files
,(a
,fs
)) ->
135 List.partition
(function (a1
,fs1
) -> a
= a1
) rest
in
137 [(a1
,fs1
)] -> (a
,union fs fs1
)::diff
139 | _ -> failwith
"not possible")
142 let sedify_ors o generic_file dir
l =
143 let l = collect_allocs l in
150 Printf.sprintf
"\"\\\\\\(%s\\\\\\)\""
151 (String.concat
"\\\\\\|" fs
) in
155 "sed s/ALLOC/%s/ %s | sed s/FREE/%s/ > %s/%s-%s_et_al.cocci\n"
156 a generic_file
sfs dir a f
) in ())
163 Printf.fprintf o
"mono_spatch_linux %s-%s_et_al.cocci &\n" a f
)
166 (* ------------------------------------------------------------------------ *)
169 let gen = ref "generic2.cocci"
172 let str = ref "detected allocator"
174 let options = [ "-sed", Arg.Set
sed, "sed output";
175 "-sp", Arg.String
(function x
-> gen := x
),
177 "-str", Arg.String
(function x
-> str := x
),
178 "cocci file for use with sed";
179 "-dir", Arg.String
(function x
-> dir := x
),
180 "dir for sed output"; ]
184 Arg.parse
(Arg.align
options) (fun x
-> file := x
) usage;
185 let i = open_in
!file in
189 let l = iterate !str l in
193 let o = open_out
(Printf.sprintf
"%s/files" !dir) in
194 Printf.fprintf
o "#!/bin/sh\n\n";
195 sedify o !gen !dir l;
196 sedify_ors o !gen !dir l;
197 Printf.fprintf
o "\nwait\n/bin/rm tmp*out\n";
200 if not
!sed then print_output l