Release coccinelle-0.2.0rc1
[bpt/coccinelle.git] / tools / dir_stats.ml
CommitLineData
34e49164
C
1(* for each marked thing, how often does it occur and in what files and
2directories *)
3
4let collect i =
5 let info = ref [] in
6 let rec loop _ =
7 let l = input_line i in
8 (if String.length l > 2 && String.get l 0 = '+'
9 then info := (String.sub l 1 (String.length l - 1))::!info);
10 loop() in
11 try loop()
12 with End_of_file -> List.rev !info
13
14let split l =
15 let rec loop acc = function
16 [] -> acc
17 | x::xs ->
18 if String.get x 0 = '+' (* the start of a new file *)
19 then
20 (match Str.split (Str.regexp " ") x with
21 _::x::_ -> loop ((x,[])::acc) xs
22 | _ -> failwith ("no file: "^x))
23 else
24 let acc =
25 match acc with
26 (file,instances)::rest -> (file,x::instances)::rest
27 | _ -> failwith "not possible" in
28 loop acc xs in
29 let res = List.rev (loop [] l) in
30 List.map (function (x,l) -> (x,List.rev l)) res
31
32let detect_alloc_free str l =
33 let try_add a f l =
34 let (same,diff) = List.partition (function (a1,f1) -> a = a1) l in
35 match same with
36 [(a1,f1)] -> if List.mem f f1 then l else (a1,f::f1) :: diff
37 | _ -> (a,[f])::l in
38 let rec loop acc = function
39 [] -> acc
40 | x::xs ->
41 match Str.split (Str.regexp (str^"\", ")) x with
42 _::matches ->
43 let acc =
44 List.fold_left
45 (function acc ->
46 function rest ->
47 (match Str.split (Str.regexp "[, )]+") rest with
48 alloc::free::_ -> try_add alloc free acc
49 | _ -> acc))
50 acc matches in
51 loop acc xs
52 | _ -> loop acc xs in
53 List.sort compare
54 (List.map (function (a,f) -> (a,List.sort compare f)) (loop [] l))
55
56let rec iterate str = function
57 [] -> []
58 | (x,l)::xs ->
59 List.fold_left
60 (function rest ->
61 function info ->
62 let (same,diff) =
63 List.partition (function (x1,l1) -> l1 = info) rest in
64 match same with
65 [(files,info)] -> (x::files,info)::diff
66 | _ -> ([x],info)::diff)
67 (iterate str xs) (detect_alloc_free str l)
68
69(* ------------------------------------------------------------------------ *)
70
71let get_dir d = Filename.dirname d
72
73let get_subsystem d =
74 let pieces = Str.split (Str.regexp "/") d in
75 let front = List.hd(List.tl pieces) in
76 match front with
77 "arch" | "drivers" -> front ^ "/" ^ (List.hd(List.tl(List.tl pieces)))
78 | _ -> front
79
80let rec remdup = function
81 [] -> []
82 | x::xs -> if List.mem x xs then remdup xs else x :: remdup xs
83
84let inc tbl key =
85 let cell =
86 (try let cell = Hashtbl.find tbl key in cell
87 with Not_found -> let c = ref 0 in Hashtbl.add tbl key c; c) in
88 cell := !cell + 1
89
90let files_per_protocol = Hashtbl.create(10)
91let dirs_per_protocol = Hashtbl.create(10)
92let subsystems_per_protocol = Hashtbl.create(10)
93let protocols_per_subsystem = Hashtbl.create(10)
94
95let collect_counts l =
96 List.iter
97 (function (files,(a,fs)) ->
98 let how_many_files = List.length files in
99 let how_many_dirs = remdup (List.map get_dir files) in
100 let how_many_subsystems = remdup (List.map get_subsystem files) in
101 let ct =
102 if how_many_files < 10
103 then how_many_files
104 else ((how_many_files / 10) * 10) in
105 inc files_per_protocol ct;
106 inc dirs_per_protocol (List.length how_many_dirs);
107 inc subsystems_per_protocol (List.length how_many_subsystems);
108 List.iter (inc protocols_per_subsystem) how_many_subsystems)
109 l
110
111let print_hashtable f tbl =
112 let l =
113 Hashtbl.fold
114 (function key -> function vl -> function rest ->
115 (key,!vl) :: rest)
116 tbl [] in
117 let l = List.sort compare l in
118 List.iter
119 (function (key,vl) ->
120 Printf.printf " "; f key; Printf.printf ": %d\n" vl)
121 l
122
123let print_range_int_hashtable range =
124 print_hashtable
125 (function x ->
126 if x < range
127 then Printf.printf "%d" x
128 else Printf.printf "%d-%d" x (x + range - 1))
129let print_int_hashtable =
130 print_hashtable (function x -> Printf.printf "%d" x)
131let print_string_hashtable =
132 print_hashtable (function x -> Printf.printf "%s" x)
133
134let histify _ =
135 Printf.printf "files per protocol:\n";
136 print_range_int_hashtable 10 files_per_protocol;
137 Printf.printf "dirs per protocol:\n";
138 print_int_hashtable dirs_per_protocol;
139 Printf.printf "subsystems per protocol:\n";
140 print_int_hashtable subsystems_per_protocol;
141 Printf.printf "protocols per subsystem:\n";
142 print_string_hashtable protocols_per_subsystem
143
144(* ------------------------------------------------------------------------ *)
145
146let dir = ref "p2"
147let file = ref ""
148let str = ref "detected allocator"
149
150let options = []
151let usage = ""
152
153let _ =
154 Arg.parse (Arg.align options) (fun x -> file := x) usage;
155 let i = open_in !file in
156 let l = collect i in
157 close_in i;
158 let l = split l in
159 let l = iterate !str l in
160 collect_counts l;
161 histify()
162
163