Release coccinelle-0.2.0rc1
[bpt/coccinelle.git] / parsing_cocci / top_level.ml
CommitLineData
34e49164
C
1(* Reorganize the top level of a rule to be a list of either top-level
2declarations or code dots. A function declaration is always considered top
3level. A statement is always considered code dots. A variable declaration
4is ambiguous. We use the heuristic that if there are code dots somewhere
5else, then the variable declaration is at top level, otherwise it applies
6both at top level and to all code. *)
7
8(* This is assumed to be done before compute_lines, and thus the info on a
9complex term is assumed to be Ast0.default_info *)
10
11module Ast0 = Ast0_cocci
12
13let top_dots l =
14 let circle x =
15 match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
16 let star x =
17 match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
18 if List.exists circle l
19 then Ast0.wrap (Ast0.CIRCLES(l))
20 else if List.exists star l
21 then Ast0.wrap (Ast0.STARS(l))
22 else Ast0.wrap (Ast0.DOTS(l))
23
24let scan_code l =
25 let statements = ref false in
26 let rec loop = function
27 [] -> ([],[])
28 | (x::xs) as all ->
29 (match Ast0.unwrap x with
30 (Ast0.OTHER(code)) ->
31 (match Ast0.unwrap code with
32 Ast0.Decl(_) ->
33 let (front,rest) = loop xs in
34 (code::front,rest)
35 | _ ->
36 statements := true;
37 let (front,rest) = loop xs in
38 (code::front,rest))
39 | _ -> ([],all)) in
40 match loop l with
41 ([],_) as res -> res
42 | (code,rest) ->
43 if !statements = true
44 then ([Ast0.wrap(Ast0.CODE(top_dots code))],rest)
45 else
46 (List.map
47 (function d ->
48 match Ast0.unwrap d with
49 Ast0.Decl(bef,x) -> Ast0.wrap (Ast0.DECL(d))
50 | _ -> failwith "impossible")
51 code,
52 rest)
53
54let rec scan_top_decl = function
55 [] -> ([],[])
56 | ((topdecl::rest) as all) ->
57 (match Ast0.unwrap topdecl with
58 Ast0.OTHER(_) -> ([],all)
59 | _ -> let (front,rest) = scan_top_decl rest in (topdecl::front,rest))
60
61(* for debugging *)
62let l2c l =
63 match Ast0.unwrap l with
64 Ast0.DECL(_) -> "decl"
65 | Ast0.CODE(_) -> "code"
66 | Ast0.FILEINFO(_,_) -> "fileinfo"
67 | Ast0.ERRORWORDS(_) -> "errorwords"
68 | Ast0.OTHER(_) -> "other"
69
70let rec top_level l =
71 match scan_code l with
72 (code,[]) -> code
73 | (code,rest) ->
74 (match scan_top_decl rest with
75 (top_decls,[]) -> code@top_decls
76 | (top_decls,rest) -> code @ top_decls @ (top_level rest))