2 String.concat
"" (Str.split
(Str.regexp
"[ ]+") s
)
4 let parse_line fp l n
=
8 if Str.string_match
(Str.regexp
"#") l
0
9 then None
(* comment line *)
11 let top_split = Str.split
(Str.regexp
":") l
in
13 cocci
::first
::others
->
14 let rec loop tag
= function
17 String.concat
"\\ " (Str.split
(Str.regexp
"[ ]+") x) in
20 let splitted = Str.split
(Str.regexp
"[ ]+") first
in
21 (match List.rev
splitted with
23 let rest = loop new_tag
rest in
24 (tag
,String.concat
"\\ " info
)::rest
25 | _
-> failwith
"bad element")
26 | _
-> failwith
"no data" in
27 Some
(cocci
,loop (drop_spaces first
) others
)
28 | _
-> failwith
(Printf.sprintf
"bad line: %s" l
)
30 let collect_lines fp i
=
35 (match parse_line fp
(input_line i
) !ln with
39 else lines := l
::!lines
42 try loop() with End_of_file
-> !lines
44 (* --------------------------------------------------------------------- *)
48 let lines = ref ([] : string list
) in
50 let l = input_line
i in
51 (if not
(Str.string_match
(Str.regexp
"#") l 0)
52 then lines := l :: !lines);
54 (try loop() with End_of_file
-> ());
58 (* --------------------------------------------------------------------- *)
60 let discard_ambiguous lines =
61 let rec loop = function
63 | (cocci
,tags
)::rest ->
66 (function (cocci2
,tags2
) -> tags
= tags2
&& not
(cocci
= cocci2
))
69 [] -> (cocci
,tags
)::loop rest
71 Printf.printf
"ignoring ambiguity:\n";
73 (function (cocci
,tags
) ->
74 Printf.printf
"%s: %s\n" cocci
77 (function (tag
,tagval
) ->
78 Printf.sprintf
"%s: %s" tag tagval
)
84 (* --------------------------------------------------------------------- *)
85 (* only actually collects the rightmost element into ors *)
87 let split_or (cocci
,line
) =
88 let rev = List.rev line
in
89 (cocci
,List.rev(List.tl
rev), List.hd
rev)
91 let collect_ors fp
lines =
92 let rec loop = function
93 [] -> failwith
"no lines"
95 let (c
,k
,v
) = split_or line
in
98 let (c
,k
,v
) = split_or line
in
99 let ((c1
,k1
,v1
),rest) = loop xs
in
100 if c
= c1
&& k
= k1
&& not
(k
= [])
103 then ((c1
,k1
,v1
),rest)
104 else ((c1
,k1
,v
::v1
),rest)
105 else ((c
,k
,[v
]),((c1
,k1
,v1
)::rest)) in
106 let ((c
,k
,v
),rest) = loop lines in
107 let res = (c
,k
,v
)::rest in
112 [] -> failwith
"not possible"
113 | [x] -> (c
,k
@v
) :: prev
116 Printf.sprintf "%s:(%s)" tag
119 (List.map (function (_,vl) -> vl) v))) in
121 Printf.sprintf "%s: %s %s" c
122 (String.concat " " (List.map (function (k,v) -> k^":"^v) k))
124 if true (*List.mem attempt fp*)
127 Printf.sprintf
"\\\\\\\\\\(%s\\\\\\\\\\)"
128 (String.concat
"\\\\\\\\\\|"
130 (List.map
(function (_
,vl
) -> vl
) v
))) in
131 (c
,k
@[(tag
,vs)]) :: prev
132 else (List.map
(function vi
-> (c
,k
@[vi
])) v
) @ prev
)
135 (* --------------------------------------------------------------------- *)
138 let _ = Sys.command s
in
141 let created = ref ([] : (string * (int ref * out_channel
)) list
)
143 let mktag n
= Printf.sprintf
"x%d" n
145 let created_files = ref ([] : (string * int ref) list
)
147 let process_line env
(cocci
,tags
) =
148 let files = List.filter
(function (c
,f
) -> c
= cocci
) env
in
150 (function (_,cocci_file
) ->
151 let resdir = Filename.chop_extension cocci_file
in
152 (if not
(Sys.file_exists cocci_file
)
153 then failwith
"no cocci file");
155 try List.assoc
resdir !created
159 (Printf.sprintf
"/bin/rm -r -f %s; mkdir %s" resdir resdir);
160 let files = Printf.sprintf
"%s/files" resdir in
161 let o = open_out
files in
162 Printf.fprintf
o "all: real_all\n\n";
163 let cell = ((ref 0),o) in
164 created := (resdir,cell) :: !created;
167 let temp_file = Filename.temp_file cocci
".cocci" in
168 command (Printf.sprintf
"cp %s %s" cocci_file
temp_file);
171 [] -> failwith
"no tags"
172 | (_,first_tag_val)::_ ->
174 try List.assoc
first_tag_val !created_files
177 created_files := (first_tag_val,c)::!created_files;
182 else Printf.sprintf
"%s%d" first_tag_val !cell in
184 (function (tag
,tagval
) ->
186 (Printf.sprintf
"sed s/%s/%s/ %s > %s_out; cp %s_out %s"
187 tag tagval
temp_file temp_file temp_file temp_file))
190 (Printf.sprintf
"mv %s %s/%s.cocci" temp_file resdir first_tag_val);
191 Printf.fprintf
o "%s:\n\tmono_spatch_linux %s.cocci ${ARGS}\n\n"
192 (mktag !n
) first_tag_val;
196 (* --------------------------------------------------------------------- *)
198 let rec mkenv = function
200 | [_] -> failwith
"required arguments: file (category x cocci file)*"
201 | category
::cocci
::rest ->
202 if Filename.check_suffix cocci
".cocci"
203 then (category
,cocci
)::mkenv rest
204 else failwith
"required arguments: file (category x cocci file)*"
206 let rec upto = function
208 | n
-> (mktag (n
-1)) :: (upto (n
-1))
212 match List.tl
(Array.to_list
Sys.argv
) with
214 let rec loop prev
= function
221 let _ = Str.search_forward
(Str.regexp
".cocci") x 0 in
224 else ([],prev
::x::xs
)
226 let (fp
,env
) = loop x xs
in
229 else (prev
::fp
,env
) in
230 let (fp
,env
) = loop "" env
in
232 | _ -> failwith
"one argument expected" in
233 let fp = List.fold_left
(@) [] (List.map
process_fp fp) in
234 let i = open_in file
in
235 let lines = collect_lines fp i in
236 let lines = collect_ors fp lines in
238 let lines = discard_ambiguous lines in
239 List.iter
(process_line env
) lines;
241 (function (resdir,(n
,o)) ->
242 Printf.fprintf
o "real_all: %s\n"
243 (String.concat
" " (List.rev (upto !n
)));