3 * Copyright (C) 2008, 2009 University of Urbana Champaign
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License (GPL)
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * file license.txt for more details.
18 val print_parsing_stat_list: parsing_stat list -> unit
21 (*****************************************************************************)
23 (*****************************************************************************)
26 mutable have_timeout
: bool;
31 mutable commentized
: int; (* by our cpp commentizer *)
33 (* if want to know exactly what was passed through, uncomment:
35 * mutable passing_through_lines: int;
37 * it differs from bad by starting from the error to
38 * the synchro point instead of starting from start of
39 * function to end of function.
42 mutable problematic_lines
:
43 (string list
(* ident in error line *) * int (* line_error *)) list
;
47 let default_stat file
= {
52 problematic_lines
= [];
55 (* todo: stat per dir ? give in terms of func_or_decl numbers:
56 * nbfunc_or_decl pbs / nbfunc_or_decl total ?/
58 * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les
59 * valeurs alors on parsera correctement tout le fichier et pourtant y'aura
60 * aucune def et donc aucune couverture en fait.
61 * ==> TODO evaluer les parties non parsé ?
64 let print_parsing_stat_list ?
(verbose
=false) = fun statxs
->
65 let total = List.length statxs
in
68 +> List.filter
(function
69 {have_timeout
= false; bad
= 0} -> true | _
-> false)
74 pr
"\n\n\n---------------------------------------------------------------";
77 +> List.filter
(function
78 | {have_timeout
= true} -> true
79 | {bad
= n
} when n
> 0 -> true
81 +> List.iter
(function
82 {filename
= file
; have_timeout
= timeout
; bad
= n
} ->
83 pr
(file ^
" " ^
(if timeout
then "TIMEOUT" else i_to_s n
));
87 pr
"files with lots of tokens passed/commentized:";
88 let threshold_passed = 100 in
90 +> List.filter
(function
91 | {commentized
= n
} when n
> threshold_passed -> true
93 +> List.iter
(function
94 {filename
= file
; commentized
= n
} ->
95 pr
(file ^
" " ^
(i_to_s n
));
98 pr
"\n\n\n---------------------------------------------------------------";
102 (sprintf
"NB total files = %d; " total) ^
103 (sprintf
"perfect = %d; " perfect) ^
104 (sprintf
"pbs = %d; " (statxs
+> List.filter
(function
105 {have_timeout
= b
; bad
= n
} when n
> 0 -> true | _
-> false)
107 (sprintf
"timeout = %d; " (statxs
+> List.filter
(function
108 {have_timeout
= true; bad
= n
} -> true | _
-> false)
110 (sprintf
"=========> %d" ((100 * perfect) / total)) ^
"%"
113 let good = statxs
+> List.fold_left
(fun acc
{correct
= x
} -> acc
+x
) 0 in
114 let bad = statxs
+> List.fold_left
(fun acc
{bad = x
} -> acc
+x
) 0 in
115 let passed = statxs
+> List.fold_left
(fun acc
{commentized
= x
} -> acc
+x
) 0
117 let gf, badf
= float_of_int
good, float_of_int
bad in
118 let passedf = float_of_int
passed in
120 (sprintf
"nb good = %d, nb passed = %d " good passed) ^
121 (sprintf
"=========> %f" (100.0 *. (passedf /. gf)) ^
"% passed")
124 (sprintf
"nb good = %d, nb bad = %d " good bad) ^
125 (sprintf
"=========> %f" (100.0 *. (gf /. (gf +. badf
))) ^
"% good"
129 (*****************************************************************************)
130 (* Recurring error diagnostic *)
131 (*****************************************************************************)
132 (* asked/inspired by reviewer of CC'09 *)
134 let lines_around_error_line ~context
(file
, line
) =
135 let arr = Common.cat_array file
in
137 let startl = max
0 (line
- context
) in
138 let endl = min
(Array.length
arr) (line
+ context
) in
141 for i
= startl to endl -1 do
142 Common.push2
arr.(i
) res
148 let print_recurring_problematic_tokens xs
=
149 let h = Hashtbl.create
101 in
150 xs
+> List.iter
(fun x
->
151 let file = x
.filename
in
152 x
.problematic_lines
+> List.iter
(fun (xs
, line_error
) ->
153 xs
+> List.iter
(fun s
->
154 Common.hupdate_default s
155 (fun (old
, example
) -> old
+ 1, example
)
156 (fun() -> 0, (file, line_error
)) h;
158 pr2_xxxxxxxxxxxxxxxxx
();
159 pr2
("maybe 10 most problematic tokens");
160 pr2_xxxxxxxxxxxxxxxxx
();
161 Common.hash_to_list
h
162 +> List.sort
(fun (k1
,(v1
,_
)) (k2
,(v2
,_
)) -> compare v2 v1
)
163 +> Common.take_safe
10
164 +> List.iter
(fun (k
,(i
, (file_ex
, line_ex
))) ->
165 pr2
(spf
"%s: present in %d parsing errors" k i
);
167 let lines = lines_around_error_line ~context
:2 (file_ex
, line_ex
) in
168 lines +> List.iter
(fun s
-> pr2
(" " ^ s
));
171 pr2_xxxxxxxxxxxxxxxxx
();
177 (*****************************************************************************)
179 (*****************************************************************************)
181 (* Those variables were written for CC09, to evaluate the need for
182 * some of our heuristics and extensions.
184 * coupling: if you add a new var, modify also assoc_stat_number below
187 let nTypedefInfer = ref 0
189 let nIncludeGrammar = ref 0
190 let nIncludeHack = ref 0
192 let nIteratorGrammar = ref 0
193 let nIteratorHeuristic = ref 0
195 let nMacroTopDecl = ref 0
196 let nMacroStructDecl = ref 0
197 let nMacroDecl = ref 0
198 let nMacroStmt = ref 0
199 let nMacroString = ref 0
200 let nMacroHigherOrder = ref 0 (* actions *)
201 let nMacrohigherTypeGrammar = ref 0
202 let nMacroAttribute = ref 0
204 let nIfdefTop = ref 0
205 let nIfdefStmt = ref 0
206 let nIfdefStruct = ref 0
207 let nIfdefInitializer = ref 0
208 (* nIfdefExpr, nIfdefType *)
210 let nIfdefFunheader = ref 0
212 let nIfdefExprPassing = ref 0
213 let nIfdefPassing = ref 0
215 let nIncludePassing = ref 0
216 let nDefinePassing = ref 0
218 let nIfdefZero = ref 0
219 let nIfdefVersion = ref 0
223 let nGccTypeof = ref 0
224 let nGccLongLong = ref 0
226 let nGccInline = ref 0
227 let nGccAttribute = ref 0
228 let nGccCaseRange = ref 0
229 let nGccMixDecl = ref 0
230 let nGccDesignator = ref 0
231 let nGccStmtExpr = ref 0
232 let nGccConstructor = ref 0
233 let nGccEmptyStruct = ref 0
234 let nGccNestedFunc = ref 0
240 let nDefineHack = ref 0
242 let nDefineConstant = ref 0
243 let nDefineStmt = ref 0
244 let nDefineExpr = ref 0
245 (* both below require some heuristic support *)
246 let nDefineWhile0 = ref 0
247 let nDefineInit = ref 0
249 let nDefineOther = ref 0
252 let nPragmaAndCo = ref 0
254 (* let nDirectiveTop = ref 0 *)
255 let nDirectiveStmt = ref 0
256 let nDirectiveStruct = ref 0
257 let nDirectiveInitializer = ref 0
260 (* from standard.h *)
261 let nMacroHint = ref 0
262 let nMacroExpand = ref 0
264 let nNotParsedCorrectly = ref 0
266 let assoc_stat_number =
268 "nTypedefInfer", nTypedefInfer;
270 "nIteratorHeuristic", nIteratorHeuristic;
272 "nMacroTopDecl", nMacroTopDecl;
273 "nMacroStructDecl", nMacroStructDecl;
274 "nMacroDecl", nMacroDecl;
275 "nMacroStmt", nMacroStmt;
276 "nMacroString", nMacroString;
277 "nMacroHigherOrder", nMacroHigherOrder;
278 "nMacroAttribute", nMacroAttribute;
280 "nMacrohigherTypeGrammar", nMacrohigherTypeGrammar;
282 "nIfdefTop", nIfdefTop;
283 "nIfdefStmt", nIfdefStmt;
284 "nIfdefStruct", nIfdefStruct;
285 "nIfdefInitializer", nIfdefInitializer;
287 "nIfdefFunheader", nIfdefFunheader;
288 "nIfdefZero", nIfdefZero;
289 "nIfdefVersion", nIfdefVersion;
290 "nIfdefExprPassing", nIfdefExprPassing;
291 "nIfdefPassing", nIfdefPassing;
293 "nIncludePassing", nIncludePassing;
294 "nDefinePassing", nDefinePassing;
296 "nMacroExpand", nMacroExpand;
297 "nMacroHint", nMacroHint;
300 "nGccTypeof", nGccTypeof;
301 "nGccLongLong", nGccLongLong;
303 "nGccInline", nGccInline;
304 "nGccAttribute", nGccAttribute;
305 "nGccCaseRange", nGccCaseRange;
306 "nGccMixDecl", nGccMixDecl;
307 "nGccDesignator", nGccDesignator;
308 "nGccStmtExpr", nGccStmtExpr;
309 "nGccConstructor", nGccConstructor;
310 "nGccEmptyStruct", nGccEmptyStruct;
311 "nGccNestedFunc", nGccNestedFunc;
313 "nGccMisc", nGccMisc;
316 "nDefineHack", nDefineHack;
318 "nDefineConstant", nDefineConstant;
319 "nDefineStmt", nDefineStmt;
320 "nDefineExpr", nDefineExpr;
321 "nDefineInit", nDefineInit;
322 "nDefineOther", nDefineOther;
325 "nPragmaAndCo", nPragmaAndCo;
327 "nDirectiveStmt", nDirectiveStmt;
328 "nDirectiveStruct", nDirectiveStruct;
329 "nDirectiveInitializer", nDirectiveInitializer;
331 "nNotParsedCorrectly", nNotParsedCorrectly;
335 "nIncludeGrammar", nIncludeGrammar;
336 "nIncludeHack", nIncludeHack;
338 "nIteratorGrammar", nIteratorGrammar;
341 let print_stat_numbers () =
342 assoc_stat_number +> List.iter
(fun (k
, vref
) ->
343 pr2
(spf
"%-30s -> %d" k
!vref
);