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.
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.
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.
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/>.
18 * The authors reserve the right to distribute this or future versions of
19 * Coccinelle under other licenses.
23 (* detect statements that are between dots in the minus code, because they
24 may need a special treatment if they are if branches *)
26 module Ast0
= Ast0_cocci
27 module Ast
= Ast_cocci
28 module V0
= Visitor_ast0
29 module VT0
= Visitor_ast0_types
31 (* --------------------------------------------------------------------- *)
32 (* --------------------------------------------------------------------- *)
36 match Ast0.undots l
with
41 match List.rev
(Ast0.undots l
) with
45 let modif_before_mcode mc
=
46 match Ast0.get_mcode_mcodekind mc
with
47 Ast0.MINUS mc
-> true (*conservative; don't want to hunt right for + code*)
48 | Ast0.PLUS
-> failwith
"not possible"
51 (Ast.BEFORE _
,_
,_
) -> true
52 | (Ast.BEFOREAFTER _
,_
,_
) -> true
54 | Ast0.MIXED mc
-> true (* don't think mcode can be mixed *)
56 let modif_after_mcodekind = function
57 Ast0.MINUS mc
-> true (*conservative; don't want to hunt right for + code*)
58 | Ast0.PLUS
-> failwith
"not possible"
61 (Ast.AFTER _
,_
,_
) -> true
62 | (Ast.BEFOREAFTER _
,_
,_
) -> true
64 | Ast0.MIXED mc
-> true (* don't think mcode can be mixed *)
66 let modif_after_mcode mc
= modif_after_mcodekind (Ast0.get_mcode_mcodekind mc
)
72 Ast.StatementTag
(_
) | Ast.StmtDotsTag
(_
)
73 | Ast.DeclarationTag
(_
) | Ast.DeclDotsTag
(_
) -> true | _
-> false))
76 match Ast0.get_mcodekind x
with
77 Ast0.PLUS
-> failwith
"not possible"
80 (* do better for the common case of replacing a stmt by another one *)
81 ([[Ast.StatementTag
(s
)]],_
) ->
82 (match Ast.unwrap s
with
83 Ast.IfThen
(_
,_
,_
) -> true (* potentially dangerous *)
86 | Ast0.CONTEXT mc
| Ast0.MIXED mc
->
88 (Ast.BEFORE _
,_
,_
) -> true
89 | (Ast.BEFOREAFTER _
,_
,_
) -> true
93 match Ast0.get_mcodekind x
with
94 Ast0.PLUS
-> failwith
"not possible"
97 (* do better for the common case of replacing a stmt by another one *)
98 ([[Ast.StatementTag
(s
)]],_
) ->
99 (match Ast.unwrap s
with
100 Ast.IfThen
(_
,_
,_
) -> true (* potentially dangerous *)
102 | (l
,_
) -> any_statements l
)
103 | Ast0.CONTEXT mc
| Ast0.MIXED mc
->
105 (Ast.AFTER _
,_
,_
) -> true
106 | (Ast.BEFOREAFTER _
,_
,_
) -> true
110 let rec left_ident i
=
112 match Ast0.unwrap i
with
113 Ast0.Id
(name
) -> modif_before_mcode name
114 | Ast0.MetaId
(name
,_
,_
) -> modif_before_mcode name
115 | Ast0.MetaFunc
(name
,_
,_
) -> modif_before_mcode name
116 | Ast0.MetaLocalFunc
(name
,_
,_
) -> modif_before_mcode name
117 | Ast0.OptIdent
(id
) -> left_ident id
118 | Ast0.UniqueIdent
(id
) -> left_ident id
120 (* --------------------------------------------------------------------- *)
123 let rec left_expression e
=
125 match Ast0.unwrap e
with
126 Ast0.Ident
(id
) -> left_ident id
127 | Ast0.Constant
(const
) -> modif_before_mcode const
128 | Ast0.FunCall
(fn
,lp
,args
,rp
) -> left_expression fn
129 | Ast0.Assignment
(left
,op
,right
,_
) -> left_expression left
130 | Ast0.CondExpr
(exp1
,why
,exp2
,colon
,exp3
) -> left_expression exp1
131 | Ast0.Postfix
(exp
,op
) -> left_expression exp
132 | Ast0.Infix
(exp
,op
) -> modif_before_mcode op
133 | Ast0.Unary
(exp
,op
) -> modif_before_mcode op
134 | Ast0.Binary
(left
,op
,right
) -> left_expression left
135 | Ast0.Nested
(left
,op
,right
) -> left_expression left
136 | Ast0.Paren
(lp
,exp
,rp
) -> modif_before_mcode lp
137 | Ast0.ArrayAccess
(exp1
,lb
,exp2
,rb
) -> left_expression exp1
138 | Ast0.RecordAccess
(exp
,pt
,field
) -> left_expression exp
139 | Ast0.RecordPtAccess
(exp
,ar
,field
) -> left_expression exp
140 | Ast0.Cast
(lp
,ty
,rp
,exp
) -> modif_before_mcode lp
141 | Ast0.SizeOfExpr
(szf
,exp
) -> modif_before_mcode szf
142 | Ast0.SizeOfType
(szf
,lp
,ty
,rp
) -> modif_before_mcode szf
143 | Ast0.TypeExp
(ty
) -> left_typeC ty
144 | Ast0.MetaErr
(name
,_
,_
) -> modif_before_mcode name
145 | Ast0.MetaExpr
(name
,_
,ty
,_
,_
) -> modif_before_mcode name
146 | Ast0.MetaExprList
(name
,_
,_
) -> modif_before_mcode name
147 | Ast0.EComma
(cm
) -> modif_before_mcode cm
148 | Ast0.DisjExpr
(_
,exp_list
,_
,_
) -> List.exists
left_expression exp_list
149 | Ast0.NestExpr
(starter
,expr_dots
,ender
,_
,multi
) ->
150 left_dots left_expression expr_dots
151 | Ast0.Edots
(dots
,_
) | Ast0.Ecircles
(dots
,_
) | Ast0.Estars
(dots
,_
) -> false
152 | Ast0.OptExp
(exp
) -> left_expression exp
153 | Ast0.UniqueExp
(exp
) -> left_expression exp
155 (* --------------------------------------------------------------------- *)
160 match Ast0.unwrap t
with
161 Ast0.ConstVol
(cv
,ty
) -> modif_before_mcode cv
162 | Ast0.BaseType
(ty
,strings
) -> modif_before_mcode (List.hd strings
)
163 | Ast0.Signed
(sgn
,ty
) -> modif_before_mcode sgn
164 | Ast0.Pointer
(ty
,star
) -> left_typeC ty
165 | Ast0.FunctionPointer
(ty
,lp1
,star
,rp1
,lp2
,params
,rp2
) -> left_typeC ty
166 | Ast0.FunctionType
(Some ty
,lp1
,params
,rp1
) -> left_typeC ty
167 | Ast0.FunctionType
(None
,lp1
,params
,rp1
) -> modif_before_mcode lp1
168 | Ast0.Array
(ty
,lb
,size
,rb
) -> left_typeC ty
169 | Ast0.EnumName
(kind
,name
) -> modif_before_mcode kind
170 | Ast0.StructUnionName
(kind
,name
) -> modif_before_mcode kind
171 | Ast0.StructUnionDef
(ty
,lb
,decls
,rb
) -> left_typeC ty
172 | Ast0.TypeName
(name
) -> modif_before_mcode name
173 | Ast0.MetaType
(name
,_
) -> modif_before_mcode name
174 | Ast0.DisjType
(lp
,types
,mids
,rp
) -> List.exists left_typeC types
175 | Ast0.OptType
(ty
) -> left_typeC ty
176 | Ast0.UniqueType
(ty
) -> left_typeC ty
178 (* --------------------------------------------------------------------- *)
179 (* Variable declaration *)
180 (* Even if the Cocci program specifies a list of declarations, they are
181 split out into multiple declarations of a single variable each. *)
183 and left_declaration d
=
185 match Ast0.unwrap d
with
186 Ast0.Init
(Some stg
,ty
,id
,eq
,ini
,sem
) -> modif_before_mcode stg
187 | Ast0.Init
(None
,ty
,id
,eq
,ini
,sem
) -> left_typeC ty
188 | Ast0.UnInit
(Some stg
,ty
,id
,sem
) -> modif_before_mcode stg
189 | Ast0.UnInit
(None
,ty
,id
,sem
) -> left_typeC ty
190 | Ast0.MacroDecl
(name
,lp
,args
,rp
,sem
) -> left_ident name
191 | Ast0.TyDecl
(ty
,sem
) -> left_typeC ty
192 | Ast0.Typedef
(stg
,ty
,id
,sem
) -> modif_before_mcode stg
193 | Ast0.DisjDecl
(_
,decls
,_
,_
) -> List.exists left_declaration decls
194 | Ast0.Ddots
(dots
,_
) -> false
195 | Ast0.OptDecl
(decl
) -> left_declaration decl
196 | Ast0.UniqueDecl
(decl
) -> left_declaration decl
198 and right_declaration d
=
200 match Ast0.unwrap d
with
201 Ast0.Init
(_
,ty
,id
,eq
,ini
,sem
) -> modif_after_mcode sem
202 | Ast0.UnInit
(_
,ty
,id
,sem
) -> modif_after_mcode sem
203 | Ast0.MacroDecl
(name
,lp
,args
,rp
,sem
) -> modif_after_mcode sem
204 | Ast0.TyDecl
(ty
,sem
) -> modif_after_mcode sem
205 | Ast0.Typedef
(stg
,ty
,id
,sem
) -> modif_after_mcode sem
206 | Ast0.DisjDecl
(_
,decls
,_
,_
) -> List.exists right_declaration decls
207 | Ast0.Ddots
(dots
,_
) -> false
208 | Ast0.OptDecl
(decl
) -> right_declaration decl
209 | Ast0.UniqueDecl
(decl
) -> right_declaration decl
211 (* --------------------------------------------------------------------- *)
214 and left_statement s
=
216 match Ast0.unwrap s
with
217 Ast0.FunDecl
(_
,fninfo
,name
,lp
,params
,rp
,lbrace
,body
,rbrace
) ->
218 (* irrelevant *) false
219 | Ast0.Decl
(_
,decl
) -> left_declaration decl
220 | Ast0.Seq
(lbrace
,body
,rbrace
) -> modif_before_mcode lbrace
221 | Ast0.ExprStatement
(exp
,sem
) -> left_expression exp
222 | Ast0.IfThen
(iff
,lp
,exp
,rp
,branch1
,(info
,aft
)) -> modif_before_mcode iff
223 | Ast0.IfThenElse
(iff
,lp
,exp
,rp
,branch1
,els
,branch2
,(info
,aft
)) ->
224 modif_before_mcode iff
225 | Ast0.While
(whl
,lp
,exp
,rp
,body
,(info
,aft
)) -> modif_before_mcode whl
226 | Ast0.Do
(d
,body
,whl
,lp
,exp
,rp
,sem
) -> modif_before_mcode d
227 | Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,body
,(info
,aft
)) ->
228 modif_before_mcode fr
229 | Ast0.Iterator
(nm
,lp
,args
,rp
,body
,(info
,aft
)) -> left_ident nm
230 | Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,cases
,rb
) -> modif_before_mcode switch
231 | Ast0.Break
(br
,sem
) -> modif_before_mcode br
232 | Ast0.Continue
(cont
,sem
) -> modif_before_mcode cont
233 | Ast0.Label
(l
,dd
) -> left_ident l
234 | Ast0.Goto
(goto
,l
,sem
) -> modif_before_mcode goto
235 | Ast0.Return
(ret
,sem
) -> modif_before_mcode ret
236 | Ast0.ReturnExpr
(ret
,exp
,sem
) -> modif_before_mcode ret
237 | Ast0.MetaStmt
(name
,pure
) -> modif_before_mcode name
238 | Ast0.MetaStmtList
(name
,_
) -> modif_before_mcode name
239 | Ast0.Disj
(_
,statement_dots_list
,_
,_
) ->
240 List.exists
(left_dots left_statement
) statement_dots_list
241 | Ast0.Nest
(starter
,stmt_dots
,ender
,whencode
,multi
) ->
242 left_dots left_statement stmt_dots
243 | Ast0.Exp
(exp
) -> false (* can only be replaced by an expression *)
244 | Ast0.TopExp
(exp
) -> false (* as above *)
245 | Ast0.Ty
(ty
) -> false (* can only be replaced by a type *)
246 | Ast0.TopInit
(init
) -> false (* can only be replaced by an init *)
247 | Ast0.Dots
(d
,whn
) | Ast0.Circles
(d
,whn
) | Ast0.Stars
(d
,whn
) -> false
248 | Ast0.Include
(inc
,s
) -> modif_before_mcode inc
249 | Ast0.Define
(def
,id
,params
,body
) -> modif_before_mcode def
250 | Ast0.OptStm
(re
) -> left_statement re
251 | Ast0.UniqueStm
(re
) -> left_statement re
253 and right_statement s
=
255 match Ast0.unwrap s
with
256 Ast0.FunDecl
(_
,fninfo
,name
,lp
,params
,rp
,lbrace
,body
,rbrace
) ->
257 (* irrelevant *) false
258 | Ast0.Decl
(_
,decl
) -> right_declaration decl
259 | Ast0.Seq
(lbrace
,body
,rbrace
) -> modif_after_mcode rbrace
260 | Ast0.ExprStatement
(exp
,sem
) -> modif_after_mcode sem
261 | Ast0.IfThen
(iff
,lp
,exp
,rp
,branch1
,(info
,aft
)) -> modif_after_mcodekind aft
262 | Ast0.IfThenElse
(iff
,lp
,exp
,rp
,branch1
,els
,branch2
,(info
,aft
)) ->
263 modif_after_mcodekind aft
264 | Ast0.While
(whl
,lp
,exp
,rp
,body
,(info
,aft
)) -> modif_after_mcodekind aft
265 | Ast0.Do
(d
,body
,whl
,lp
,exp
,rp
,sem
) -> modif_after_mcode sem
266 | Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,body
,(info
,aft
)) ->
267 modif_after_mcodekind aft
268 | Ast0.Iterator
(nm
,lp
,args
,rp
,body
,(info
,aft
)) ->
269 modif_after_mcodekind aft
270 | Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,cases
,rb
) -> modif_after_mcode rb
271 | Ast0.Break
(br
,sem
) -> modif_after_mcode sem
272 | Ast0.Continue
(cont
,sem
) -> modif_after_mcode sem
273 | Ast0.Label
(l
,dd
) -> modif_after_mcode dd
274 | Ast0.Goto
(goto
,l
,sem
) -> modif_after_mcode sem
275 | Ast0.Return
(ret
,sem
) -> modif_after_mcode sem
276 | Ast0.ReturnExpr
(ret
,exp
,sem
) -> modif_after_mcode sem
277 | Ast0.MetaStmt
(name
,pure
) -> modif_after_mcode name
278 | Ast0.MetaStmtList
(name
,_
) -> modif_after_mcode name
279 | Ast0.Disj
(_
,statement_dots_list
,_
,_
) ->
280 List.exists
(right_dots right_statement
) statement_dots_list
281 | Ast0.Nest
(starter
,stmt_dots
,ender
,whencode
,multi
) ->
282 right_dots right_statement stmt_dots
283 | Ast0.Exp
(exp
) -> false (* can only be replaced by an expression *)
284 | Ast0.TopExp
(exp
) -> false (* as above *)
285 | Ast0.Ty
(ty
) -> false (* can only be replaced by a type *)
286 | Ast0.TopInit
(init
) -> false (* can only be replaced by an init *)
287 | Ast0.Dots
(d
,whn
) | Ast0.Circles
(d
,whn
) | Ast0.Stars
(d
,whn
) -> false
288 | Ast0.Include
(inc
,s
) -> modif_after_mcode s
289 | Ast0.Define
(def
,id
,params
,body
) -> right_dots right_statement body
290 | Ast0.OptStm
(re
) -> right_statement re
291 | Ast0.UniqueStm
(re
) -> right_statement re
293 (* --------------------------------------------------------------------- *)
296 (* A very coarse approximation. We would really only like to return true
297 if a new statement is added. For this it would be best to correlate with the
298 plus slice. Or at least be sure that the new stuff is on the far left or
301 let rec adding_something s
=
302 match Ast0.get_mcodekind s
with
305 (* do better for the common case of replacing a stmt by another one *)
306 ([[Ast.StatementTag
(s
)]],_
) ->
307 (match Ast.unwrap s
with
308 Ast.IfThen
(_
,_
,_
) -> true (* potentially dangerous *)
311 | Ast0.CONTEXT
(mc
) ->
312 let (text
,tinfo1
,tinfo2
) = !mc
in
313 (match text
with Ast.NOTHING
-> false | _
-> true)
315 not
(contains_only_minus
.VT0.combiner_rec_statement s
) (*&&
316 (left_statement s) or (right_statement s)*)
317 | _
-> failwith
"unexpected plus code"
319 (* why do we need this; MINUS should mean the same thing *)
320 and contains_only_minus
=
321 let bind x y
= x
&& y
in
322 let option_default = true in
323 let mcodekind = function
328 | Ast0.CONTEXT
(mc
) -> false
330 let mcode (_
,_
,_
,mc
,_
) = mcodekind mc
in
332 let donothing r k e
= mcodekind (Ast0.get_mcodekind e
) && k e
in
335 match Ast0.unwrap e
with
336 Ast0.DOTS
([]) | Ast0.CIRCLES
([]) | Ast0.STARS
([]) -> true
339 let expression r k e
=
340 mcodekind (Ast0.get_mcodekind e
) &&
341 match Ast0.unwrap e
with
342 Ast0.DisjExpr
(starter
,expr_list
,mids
,ender
) ->
343 List.for_all r
.VT0.combiner_rec_expression expr_list
346 let declaration r k e
=
347 mcodekind (Ast0.get_mcodekind e
) &&
348 match Ast0.unwrap e
with
349 Ast0.DisjDecl
(starter
,decls
,mids
,ender
) ->
350 List.for_all r
.VT0.combiner_rec_declaration decls
354 mcodekind (Ast0.get_mcodekind e
) &&
355 match Ast0.unwrap e
with
356 Ast0.DisjType
(starter
,types
,mids
,ender
) ->
357 List.for_all r
.VT0.combiner_rec_typeC types
360 let statement r k e
=
361 mcodekind (Ast0.get_mcodekind e
) &&
362 match Ast0.unwrap e
with
363 Ast0.Disj
(starter
,statement_dots_list
,mids
,ender
) ->
364 List.for_all r
.VT0.combiner_rec_statement_dots statement_dots_list
367 V0.flat_combiner
bind option_default
368 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
369 dots dots dots dots dots dots
370 donothing expression typeC donothing donothing declaration
371 statement donothing donothing
374 (* needs a special case when there is a Disj or an empty DOTS *)
375 (* ---------------------------------------------------------------------- *)
380 if (acpi_device_dir(device))
382 remove_proc_entry(acpi_device_bid(device), acpi_ac_dir);
383 + acpi_device_dir(device) = NULL;
386 The last two + lines get associated with the end of the if, not with the
387 branch, so the braces get added in oddly.
390 let add_braces orig_s
=
392 (Iso_pattern.rebuild_mcode None
).VT0.rebuilder_rec_statement orig_s
in
394 match Ast0.get_mcodekind
s with
396 let (text
,tinfo
) = !mc
in
397 Ast0.MINUS
(ref([Ast.mkToken
"{"]::text
@[[Ast.mkToken
"}"]],tinfo
))
398 | Ast0.CONTEXT
(mc
) ->
399 let (text
,tinfo1
,tinfo2
) = !mc
in
403 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,[[Ast.mkToken
"}"]])
405 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],aft
@[[Ast.mkToken
"}"]])
406 | Ast.BEFOREAFTER
(bef
,aft
) ->
407 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,aft
@[[Ast.mkToken
"}"]])
409 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],[[Ast.mkToken
"}"]]) in
410 Ast0.CONTEXT
(ref(new_text,tinfo1
,tinfo2
))
412 let (text
,tinfo1
,tinfo2
) = !mc
in
416 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,[[Ast.mkToken
"}"]])
418 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],aft
@[[Ast.mkToken
"}"]])
419 | Ast.BEFOREAFTER
(bef
,aft
) ->
420 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,aft
@[[Ast.mkToken
"}"]])
422 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],[[Ast.mkToken
"}"]]) in
423 Ast0.MIXED
(ref(new_text,tinfo1
,tinfo2
))
424 | _
-> failwith
"unexpected plus code" in
425 Ast0.set_mcodekind
s new_mcodekind;
426 Compute_lines.statement s
428 (* ---------------------------------------------------------------------- *)
431 match Ast0.unwrap x
with
432 Ast0.Dots
(_
,_
) | Ast0.Circles
(_
,_
) | Ast0.Stars
(_
,_
)
433 | Ast0.Nest
(_
,_
,_
,_
,_
) -> true
437 match Ast0.get_mcodekind
s with
438 Ast0.MINUS
(_
) -> true
441 let rec unchanged_minus s =
442 match Ast0.get_mcodekind
s with
443 Ast0.MINUS
(mc
) -> (match !mc
with ([],_
) -> true | _
-> false)
446 let rec do_branch s =
449 Ast0.set_dots_bef_aft
s (Ast0.DroppingBetweenDots
(add_braces s))
451 match Ast0.unwrap
s with
452 Ast0.Disj
(starter
,statement_dots_list
,mids
,ender
) ->
456 match Ast0.unwrap
s with
458 Ast0.rewrap
s (Ast0.DOTS
([do_branch s]))
460 | _
-> failwith
"not supported")
461 statement_dots_list
in
462 Ast0.rewrap
s (Ast0.Disj
(starter
,stmts,mids
,ender
))
465 let rec statement dots_before dots_after
s =
467 if dots_before
&& dots_after
471 (let with_braces = add_braces s in
472 Ast0.set_dots_bef_aft
s (Ast0.DroppingBetweenDots
(with_braces)))
473 else if adding_something s
475 (let with_braces = add_braces s in
476 Ast0.set_dots_bef_aft
s (Ast0.AddingBetweenDots
(with_braces)))
480 match Ast0.unwrap
s with
481 Ast0.FunDecl
(x
,fninfo
,name
,lp
,params
,rp
,lbrace
,body
,rbrace
) ->
482 (* true for close brace, because that represents any way we can
483 exit the function, which is not necessarily followed by an explicit
486 (Ast0.FunDecl
(x
,fninfo
,name
,lp
,params
,rp
,lbrace
,
487 statement_dots
false true body
,
489 | Ast0.Decl
(_
,_
) -> s
490 | Ast0.Seq
(lbrace
,body
,rbrace
) ->
492 (Ast0.Seq
(lbrace
,statement_dots
false false body
,rbrace
))
493 | Ast0.ExprStatement
(exp
,sem
) -> do_one s
494 | Ast0.IfThen
(iff
,lp
,exp
,rp
,branch1
,x
) ->
497 (Ast0.IfThen
(iff
,lp
,exp
,rp
,statement false false branch1
,x
)))
498 | Ast0.IfThenElse
(iff
,lp
,exp
,rp
,branch1
,els
,branch2
,x
) ->
503 statement false false branch1
,els
,
504 statement false false branch2
,x
)))
505 | Ast0.While
(whl
,lp
,exp
,rp
,body
,x
) ->
508 (Ast0.While
(whl
,lp
,exp
,rp
,statement false false body
,x
)))
509 | Ast0.Do
(d
,body
,whl
,lp
,exp
,rp
,sem
) ->
512 (Ast0.Do
(d
,statement false false body
,whl
,lp
,exp
,rp
,sem
)))
513 | Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,body
,x
) ->
516 (Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,
517 statement false false body
,x
)))
518 | Ast0.Iterator
(nm
,lp
,args
,rp
,body
,x
) ->
521 (Ast0.Iterator
(nm
,lp
,args
,rp
,statement false false body
,x
)))
522 | Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,cases
,rb
) ->
525 (Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,
527 (Ast0.DOTS
(List.map case_line
(Ast0.undots cases
))),
529 | Ast0.Break
(br
,sem
) -> do_one s
530 | Ast0.Continue
(cont
,sem
) -> do_one s
531 | Ast0.Label
(l
,dd
) -> do_one s
532 | Ast0.Goto
(goto
,l
,sem
) -> do_one s
533 | Ast0.Return
(ret
,sem
) -> do_one s
534 | Ast0.ReturnExpr
(ret
,exp
,sem
) -> do_one s
535 | Ast0.MetaStmt
(name
,_
) -> do_one s
536 | Ast0.MetaStmtList
(name
,_
) -> do_one s
537 | Ast0.Disj
(starter
,statement_dots_list
,mids
,ender
) ->
540 List.map
(statement_dots dots_before dots_after
)
543 | Ast0.Nest
(starter
,stmt_dots
,ender
,whencode
,multi
) ->
546 (starter
,statement_dots
true true stmt_dots
,ender
,whencode
,multi
))
548 | Ast0.TopExp
(exp
) -> s
550 | Ast0.TopInit
(init
) -> s
551 | Ast0.Dots
(d
,whn
) | Ast0.Circles
(d
,whn
) | Ast0.Stars
(d
,whn
) -> s
552 | Ast0.Include
(inc
,string) -> s (* doesn't affect the need for braces *)
553 | Ast0.Define
(def
,id
,params
,body
) -> s (* same as include *)
556 (Ast0.OptStm
(statement dots_before dots_after re
))
557 | Ast0.UniqueStm
(re
) ->
559 (Ast0.UniqueStm
(statement dots_before dots_after re
))
563 (match Ast0.unwrap c
with
564 Ast0.Default
(def
,colon
,code
) ->
565 Ast0.Default
(def
,colon
,statement_dots
false false code
)
566 | Ast0.Case
(case
,exp
,colon
,code
) ->
567 Ast0.Case
(case
,exp
,colon
,statement_dots
false false code
)
568 | Ast0.OptCase
(case
) -> Ast0.OptCase
(case_line c
))
570 and do_statement_dots dots_before dots_after
= function
572 | [x
] -> [statement dots_before dots_after x
]
573 | dots::rest
when is_dots dots ->
574 dots::(do_statement_dots
true dots_after rest
)
575 | x
::(dots::_
as rest
) when is_dots dots ->
576 (statement dots_before
true x
)::
577 do_statement_dots
false dots_after rest
579 (statement dots_before
false x
)::
580 do_statement_dots
false dots_after rest
582 and statement_dots dots_before dots_after d
=
584 (match Ast0.unwrap d
with
586 Ast0.DOTS
(do_statement_dots dots_before dots_after l
)
588 Ast0.CIRCLES
(do_statement_dots dots_before dots_after l
)
590 Ast0.STARS
(do_statement_dots dots_before dots_after l
))
594 (match Ast0.unwrap t
with
595 Ast0.DECL
(stmt_dots
) -> Ast0.DECL
(statement true true stmt_dots
)
596 | Ast0.CODE
(stmt_dots
) -> Ast0.CODE
(statement_dots
true true stmt_dots
)
599 let single_statement l
=
600 if !Flag_parsing_cocci.sgrep_mode
then l
else List.map
top_level l