Release coccinelle-0.2.5-rc1
[bpt/coccinelle.git] / parsing_cocci / parse_aux.ml
CommitLineData
c491d8ee
C
1(*
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.
7 *
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.
11 *
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.
16 *
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/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
34e49164
C
25(* exports everything, used only by parser_cocci_menhir.mly *)
26module Ast0 = Ast0_cocci
27module Ast = Ast_cocci
28
29(* types for metavariable tokens *)
30type info = Ast.meta_name * Ast0.pure * Data.clt
31type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt
32type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt
33type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt
88e71198 34type list_info = Ast.meta_name * Ast.list_len * Ast0.pure * Data.clt
951c7801 35type typed_expinfo =
34e49164
C
36 Ast.meta_name * Data.econstraints * Ast0.pure *
37 Type_cocci.typeC list option * Data.clt
38type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt
39
34e49164
C
40let get_option fn = function
41 None -> None
42 | Some x -> Some (fn x)
43
44let make_info line logical_line offset col strbef straft =
0708f913
C
45 let new_pos_info =
46 {Ast0.line_start = line; Ast0.line_end = line;
47 Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
708f4980 48 Ast0.column = col; Ast0.offset = offset; } in
0708f913 49 { Ast0.pos_info = new_pos_info;
34e49164
C
50 Ast0.attachable_start = true; Ast0.attachable_end = true;
51 Ast0.mcode_start = []; Ast0.mcode_end = [];
34e49164
C
52 Ast0.strings_before = strbef; Ast0.strings_after = straft; }
53
54let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) =
55 make_info line logical_line offset col strbef straft
56
57let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) =
58 (arity,line,lline,offset,col,[],straft,pos)
59
60let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) =
61 (arity,line,lline,offset,col,strbef,[],pos)
62
7f004419
C
63let drop_pos (arity,line,lline,offset,col,strbef,straft,pos) =
64 (arity,line,lline,offset,col,strbef,straft,Ast0.NoMetaPos)
65
34e49164
C
66let clt2mcode str = function
67 (Data.MINUS,line,lline,offset,col,strbef,straft,pos) ->
68 (str,Ast0.NONE,make_info line lline offset col strbef straft,
708f4980 69 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1)
34e49164
C
70 | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos) ->
71 (str,Ast0.OPT,make_info line lline offset col strbef straft,
708f4980 72 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1)
34e49164
C
73 | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) ->
74 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
708f4980 75 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1)
34e49164 76 | (Data.PLUS,line,lline,offset,col,strbef,straft,pos) ->
951c7801
C
77 (str,Ast0.NONE,make_info line lline offset col strbef straft,
78 Ast0.PLUS(Ast.ONE),ref pos,-1)
79 | (Data.PLUSPLUS,line,lline,offset,col,strbef,straft,pos) ->
80 (str,Ast0.NONE,make_info line lline offset col strbef straft,
81 Ast0.PLUS(Ast.MANY),ref pos,-1)
34e49164
C
82 | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos) ->
83 (str,Ast0.NONE,make_info line lline offset col strbef straft,
84 Ast0.CONTEXT(ref(Ast.NOTHING,
85 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 86 ref pos,-1)
34e49164
C
87 | (Data.OPT,line,lline,offset,col,strbef,straft,pos) ->
88 (str,Ast0.OPT,make_info line lline offset col strbef straft,
89 Ast0.CONTEXT(ref(Ast.NOTHING,
90 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 91 ref pos,-1)
34e49164
C
92 | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) ->
93 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
94 Ast0.CONTEXT(ref(Ast.NOTHING,
95 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 96 ref pos,-1)
34e49164
C
97
98let id2name (name, clt) = name
99let id2clt (name, clt) = clt
100let id2mcode (name, clt) = clt2mcode name clt
101
102let mkdots str (dot,whencode) =
103 match str with
104 "..." -> Ast0.wrap(Ast0.Dots(clt2mcode str dot, whencode))
105 | "ooo" -> Ast0.wrap(Ast0.Circles(clt2mcode str dot, whencode))
106 | "***" -> Ast0.wrap(Ast0.Stars(clt2mcode str dot, whencode))
107 | _ -> failwith "cannot happen"
108
109let mkedots str (dot,whencode) =
110 match str with
111 "..." -> Ast0.wrap(Ast0.Edots(clt2mcode str dot, whencode))
112 | "ooo" -> Ast0.wrap(Ast0.Ecircles(clt2mcode str dot, whencode))
113 | "***" -> Ast0.wrap(Ast0.Estars(clt2mcode str dot, whencode))
114 | _ -> failwith "cannot happen"
115
116let mkdpdots str dot =
117 match str with
118 "..." -> Ast0.wrap(Ast0.DPdots(clt2mcode str dot))
119 | "ooo" -> Ast0.wrap(Ast0.DPcircles(clt2mcode str dot))
120 | _ -> failwith "cannot happen"
121
122let mkidots str (dot,whencode) =
123 match str with
124 "..." -> Ast0.wrap(Ast0.Idots(clt2mcode str dot, whencode))
125 | _ -> failwith "cannot happen"
126
127let mkddots str (dot,whencode) =
128 match (str,whencode) with
129 ("...",None) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, None))
130 | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w))
131 | _ -> failwith "cannot happen"
132
c491d8ee
C
133let mkddots_one str (dot,whencode) =
134 match str with
135 "..." -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, whencode))
136 | _ -> failwith "cannot happen"
137
34e49164
C
138let mkpdots str dot =
139 match str with
140 "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot))
141 | "ooo" -> Ast0.wrap(Ast0.Pcircles(clt2mcode str dot))
142 | _ -> failwith "cannot happen"
143
144let arith_op ast_op left op right =
145 Ast0.wrap
146 (Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right))
147
148let logic_op ast_op left op right =
149 Ast0.wrap
150 (Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right))
151
152let make_cv cv ty =
153 match cv with None -> ty | Some x -> Ast0.wrap (Ast0.ConstVol(x,ty))
154
155let top_dots l =
156 let circle x =
157 match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
158 let star x =
159 match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
160 if List.exists circle l
161 then Ast0.wrap(Ast0.CIRCLES(l))
162 else
163 if List.exists star l
164 then Ast0.wrap(Ast0.STARS(l))
165 else Ast0.wrap(Ast0.DOTS(l))
166
167(* here the offset is that of the first in the sequence of *s, not that of
168each * individually *)
169let pointerify ty m =
170 List.fold_left
171 (function inner ->
172 function cur ->
173 Ast0.wrap(Ast0.Pointer(inner,clt2mcode "*" cur)))
174 ty m
175
176let ty_pointerify ty m =
177 List.fold_left
178 (function inner -> function cur -> Type_cocci.Pointer(inner))
179 ty m
180
181(* Left is <=>, Right is =>. Collect <=>s. *)
182(* The parser should have done this, with precedences. But whatever... *)
c3e37e97 183let iso_adjust first_fn fn first rest =
34e49164
C
184 let rec loop = function
185 [] -> [[]]
186 | (Common.Left x)::rest ->
187 (match loop rest with
188 front::after -> (fn x::front)::after
189 | _ -> failwith "not possible")
190 | (Common.Right x)::rest ->
191 (match loop rest with
192 front::after -> []::(fn x::front)::after
193 | _ -> failwith "not possible") in
194 match loop rest with
c3e37e97 195 front::after -> (first_fn first::front)::after
34e49164
C
196 | _ -> failwith "not possible"
197
174d1640
C
198let lookup rule name =
199 try
200 let info = Hashtbl.find Data.all_metadecls rule in
201 List.find (function mv -> Ast.get_meta_name mv = (rule,name)) info
202 with
203 Not_found ->
204 raise
205 (Semantic_cocci.Semantic("bad rule "^rule^" or bad variable "^name))
206
207let check_meta_tyopt type_irrelevant = function
34e49164
C
208 Ast.MetaIdDecl(Ast.NONE,(rule,name)) ->
209 (match lookup rule name with
210 Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> ()
211 | _ ->
212 raise
213 (Semantic_cocci.Semantic
214 ("incompatible inheritance declaration "^name)))
b1b2de81 215 | Ast.MetaFreshIdDecl((rule,name),seed) ->
34e49164
C
216 raise
217 (Semantic_cocci.Semantic
218 "can't inherit the freshness of an identifier")
219 | Ast.MetaListlenDecl((rule,name)) ->
220 (match lookup rule name with
221 Ast.MetaListlenDecl(_) -> ()
222 | _ ->
223 raise
224 (Semantic_cocci.Semantic
225 ("incompatible inheritance declaration "^name)))
226 | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) ->
227 (match lookup rule name with
228 Ast.MetaTypeDecl(_,_) -> ()
229 | _ ->
230 raise
231 (Semantic_cocci.Semantic
232 ("incompatible inheritance declaration "^name)))
113803cf
C
233 | Ast.MetaInitDecl(Ast.NONE,(rule,name)) ->
234 (match lookup rule name with
235 Ast.MetaInitDecl(_,_) -> ()
236 | _ ->
237 raise
238 (Semantic_cocci.Semantic
239 ("incompatible inheritance declaration "^name)))
34e49164
C
240 | Ast.MetaParamDecl(Ast.NONE,(rule,name)) ->
241 (match lookup rule name with
242 Ast.MetaParamDecl(_,_) -> ()
243 | _ ->
244 raise
245 (Semantic_cocci.Semantic
246 ("incompatible inheritance declaration "^name)))
247 | Ast.MetaParamListDecl(Ast.NONE,(rule,name),len_name) ->
248 (match lookup rule name with
249 Ast.MetaParamListDecl(_,_,_) -> ()
250 | _ ->
251 raise
252 (Semantic_cocci.Semantic
253 ("incompatible inheritance declaration "^name)))
254 | Ast.MetaErrDecl(Ast.NONE,(rule,name)) ->
255 (match lookup rule name with
256 Ast.MetaErrDecl(_,_) -> ()
257 | _ ->
258 raise
259 (Semantic_cocci.Semantic
260 ("incompatible inheritance declaration "^name)))
261 | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) ->
262 (match lookup rule name with
5636bb2c 263 Ast.MetaExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
264 | _ ->
265 raise
266 (Semantic_cocci.Semantic
267 ("incompatible inheritance declaration "^name)))
268 | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) ->
269 (match lookup rule name with
5636bb2c 270 Ast.MetaIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
271 | _ ->
272 raise
273 (Semantic_cocci.Semantic
274 ("incompatible inheritance declaration "^name)))
275 | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) ->
276 (match lookup rule name with
5636bb2c 277 Ast.MetaLocalIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
278 | _ ->
279 raise
280 (Semantic_cocci.Semantic
281 ("incompatible inheritance declaration "^name)))
282 | Ast.MetaExpListDecl(Ast.NONE,(rule,name),len_name) ->
283 (match lookup rule name with
284 Ast.MetaExpListDecl(_,_,_) -> ()
faf9a90c 285 | Ast.MetaParamListDecl(_,_,_) when not (!Flag.make_hrule = None) -> ()
34e49164
C
286 | _ ->
287 raise
288 (Semantic_cocci.Semantic
289 ("incompatible inheritance declaration "^name)))
290 | Ast.MetaStmDecl(Ast.NONE,(rule,name)) ->
291 (match lookup rule name with
292 Ast.MetaStmDecl(_,_) -> ()
293 | _ ->
294 raise
295 (Semantic_cocci.Semantic
296 ("incompatible inheritance declaration "^name)))
297 | Ast.MetaStmListDecl(Ast.NONE,(rule,name)) ->
298 (match lookup rule name with
299 Ast.MetaStmListDecl(_,_) -> ()
300 | _ ->
301 raise
302 (Semantic_cocci.Semantic
303 ("incompatible inheritance declaration "^name)))
304 | Ast.MetaFuncDecl(Ast.NONE,(rule,name)) ->
305 (match lookup rule name with
306 Ast.MetaFuncDecl(_,_) -> ()
307 | _ ->
308 raise
309 (Semantic_cocci.Semantic
310 ("incompatible inheritance declaration "^name)))
311 | Ast.MetaLocalFuncDecl(Ast.NONE,(rule,name)) ->
312 (match lookup rule name with
313 Ast.MetaLocalFuncDecl(_,_) -> ()
314 | _ ->
315 raise
316 (Semantic_cocci.Semantic
317 ("incompatible inheritance declaration "^name)))
318 | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) ->
319 (match lookup rule name with
5636bb2c 320 Ast.MetaConstDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
321 | _ ->
322 raise
323 (Semantic_cocci.Semantic
324 ("incompatible inheritance declaration "^name)))
325 | Ast.MetaPosDecl(Ast.NONE,(rule,name)) ->
326 (match lookup rule name with
327 Ast.MetaPosDecl(_,_) ->
328 if not (List.mem rule !Data.inheritable_positions)
329 then
330 raise
331 (Semantic_cocci.Semantic
332 ("position cannot be inherited over modifications: "^name))
333 | _ ->
334 raise
335 (Semantic_cocci.Semantic
336 ("incompatible inheritance declaration "^name)))
337 | _ ->
338 raise
339 (Semantic_cocci.Semantic ("arity not allowed on imported declaration"))
340
5636bb2c
C
341let check_meta m = check_meta_tyopt false m
342
343let check_inherited_constraint meta_name fn =
344 match meta_name with
345 (None,_) -> failwith "constraint must be an inherited variable"
346 | (Some rule,name) ->
347 let i = (rule,name) in
348 check_meta_tyopt true (fn i);
349 i
350
34e49164
C
351let create_metadec ar ispure kindfn ids current_rule =
352 List.concat
353 (List.map
354 (function (rule,nm) ->
355 let (rule,checker) =
356 match rule with
357 None -> ((current_rule,nm),function x -> [Common.Left x])
358 | Some rule ->
359 ((rule,nm),
360 function x -> check_meta x; [Common.Right x]) in
361 kindfn ar rule ispure checker)
362 ids)
363
ae4735db
C
364
365let create_metadec_virt ar ispure kindfn ids current_rule =
366 List.concat
367 (List.map
368 (function nm ->
369 let checker = function x -> [Common.Right x] in
370 kindfn ar nm ispure checker !Flag.defined_virtual_env)
371 ids)
372
b1b2de81
C
373let create_fresh_metadec kindfn ids current_rule =
374 List.concat
375 (List.map
376 (function ((rule,nm),seed) ->
377 let (rule,checker) =
378 match rule with
379 None -> ((current_rule,nm),function x -> [Common.Left x])
380 | Some rule ->
381 ((rule,nm),
382 function x -> check_meta x; [Common.Right x]) in
383 kindfn rule checker seed)
384 ids)
385
951c7801 386let create_metadec_with_constraints ar ispure kindfn ids current_rule =
34e49164
C
387 List.concat
388 (List.map
389 (function ((rule,nm),constraints) ->
390 let (rule,checker) =
391 match rule with
951c7801
C
392 None -> ((current_rule,nm),function x -> [Common.Left x])
393 | Some rule ->
394 ((rule,nm),
395 function x -> check_meta x; [Common.Right x]) in
396 kindfn ar rule ispure checker constraints)
34e49164
C
397 ids)
398
399let create_metadec_ty ar ispure kindfn ids current_rule =
400 List.concat
401 (List.map
402 (function ((rule,nm),constraints) ->
403 let (rule,checker) =
404 match rule with
405 None -> ((current_rule,nm),function x -> [Common.Left x])
406 | Some rule ->
407 ((rule,nm),
408 function x -> check_meta x; [Common.Right x]) in
409 kindfn ar rule ispure checker constraints)
410 ids)
411
412let create_len_metadec ar ispure kindfn lenid ids current_rule =
88e71198
C
413 let (lendec,lenname) =
414 match lenid with
415 Common.Left lenid ->
416 let lendec =
417 create_metadec Ast.NONE Ast0.Impure
418 (fun _ name _ check_meta -> check_meta(Ast.MetaListlenDecl(name)))
419 [lenid] current_rule in
420 let lenname =
421 match lendec with
422 [Common.Left (Ast.MetaListlenDecl(x))] -> Ast.MetaLen x
423 | [Common.Right (Ast.MetaListlenDecl(x))] -> Ast.MetaLen x
424 | _ -> failwith "unexpected length declaration" in
425 (lendec,lenname)
426 | Common.Right n -> ([],Ast.CstLen n) in
34e49164
C
427 lendec@(create_metadec ar ispure (kindfn lenname) ids current_rule)
428
429(* ---------------------------------------------------------------------- *)
430
431let str2inc s =
432 let elements = Str.split (Str.regexp "/") s in
433 List.map (function "..." -> Ast.IncDots | s -> Ast.IncPath s) elements
434
435(* ---------------------------------------------------------------------- *)
413ffc02
C
436(* declarations and statements *)
437
438let meta_decl name =
439 let (nm,pure,clt) = name in
440 Ast0.wrap(Ast0.MetaDecl(clt2mcode nm clt,pure))
441
442let meta_field name =
443 let (nm,pure,clt) = name in
444 Ast0.wrap(Ast0.MetaField(clt2mcode nm clt,pure))
34e49164
C
445
446let meta_stm name =
447 let (nm,pure,clt) = name in
448 Ast0.wrap(Ast0.MetaStmt(clt2mcode nm clt,pure))
449
450let exp_stm exp pv =
451 Ast0.wrap(Ast0.ExprStatement (exp, clt2mcode ";" pv))
452
453let ifthen iff lp tst rp thn =
454 Ast0.wrap(Ast0.IfThen(clt2mcode "if" iff,
455 clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
456 (Ast0.default_info(),Ast0.context_befaft())))
457
458let ifthenelse iff lp tst rp thn e els =
459 Ast0.wrap(Ast0.IfThenElse(clt2mcode "if" iff,
460 clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
461 clt2mcode "else" e,els,
462 (Ast0.default_info(),Ast0.context_befaft())))
463
464let forloop fr lp e1 sc1 e2 sc2 e3 rp s =
465 Ast0.wrap(Ast0.For(clt2mcode "for" fr,clt2mcode "(" lp,e1,
466 clt2mcode ";" sc1,e2,
467 clt2mcode ";" sc2,e3,clt2mcode ")" rp,s,
468 (Ast0.default_info(),Ast0.context_befaft())))
469
470let whileloop w lp e rp s =
471 Ast0.wrap(Ast0.While(clt2mcode "while" w,clt2mcode "(" lp,
472 e,clt2mcode ")" rp,s,
473 (Ast0.default_info(),Ast0.context_befaft())))
474
475let doloop d s w lp e rp pv =
476 Ast0.wrap(Ast0.Do(clt2mcode "do" d,s,clt2mcode "while" w,
477 clt2mcode "(" lp,e,clt2mcode ")" rp,
478 clt2mcode ";" pv))
479
480let iterator i lp e rp s =
481 Ast0.wrap(Ast0.Iterator(i,clt2mcode "(" lp,e,clt2mcode ")" rp,s,
482 (Ast0.default_info(),Ast0.context_befaft())))
483
fc1ad971
C
484let switch s lp e rp lb d c rb =
485 let d =
486 List.map
487 (function d ->
488 Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),d)))
489 d in
34e49164
C
490 Ast0.wrap(Ast0.Switch(clt2mcode "switch" s,clt2mcode "(" lp,e,
491 clt2mcode ")" rp,clt2mcode "{" lb,
fc1ad971 492 Ast0.wrap(Ast0.DOTS(d)),
34e49164
C
493 Ast0.wrap(Ast0.DOTS(c)),clt2mcode "}" rb))
494
495let ret_exp r e pv =
496 Ast0.wrap(Ast0.ReturnExpr(clt2mcode "return" r,e,clt2mcode ";" pv))
497
498let ret r pv =
499 Ast0.wrap(Ast0.Return(clt2mcode "return" r,clt2mcode ";" pv))
500
501let break b pv =
502 Ast0.wrap(Ast0.Break(clt2mcode "break" b,clt2mcode ";" pv))
503
504let cont c pv =
505 Ast0.wrap(Ast0.Continue(clt2mcode "continue" c,clt2mcode ";" pv))
506
507let label i dd =
508 Ast0.wrap(Ast0.Label(i,clt2mcode ":" dd))
509
510let goto g i pv =
511 Ast0.wrap(Ast0.Goto(clt2mcode "goto" g,i,clt2mcode ";" pv))
512
513let seq lb s rb =
514 Ast0.wrap(Ast0.Seq(clt2mcode "{" lb,s,clt2mcode "}" rb))
515
516(* ---------------------------------------------------------------------- *)
517
413ffc02 518let check_rule_name = function
34e49164
C
519 Some nm ->
520 let n = id2name nm in
521 (try let _ = Hashtbl.find Data.all_metadecls n in
522 raise (Semantic_cocci.Semantic ("repeated rule name"))
413ffc02
C
523 with Not_found -> Some n)
524 | None -> None
525
526let make_iso_rule_name_result n =
527 (try let _ = Hashtbl.find Data.all_metadecls n in
528 raise (Semantic_cocci.Semantic ("repeated rule name"))
529 with Not_found -> ());
530 Ast.CocciRulename
531 (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*))
532
533let make_cocci_rule_name_result nm d i a e ee =
534 Ast.CocciRulename (check_rule_name nm,d,i,a,e,ee)
34e49164 535
faf9a90c 536let make_generated_rule_name_result nm d i a e ee =
413ffc02 537 Ast.GeneratedRulename (check_rule_name nm,d,i,a,e,ee)
faf9a90c 538
413ffc02 539let make_script_rule_name_result lang nm deps =
34e49164 540 let l = id2name lang in
413ffc02 541 Ast.ScriptRulename (check_rule_name nm,l,deps)
b1b2de81 542
c3e37e97 543let make_initial_script_rule_name_result lang deps =
b1b2de81 544 let l = id2name lang in
174d1640 545 Ast.InitialScriptRulename(None,l,deps)
b1b2de81 546
c3e37e97 547let make_final_script_rule_name_result lang deps =
b1b2de81 548 let l = id2name lang in
174d1640 549 Ast.FinalScriptRulename(None,l,deps)
978fd7e5
C
550
551(* Allows type alone only when it is void and only when there is only one
552 parameter. This avoids ambiguity problems in the parser. *)
553let verify_parameter_declarations = function
554 [] -> ()
555 | [x] ->
556 (match Ast0.unwrap x with
557 Ast0.Param(t, None) ->
558 (match Ast0.unwrap t with
559 Ast0.BaseType(Ast.VoidType,_) -> ()
560 | _ ->
561 failwith
562 (Printf.sprintf
563 "%d: only void can be a parameter without an identifier"
564 (Ast0.get_line t)))
565 | _ -> ())
566 | l ->
567 List.iter
568 (function x ->
569 match Ast0.unwrap x with
570 Ast0.Param(t, None) ->
571 failwith
572 (Printf.sprintf
573 "%d: only void alone can be a parameter without an identifier"
574 (Ast0.get_line t))
575 | _ -> ())
576 l
c491d8ee
C
577
578(* ---------------------------------------------------------------------- *)
579(* decide whether an init list is ordered or unordered *)
580
581let struct_initializer initlist =
582 let rec loop i =
583 match Ast0.unwrap i with
584 Ast0.InitGccExt _ -> true
585 | Ast0.InitGccName _ -> true
586 | Ast0.OptIni i | Ast0.UniqueIni i -> loop i
587 | Ast0.MetaInit _ -> true (* ambiguous... *)
588 | _ -> false in
589 let l = Ast0.undots initlist in
590 (l = []) or (List.exists loop l)
591
592let drop_dot_commas initlist =
593 match Ast0.unwrap initlist with
594 Ast0.DOTS(l) ->
595 let rec loop after_comma = function
596 [] -> []
597 | x::xs ->
598 (match Ast0.unwrap x with
599 Ast0.Idots(dots,whencode) -> x :: (loop true xs)
600 | Ast0.IComma(comma) when after_comma -> (*drop*) loop false xs
601 | _ -> x :: (loop false xs)) in
602 Ast0.rewrap initlist (Ast0.DOTS(loop false l))
603 | _ -> failwith "not supported"
604