Release coccinelle-0.2.4
[bpt/coccinelle.git] / parsing_cocci / top_level.ml
CommitLineData
9bc82bae
C
1(*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
c491d8ee
C
25(*
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
31 *
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
35 *
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
43 *
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
46 *)
47
48
34e49164
C
49(* Reorganize the top level of a rule to be a list of either top-level
50declarations or code dots. A function declaration is always considered top
51level. A statement is always considered code dots. A variable declaration
52is ambiguous. We use the heuristic that if there are code dots somewhere
53else, then the variable declaration is at top level, otherwise it applies
54both at top level and to all code. *)
55
56(* This is assumed to be done before compute_lines, and thus the info on a
57complex term is assumed to be Ast0.default_info *)
58
59module Ast0 = Ast0_cocci
60
61let top_dots l =
62 let circle x =
63 match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
64 let star x =
65 match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
66 if List.exists circle l
67 then Ast0.wrap (Ast0.CIRCLES(l))
68 else if List.exists star l
69 then Ast0.wrap (Ast0.STARS(l))
70 else Ast0.wrap (Ast0.DOTS(l))
71
72let scan_code l =
73 let statements = ref false in
74 let rec loop = function
75 [] -> ([],[])
76 | (x::xs) as all ->
77 (match Ast0.unwrap x with
78 (Ast0.OTHER(code)) ->
79 (match Ast0.unwrap code with
80 Ast0.Decl(_) ->
81 let (front,rest) = loop xs in
82 (code::front,rest)
83 | _ ->
84 statements := true;
85 let (front,rest) = loop xs in
86 (code::front,rest))
87 | _ -> ([],all)) in
88 match loop l with
89 ([],_) as res -> res
90 | (code,rest) ->
91 if !statements = true
92 then ([Ast0.wrap(Ast0.CODE(top_dots code))],rest)
93 else
94 (List.map
95 (function d ->
96 match Ast0.unwrap d with
97 Ast0.Decl(bef,x) -> Ast0.wrap (Ast0.DECL(d))
98 | _ -> failwith "impossible")
99 code,
100 rest)
101
102let rec scan_top_decl = function
103 [] -> ([],[])
104 | ((topdecl::rest) as all) ->
105 (match Ast0.unwrap topdecl with
106 Ast0.OTHER(_) -> ([],all)
107 | _ -> let (front,rest) = scan_top_decl rest in (topdecl::front,rest))
108
109(* for debugging *)
110let l2c l =
111 match Ast0.unwrap l with
112 Ast0.DECL(_) -> "decl"
113 | Ast0.CODE(_) -> "code"
114 | Ast0.FILEINFO(_,_) -> "fileinfo"
115 | Ast0.ERRORWORDS(_) -> "errorwords"
116 | Ast0.OTHER(_) -> "other"
117
118let rec top_level l =
119 match scan_code l with
120 (code,[]) -> code
121 | (code,rest) ->
122 (match scan_top_decl rest with
123 (top_decls,[]) -> code@top_decls
124 | (top_decls,rest) -> code @ top_decls @ (top_level rest))