permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_cocci / disjdistr.ml
... / ...
CommitLineData
1(*
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.
9 *
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.
13 *
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.
18 *
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/>.
21 *
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
24 *)
25
26
27# 0 "./disjdistr.ml"
28module Ast = Ast_cocci
29module V = Visitor_ast
30
31let disjmult2 e1 e2 k =
32 List.concat
33 (List.map (function e1 -> List.map (function e2 -> k e1 e2) e2) e1)
34
35let disjmult3 e1 e2 e3 k =
36 List.concat
37 (List.map
38 (function e1 ->
39 List.concat
40 (List.map
41 (function e2 -> List.map (function e3 -> k e1 e2 e3) e3)
42 e2))
43 e1)
44
45let rec disjmult f = function
46 [] -> [[]]
47 | x::xs ->
48 let cur = f x in
49 let rest = disjmult f xs in
50 disjmult2 cur rest (function cur -> function rest -> cur :: rest)
51
52let rec disjmult_two fstart frest (start,rest) =
53 let cur = fstart start in
54 let rest = disjmult frest rest in
55 disjmult2 cur rest (function cur -> function rest -> (cur,rest))
56
57let disjoption f = function
58 None -> [None]
59 | Some x -> List.map (function x -> Some x) (f x)
60
61let disjdots f d =
62 match Ast.unwrap d with
63 Ast.DOTS(l) ->
64 List.map (function l -> Ast.rewrap d (Ast.DOTS(l))) (disjmult f l)
65 | Ast.CIRCLES(l) ->
66 List.map (function l -> Ast.rewrap d (Ast.CIRCLES(l))) (disjmult f l)
67 | Ast.STARS(l) ->
68 List.map (function l -> Ast.rewrap d (Ast.STARS(l))) (disjmult f l)
69
70let rec disjty ft =
71 match Ast.unwrap ft with
72 Ast.Type(allminus,cv,ty) ->
73 let ty = disjtypeC ty in
74 List.map (function ty -> Ast.rewrap ft (Ast.Type(allminus,cv,ty))) ty
75 | Ast.AsType(ty,asty) -> (* as ty doesn't contain disj *)
76 let ty = disjty ty in
77 List.map (function ty -> Ast.rewrap ft (Ast.AsType(ty,asty))) ty
78 | Ast.DisjType(types) -> List.concat (List.map disjty types)
79 | Ast.OptType(ty) ->
80 let ty = disjty ty in
81 List.map (function ty -> Ast.rewrap ft (Ast.OptType(ty))) ty
82 | Ast.UniqueType(ty) ->
83 let ty = disjty ty in
84 List.map (function ty -> Ast.rewrap ft (Ast.UniqueType(ty))) ty
85
86and disjtypeC bty =
87 match Ast.unwrap bty with
88 Ast.BaseType(_) | Ast.SignedT(_,_) -> [bty]
89 | Ast.Pointer(ty,star) ->
90 let ty = disjty ty in
91 List.map (function ty -> Ast.rewrap bty (Ast.Pointer(ty,star))) ty
92 | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
93 let ty = disjty ty in
94 List.map
95 (function ty ->
96 Ast.rewrap bty (Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2)))
97 ty
98 | Ast.FunctionType (s,ty,lp1,params,rp1) ->
99 let ty = disjoption disjty ty in
100 List.map
101 (function ty ->
102 Ast.rewrap bty (Ast.FunctionType (s,ty,lp1,params,rp1)))
103 ty
104 | Ast.Array(ty,lb,size,rb) ->
105 disjmult2 (disjty ty) (disjoption disjexp size)
106 (function ty -> function size ->
107 Ast.rewrap bty (Ast.Array(ty,lb,size,rb)))
108 | Ast.EnumName(_,_) | Ast.StructUnionName(_,_) -> [bty]
109 | Ast.EnumDef(ty,lb,ids,rb) ->
110 disjmult2 (disjty ty) (disjdots disjexp ids)
111 (function ty -> function ids ->
112 Ast.rewrap bty (Ast.EnumDef(ty,lb,ids,rb)))
113 | Ast.StructUnionDef(ty,lb,decls,rb) ->
114 disjmult2 (disjty ty) (disjdots disjdecl decls)
115 (function ty -> function decls ->
116 Ast.rewrap bty (Ast.StructUnionDef(ty,lb,decls,rb)))
117 | Ast.TypeName(_) | Ast.MetaType(_,_,_) -> [bty]
118
119and disjident e =
120 match Ast.unwrap e with
121 Ast.DisjId(id_list) -> List.concat (List.map disjident id_list)
122 | Ast.OptIdent(id) ->
123 let id = disjident id in
124 List.map (function id -> Ast.rewrap e (Ast.OptIdent(id))) id
125 | Ast.UniqueIdent(id) ->
126 let id = disjident id in
127 List.map (function id -> Ast.rewrap e (Ast.UniqueIdent(id))) id
128 | _ -> [e]
129
130and disjexp e =
131 match Ast.unwrap e with
132 Ast.Ident(_) | Ast.Constant(_) -> [e] (* even Ident can't contain disj *)
133 | Ast.FunCall(fn,lp,args,rp) ->
134 disjmult2 (disjexp fn) (disjdots disjexp args)
135 (function fn -> function args ->
136 Ast.rewrap e (Ast.FunCall(fn,lp,args,rp)))
137 | Ast.Assignment(left,op,right,simple) ->
138 disjmult2 (disjexp left) (disjexp right)
139 (function left -> function right ->
140 Ast.rewrap e (Ast.Assignment(left,op,right,simple)))
141 | Ast.Sequence(left,op,right) ->
142 disjmult2 (disjexp left) (disjexp right)
143 (function left -> function right ->
144 Ast.rewrap e (Ast.Sequence(left,op,right)))
145 | Ast.CondExpr(exp1,why,Some exp2,colon,exp3) ->
146 let res = disjmult disjexp [exp1;exp2;exp3] in
147 List.map
148 (function
149 [exp1;exp2;exp3] ->
150 Ast.rewrap e (Ast.CondExpr(exp1,why,Some exp2,colon,exp3))
151 | _ -> failwith "not possible")
152 res
153 | Ast.CondExpr(exp1,why,None,colon,exp3) ->
154 disjmult2 (disjexp exp1) (disjexp exp3)
155 (function exp1 -> function exp3 ->
156 Ast.rewrap e (Ast.CondExpr(exp1,why,None,colon,exp3)))
157 | Ast.Postfix(exp,op) ->
158 let exp = disjexp exp in
159 List.map (function exp -> Ast.rewrap e (Ast.Postfix(exp,op))) exp
160 | Ast.Infix(exp,op) ->
161 let exp = disjexp exp in
162 List.map (function exp -> Ast.rewrap e (Ast.Infix(exp,op))) exp
163 | Ast.Unary(exp,op) ->
164 let exp = disjexp exp in
165 List.map (function exp -> Ast.rewrap e (Ast.Unary(exp,op))) exp
166 | Ast.Binary(left,op,right) ->
167 disjmult2 (disjexp left) (disjexp right)
168 (function left -> function right ->
169 Ast.rewrap e (Ast.Binary(left,op,right)))
170 | Ast.Nested(exp,op,right) ->
171 (* disj not possible in right *)
172 let exp = disjexp exp in
173 List.map (function exp -> Ast.rewrap e (Ast.Nested(exp,op,right))) exp
174 | Ast.Paren(lp,exp,rp) ->
175 let exp = disjexp exp in
176 List.map (function exp -> Ast.rewrap e (Ast.Paren(lp,exp,rp))) exp
177 | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
178 disjmult2 (disjexp exp1) (disjexp exp2)
179 (function exp1 -> function exp2 ->
180 Ast.rewrap e (Ast.ArrayAccess(exp1,lb,exp2,rb)))
181 | Ast.RecordAccess(exp,pt,field) ->
182 let exp = disjexp exp in
183 List.map
184 (function exp -> Ast.rewrap e (Ast.RecordAccess(exp,pt,field))) exp
185 | Ast.RecordPtAccess(exp,ar,field) ->
186 let exp = disjexp exp in
187 List.map
188 (function exp -> Ast.rewrap e (Ast.RecordPtAccess(exp,ar,field))) exp
189 | Ast.Cast(lp,ty,rp,exp) ->
190 disjmult2 (disjty ty) (disjexp exp)
191 (function ty -> function exp -> Ast.rewrap e (Ast.Cast(lp,ty,rp,exp)))
192 | Ast.SizeOfExpr(szf,exp) ->
193 let exp = disjexp exp in
194 List.map (function exp -> Ast.rewrap e (Ast.SizeOfExpr(szf,exp))) exp
195 | Ast.SizeOfType(szf,lp,ty,rp) ->
196 let ty = disjty ty in
197 List.map
198 (function ty -> Ast.rewrap e (Ast.SizeOfType(szf,lp,ty,rp))) ty
199 | Ast.TypeExp(ty) ->
200 let ty = disjty ty in
201 List.map (function ty -> Ast.rewrap e (Ast.TypeExp(ty))) ty
202 | Ast.Constructor(lp,ty,rp,init) ->
203 disjmult2 (disjty ty) (disjini init)
204 (function ty ->
205 function exp -> Ast.rewrap e (Ast.Constructor(lp,ty,rp,init)))
206 | Ast.MetaErr(_,_,_,_) | Ast.MetaExpr(_,_,_,_,_,_)
207 | Ast.MetaExprList(_,_,_,_) | Ast.EComma(_) -> [e]
208 | Ast.AsExpr(exp,asexp) -> (* as exp doesn't contain disj *)
209 let exp = disjexp exp in
210 List.map (function exp -> Ast.rewrap e (Ast.AsExpr(exp,asexp))) exp
211 | Ast.DisjExpr(exp_list) -> List.concat (List.map disjexp exp_list)
212 | Ast.NestExpr(starter,expr_dots,ender,whencode,multi) ->
213 (* not sure what to do here, so ambiguities still possible *)
214 [e]
215 | Ast.Edots(dots,_) | Ast.Ecircles(dots,_) | Ast.Estars(dots,_) -> [e]
216 | Ast.OptExp(exp) ->
217 let exp = disjexp exp in
218 List.map (function exp -> Ast.rewrap e (Ast.OptExp(exp))) exp
219 | Ast.UniqueExp(exp) ->
220 let exp = disjexp exp in
221 List.map (function exp -> Ast.rewrap e (Ast.UniqueExp(exp))) exp
222
223and disjparam p =
224 match Ast.unwrap p with
225 Ast.VoidParam(ty) -> [p] (* void is the only possible value *)
226 | Ast.Param(ty,id) ->
227 let ty = disjty ty in
228 List.map (function ty -> Ast.rewrap p (Ast.Param(ty,id))) ty
229 | Ast.AsParam(pm,asexp) -> (* as exp doesn't contain disj *)
230 let pm = disjparam pm in
231 List.map (function pm -> Ast.rewrap p (Ast.AsParam(pm,asexp))) pm
232 | Ast.MetaParam(_,_,_) | Ast.MetaParamList(_,_,_,_) | Ast.PComma(_) -> [p]
233 | Ast.Pdots(dots) | Ast.Pcircles(dots) -> [p]
234 | Ast.OptParam(param) ->
235 let param = disjparam param in
236 List.map (function param -> Ast.rewrap p (Ast.OptParam(param))) param
237 | Ast.UniqueParam(param) ->
238 let param = disjparam param in
239 List.map (function param -> Ast.rewrap p (Ast.UniqueParam(param))) param
240
241and disjini i =
242 match Ast.unwrap i with
243 Ast.MetaInit(_,_,_) | Ast.MetaInitList(_,_,_,_) -> [i]
244 | Ast.AsInit(ini,asini) ->
245 let ini = disjini ini in
246 List.map (function ini -> Ast.rewrap i (Ast.AsInit(ini,asini))) ini
247 | Ast.InitExpr(exp) ->
248 let exp = disjexp exp in
249 List.map (function exp -> Ast.rewrap i (Ast.InitExpr(exp))) exp
250 | Ast.ArInitList(lb,initlist,rb) ->
251 List.map
252 (function initlist ->
253 Ast.rewrap i (Ast.ArInitList(lb,initlist,rb)))
254 (disjdots disjini initlist)
255 | Ast.StrInitList(allminus,lb,initlist,rb,whencode) ->
256 List.map
257 (function initlist ->
258 Ast.rewrap i (Ast.StrInitList(allminus,lb,initlist,rb,whencode)))
259 (disjmult disjini initlist)
260 | Ast.InitGccExt(designators,eq,ini) ->
261 let designators = disjmult designator designators in
262 let ini = disjini ini in
263 disjmult2 designators ini
264 (function designators -> function ini ->
265 Ast.rewrap i (Ast.InitGccExt(designators,eq,ini)))
266 | Ast.InitGccName(name,eq,ini) ->
267 let ini = disjini ini in
268 List.map
269 (function ini -> Ast.rewrap i (Ast.InitGccName(name,eq,ini)))
270 ini
271 | Ast.IComma(comma) -> [i]
272 | Ast.Idots(dots,_) -> [i]
273 | Ast.OptIni(ini) ->
274 let ini = disjini ini in
275 List.map (function ini -> Ast.rewrap i (Ast.OptIni(ini))) ini
276 | Ast.UniqueIni(ini) ->
277 let ini = disjini ini in
278 List.map (function ini -> Ast.rewrap i (Ast.UniqueIni(ini))) ini
279
280and designator = function
281 Ast.DesignatorField(dot,id) -> [Ast.DesignatorField(dot,id)]
282 | Ast.DesignatorIndex(lb,exp,rb) ->
283 let exp = disjexp exp in
284 List.map (function exp -> Ast.DesignatorIndex(lb,exp,rb)) exp
285 | Ast.DesignatorRange(lb,min,dots,max,rb) ->
286 disjmult2 (disjexp min) (disjexp max)
287 (function min -> function max ->
288 Ast.DesignatorRange(lb,min,dots,max,rb))
289
290and disjdecl d =
291 match Ast.unwrap d with
292 Ast.MetaDecl(_,_,_) | Ast.MetaField(_,_,_)
293 | Ast.MetaFieldList(_,_,_,_) -> [d]
294 | Ast.AsDecl(decl,asdecl) ->
295 let decl = disjdecl decl in
296 List.map (function decl -> Ast.rewrap d (Ast.AsDecl(decl,asdecl))) decl
297 | Ast.Init(stg,ty,id,eq,ini,sem) ->
298 disjmult2 (disjty ty) (disjini ini)
299 (function ty -> function ini ->
300 Ast.rewrap d (Ast.Init(stg,ty,id,eq,ini,sem)))
301 | Ast.UnInit(stg,ty,id,sem) ->
302 let ty = disjty ty in
303 List.map (function ty -> Ast.rewrap d (Ast.UnInit(stg,ty,id,sem))) ty
304 | Ast.MacroDecl(name,lp,args,rp,sem) ->
305 List.map
306 (function args -> Ast.rewrap d (Ast.MacroDecl(name,lp,args,rp,sem)))
307 (disjdots disjexp args)
308 | Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem) ->
309 disjmult2 (disjdots disjexp args) (disjini ini)
310 (function args -> function ini ->
311 Ast.rewrap d (Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem)))
312 | Ast.TyDecl(ty,sem) ->
313 let ty = disjty ty in
314 List.map (function ty -> Ast.rewrap d (Ast.TyDecl(ty,sem))) ty
315 | Ast.Typedef(stg,ty,id,sem) ->
316 let ty = disjty ty in (* disj not allowed in id *)
317 List.map (function ty -> Ast.rewrap d (Ast.Typedef(stg,ty,id,sem))) ty
318 | Ast.DisjDecl(decls) -> List.concat (List.map disjdecl decls)
319 | Ast.Ddots(_,_) -> [d]
320 | Ast.OptDecl(decl) ->
321 let decl = disjdecl decl in
322 List.map (function decl -> Ast.rewrap d (Ast.OptDecl(decl))) decl
323 | Ast.UniqueDecl(decl) ->
324 let decl = disjdecl decl in
325 List.map (function decl -> Ast.rewrap d (Ast.UniqueDecl(decl))) decl
326
327let generic_orify_rule_elem f re exp rebuild =
328 match f exp with
329 [exp] -> re
330 | orexps -> Ast.rewrap re (Ast.DisjRuleElem (List.map rebuild orexps))
331
332let orify_rule_elem re exp rebuild =
333 generic_orify_rule_elem disjexp re exp rebuild
334
335let orify_rule_elem_ty = generic_orify_rule_elem disjty
336let orify_rule_elem_param = generic_orify_rule_elem disjparam
337let orify_rule_elem_decl = generic_orify_rule_elem disjdecl
338let orify_rule_elem_ini = generic_orify_rule_elem disjini
339
340let rec disj_rule_elem r k re =
341 match Ast.unwrap re with
342 Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) ->
343 generic_orify_rule_elem (disjdots disjparam) re params
344 (function params ->
345 Ast.rewrap re
346 (Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp)))
347 | Ast.Decl(bef,allminus,decl) ->
348 orify_rule_elem_decl re decl
349 (function decl -> Ast.rewrap re (Ast.Decl(bef,allminus,decl)))
350 | Ast.SeqStart(brace) -> re
351 | Ast.SeqEnd(brace) -> re
352 | Ast.ExprStatement(Some exp,sem) ->
353 orify_rule_elem re exp
354 (function exp -> Ast.rewrap re (Ast.ExprStatement(Some exp,sem)))
355 | Ast.ExprStatement(None,sem) -> re
356 | Ast.IfHeader(iff,lp,exp,rp) ->
357 orify_rule_elem re exp
358 (function exp -> Ast.rewrap re (Ast.IfHeader(iff,lp,exp,rp)))
359 | Ast.Else(els) -> re
360 | Ast.WhileHeader(whl,lp,exp,rp) ->
361 orify_rule_elem re exp
362 (function exp -> Ast.rewrap re (Ast.WhileHeader(whl,lp,exp,rp)))
363 | Ast.DoHeader(d) -> re
364 | Ast.WhileTail(whl,lp,exp,rp,sem) ->
365 orify_rule_elem re exp
366 (function exp -> Ast.rewrap re (Ast.WhileTail(whl,lp,exp,rp,sem)))
367 | Ast.ForHeader(fr,lp,first,e2,sem2,e3,rp) ->
368 let disjfirst = function
369 Ast.ForExp(e1,sem1) ->
370 List.map (function e1 -> Ast.ForExp(e1,sem1))
371 (disjoption disjexp e1)
372 | Ast.ForDecl (bef,allminus,decl) ->
373 List.map (function decl -> Ast.ForDecl (bef,allminus,decl))
374 (disjdecl decl) in
375 generic_orify_rule_elem
376 (disjmult_two disjfirst (disjoption disjexp)) re (first,[e2;e3])
377 (function
378 (first,[exp2;exp3]) ->
379 Ast.rewrap re (Ast.ForHeader(fr,lp,first,exp2,sem2,exp3,rp))
380 | _ -> failwith "not possible")
381 | Ast.IteratorHeader(whl,lp,args,rp) ->
382 generic_orify_rule_elem (disjdots disjexp) re args
383 (function args -> Ast.rewrap re (Ast.IteratorHeader(whl,lp,args,rp)))
384 | Ast.SwitchHeader(switch,lp,exp,rp) ->
385 orify_rule_elem re exp
386 (function exp -> Ast.rewrap re (Ast.SwitchHeader(switch,lp,exp,rp)))
387 | Ast.Break(_,_) | Ast.Continue(_,_) | Ast.Label(_,_) | Ast.Goto(_,_,_)
388 | Ast.Return(_,_) -> re
389 | Ast.ReturnExpr(ret,exp,sem) ->
390 orify_rule_elem re exp
391 (function exp -> Ast.rewrap re (Ast.ReturnExpr(ret,exp,sem)))
392 | Ast.MetaRuleElem(_,_,_) | Ast.MetaStmt(_,_,_,_)
393 | Ast.MetaStmtList(_,_,_) -> re
394 | Ast.Exp(exp) ->
395 orify_rule_elem re exp (function exp -> Ast.rewrap exp (Ast.Exp(exp)))
396 | Ast.TopExp(exp) ->
397 orify_rule_elem re exp (function exp -> Ast.rewrap exp (Ast.TopExp(exp)))
398 | Ast.Ty(ty) ->
399 orify_rule_elem_ty re ty (function ty -> Ast.rewrap ty (Ast.Ty(ty)))
400 | Ast.TopInit(init) ->
401 orify_rule_elem_ini re init
402 (function init -> Ast.rewrap init (Ast.TopInit(init)))
403 | Ast.Include(inc,s) -> re
404 | Ast.Undef(def,id) -> re
405 | Ast.DefineHeader(def,id,params) -> re
406 | Ast.Default(def,colon) -> re
407 | Ast.Case(case,exp,colon) ->
408 orify_rule_elem re exp
409 (function exp -> Ast.rewrap re (Ast.Case(case,exp,colon)))
410 | Ast.DisjRuleElem(l) ->
411 (* only case lines *)
412 Ast.rewrap re(Ast.DisjRuleElem(List.map (disj_rule_elem r k) l))
413
414let disj_all =
415 let mcode x = x in
416 let donothing r k e = k e in
417 V.rebuilder
418 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
419 donothing donothing donothing donothing donothing
420 donothing donothing donothing donothing donothing donothing donothing
421 disj_rule_elem donothing donothing donothing donothing
422
423(* ----------------------------------------------------------------------- *)
424(* collect iso information at the rule_elem level *)
425
426let collect_all_isos =
427 let bind = (@) in
428 let option_default = [] in
429 let mcode r x = [] in
430 let donothing r k e = Common.union_set (Ast.get_isos e) (k e) in
431 let doanything r k e = k e in
432 V.combiner bind option_default
433 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
434 donothing donothing donothing donothing donothing donothing donothing
435 donothing donothing donothing donothing donothing donothing donothing
436 donothing donothing doanything
437
438let collect_iso_info =
439 let mcode x = x in
440 let donothing r k e = k e in
441 let rule_elem r k e =
442 match Ast.unwrap e with
443 Ast.DisjRuleElem(l) -> k e
444 | _ ->
445 let isos = collect_all_isos.V.combiner_rule_elem e in
446 Ast.set_isos e isos in
447 V.rebuilder
448 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
449 donothing donothing donothing donothing donothing donothing donothing
450 donothing
451 donothing donothing donothing donothing rule_elem donothing donothing
452 donothing donothing
453
454(* ----------------------------------------------------------------------- *)
455
456let disj rules =
457 List.map
458 (function (mv,r) ->
459 match r with
460 Ast.ScriptRule _
461 | Ast.InitialScriptRule _ | Ast.FinalScriptRule _ -> (mv, r)
462 | Ast.CocciRule (nm, rule_info, r, isexp, ruletype) ->
463 let res =
464 List.map
465 (function x ->
466 let res = disj_all.V.rebuilder_top_level x in
467 if !Flag.track_iso_usage
468 then collect_iso_info.V.rebuilder_top_level res
469 else res)
470 r in
471 (mv, Ast.CocciRule (nm,rule_info,res,isexp,ruletype)))
472 rules