6
(* --------------------------------------------------------------------- *)
9
type cocci_predicate = Lib_engine.predicate * Ast.meta_name Ast_ctl.modif
11
(cocci_predicate,Ast_cocci.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl
13
(* --------------------------------------------------------------------- *)
16
let bind x y = x or y in
17
let option_default = false in
18
let mcode r (_,_,kind,_) =
20
Ast.MINUS(_,_) -> true
21
| Ast.PLUS -> failwith "not possible"
22
| Ast.CONTEXT(_,info) -> not (info = Ast.NOTHING) in
23
let do_nothing r k e = k e in
24
let rule_elem r k re =
26
match Ast.unwrap re with
27
Ast.FunHeader(bef,_,fninfo,name,lp,params,rp) ->
28
bind (mcode r ((),(),bef,Ast.NoMetaPos)) res
29
| Ast.Decl(bef,_,decl) -> bind (mcode r ((),(),bef,Ast.NoMetaPos)) res
32
V.combiner bind option_default
33
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
35
do_nothing do_nothing do_nothing do_nothing
36
do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
37
do_nothing rule_elem do_nothing do_nothing do_nothing do_nothing in
38
recursor.V.combiner_rule_elem
40
let ctl_exists v x keep_wit = CTL.Exists(v,x,keep_wit)
42
let predmaker guard term =
43
if guard && contains_modif term
47
(CTL.Pred (Lib_engine.Match(term),CTL.Modif v))
48
else CTL.Pred (Lib_engine.Match(term),CTL.Control)
50
(* --------------------------------------------------------------------- *)
52
let is_true = function CTL.True -> true | _ -> false
54
let is_false = function CTL.False -> true | _ -> false
56
let ctl_true = CTL.True
58
let ctl_false = CTL.False
62
else if is_true y then x else CTL.And(CTL.STRICT,x,y)
66
else if is_false y then x else CTL.Or(x,y)
68
let ctl_seqor x y = CTL.SeqOr(x,y)
70
let ctl_not x = CTL.Not(x)
73
if is_true x then CTL.True
74
else CTL.AX(CTL.FORWARD,CTL.STRICT,x)
77
if is_true x then CTL.True
78
else CTL.EX(CTL.FORWARD,x)
81
if is_true x then CTL.True
82
else CTL.EX(CTL.BACKWARD,x)
84
let after = CTL.Pred(Lib_engine.After, CTL.Control)
85
let fall = CTL.Pred(Lib_engine.FallThrough, CTL.Control)
86
let exit = CTL.Pred(Lib_engine.Exit, CTL.Control)
87
let truepred = CTL.Pred(Lib_engine.TrueBranch, CTL.Control)
88
let falsepred = CTL.Pred(Lib_engine.FalseBranch, CTL.Control)
89
let retpred = CTL.Pred(Lib_engine.Return, CTL.Control)
91
let string2var x = ("",x)
95
let cur = !labelctr in
97
string2var (Printf.sprintf "l%d" cur)
99
let ctl_au x y = CTL.AU(CTL.FORWARD,CTL.STRICT,x,y)
101
let ctl_uncheck x = CTL.Uncheck(x)
103
let make_meta_rule_elem d =
105
Ast.make_meta_rule_elem nm d ([],[],[])
107
(* --------------------------------------------------------------------- *)
109
let rec ctl_seq keep_wit a = function
110
Past.Seq(elem,seq) ->
111
ctl_element keep_wit (ctl_seq keep_wit a seq) elem
113
| Past.SExists(var,seq) -> ctl_exists keep_wit var (ctl_seq keep_wit a seq)
115
and ctl_term keep_wit a = function
117
(match Ast.unwrap term with
118
Ast.MetaStmt(_,_,_,_) -> ctl_true
119
| _ -> ctl_and (predmaker keep_wit term) (ctl_ax a))
120
| Past.TExists(var,term) ->
121
ctl_exists keep_wit var (ctl_term keep_wit a term)
123
and ctl_element keep_wit a = function
124
Past.Atomic(term,ba) ->
125
do_between_dots keep_wit ba (ctl_term keep_wit a term) a
126
| Past.IfThen(test,thn,(_,_,_,aft),ba) ->
127
do_between_dots keep_wit ba (ifthen keep_wit (Some a) test thn aft) a
128
| Past.Or(seq1,seq2) ->
129
ctl_seqor (ctl_seq keep_wit a seq1) (ctl_seq keep_wit a seq2)
130
| Past.DInfo(dots) -> ctl_au (guard_ctl_dots keep_wit a dots) a
131
| Past.EExists(var,elem) ->
132
ctl_exists keep_wit var (ctl_element keep_wit a elem)
134
(* --------------------------------------------------------------------- *)
136
and guard_ctl_seq keep_wit a = function
137
Past.Seq(elem,Past.Empty) -> guard_ctl_element keep_wit a elem
138
| Past.Seq(elem,seq) ->
139
ctl_element keep_wit (guard_ctl_seq keep_wit a seq) elem
140
| Past.Empty -> ctl_true
141
| Past.SExists(var,seq) ->
142
ctl_exists keep_wit var (guard_ctl_seq keep_wit a seq)
144
and guard_ctl_term keep_wit a = function
146
(match Ast.unwrap term with
147
Ast.MetaStmt(_,_,_,_) -> ctl_true
148
| _ -> predmaker keep_wit term)
149
| Past.TExists(var,term) ->
150
ctl_exists keep_wit var (guard_ctl_term keep_wit a term)
152
and guard_ctl_element keep_wit a = function
153
Past.Atomic(term,_) -> guard_ctl_term keep_wit a term
154
| Past.IfThen(test,thn,(_,_,_,aft),_) -> ifthen keep_wit None test thn aft
155
| Past.Or(seq1,seq2) ->
157
(guard_ctl_seq keep_wit a seq1) (guard_ctl_seq keep_wit a seq2)
158
| Past.DInfo(dots) -> ctl_au (guard_ctl_dots keep_wit a dots) a
159
| Past.EExists(var,elem) ->
160
ctl_exists keep_wit var (guard_ctl_element keep_wit a elem)
162
and guard_ctl_dots keep_wit a = function
163
Past.Dots -> ctl_true
164
| Past.Nest(_) when not keep_wit -> ctl_true
167
(guard_ctl_seq true a seq)
168
(ctl_not (guard_ctl_seq false a seq))
169
| Past.When(dots,seq) ->
171
(guard_ctl_dots keep_wit a dots)
172
(ctl_not (guard_ctl_seq false a seq))
174
(* --------------------------------------------------------------------- *)
176
and ifthen keep_wit a test thn aft =
177
(* "if (test) thn; after" becomes:
178
if(test) & AX((TrueBranch & AX thn) v FallThrough v (After & AXAX after))
180
(* doesn't work for C code if (x) return 1; else return 2; *)
184
(Ast.CONTEXT(_,Ast.NOTHING),None) -> ctl_true
185
| (Ast.CONTEXT(_,Ast.NOTHING),Some a) -> ctl_ax (ctl_ax a)
186
| (_,None) -> failwith "not possible"
190
(predmaker keep_wit (make_meta_rule_elem aft))
196
(guard_ctl_element keep_wit ctl_true (* not used *) thn)))
198
(ctl_and after end_code)) in
199
ctl_and (ctl_term keep_wit body test) (ctl_ex after)
201
and do_between_dots keep_wit ba term after =
203
Past.AddingBetweenDots (brace_term,n)
204
| Past.DroppingBetweenDots (brace_term,n) ->
205
(* not sure at all what to do here for after... *)
206
let match_brace = ctl_element keep_wit after brace_term in
207
let v = Printf.sprintf "_r_%d" n in
208
let case1 = ctl_and (CTL.Ref v) match_brace in
209
let case2 = ctl_and (ctl_not (CTL.Ref v)) term in
212
(ctl_back_ex truepred)
213
(ctl_back_ex (ctl_back_ex falsepred)),
215
| Past.NoDots -> term
217
(* --------------------------------------------------------------------- *)
219
let toctl sl = ctl_seq true ctl_true sl