Release coccinelle-0.1.6
[bpt/coccinelle.git] / parsing_cocci / .#parse_aux.ml.1.26
CommitLineData
113803cf
C
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
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(* exports everything, used only by parser_cocci_menhir.mly *)
24module Ast0 = Ast0_cocci
25module Ast = Ast_cocci
26
27(* types for metavariable tokens *)
28type info = Ast.meta_name * Ast0.pure * Data.clt
29type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt
30type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt
31type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt
32type list_info = Ast.meta_name * Ast.meta_name option * Ast0.pure * Data.clt
33type typed_info =
34 Ast.meta_name * Data.econstraints * Ast0.pure *
35 Type_cocci.typeC list option * Data.clt
36type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt
37
38
39let get_option fn = function
40 None -> None
41 | Some x -> Some (fn x)
42
43let make_info line logical_line offset col strbef straft =
44 { Ast0.line_start = line; Ast0.line_end = line;
45 Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
46 Ast0.attachable_start = true; Ast0.attachable_end = true;
47 Ast0.mcode_start = []; Ast0.mcode_end = [];
48 Ast0.column = col; Ast0.offset = offset;
49 Ast0.strings_before = strbef; Ast0.strings_after = straft; }
50
51let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) =
52 make_info line logical_line offset col strbef straft
53
54let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) =
55 (arity,line,lline,offset,col,[],straft,pos)
56
57let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) =
58 (arity,line,lline,offset,col,strbef,[],pos)
59
60let clt2mcode str = function
61 (Data.MINUS,line,lline,offset,col,strbef,straft,pos) ->
62 (str,Ast0.NONE,make_info line lline offset col strbef straft,
63 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos)
64 | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos) ->
65 (str,Ast0.OPT,make_info line lline offset col strbef straft,
66 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos)
67 | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) ->
68 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
69 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos)
70 | (Data.PLUS,line,lline,offset,col,strbef,straft,pos) ->
71 (str,Ast0.NONE,make_info line lline offset col strbef straft,Ast0.PLUS,
72 ref pos)
73 | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos) ->
74 (str,Ast0.NONE,make_info line lline offset col strbef straft,
75 Ast0.CONTEXT(ref(Ast.NOTHING,
76 Ast0.default_token_info,Ast0.default_token_info)),
77 ref pos)
78 | (Data.OPT,line,lline,offset,col,strbef,straft,pos) ->
79 (str,Ast0.OPT,make_info line lline offset col strbef straft,
80 Ast0.CONTEXT(ref(Ast.NOTHING,
81 Ast0.default_token_info,Ast0.default_token_info)),
82 ref pos)
83 | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) ->
84 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
85 Ast0.CONTEXT(ref(Ast.NOTHING,
86 Ast0.default_token_info,Ast0.default_token_info)),
87 ref pos)
88
89let id2name (name, clt) = name
90let id2clt (name, clt) = clt
91let id2mcode (name, clt) = clt2mcode name clt
92
93let mkdots str (dot,whencode) =
94 match str with
95 "..." -> Ast0.wrap(Ast0.Dots(clt2mcode str dot, whencode))
96 | "ooo" -> Ast0.wrap(Ast0.Circles(clt2mcode str dot, whencode))
97 | "***" -> Ast0.wrap(Ast0.Stars(clt2mcode str dot, whencode))
98 | _ -> failwith "cannot happen"
99
100let mkedots str (dot,whencode) =
101 match str with
102 "..." -> Ast0.wrap(Ast0.Edots(clt2mcode str dot, whencode))
103 | "ooo" -> Ast0.wrap(Ast0.Ecircles(clt2mcode str dot, whencode))
104 | "***" -> Ast0.wrap(Ast0.Estars(clt2mcode str dot, whencode))
105 | _ -> failwith "cannot happen"
106
107let mkdpdots str dot =
108 match str with
109 "..." -> Ast0.wrap(Ast0.DPdots(clt2mcode str dot))
110 | "ooo" -> Ast0.wrap(Ast0.DPcircles(clt2mcode str dot))
111 | _ -> failwith "cannot happen"
112
113let mkidots str (dot,whencode) =
114 match str with
115 "..." -> Ast0.wrap(Ast0.Idots(clt2mcode str dot, whencode))
116 | _ -> failwith "cannot happen"
117
118let mkddots str (dot,whencode) =
119 match (str,whencode) with
120 ("...",None) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, None))
121 | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w))
122 | _ -> failwith "cannot happen"
123
124let mkpdots str dot =
125 match str with
126 "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot))
127 | "ooo" -> Ast0.wrap(Ast0.Pcircles(clt2mcode str dot))
128 | _ -> failwith "cannot happen"
129
130let arith_op ast_op left op right =
131 Ast0.wrap
132 (Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right))
133
134let logic_op ast_op left op right =
135 Ast0.wrap
136 (Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right))
137
138let make_cv cv ty =
139 match cv with None -> ty | Some x -> Ast0.wrap (Ast0.ConstVol(x,ty))
140
141let top_dots l =
142 let circle x =
143 match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
144 let star x =
145 match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
146 if List.exists circle l
147 then Ast0.wrap(Ast0.CIRCLES(l))
148 else
149 if List.exists star l
150 then Ast0.wrap(Ast0.STARS(l))
151 else Ast0.wrap(Ast0.DOTS(l))
152
153(* here the offset is that of the first in the sequence of *s, not that of
154each * individually *)
155let pointerify ty m =
156 List.fold_left
157 (function inner ->
158 function cur ->
159 Ast0.wrap(Ast0.Pointer(inner,clt2mcode "*" cur)))
160 ty m
161
162let ty_pointerify ty m =
163 List.fold_left
164 (function inner -> function cur -> Type_cocci.Pointer(inner))
165 ty m
166
167(* Left is <=>, Right is =>. Collect <=>s. *)
168(* The parser should have done this, with precedences. But whatever... *)
169let iso_adjust fn first rest =
170 let rec loop = function
171 [] -> [[]]
172 | (Common.Left x)::rest ->
173 (match loop rest with
174 front::after -> (fn x::front)::after
175 | _ -> failwith "not possible")
176 | (Common.Right x)::rest ->
177 (match loop rest with
178 front::after -> []::(fn x::front)::after
179 | _ -> failwith "not possible") in
180 match loop rest with
181 front::after -> (fn first::front)::after
182 | _ -> failwith "not possible"
183
184let check_meta tok =
185 let lookup rule name =
186 try
187 let info = Hashtbl.find Data.all_metadecls rule in
188 List.find (function mv -> Ast.get_meta_name mv = (rule,name)) info
189 with
190 Not_found ->
191 raise
192 (Semantic_cocci.Semantic
193 ("bad rule "^rule^" or bad variable "^name)) in
194 match tok with
195 Ast.MetaIdDecl(Ast.NONE,(rule,name)) ->
196 (match lookup rule name with
197 Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> ()
198 | _ ->
199 raise
200 (Semantic_cocci.Semantic
201 ("incompatible inheritance declaration "^name)))
202 | Ast.MetaFreshIdDecl(Ast.NONE,(rule,name)) ->
203 raise
204 (Semantic_cocci.Semantic
205 "can't inherit the freshness of an identifier")
206 | Ast.MetaListlenDecl((rule,name)) ->
207 (match lookup rule name with
208 Ast.MetaListlenDecl(_) -> ()
209 | _ ->
210 raise
211 (Semantic_cocci.Semantic
212 ("incompatible inheritance declaration "^name)))
213 | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) ->
214 (match lookup rule name with
215 Ast.MetaTypeDecl(_,_) -> ()
216 | _ ->
217 raise
218 (Semantic_cocci.Semantic
219 ("incompatible inheritance declaration "^name)))
220 | Ast.MetaParamDecl(Ast.NONE,(rule,name)) ->
221 (match lookup rule name with
222 Ast.MetaParamDecl(_,_) -> ()
223 | _ ->
224 raise
225 (Semantic_cocci.Semantic
226 ("incompatible inheritance declaration "^name)))
227 | Ast.MetaParamListDecl(Ast.NONE,(rule,name),len_name) ->
228 (match lookup rule name with
229 Ast.MetaParamListDecl(_,_,_) -> ()
230 | _ ->
231 raise
232 (Semantic_cocci.Semantic
233 ("incompatible inheritance declaration "^name)))
234 | Ast.MetaErrDecl(Ast.NONE,(rule,name)) ->
235 (match lookup rule name with
236 Ast.MetaErrDecl(_,_) -> ()
237 | _ ->
238 raise
239 (Semantic_cocci.Semantic
240 ("incompatible inheritance declaration "^name)))
241 | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) ->
242 (match lookup rule name with
243 Ast.MetaExpDecl(_,_,ty1) when ty = ty1 -> ()
244 | _ ->
245 raise
246 (Semantic_cocci.Semantic
247 ("incompatible inheritance declaration "^name)))
248 | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) ->
249 (match lookup rule name with
250 Ast.MetaIdExpDecl(_,_,ty1) when ty = ty1 -> ()
251 | _ ->
252 raise
253 (Semantic_cocci.Semantic
254 ("incompatible inheritance declaration "^name)))
255 | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) ->
256 (match lookup rule name with
257 Ast.MetaLocalIdExpDecl(_,_,ty1) when ty = ty1 -> ()
258 | _ ->
259 raise
260 (Semantic_cocci.Semantic
261 ("incompatible inheritance declaration "^name)))
262 | Ast.MetaExpListDecl(Ast.NONE,(rule,name),len_name) ->
263 (match lookup rule name with
264 Ast.MetaExpListDecl(_,_,_) -> ()
265 | Ast.MetaParamListDecl(_,_,_) when not (!Flag.make_hrule = None) -> ()
266 | _ ->
267 raise
268 (Semantic_cocci.Semantic
269 ("incompatible inheritance declaration "^name)))
270 | Ast.MetaStmDecl(Ast.NONE,(rule,name)) ->
271 (match lookup rule name with
272 Ast.MetaStmDecl(_,_) -> ()
273 | _ ->
274 raise
275 (Semantic_cocci.Semantic
276 ("incompatible inheritance declaration "^name)))
277 | Ast.MetaStmListDecl(Ast.NONE,(rule,name)) ->
278 (match lookup rule name with
279 Ast.MetaStmListDecl(_,_) -> ()
280 | _ ->
281 raise
282 (Semantic_cocci.Semantic
283 ("incompatible inheritance declaration "^name)))
284 | Ast.MetaFuncDecl(Ast.NONE,(rule,name)) ->
285 (match lookup rule name with
286 Ast.MetaFuncDecl(_,_) -> ()
287 | _ ->
288 raise
289 (Semantic_cocci.Semantic
290 ("incompatible inheritance declaration "^name)))
291 | Ast.MetaLocalFuncDecl(Ast.NONE,(rule,name)) ->
292 (match lookup rule name with
293 Ast.MetaLocalFuncDecl(_,_) -> ()
294 | _ ->
295 raise
296 (Semantic_cocci.Semantic
297 ("incompatible inheritance declaration "^name)))
298 | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) ->
299 (match lookup rule name with
300 Ast.MetaConstDecl(_,_,ty1) when ty = ty1 -> ()
301 | _ ->
302 raise
303 (Semantic_cocci.Semantic
304 ("incompatible inheritance declaration "^name)))
305 | Ast.MetaPosDecl(Ast.NONE,(rule,name)) ->
306 (match lookup rule name with
307 Ast.MetaPosDecl(_,_) ->
308 if not (List.mem rule !Data.inheritable_positions)
309 then
310 raise
311 (Semantic_cocci.Semantic
312 ("position cannot be inherited over modifications: "^name))
313 | _ ->
314 raise
315 (Semantic_cocci.Semantic
316 ("incompatible inheritance declaration "^name)))
317 | _ ->
318 raise
319 (Semantic_cocci.Semantic ("arity not allowed on imported declaration"))
320
321let create_metadec ar ispure kindfn ids current_rule =
322 List.concat
323 (List.map
324 (function (rule,nm) ->
325 let (rule,checker) =
326 match rule with
327 None -> ((current_rule,nm),function x -> [Common.Left x])
328 | Some rule ->
329 ((rule,nm),
330 function x -> check_meta x; [Common.Right x]) in
331 kindfn ar rule ispure checker)
332 ids)
333
334let create_metadec_ne ar ispure kindfn ids current_rule =
335 List.concat
336 (List.map
337 (function ((rule,nm),constraints) ->
338 let (rule,checker) =
339 match rule with
340 None -> ((current_rule,nm),function x -> [Common.Left x])
341 | Some rule ->
342 ((rule,nm),
343 function x -> check_meta x; [Common.Right x]) in
344 kindfn ar rule ispure checker constraints)
345 ids)
346
347let create_metadec_ty ar ispure kindfn ids current_rule =
348 List.concat
349 (List.map
350 (function ((rule,nm),constraints) ->
351 let (rule,checker) =
352 match rule with
353 None -> ((current_rule,nm),function x -> [Common.Left x])
354 | Some rule ->
355 ((rule,nm),
356 function x -> check_meta x; [Common.Right x]) in
357 kindfn ar rule ispure checker constraints)
358 ids)
359
360let create_len_metadec ar ispure kindfn lenid ids current_rule =
361 let lendec =
362 create_metadec Ast.NONE Ast0.Impure
363 (fun _ name _ check_meta -> check_meta(Ast.MetaListlenDecl(name)))
364 [lenid] current_rule in
365 let lenname =
366 match lendec with
367 [Common.Left (Ast.MetaListlenDecl(x))] -> x
368 | [Common.Right (Ast.MetaListlenDecl(x))] -> x
369 | _ -> failwith "unexpected length declaration" in
370 lendec@(create_metadec ar ispure (kindfn lenname) ids current_rule)
371
372(* ---------------------------------------------------------------------- *)
373
374let str2inc s =
375 let elements = Str.split (Str.regexp "/") s in
376 List.map (function "..." -> Ast.IncDots | s -> Ast.IncPath s) elements
377
378(* ---------------------------------------------------------------------- *)
379(* statements *)
380
381let meta_stm name =
382 let (nm,pure,clt) = name in
383 Ast0.wrap(Ast0.MetaStmt(clt2mcode nm clt,pure))
384
385let exp_stm exp pv =
386 Ast0.wrap(Ast0.ExprStatement (exp, clt2mcode ";" pv))
387
388let ifthen iff lp tst rp thn =
389 Ast0.wrap(Ast0.IfThen(clt2mcode "if" iff,
390 clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
391 (Ast0.default_info(),Ast0.context_befaft())))
392
393let ifthenelse iff lp tst rp thn e els =
394 Ast0.wrap(Ast0.IfThenElse(clt2mcode "if" iff,
395 clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
396 clt2mcode "else" e,els,
397 (Ast0.default_info(),Ast0.context_befaft())))
398
399let forloop fr lp e1 sc1 e2 sc2 e3 rp s =
400 Ast0.wrap(Ast0.For(clt2mcode "for" fr,clt2mcode "(" lp,e1,
401 clt2mcode ";" sc1,e2,
402 clt2mcode ";" sc2,e3,clt2mcode ")" rp,s,
403 (Ast0.default_info(),Ast0.context_befaft())))
404
405let whileloop w lp e rp s =
406 Ast0.wrap(Ast0.While(clt2mcode "while" w,clt2mcode "(" lp,
407 e,clt2mcode ")" rp,s,
408 (Ast0.default_info(),Ast0.context_befaft())))
409
410let doloop d s w lp e rp pv =
411 Ast0.wrap(Ast0.Do(clt2mcode "do" d,s,clt2mcode "while" w,
412 clt2mcode "(" lp,e,clt2mcode ")" rp,
413 clt2mcode ";" pv))
414
415let iterator i lp e rp s =
416 Ast0.wrap(Ast0.Iterator(i,clt2mcode "(" lp,e,clt2mcode ")" rp,s,
417 (Ast0.default_info(),Ast0.context_befaft())))
418
419let switch s lp e rp lb c rb =
420 Ast0.wrap(Ast0.Switch(clt2mcode "switch" s,clt2mcode "(" lp,e,
421 clt2mcode ")" rp,clt2mcode "{" lb,
422 Ast0.wrap(Ast0.DOTS(c)),clt2mcode "}" rb))
423
424let ret_exp r e pv =
425 Ast0.wrap(Ast0.ReturnExpr(clt2mcode "return" r,e,clt2mcode ";" pv))
426
427let ret r pv =
428 Ast0.wrap(Ast0.Return(clt2mcode "return" r,clt2mcode ";" pv))
429
430let break b pv =
431 Ast0.wrap(Ast0.Break(clt2mcode "break" b,clt2mcode ";" pv))
432
433let cont c pv =
434 Ast0.wrap(Ast0.Continue(clt2mcode "continue" c,clt2mcode ";" pv))
435
436let label i dd =
437 Ast0.wrap(Ast0.Label(i,clt2mcode ":" dd))
438
439let goto g i pv =
440 Ast0.wrap(Ast0.Goto(clt2mcode "goto" g,i,clt2mcode ";" pv))
441
442let seq lb s rb =
443 Ast0.wrap(Ast0.Seq(clt2mcode "{" lb,s,clt2mcode "}" rb))
444
445(* ---------------------------------------------------------------------- *)
446
447let make_iso_rule_name_result n =
448 (try let _ = Hashtbl.find Data.all_metadecls n in
449 raise (Semantic_cocci.Semantic ("repeated rule name"))
450 with Not_found -> ());
451 Ast.CocciRulename (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*))
452
453let make_cocci_rule_name_result nm d i a e ee =
454 match nm with
455 Some nm ->
456 let n = id2name nm in
457 (try let _ = Hashtbl.find Data.all_metadecls n in
458 raise (Semantic_cocci.Semantic ("repeated rule name"))
459 with Not_found -> ());
460 Ast.CocciRulename (Some n,d,i,a,e,ee)
461 | None -> Ast.CocciRulename (None,d,i,a,e,ee)
462
463let make_generated_rule_name_result nm d i a e ee =
464 match nm with
465 Some nm ->
466 let n = id2name nm in
467 (try let _ = Hashtbl.find Data.all_metadecls n in
468 raise (Semantic_cocci.Semantic ("repeated rule name"))
469 with Not_found -> ());
470 Ast.GeneratedRulename (Some n,d,i,a,e,ee)
471 | None -> Ast.GeneratedRulename (None,d,i,a,e,ee)
472
473let make_script_rule_name_result lang deps =
474 let l = id2name lang in
475 Ast.ScriptRulename (l,deps)