1 (* detect statements that are between dots in the minus code, because they
2 may need a special treatment if they are if branches *)
4 module Ast0
= Ast0_cocci
6 module V0
= Visitor_ast0
7 module VT0
= Visitor_ast0_types
9 (* --------------------------------------------------------------------- *)
10 (* --------------------------------------------------------------------- *)
14 match Ast0.undots l
with
19 match List.rev
(Ast0.undots l
) with
23 let modif_before_mcode mc
=
24 match Ast0.get_mcode_mcodekind mc
with
25 Ast0.MINUS mc
-> true (*conservative; don't want to hunt right for + code*)
26 | Ast0.PLUS _
-> failwith
"not possible"
29 (Ast.BEFORE _
,_
,_
) -> true
30 | (Ast.BEFOREAFTER _
,_
,_
) -> true
32 | Ast0.MIXED mc
-> true (* don't think mcode can be mixed *)
34 let modif_after_mcodekind = function
35 Ast0.MINUS mc
-> true (*conservative; don't want to hunt right for + code*)
36 | Ast0.PLUS _
-> failwith
"not possible"
39 (Ast.AFTER _
,_
,_
) -> true
40 | (Ast.BEFOREAFTER _
,_
,_
) -> true
42 | Ast0.MIXED mc
-> true (* don't think mcode can be mixed *)
44 let modif_after_mcode mc
= modif_after_mcodekind (Ast0.get_mcode_mcodekind mc
)
50 Ast.StatementTag
(_
) | Ast.StmtDotsTag
(_
)
51 | Ast.DeclarationTag
(_
) | Ast.DeclDotsTag
(_
) -> true | _
-> false))
54 match Ast0.get_mcodekind x
with
55 Ast0.PLUS _
-> failwith
"not possible"
58 (* do better for the common case of replacing a stmt by another one *)
59 ([[Ast.StatementTag
(s
)]],ti
) ->
60 (match Ast.unwrap s
with
61 Ast.IfThen
(_
,_
,_
) -> true (* potentially dangerous *)
62 | _
-> mc
:= ([[Ast.StatementTag
(s
)]],ti
); false)
64 | Ast0.CONTEXT mc
| Ast0.MIXED mc
->
66 (Ast.BEFORE _
,_
,_
) -> true
67 | (Ast.BEFOREAFTER _
,_
,_
) -> true
71 match Ast0.get_mcodekind x
with
72 Ast0.PLUS _
-> failwith
"not possible"
75 (* do better for the common case of replacing a stmt by another one *)
76 ([[Ast.StatementTag
(s
)]],ti
) ->
77 (match Ast.unwrap s
with
78 Ast.IfThen
(_
,_
,_
) -> true (* potentially dangerous *)
79 | _
-> mc
:= ([[Ast.StatementTag
(s
)]],ti
); false)
80 | (l
,_
) when any_statements l
-> true
81 | (l
,ti
) -> mc
:= (l
,ti
); false)
82 | Ast0.CONTEXT mc
| Ast0.MIXED mc
->
84 (Ast.AFTER _
,_
,_
) -> true
85 | (Ast.BEFOREAFTER _
,_
,_
) -> true
89 let rec left_ident i
=
91 match Ast0.unwrap i
with
92 Ast0.Id
(name
) -> modif_before_mcode name
93 | Ast0.MetaId
(name
,_
,_
) -> modif_before_mcode name
94 | Ast0.MetaFunc
(name
,_
,_
) -> modif_before_mcode name
95 | Ast0.MetaLocalFunc
(name
,_
,_
) -> modif_before_mcode name
96 | Ast0.OptIdent
(id
) -> left_ident id
97 | Ast0.UniqueIdent
(id
) -> left_ident id
99 (* --------------------------------------------------------------------- *)
102 let rec left_expression e
=
104 match Ast0.unwrap e
with
105 Ast0.Ident
(id
) -> left_ident id
106 | Ast0.Constant
(const
) -> modif_before_mcode const
107 | Ast0.FunCall
(fn
,lp
,args
,rp
) -> left_expression fn
108 | Ast0.Assignment
(left
,op
,right
,_
) -> left_expression left
109 | Ast0.CondExpr
(exp1
,why
,exp2
,colon
,exp3
) -> left_expression exp1
110 | Ast0.Postfix
(exp
,op
) -> left_expression exp
111 | Ast0.Infix
(exp
,op
) -> modif_before_mcode op
112 | Ast0.Unary
(exp
,op
) -> modif_before_mcode op
113 | Ast0.Binary
(left
,op
,right
) -> left_expression left
114 | Ast0.Nested
(left
,op
,right
) -> left_expression left
115 | Ast0.Paren
(lp
,exp
,rp
) -> modif_before_mcode lp
116 | Ast0.ArrayAccess
(exp1
,lb
,exp2
,rb
) -> left_expression exp1
117 | Ast0.RecordAccess
(exp
,pt
,field
) -> left_expression exp
118 | Ast0.RecordPtAccess
(exp
,ar
,field
) -> left_expression exp
119 | Ast0.Cast
(lp
,ty
,rp
,exp
) -> modif_before_mcode lp
120 | Ast0.SizeOfExpr
(szf
,exp
) -> modif_before_mcode szf
121 | Ast0.SizeOfType
(szf
,lp
,ty
,rp
) -> modif_before_mcode szf
122 | Ast0.TypeExp
(ty
) -> left_typeC ty
123 | Ast0.MetaErr
(name
,_
,_
) -> modif_before_mcode name
124 | Ast0.MetaExpr
(name
,_
,ty
,_
,_
) -> modif_before_mcode name
125 | Ast0.MetaExprList
(name
,_
,_
) -> modif_before_mcode name
126 | Ast0.EComma
(cm
) -> modif_before_mcode cm
127 | Ast0.DisjExpr
(_
,exp_list
,_
,_
) -> List.exists
left_expression exp_list
128 | Ast0.NestExpr
(starter
,expr_dots
,ender
,_
,multi
) ->
129 left_dots left_expression expr_dots
130 | Ast0.Edots
(dots
,_
) | Ast0.Ecircles
(dots
,_
) | Ast0.Estars
(dots
,_
) -> false
131 | Ast0.OptExp
(exp
) -> left_expression exp
132 | Ast0.UniqueExp
(exp
) -> left_expression exp
134 (* --------------------------------------------------------------------- *)
139 match Ast0.unwrap t
with
140 Ast0.ConstVol
(cv
,ty
) -> modif_before_mcode cv
141 | Ast0.BaseType
(ty
,strings
) -> modif_before_mcode (List.hd strings
)
142 | Ast0.Signed
(sgn
,ty
) -> modif_before_mcode sgn
143 | Ast0.Pointer
(ty
,star
) -> left_typeC ty
144 | Ast0.FunctionPointer
(ty
,lp1
,star
,rp1
,lp2
,params
,rp2
) -> left_typeC ty
145 | Ast0.FunctionType
(Some ty
,lp1
,params
,rp1
) -> left_typeC ty
146 | Ast0.FunctionType
(None
,lp1
,params
,rp1
) -> modif_before_mcode lp1
147 | Ast0.Array
(ty
,lb
,size
,rb
) -> left_typeC ty
148 | Ast0.EnumName
(kind
,name
) -> modif_before_mcode kind
149 | Ast0.StructUnionName
(kind
,name
) -> modif_before_mcode kind
150 | Ast0.StructUnionDef
(ty
,lb
,decls
,rb
) -> left_typeC ty
151 | Ast0.TypeName
(name
) -> modif_before_mcode name
152 | Ast0.MetaType
(name
,_
) -> modif_before_mcode name
153 | Ast0.DisjType
(lp
,types
,mids
,rp
) -> List.exists left_typeC types
154 | Ast0.OptType
(ty
) -> left_typeC ty
155 | Ast0.UniqueType
(ty
) -> left_typeC ty
157 (* --------------------------------------------------------------------- *)
158 (* Variable declaration *)
159 (* Even if the Cocci program specifies a list of declarations, they are
160 split out into multiple declarations of a single variable each. *)
162 and left_declaration d
=
164 match Ast0.unwrap d
with
165 Ast0.Init
(Some stg
,ty
,id
,eq
,ini
,sem
) -> modif_before_mcode stg
166 | Ast0.Init
(None
,ty
,id
,eq
,ini
,sem
) -> left_typeC ty
167 | Ast0.UnInit
(Some stg
,ty
,id
,sem
) -> modif_before_mcode stg
168 | Ast0.UnInit
(None
,ty
,id
,sem
) -> left_typeC ty
169 | Ast0.MacroDecl
(name
,lp
,args
,rp
,sem
) -> left_ident name
170 | Ast0.TyDecl
(ty
,sem
) -> left_typeC ty
171 | Ast0.Typedef
(stg
,ty
,id
,sem
) -> modif_before_mcode stg
172 | Ast0.DisjDecl
(_
,decls
,_
,_
) -> List.exists left_declaration decls
173 | Ast0.Ddots
(dots
,_
) -> false
174 | Ast0.OptDecl
(decl
) -> left_declaration decl
175 | Ast0.UniqueDecl
(decl
) -> left_declaration decl
177 and right_declaration d
=
179 match Ast0.unwrap d
with
180 Ast0.Init
(_
,ty
,id
,eq
,ini
,sem
) -> modif_after_mcode sem
181 | Ast0.UnInit
(_
,ty
,id
,sem
) -> modif_after_mcode sem
182 | Ast0.MacroDecl
(name
,lp
,args
,rp
,sem
) -> modif_after_mcode sem
183 | Ast0.TyDecl
(ty
,sem
) -> modif_after_mcode sem
184 | Ast0.Typedef
(stg
,ty
,id
,sem
) -> modif_after_mcode sem
185 | Ast0.DisjDecl
(_
,decls
,_
,_
) -> List.exists right_declaration decls
186 | Ast0.Ddots
(dots
,_
) -> false
187 | Ast0.OptDecl
(decl
) -> right_declaration decl
188 | Ast0.UniqueDecl
(decl
) -> right_declaration decl
190 (* --------------------------------------------------------------------- *)
193 and left_statement s
=
195 match Ast0.unwrap s
with
196 Ast0.FunDecl
(_
,fninfo
,name
,lp
,params
,rp
,lbrace
,body
,rbrace
) ->
197 (* irrelevant *) false
198 | Ast0.Decl
(_
,decl
) -> left_declaration decl
199 | Ast0.Seq
(lbrace
,body
,rbrace
) -> modif_before_mcode lbrace
200 | Ast0.ExprStatement
(exp
,sem
) -> left_expression exp
201 | Ast0.IfThen
(iff
,lp
,exp
,rp
,branch1
,(info
,aft
)) -> modif_before_mcode iff
202 | Ast0.IfThenElse
(iff
,lp
,exp
,rp
,branch1
,els
,branch2
,(info
,aft
)) ->
203 modif_before_mcode iff
204 | Ast0.While
(whl
,lp
,exp
,rp
,body
,(info
,aft
)) -> modif_before_mcode whl
205 | Ast0.Do
(d
,body
,whl
,lp
,exp
,rp
,sem
) -> modif_before_mcode d
206 | Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,body
,(info
,aft
)) ->
207 modif_before_mcode fr
208 | Ast0.Iterator
(nm
,lp
,args
,rp
,body
,(info
,aft
)) -> left_ident nm
209 | Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,decls
,cases
,rb
) ->
210 modif_before_mcode switch
211 | Ast0.Break
(br
,sem
) -> modif_before_mcode br
212 | Ast0.Continue
(cont
,sem
) -> modif_before_mcode cont
213 | Ast0.Label
(l
,dd
) -> left_ident l
214 | Ast0.Goto
(goto
,l
,sem
) -> modif_before_mcode goto
215 | Ast0.Return
(ret
,sem
) -> modif_before_mcode ret
216 | Ast0.ReturnExpr
(ret
,exp
,sem
) -> modif_before_mcode ret
217 | Ast0.MetaStmt
(name
,pure
) -> modif_before_mcode name
218 | Ast0.MetaStmtList
(name
,_
) -> modif_before_mcode name
219 | Ast0.Disj
(_
,statement_dots_list
,_
,_
) ->
220 List.exists
(left_dots left_statement
) statement_dots_list
221 | Ast0.Nest
(starter
,stmt_dots
,ender
,whencode
,multi
) ->
222 left_dots left_statement stmt_dots
223 | Ast0.Exp
(exp
) -> false (* can only be replaced by an expression *)
224 | Ast0.TopExp
(exp
) -> false (* as above *)
225 | Ast0.Ty
(ty
) -> false (* can only be replaced by a type *)
226 | Ast0.TopInit
(init
) -> false (* can only be replaced by an init *)
227 | Ast0.Dots
(d
,whn
) | Ast0.Circles
(d
,whn
) | Ast0.Stars
(d
,whn
) -> false
228 | Ast0.Include
(inc
,s
) -> modif_before_mcode inc
229 | Ast0.Define
(def
,id
,params
,body
) -> modif_before_mcode def
230 | Ast0.OptStm
(re
) -> left_statement re
231 | Ast0.UniqueStm
(re
) -> left_statement re
233 and right_statement s
=
235 match Ast0.unwrap s
with
236 Ast0.FunDecl
(_
,fninfo
,name
,lp
,params
,rp
,lbrace
,body
,rbrace
) ->
237 (* irrelevant *) false
238 | Ast0.Decl
(_
,decl
) -> right_declaration decl
239 | Ast0.Seq
(lbrace
,body
,rbrace
) -> modif_after_mcode rbrace
240 | Ast0.ExprStatement
(exp
,sem
) -> modif_after_mcode sem
241 | Ast0.IfThen
(iff
,lp
,exp
,rp
,branch1
,(info
,aft
)) -> modif_after_mcodekind aft
242 | Ast0.IfThenElse
(iff
,lp
,exp
,rp
,branch1
,els
,branch2
,(info
,aft
)) ->
243 modif_after_mcodekind aft
244 | Ast0.While
(whl
,lp
,exp
,rp
,body
,(info
,aft
)) -> modif_after_mcodekind aft
245 | Ast0.Do
(d
,body
,whl
,lp
,exp
,rp
,sem
) -> modif_after_mcode sem
246 | Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,body
,(info
,aft
)) ->
247 modif_after_mcodekind aft
248 | Ast0.Iterator
(nm
,lp
,args
,rp
,body
,(info
,aft
)) ->
249 modif_after_mcodekind aft
250 | Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,decls
,cases
,rb
) -> modif_after_mcode rb
251 | Ast0.Break
(br
,sem
) -> modif_after_mcode sem
252 | Ast0.Continue
(cont
,sem
) -> modif_after_mcode sem
253 | Ast0.Label
(l
,dd
) -> modif_after_mcode dd
254 | Ast0.Goto
(goto
,l
,sem
) -> modif_after_mcode sem
255 | Ast0.Return
(ret
,sem
) -> modif_after_mcode sem
256 | Ast0.ReturnExpr
(ret
,exp
,sem
) -> modif_after_mcode sem
257 | Ast0.MetaStmt
(name
,pure
) -> modif_after_mcode name
258 | Ast0.MetaStmtList
(name
,_
) -> modif_after_mcode name
259 | Ast0.Disj
(_
,statement_dots_list
,_
,_
) ->
260 List.exists
(right_dots right_statement
) statement_dots_list
261 | Ast0.Nest
(starter
,stmt_dots
,ender
,whencode
,multi
) ->
262 right_dots right_statement stmt_dots
263 | Ast0.Exp
(exp
) -> false (* can only be replaced by an expression *)
264 | Ast0.TopExp
(exp
) -> false (* as above *)
265 | Ast0.Ty
(ty
) -> false (* can only be replaced by a type *)
266 | Ast0.TopInit
(init
) -> false (* can only be replaced by an init *)
267 | Ast0.Dots
(d
,whn
) | Ast0.Circles
(d
,whn
) | Ast0.Stars
(d
,whn
) -> false
268 | Ast0.Include
(inc
,s
) -> modif_after_mcode s
269 | Ast0.Define
(def
,id
,params
,body
) -> right_dots right_statement body
270 | Ast0.OptStm
(re
) -> right_statement re
271 | Ast0.UniqueStm
(re
) -> right_statement re
273 (* --------------------------------------------------------------------- *)
276 (* A very coarse approximation. We would really only like to return true
277 if a new statement is added. For this it would be best to correlate with the
278 plus slice. Or at least be sure that the new stuff is on the far left or
281 let rec adding_something s
=
282 match Ast0.get_mcodekind s
with
285 (* do better for the common case of replacing a stmt by another one *)
286 ([[Ast.StatementTag
(s
)]],ti
) ->
287 (match Ast.unwrap s
with
288 Ast.IfThen
(_
,_
,_
) -> true (* potentially dangerous *)
289 | _
-> mc
:= ([[Ast.StatementTag
(s
)]],ti
); false)
291 | Ast0.CONTEXT
(mc
) ->
292 let (text
,tinfo1
,tinfo2
) = !mc
in
293 (match text
with Ast.NOTHING
-> false | _
-> true)
295 not
(contains_only_minus
.VT0.combiner_rec_statement s
) (*&&
296 (left_statement s) or (right_statement s)*)
297 | _
-> failwith
"unexpected plus code"
299 (* why do we need this; MINUS should mean the same thing *)
300 and contains_only_minus
=
301 let bind x y
= x
&& y
in
302 let option_default = true in
303 let mcodekind = function
308 | Ast0.CONTEXT
(mc
) -> false
310 let mcode (_
,_
,_
,mc
,_
,_
) = mcodekind mc
in
312 let donothing r k e
= mcodekind (Ast0.get_mcodekind e
) && k e
in
315 match Ast0.unwrap e
with
316 Ast0.DOTS
([]) | Ast0.CIRCLES
([]) | Ast0.STARS
([]) -> true
319 let expression r k e
=
320 mcodekind (Ast0.get_mcodekind e
) &&
321 match Ast0.unwrap e
with
322 Ast0.DisjExpr
(starter
,expr_list
,mids
,ender
) ->
323 List.for_all r
.VT0.combiner_rec_expression expr_list
326 let declaration r k e
=
327 mcodekind (Ast0.get_mcodekind e
) &&
328 match Ast0.unwrap e
with
329 Ast0.DisjDecl
(starter
,decls
,mids
,ender
) ->
330 List.for_all r
.VT0.combiner_rec_declaration decls
334 mcodekind (Ast0.get_mcodekind e
) &&
335 match Ast0.unwrap e
with
336 Ast0.DisjType
(starter
,types
,mids
,ender
) ->
337 List.for_all r
.VT0.combiner_rec_typeC types
340 let statement r k e
=
341 mcodekind (Ast0.get_mcodekind e
) &&
342 match Ast0.unwrap e
with
343 Ast0.Disj
(starter
,statement_dots_list
,mids
,ender
) ->
344 List.for_all r
.VT0.combiner_rec_statement_dots statement_dots_list
347 let case_line r k e
=
348 mcodekind (Ast0.get_mcodekind e
) &&
349 match Ast0.unwrap e
with
350 Ast0.DisjCase
(starter
,case_list
,mids
,ender
) ->
351 List.for_all r
.VT0.combiner_rec_case_line case_list
354 V0.flat_combiner
bind option_default
355 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
356 dots dots dots dots dots dots
357 donothing expression typeC donothing donothing declaration
358 statement case_line donothing
361 (* needs a special case when there is a Disj or an empty DOTS *)
362 (* ---------------------------------------------------------------------- *)
367 if (acpi_device_dir(device))
369 remove_proc_entry(acpi_device_bid(device), acpi_ac_dir);
370 + acpi_device_dir(device) = NULL;
373 The last two + lines get associated with the end of the if, not with the
374 branch, so the braces get added in oddly.
377 let add_braces orig_s
=
379 (Iso_pattern.rebuild_mcode None
).VT0.rebuilder_rec_statement orig_s
in
381 match Ast0.get_mcodekind
s with
383 let (text
,tinfo
) = !mc
in
384 Ast0.MINUS
(ref([Ast.mkToken
"{"]::text
@[[Ast.mkToken
"}"]],tinfo
))
385 | Ast0.CONTEXT
(mc
) ->
386 let (text
,tinfo1
,tinfo2
) = !mc
in
388 (* this is going to be a mess if we allow it to be iterable...
389 there would be one level of braces for every added things.
390 need to come up with something better, or just add {} in the
394 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,[[Ast.mkToken
"}"]],
396 | Ast.AFTER
(aft
,_
) ->
397 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],aft
@[[Ast.mkToken
"}"]],
399 | Ast.BEFOREAFTER
(bef
,aft
,_
) ->
400 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,aft
@[[Ast.mkToken
"}"]],
403 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],[[Ast.mkToken
"}"]],
405 Ast0.CONTEXT
(ref(new_text,tinfo1
,tinfo2
))
407 let (text
,tinfo1
,tinfo2
) = !mc
in
411 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,[[Ast.mkToken
"}"]],
413 | Ast.AFTER
(aft
,_
) ->
414 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],aft
@[[Ast.mkToken
"}"]],
416 | Ast.BEFOREAFTER
(bef
,aft
,_
) ->
417 Ast.BEFOREAFTER
([Ast.mkToken
"{"]::bef
,aft
@[[Ast.mkToken
"}"]],
420 Ast.BEFOREAFTER
([[Ast.mkToken
"{"]],[[Ast.mkToken
"}"]],
422 Ast0.MIXED
(ref(new_text,tinfo1
,tinfo2
))
423 | _
-> failwith
"unexpected plus code" in
424 Ast0.set_mcodekind
s new_mcodekind;
425 Compute_lines.compute_statement_lines
true s
427 (* ---------------------------------------------------------------------- *)
430 match Ast0.unwrap x
with
431 Ast0.Dots
(_
,_
) | Ast0.Circles
(_
,_
) | Ast0.Stars
(_
,_
)
432 | Ast0.Nest
(_
,_
,_
,_
,_
) -> true
436 match Ast0.get_mcodekind
s with
437 Ast0.MINUS
(_
) -> true
440 let rec unchanged_minus s =
441 match Ast0.get_mcodekind
s with
442 Ast0.MINUS
(mc
) -> (match !mc
with ([],_
) -> true | _
-> false)
445 let rec do_branch s =
448 Ast0.set_dots_bef_aft
s (Ast0.DroppingBetweenDots
(add_braces s))
450 match Ast0.unwrap
s with
451 Ast0.Disj
(starter
,statement_dots_list
,mids
,ender
) ->
455 match Ast0.unwrap
s with
457 Ast0.rewrap
s (Ast0.DOTS
([do_branch s]))
459 | _
-> failwith
"not supported")
460 statement_dots_list
in
461 Ast0.rewrap
s (Ast0.Disj
(starter
,stmts,mids
,ender
))
464 let rec statement dots_before dots_after
s =
466 if dots_before
&& dots_after
470 (let with_braces = add_braces s in
471 Ast0.set_dots_bef_aft
s (Ast0.DroppingBetweenDots
(with_braces)))
472 else if adding_something s
474 (let with_braces = add_braces s in
475 Ast0.set_dots_bef_aft
s (Ast0.AddingBetweenDots
(with_braces)))
479 match Ast0.unwrap
s with
480 Ast0.FunDecl
(x
,fninfo
,name
,lp
,params
,rp
,lbrace
,body
,rbrace
) ->
481 (* true for close brace, because that represents any way we can
482 exit the function, which is not necessarily followed by an explicit
485 (Ast0.FunDecl
(x
,fninfo
,name
,lp
,params
,rp
,lbrace
,
486 statement_dots
false true body
,
488 | Ast0.Decl
(_
,_
) -> s
489 | Ast0.Seq
(lbrace
,body
,rbrace
) ->
491 (Ast0.Seq
(lbrace
,statement_dots
false false body
,rbrace
))
492 | Ast0.ExprStatement
(exp
,sem
) -> do_one s
493 | Ast0.IfThen
(iff
,lp
,exp
,rp
,branch1
,x
) ->
496 (Ast0.IfThen
(iff
,lp
,exp
,rp
,statement false false branch1
,x
)))
497 | Ast0.IfThenElse
(iff
,lp
,exp
,rp
,branch1
,els
,branch2
,x
) ->
502 statement false false branch1
,els
,
503 statement false false branch2
,x
)))
504 | Ast0.While
(whl
,lp
,exp
,rp
,body
,x
) ->
507 (Ast0.While
(whl
,lp
,exp
,rp
,statement false false body
,x
)))
508 | Ast0.Do
(d
,body
,whl
,lp
,exp
,rp
,sem
) ->
511 (Ast0.Do
(d
,statement false false body
,whl
,lp
,exp
,rp
,sem
)))
512 | Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,body
,x
) ->
515 (Ast0.For
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
,
516 statement false false body
,x
)))
517 | Ast0.Iterator
(nm
,lp
,args
,rp
,body
,x
) ->
520 (Ast0.Iterator
(nm
,lp
,args
,rp
,statement false false body
,x
)))
521 | Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,decls
,cases
,rb
) ->
524 (Ast0.Switch
(switch
,lp
,exp
,rp
,lb
,decls
,
527 (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.DisjCase
(starter
,case_lines
,mids
,ender
) ->
569 Ast0.DisjCase
(starter
,List.map
case_line case_lines
,mids
,ender
)
570 | Ast0.OptCase
(case
) -> Ast0.OptCase
(case_line c
))
572 and do_statement_dots dots_before dots_after
= function
574 | [x
] -> [statement dots_before dots_after x
]
575 | dots::rest
when is_dots dots ->
576 dots::(do_statement_dots
true dots_after rest
)
577 | x
::(dots::_
as rest
) when is_dots dots ->
578 (statement dots_before
true x
)::
579 do_statement_dots
false dots_after rest
581 (statement dots_before
false x
)::
582 do_statement_dots
false dots_after rest
584 and statement_dots dots_before dots_after d
=
586 (match Ast0.unwrap d
with
588 Ast0.DOTS
(do_statement_dots dots_before dots_after l
)
590 Ast0.CIRCLES
(do_statement_dots dots_before dots_after l
)
592 Ast0.STARS
(do_statement_dots dots_before dots_after l
))
596 (match Ast0.unwrap t
with
597 Ast0.DECL
(stmt_dots
) -> Ast0.DECL
(statement true true stmt_dots
)
598 | Ast0.CODE
(stmt_dots
) -> Ast0.CODE
(statement_dots
true true stmt_dots
)
601 let single_statement l
=
602 if !Flag_parsing_cocci.sgrep_mode
then l
else List.map
top_level l