1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
(*
* This file is part of Coccinelle, licensed under the terms of the GPL v2.
* See copyright.txt in the Coccinelle source code for more information.
* The Coccinelle source code can be obtained at http://coccinelle.lip6.fr
*)
module Ast0 = Ast0_cocci
module Ast = Ast_cocci
module V0 = Visitor_ast0
module VT0 = Visitor_ast0_types
(* Negate counter of open brace when that is minus and preceding ) is context.
In that case, the brace should somehow be like the preceding ) (from an
if, while, etc) rather than like the rest of the statement. *)
let redo (_,_,_,mc,_,_) stm =
match mc with
Ast0.CONTEXT _ ->
(match Ast0.unwrap stm with
Ast0.Seq((a,b,c,mc_lbrace,d,adj),body,rbrace) ->
(match mc_lbrace with
Ast0.MINUS _ ->
(* subtract 1 in case -1 is used for some unknown values *)
let adj = { adj with Ast.counter = -1 * adj.Ast.counter - 1 } in
Ast0.rewrap stm (Ast0.Seq((a,b,c,mc_lbrace,d,adj),body,rbrace))
| _ -> stm)
| _ -> stm)
| _ -> stm
let compute_adjacency p =
let prev = ref { Ast.counter = 0; Ast.ender = false } in
let counter = ref 0 in
let get_adj _ =
let adj = { Ast.counter = !counter; Ast.ender = false } in
prev := adj;
adj in
let mcode (a,b,c,d,e,_) = (a,b,c,d,e,get_adj()) in
let string_mcode ((str,_,info,mc,_,_) as x) =
match str with
"..." | "<..." | "...>" | "<+..." | "...+>" ->
(!prev).Ast.ender <- true;
(match mc with
Ast0.MINUS _ -> mcode x
| Ast0.CONTEXT _ -> counter := !counter + 1; x
| _ -> failwith "unexpected mcode for ...")
| _ -> mcode x in
let statement r k s =
let s = k s in
(* a case for each kind of term that has a fake node *)
Ast0.rewrap s
(match Ast0.unwrap s with
Ast0.IfThen(iff,lp,exp,rp,branch,(info,mc,_)) ->
let branch = redo rp branch in
Ast0.IfThen(iff,lp,exp,rp,branch,(info,mc,get_adj()))
| Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(info,mc,_)) ->
let branch1 = redo rp branch1 in
let branch2 = redo els branch2 in
let adj = { Ast.counter = !counter; Ast.ender = false } in
prev := adj;
Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(info,mc,get_adj()))
| Ast0.While(wh,lp,exp,rp,body,(info,mc,_)) ->
let body = redo rp body in
let adj = { Ast.counter = !counter; Ast.ender = false } in
prev := adj;
Ast0.While(wh,lp,exp,rp,body,(info,mc,get_adj()))
| Ast0.For(fr,lp,first,rp,body,(info,mc,_)) ->
let body = redo rp body in
let adj = { Ast.counter = !counter; Ast.ender = false } in
prev := adj;
Ast0.For(fr,lp,first,rp,body,(info,mc,get_adj()))
| Ast0.Iterator(nm,lp,args,rp,body,(info,mc,_)) ->
let body = redo rp body in
let adj = { Ast.counter = !counter; Ast.ender = false } in
prev := adj;
Ast0.Iterator(nm,lp,args,rp,body,(info,mc,get_adj()))
| s -> s) in
let fn =
V0.rebuilder
{V0.rebuilder_functions with
VT0.rebuilder_meta_mcode = mcode;
VT0.rebuilder_string_mcode = string_mcode;
VT0.rebuilder_const_mcode = mcode;
VT0.rebuilder_simpleAssign_mcode = mcode;
VT0.rebuilder_opAssign_mcode = mcode;
VT0.rebuilder_fix_mcode = mcode;
VT0.rebuilder_unary_mcode = mcode;
VT0.rebuilder_arithOp_mcode = mcode;
VT0.rebuilder_logicalOp_mcode = mcode;
VT0.rebuilder_cv_mcode = mcode;
VT0.rebuilder_sign_mcode = mcode;
VT0.rebuilder_struct_mcode = mcode;
VT0.rebuilder_storage_mcode = mcode;
VT0.rebuilder_inc_mcode = mcode;
VT0.rebuilder_stmtfn = statement;} in
List.map fn.VT0.rebuilder_rec_top_level p
|