Release coccinelle-0.2.0rc1
[bpt/coccinelle.git] / parsing_cocci / adjust_pragmas.ml
1 (* Find a directive or comment at the end of a statement. Things with aft
2 given None, because they can accomodate their own directives or comments *)
3
4 module Ast0 = Ast0_cocci
5 module Ast = Ast_cocci
6 module V0 = Visitor_ast0
7 module VT0 = Visitor_ast0_types
8
9 let call_right processor data s cont =
10 match processor data with
11 None -> None
12 | Some(pragmas,data) -> Some (pragmas,Ast0.rewrap s (cont data))
13
14 let left_mcode (a,b,info,mcodekind,d,e) =
15 match (info.Ast0.strings_before,mcodekind) with
16 ([],_) | (_,Ast0.PLUS _) -> None
17 | (l,_) -> Some(l,(a,b,{info with Ast0.strings_before = []},mcodekind,d,e))
18
19 let right_mcode (a,b,info,mcodekind,d,e) =
20 match (info.Ast0.strings_after,mcodekind) with
21 ([],_) | (_,Ast0.PLUS _) -> None
22 | (l,_) -> Some(l,(a,b,{info with Ast0.strings_after = []},mcodekind,d,e))
23
24 let update_before pragmas (info,x) =
25 ({info with Ast0.strings_before = pragmas @ info.Ast0.strings_before},
26 Ast0.PLUS Ast.ONE) (* not sure what the arg should be... one seems safe *)
27
28 let update_after pragmas (info,x) =
29 ({info with Ast0.strings_after = info.Ast0.strings_after @ pragmas},
30 Ast0.PLUS Ast.ONE) (* not sure what the arg should be... one seems safe *)
31
32 let rec right_decl d =
33 match Ast0.unwrap d with
34 Ast0.Init(Some stg,ty,id,eq,ini,sem) ->
35 call_right right_mcode sem d
36 (function sem -> Ast0.Init(Some stg,ty,id,eq,ini,sem))
37 | Ast0.Init(None,ty,id,eq,ini,sem) ->
38 call_right right_mcode sem d
39 (function sem -> Ast0.Init(None,ty,id,eq,ini,sem))
40 | Ast0.UnInit(Some stg,ty,id,sem) ->
41 call_right right_mcode sem d
42 (function sem -> Ast0.UnInit(Some stg,ty,id,sem))
43 | Ast0.UnInit(None,ty,id,sem) ->
44 call_right right_mcode sem d
45 (function sem -> Ast0.UnInit(None,ty,id,sem))
46 | Ast0.MacroDecl(name,lp,args,rp,sem) ->
47 call_right right_mcode sem d
48 (function sem -> Ast0.MacroDecl(name,lp,args,rp,sem))
49 | Ast0.TyDecl(ty,sem) ->
50 call_right right_mcode sem d
51 (function sem -> Ast0.TyDecl(ty,sem))
52 | Ast0.Typedef(stg,ty,id,sem) ->
53 call_right right_mcode sem d
54 (function sem -> Ast0.Typedef(stg,ty,id,sem))
55 | Ast0.DisjDecl(starter,decls,mids,ender) -> None
56 | Ast0.Ddots(dots,whencode) -> None
57 | Ast0.OptDecl(decl) ->
58 call_right right_decl decl d (function decl -> Ast0.OptDecl(decl))
59 | Ast0.UniqueDecl(decl) ->
60 call_right right_decl decl d (function decl -> Ast0.UniqueDecl(decl))
61
62 let rec right_statement s =
63 match Ast0.unwrap s with
64 Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) -> None
65 | Ast0.Decl(bef,decl) ->
66 call_right right_decl decl s
67 (function decl -> Ast0.Decl(bef,decl))
68 | Ast0.Seq(lbrace,body,rbrace) ->
69 call_right right_mcode rbrace s
70 (function rbrace -> Ast0.Seq(lbrace,body,rbrace))
71 | Ast0.ExprStatement(exp,sem) ->
72 call_right right_mcode sem s
73 (function sem -> Ast0.ExprStatement(exp,sem))
74 | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) -> None
75 | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) -> None
76 | Ast0.While(whl,lp,exp,rp,body,aft) -> None
77 | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
78 call_right right_mcode sem s
79 (function sem -> Ast0.Do(d,body,whl,lp,exp,rp,sem))
80 | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) -> None
81 | Ast0.Iterator(nm,lp,args,rp,body,aft) -> None
82 | Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb) ->
83 call_right right_mcode rb s
84 (function rb -> Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb))
85 | Ast0.Break(br,sem) ->
86 call_right right_mcode sem s
87 (function sem -> Ast0.Break(br,sem))
88 | Ast0.Continue(cont,sem) ->
89 call_right right_mcode sem s
90 (function sem -> Ast0.Continue(cont,sem))
91 | Ast0.Label(l,dd) ->
92 call_right right_mcode dd s
93 (function dd -> Ast0.Label(l,dd))
94 | Ast0.Goto(goto,l,sem) ->
95 call_right right_mcode sem s
96 (function sem -> Ast0.Goto(goto,l,sem))
97 | Ast0.Return(ret,sem) ->
98 call_right right_mcode sem s
99 (function sem -> Ast0.Return(ret,sem))
100 | Ast0.ReturnExpr(ret,exp,sem) ->
101 call_right right_mcode sem s
102 (function sem -> Ast0.ReturnExpr(ret,exp,sem))
103 | Ast0.MetaStmt(name,pure) ->
104 call_right right_mcode name s
105 (function name -> Ast0.MetaStmt(name,pure))
106 | Ast0.MetaStmtList(name,pure) ->
107 call_right right_mcode name s
108 (function name -> Ast0.MetaStmtList(name,pure))
109 | Ast0.Disj(starter,statement_dots_list,mids,ender) -> None
110 | Ast0.Nest(starter,stmt_dots,ender,whn,multi) -> None
111 (* the following are None, because they can't be adjacent to an aft node *)
112 | Ast0.Exp(exp) -> None
113 | Ast0.TopExp(exp) -> None
114 | Ast0.Ty(ty) -> None
115 | Ast0.TopInit(init) -> None
116 | Ast0.Dots(d,whn) -> None
117 | Ast0.Circles(d,whn) -> None
118 | Ast0.Stars(d,whn) -> None
119 | Ast0.Include(inc,name) ->
120 call_right right_mcode name s
121 (function name -> Ast0.Include(inc,name))
122 | Ast0.Define(def,id,params,body) ->
123 call_right right_statement_dots body s
124 (function body -> Ast0.Define(def,id,params,body))
125 | Ast0.OptStm(re) ->
126 call_right right_statement re s (function re -> Ast0.OptStm(re))
127 | Ast0.UniqueStm(re) ->
128 call_right right_statement re s (function re -> Ast0.UniqueStm(re))
129
130 and right_statement_dots sd =
131 match Ast0.unwrap sd with
132 Ast0.DOTS([]) -> failwith "empty statement dots"
133 | Ast0.DOTS(s::r) ->
134 call_right right_statement s sd
135 (function s -> Ast0.DOTS(List.rev(s::r)))
136 | _ -> failwith "circles and stars not supported"
137
138 let rec left_ty t =
139 match Ast0.unwrap t with
140 Ast0.ConstVol(cv,ty) ->
141 call_right left_mcode cv t (function cv -> Ast0.ConstVol(cv,ty))
142 | Ast0.BaseType(ty,strings) ->
143 (match strings with
144 [] -> failwith "empty strings in type"
145 | s::r ->
146 call_right left_mcode s t (function s -> Ast0.BaseType(ty,s::r)))
147 | Ast0.Signed(sign,ty) ->
148 call_right left_mcode sign t (function sign -> Ast0.Signed(sign,ty))
149 | Ast0.Pointer(ty,star) ->
150 call_right left_ty ty t (function ty -> Ast0.Pointer(ty,star))
151 | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
152 call_right left_ty ty t
153 (function ty -> Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2))
154 | Ast0.FunctionType(Some ty,lp1,params,rp1) ->
155 call_right left_ty ty t
156 (function ty -> Ast0.FunctionType(Some ty,lp1,params,rp1))
157 | Ast0.FunctionType(None,lp1,params,rp1) ->
158 call_right left_mcode lp1 t
159 (function lp1 -> Ast0.FunctionType(None,lp1,params,rp1))
160 | Ast0.Array(ty,lb,size,rb) ->
161 call_right left_ty ty t (function ty -> Ast0.Array(ty,lb,size,rb))
162 | Ast0.EnumName(kind,name) ->
163 call_right left_mcode kind t (function kind -> Ast0.EnumName(kind,name))
164 | Ast0.StructUnionName(kind,name) ->
165 call_right left_mcode kind t
166 (function kind -> Ast0.StructUnionName(kind,name))
167 | Ast0.StructUnionDef(ty,lb,decls,rb) ->
168 call_right left_ty ty t
169 (function ty -> Ast0.StructUnionDef(ty,lb,decls,rb))
170 | Ast0.TypeName(name) ->
171 call_right left_mcode name t (function name -> Ast0.TypeName(name))
172 | Ast0.MetaType(name,x) ->
173 call_right left_mcode name t (function name -> Ast0.MetaType(name,x))
174 | Ast0.DisjType(starter,types,mids,ender) -> None
175 | Ast0.OptType(ty) ->
176 call_right left_ty ty t (function ty -> Ast0.OptType(ty))
177 | Ast0.UniqueType(ty) ->
178 call_right left_ty ty t (function ty -> Ast0.UniqueType(ty))
179
180 let rec left_ident i =
181 match Ast0.unwrap i with
182 Ast0.Id(name) ->
183 call_right left_mcode name i
184 (function name -> Ast0.Id(name))
185 | Ast0.MetaId(name,a,b) ->
186 call_right left_mcode name i
187 (function name -> Ast0.MetaId(name,a,b))
188 | Ast0.MetaFunc(name,a,b) ->
189 call_right left_mcode name i
190 (function name -> Ast0.MetaFunc(name,a,b))
191 | Ast0.MetaLocalFunc(name,a,b) ->
192 call_right left_mcode name i
193 (function name -> Ast0.MetaLocalFunc(name,a,b))
194 | Ast0.OptIdent(id) ->
195 call_right left_ident id i (function id -> Ast0.OptIdent(id))
196 | Ast0.UniqueIdent(id) ->
197 call_right left_ident id i (function id -> Ast0.UniqueIdent(id))
198
199 let left_fundecl name fninfo =
200 let fncall_right processor data cont =
201 match processor data with
202 None -> None
203 | Some(pragmas,data) -> Some (pragmas,cont data,name) in
204 match fninfo with
205 [] ->
206 (match left_ident name with
207 None -> None
208 | Some(pragmas,name) -> Some(pragmas,fninfo,name))
209 | (Ast0.FStorage sto)::x ->
210 fncall_right left_mcode sto (function sto -> (Ast0.FStorage sto)::x)
211 | (Ast0.FType ty)::x ->
212 fncall_right left_ty ty (function ty -> (Ast0.FType ty)::x)
213 | (Ast0.FInline inl)::x ->
214 fncall_right left_mcode inl (function inl -> (Ast0.FInline inl)::x)
215 | (Ast0.FAttr atr)::x ->
216 fncall_right left_mcode atr (function atr -> (Ast0.FAttr atr)::x)
217
218 let rec left_decl decl =
219 match Ast0.unwrap decl with
220 Ast0.Init(Some stg,ty,id,eq,ini,sem) ->
221 call_right left_mcode stg decl
222 (function stg -> Ast0.Init(Some stg,ty,id,eq,ini,sem))
223 | Ast0.Init(None,ty,id,eq,ini,sem) ->
224 call_right left_ty ty decl
225 (function ty -> Ast0.Init(None,ty,id,eq,ini,sem))
226 | Ast0.UnInit(Some stg,ty,id,sem) ->
227 call_right left_mcode stg decl
228 (function stg -> Ast0.UnInit(Some stg,ty,id,sem))
229 | Ast0.UnInit(None,ty,id,sem) ->
230 call_right left_ty ty decl
231 (function ty -> Ast0.UnInit(None,ty,id,sem))
232 | Ast0.MacroDecl(name,lp,args,rp,sem) ->
233 call_right left_ident name decl
234 (function name -> Ast0.MacroDecl(name,lp,args,rp,sem))
235 | Ast0.TyDecl(ty,sem) ->
236 call_right left_ty ty decl (function ty -> Ast0.TyDecl(ty,sem))
237 | Ast0.Typedef(stg,ty,id,sem) ->
238 call_right left_mcode stg decl
239 (function stg -> Ast0.Typedef(stg,ty,id,sem))
240 | Ast0.DisjDecl(starter,decls,mids,ender) -> None
241 | Ast0.Ddots(dots,whencode) -> None
242 | Ast0.OptDecl(d) ->
243 call_right left_decl d decl (function decl -> Ast0.OptDecl(decl))
244 | Ast0.UniqueDecl(d) ->
245 call_right left_decl d decl (function decl -> Ast0.UniqueDecl(decl))
246
247 let process =
248 let statement r k s =
249 let s = k s in
250 Ast0.rewrap s
251 (match Ast0.unwrap s with
252 Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
253 (match left_fundecl name fi with
254 None -> Ast0.unwrap s
255 | Some (pragmas,fi,name) ->
256 Ast0.FunDecl
257 (update_after pragmas bef,
258 fi,name,lp,params,rp,lbrace,body,rbrace))
259 | Ast0.Decl(bef,decl) ->
260 (match left_decl decl with
261 None -> Ast0.unwrap s
262 | Some (pragmas,decl) ->
263 Ast0.Decl(update_after pragmas bef,decl))
264 | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
265 (match right_statement branch1 with
266 None -> Ast0.unwrap s
267 | Some (pragmas,branch1) ->
268 Ast0.IfThen
269 (iff,lp,exp,rp,branch1,update_before pragmas aft))
270 | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
271 (match right_statement branch2 with
272 None -> Ast0.unwrap s
273 | Some (pragmas,branch2) ->
274 Ast0.IfThenElse
275 (iff,lp,exp,rp,branch1,els,branch2,
276 update_before pragmas aft))
277 | Ast0.While(whl,lp,exp,rp,body,aft) ->
278 (match right_statement body with
279 None -> Ast0.unwrap s
280 | Some (pragmas,body) ->
281 Ast0.While(whl,lp,exp,rp,body,update_before pragmas aft))
282 | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
283 (match right_statement body with
284 None -> Ast0.unwrap s
285 | Some (pragmas,body) ->
286 Ast0.For
287 (fr,lp,e1,sem1,e2,sem2,e3,rp,body,
288 update_before pragmas aft))
289 | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
290 (match right_statement body with
291 None -> Ast0.unwrap s
292 | Some (pragmas,body) ->
293 Ast0.Iterator(nm,lp,args,rp,body,update_before pragmas aft))
294 | _ -> Ast0.unwrap s) in
295
296 let res = V0.rebuilder
297 {V0.rebuilder_functions with VT0.rebuilder_stmtfn = statement} in
298
299 List.map res.VT0.rebuilder_rec_top_level