1 (* Copyright (C) 2007, 2008 Yoann Padioleau
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License (GPL)
5 * version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * file license.txt for more details.
14 (*****************************************************************************)
16 (*****************************************************************************)
18 (* todo?: al_expr doit enlever les infos de type ? et doit remettre en
22 (* drop all info information *)
24 let strip_info_visitor _
=
25 { Visitor_c.default_visitor_c_s
with
27 (* traversal should be deterministic... *)
30 function i
-> ctr := !ctr + 1; Ast_c.al_info
!ctr i
));
32 Visitor_c.kexpr_s
= (fun (k
,_
) e
->
33 let (e'
, ty
),ii'
= k e
in
34 (e'
, Ast_c.noType
()(*ref !ty*)), ii'
(* keep type - jll *)
38 Visitor_c.ktype_s = (fun (k,_) ft ->
40 match Ast_c.unwrap_typeC ft' with
41 | Ast_c.TypeName (s,_typ) ->
42 Ast_c.TypeName (s, Ast_c.noTypedefDef()) +> Ast_c.rewrap_typeC ft'
50 let al_expr x
= Visitor_c.vk_expr_s
(strip_info_visitor()) x
51 let al_statement x
= Visitor_c.vk_statement_s
(strip_info_visitor()) x
52 let al_type x
= Visitor_c.vk_type_s
(strip_info_visitor()) x
53 let al_param x
= Visitor_c.vk_param_s
(strip_info_visitor()) x
54 let al_params x
= Visitor_c.vk_params_s
(strip_info_visitor()) x
55 let al_arguments x
= Visitor_c.vk_arguments_s
(strip_info_visitor()) x
56 let al_fields x
= Visitor_c.vk_struct_fields_s
(strip_info_visitor()) x
58 let al_node x
= Visitor_c.vk_node_s
(strip_info_visitor()) x
60 let al_program x
= List.map
(Visitor_c.vk_toplevel_s
(strip_info_visitor())) x
61 let al_ii x
= Visitor_c.vk_ii_s
(strip_info_visitor()) x
68 let semi_strip_info_visitor = (* keep position information *)
69 { Visitor_c.default_visitor_c_s
with
70 Visitor_c.kinfo_s
= (fun (k
,_
) i
-> Ast_c.semi_al_info i
);
72 Visitor_c.kexpr_s
= (fun (k
,_
) e
->
73 let (e'
, ty
),ii'
= k e
in
74 (e'
, Ast_c.noType
()(*ref !ty*)), ii'
(* keep type - jll *)
79 let semi_al_expr = Visitor_c.vk_expr_s
semi_strip_info_visitor
80 let semi_al_statement = Visitor_c.vk_statement_s
semi_strip_info_visitor
81 let semi_al_type = Visitor_c.vk_type_s
semi_strip_info_visitor
82 let semi_al_param = Visitor_c.vk_param_s
semi_strip_info_visitor
83 let semi_al_params = Visitor_c.vk_params_s
semi_strip_info_visitor
84 let semi_al_arguments = Visitor_c.vk_arguments_s
semi_strip_info_visitor
86 let semi_al_program = List.map
(Visitor_c.vk_toplevel_s
semi_strip_info_visitor)
92 let real_strip_info_visitor _
=
93 { Visitor_c.default_visitor_c_s
with
94 Visitor_c.kinfo_s
= (fun (k
,_
) i
->
98 Visitor_c.kexpr_s
= (fun (k
,_
) e
->
99 let (e'
, ty
),ii'
= k e
in
100 (e'
, Ast_c.noType
()), ii'
104 Visitor_c.ktype_s = (fun (k,_) ft ->
106 match Ast_c.unwrap_typeC ft' with
107 | Ast_c.TypeName (s,_typ) ->
108 Ast_c.TypeName (s, Ast_c.noTypedefDef()) +> Ast_c.rewrap_typeC ft'
116 let real_al_expr x
= Visitor_c.vk_expr_s
(real_strip_info_visitor()) x
117 let real_al_node x
= Visitor_c.vk_node_s
(real_strip_info_visitor()) x
118 let real_al_type x
= Visitor_c.vk_type_s
(real_strip_info_visitor()) x
121 (*****************************************************************************)
123 (*****************************************************************************)
125 let extract_info_visitor recursor x
=
126 let globals = ref [] in
129 Visitor_c.default_visitor_c
with
130 Visitor_c.kinfo
= (fun (k
, _
) i
-> Common.push2 i
globals)
137 let ii_of_decl = extract_info_visitor Visitor_c.vk_decl
138 let ii_of_node = extract_info_visitor Visitor_c.vk_node
139 let ii_of_expr = extract_info_visitor Visitor_c.vk_expr
140 let ii_of_stmt = extract_info_visitor Visitor_c.vk_statement
141 let ii_of_args = extract_info_visitor Visitor_c.vk_args_splitted
142 let ii_of_type = extract_info_visitor Visitor_c.vk_type
143 let ii_of_ini = extract_info_visitor Visitor_c.vk_ini
144 let ii_of_param = extract_info_visitor Visitor_c.vk_param
145 let ii_of_params = extract_info_visitor Visitor_c.vk_params_splitted
146 let ii_of_struct_fields = extract_info_visitor Visitor_c.vk_struct_fields
147 (*let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field*)
148 let ii_of_struct_fieldkinds = extract_info_visitor Visitor_c.vk_struct_fieldkinds
149 let ii_of_cst = extract_info_visitor Visitor_c.vk_cst
150 let ii_of_define_params =
151 extract_info_visitor Visitor_c.vk_define_params_splitted
152 let ii_of_toplevel = extract_info_visitor Visitor_c.vk_toplevel
154 (*****************************************************************************)
156 (*****************************************************************************)
157 let max_min_ii_by_pos xs
=
159 | [] -> failwith
"empty list, max_min_ii_by_pos"
162 let pos_leq p1 p2
= (Ast_c.compare_pos p1 p2
) = (-1) in
163 xs
+> List.fold_left
(fun (maxii
,minii
) e
->
164 let maxii'
= if pos_leq maxii e
then e
else maxii in
165 let minii'
= if pos_leq e
minii then e
else minii in
169 let info_to_fixpos ii
=
170 match Ast_c.pinfo_of_info ii
with
171 Ast_c.OriginTok pi
-> Ast_cocci.Real pi
.Common.charpos
172 | Ast_c.ExpandedTok
(_
,(pi
,offset
)) ->
173 Ast_cocci.Virt
(pi
.Common.charpos
,offset
)
174 | Ast_c.FakeTok
(_
,(pi
,offset
)) ->
175 Ast_cocci.Virt
(pi
.Common.charpos
,offset
)
176 | Ast_c.AbstractLineTok pi
-> failwith
"unexpected abstract"
178 let max_min_by_pos xs
=
179 let (i1
, i2
) = max_min_ii_by_pos xs
in
180 (info_to_fixpos i1
, info_to_fixpos i2
)
182 let lin_col_by_pos xs
=
183 (* put min before max; no idea why they are backwards above *)
184 let (i2
, i1
) = max_min_ii_by_pos xs
in
185 let posf x
= Ast_c.col_of_info x
in
186 let mposf x
= Ast_c.col_of_info x
+ String.length
(Ast_c.str_of_info x
) in
187 (Ast_c.file_of_info i1
,!Flag.current_element
,
188 (Ast_c.line_of_info i1
, posf i1
), (Ast_c.line_of_info i2
, mposf i2
))
194 let min_pinfo_of_node node
=
195 let ii = ii_of_node node
in
196 let (maxii, minii) = max_min_ii_by_pos ii in
197 Ast_c.parse_info_of_info
minii
200 let (range_of_origin_ii
: Ast_c.info list
-> (int * int) option) =
202 let ii = List.filter
Ast_c.is_origintok
ii in
204 let (max
, min
) = max_min_ii_by_pos ii in
205 assert(Ast_c.is_origintok max
);
206 assert(Ast_c.is_origintok min
);
207 let strmax = Ast_c.str_of_info max
in
209 (Ast_c.pos_of_info min
, Ast_c.pos_of_info max
+ String.length
strmax)