3 * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
4 * Copyright (C) 2008, 2009 University of Urbana Champaign
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License (GPL)
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * file license.txt for more details.
19 val print_parsing_stat_list: parsing_stat list -> unit
22 (*****************************************************************************)
24 (*****************************************************************************)
27 mutable have_timeout
: bool;
32 mutable commentized
: int; (* by our cpp commentizer *)
34 (* if want to know exactly what was passed through, uncomment:
36 * mutable passing_through_lines: int;
38 * it differs from bad by starting from the error to
39 * the synchro point instead of starting from start of
40 * function to end of function.
43 mutable problematic_lines
:
44 (string list
(* ident in error line *) * int (* line_error *)) list
;
48 let default_stat file
= {
53 problematic_lines
= [];
56 (* todo: stat per dir ? give in terms of func_or_decl numbers:
57 * nbfunc_or_decl pbs / nbfunc_or_decl total ?/
59 * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les
60 * valeurs alors on parsera correctement tout le fichier et pourtant y'aura
61 * aucune def et donc aucune couverture en fait.
62 * ==> TODO evaluer les parties non parsé ?
65 let print_parsing_stat_list ?
(verbose
=false) = fun statxs
->
66 let total = List.length statxs
in
69 +> List.filter
(function
70 {have_timeout
= false; bad
= 0} -> true | _
-> false)
75 pr
"\n\n\n---------------------------------------------------------------";
78 +> List.filter
(function
79 | {have_timeout
= true} -> true
80 | {bad
= n
} when n
> 0 -> true
82 +> List.iter
(function
83 {filename
= file
; have_timeout
= timeout
; bad
= n
} ->
84 pr
(file ^
" " ^
(if timeout
then "TIMEOUT" else i_to_s n
));
88 pr
"files with lots of tokens passed/commentized:";
89 let threshold_passed = 100 in
91 +> List.filter
(function
92 | {commentized
= n
} when n
> threshold_passed -> true
94 +> List.iter
(function
95 {filename
= file
; commentized
= n
} ->
96 pr
(file ^
" " ^
(i_to_s n
));
99 pr
"\n\n\n---------------------------------------------------------------";
103 (sprintf
"NB total files = %d; " total) ^
104 (sprintf
"perfect = %d; " perfect) ^
105 (sprintf
"pbs = %d; " (statxs
+> List.filter
(function
106 {have_timeout
= b
; bad
= n
} when n
> 0 -> true | _
-> false)
108 (sprintf
"timeout = %d; " (statxs
+> List.filter
(function
109 {have_timeout
= true; bad
= n
} -> true | _
-> false)
111 (sprintf
"=========> %d" ((100 * perfect) / total)) ^
"%"
114 let good = statxs
+> List.fold_left
(fun acc
{correct
= x
} -> acc
+x
) 0 in
115 let bad = statxs
+> List.fold_left
(fun acc
{bad = x
} -> acc
+x
) 0 in
116 let passed = statxs
+> List.fold_left
(fun acc
{commentized
= x
} -> acc
+x
) 0
118 let gf, badf
= float_of_int
good, float_of_int
bad in
119 let passedf = float_of_int
passed in
121 (sprintf
"nb good = %d, nb passed = %d " good passed) ^
122 (sprintf
"=========> %f" (100.0 *. (passedf /. gf)) ^
"% passed")
125 (sprintf
"nb good = %d, nb bad = %d " good bad) ^
126 (sprintf
"=========> %f" (100.0 *. (gf /. (gf +. badf
))) ^
"% good"
130 (*****************************************************************************)
131 (* Recurring error diagnostic *)
132 (*****************************************************************************)
133 (* asked/inspired by reviewer of CC'09 *)
135 let lines_around_error_line ~context
(file
, line
) =
136 let arr = Common.cat_array file
in
138 let startl = max
0 (line
- context
) in
139 let endl = min
(Array.length
arr) (line
+ context
) in
142 for i
= startl to endl -1 do
143 Common.push2
arr.(i
) res
149 let print_recurring_problematic_tokens xs
=
150 let h = Hashtbl.create
101 in
151 xs
+> List.iter
(fun x
->
152 let file = x
.filename
in
153 x
.problematic_lines
+> List.iter
(fun (xs
, line_error
) ->
154 xs
+> List.iter
(fun s
->
155 Common.hupdate_default s
156 (fun (old
, example
) -> old
+ 1, example
)
157 (fun() -> 0, (file, line_error
)) h;
159 pr2_xxxxxxxxxxxxxxxxx
();
160 pr2
("maybe 10 most problematic tokens");
161 pr2_xxxxxxxxxxxxxxxxx
();
162 Common.hash_to_list
h
163 +> List.sort
(fun (k1
,(v1
,_
)) (k2
,(v2
,_
)) -> compare v2 v1
)
164 +> Common.take_safe
10
165 +> List.iter
(fun (k
,(i
, (file_ex
, line_ex
))) ->
166 pr2
(spf
"%s: present in %d parsing errors" k i
);
168 let lines = lines_around_error_line ~context
:2 (file_ex
, line_ex
) in
169 lines +> List.iter
(fun s
-> pr2
(" " ^ s
));
172 pr2_xxxxxxxxxxxxxxxxx
();
178 (*****************************************************************************)
180 (*****************************************************************************)
182 (* Those variables were written for CC09, to evaluate the need for
183 * some of our heuristics and extensions.
185 * coupling: if you add a new var, modify also assoc_stat_number below
188 let nTypedefInfer = ref 0
190 let nIncludeGrammar = ref 0
191 let nIncludeHack = ref 0
193 let nIteratorGrammar = ref 0
194 let nIteratorHeuristic = ref 0
196 let nMacroTopDecl = ref 0
197 let nMacroStructDecl = ref 0
198 let nMacroDecl = ref 0
199 let nMacroStmt = ref 0
200 let nMacroString = ref 0
201 let nMacroHigherOrder = ref 0 (* actions *)
202 let nMacrohigherTypeGrammar = ref 0
203 let nMacroAttribute = ref 0
205 let nIfdefTop = ref 0
206 let nIfdefStmt = ref 0
207 let nIfdefStruct = ref 0
208 let nIfdefInitializer = ref 0
209 (* nIfdefExpr, nIfdefType *)
211 let nIfdefFunheader = ref 0
213 let nIfdefExprPassing = ref 0
214 let nIfdefPassing = ref 0
216 let nIncludePassing = ref 0
217 let nUndefPassing = ref 0
218 let nDefinePassing = ref 0
220 let nIfdefZero = ref 0
221 let nIfdefVersion = ref 0
225 let nGccTypeof = ref 0
226 let nGccLongLong = ref 0
228 let nGccInline = ref 0
229 let nGccAttribute = ref 0
230 let nGccCaseRange = ref 0
231 let nGccMixDecl = ref 0
232 let nGccDesignator = ref 0
233 let nGccStmtExpr = ref 0
234 let nGccConstructor = ref 0
235 let nGccEmptyStruct = ref 0
236 let nGccNestedFunc = ref 0
242 let nDefineHack = ref 0
244 let nDefineConstant = ref 0
245 let nDefineStmt = ref 0
246 let nDefineExpr = ref 0
247 (* both below require some heuristic support *)
248 let nDefineWhile0 = ref 0
249 let nDefineInit = ref 0
251 let nDefineOther = ref 0
254 let nPragmaAndCo = ref 0
256 (* let nDirectiveTop = ref 0 *)
257 let nDirectiveStmt = ref 0
258 let nDirectiveStruct = ref 0
259 let nDirectiveInitializer = ref 0
262 (* from standard.h *)
263 let nMacroHint = ref 0
264 let nMacroExpand = ref 0
266 let nNotParsedCorrectly = ref 0
268 let assoc_stat_number =
270 "nTypedefInfer", nTypedefInfer;
272 "nIteratorHeuristic", nIteratorHeuristic;
274 "nMacroTopDecl", nMacroTopDecl;
275 "nMacroStructDecl", nMacroStructDecl;
276 "nMacroDecl", nMacroDecl;
277 "nMacroStmt", nMacroStmt;
278 "nMacroString", nMacroString;
279 "nMacroHigherOrder", nMacroHigherOrder;
280 "nMacroAttribute", nMacroAttribute;
282 "nMacrohigherTypeGrammar", nMacrohigherTypeGrammar;
284 "nIfdefTop", nIfdefTop;
285 "nIfdefStmt", nIfdefStmt;
286 "nIfdefStruct", nIfdefStruct;
287 "nIfdefInitializer", nIfdefInitializer;
289 "nIfdefFunheader", nIfdefFunheader;
290 "nIfdefZero", nIfdefZero;
291 "nIfdefVersion", nIfdefVersion;
292 "nIfdefExprPassing", nIfdefExprPassing;
293 "nIfdefPassing", nIfdefPassing;
295 "nIncludePassing", nIncludePassing;
296 "nDefinePassing", nDefinePassing;
297 "nUndefPassing", nUndefPassing;
299 "nMacroExpand", nMacroExpand;
300 "nMacroHint", nMacroHint;
303 "nGccTypeof", nGccTypeof;
304 "nGccLongLong", nGccLongLong;
306 "nGccInline", nGccInline;
307 "nGccAttribute", nGccAttribute;
308 "nGccCaseRange", nGccCaseRange;
309 "nGccMixDecl", nGccMixDecl;
310 "nGccDesignator", nGccDesignator;
311 "nGccStmtExpr", nGccStmtExpr;
312 "nGccConstructor", nGccConstructor;
313 "nGccEmptyStruct", nGccEmptyStruct;
314 "nGccNestedFunc", nGccNestedFunc;
316 "nGccMisc", nGccMisc;
319 "nDefineHack", nDefineHack;
321 "nDefineConstant", nDefineConstant;
322 "nDefineStmt", nDefineStmt;
323 "nDefineExpr", nDefineExpr;
324 "nDefineInit", nDefineInit;
325 "nDefineOther", nDefineOther;
328 "nPragmaAndCo", nPragmaAndCo;
330 "nDirectiveStmt", nDirectiveStmt;
331 "nDirectiveStruct", nDirectiveStruct;
332 "nDirectiveInitializer", nDirectiveInitializer;
334 "nNotParsedCorrectly", nNotParsedCorrectly;
338 "nIncludeGrammar", nIncludeGrammar;
339 "nIncludeHack", nIncludeHack;
341 "nIteratorGrammar", nIteratorGrammar;
344 let print_stat_numbers () =
345 assoc_stat_number +> List.iter
(fun (k
, vref
) ->
346 pr2
(spf
"%-30s -> %d" k
!vref
);