permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_c / parsing_stat.ml
index c6270bc..8723eea 100644 (file)
@@ -1,18 +1,19 @@
 (* Yoann Padioleau
- * 
+ *
+ * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
  * Copyright (C) 2008, 2009 University of Urbana Champaign
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
  * version 2 as published by the Free Software Foundation.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * file license.txt for more details.
  *)
 
-open Common 
+open Common
 
 (* if do .mli:
 val print_parsing_stat_list: parsing_stat list -> unit
@@ -25,26 +26,26 @@ type parsing_stat = {
     filename: filename;
     mutable have_timeout: bool;
 
-    mutable correct: int;  
+    mutable correct: int;
     mutable bad: int;
 
     mutable commentized: int; (* by our cpp commentizer *)
 
     (* if want to know exactly what was passed through, uncomment:
-     *  
+     *
      * mutable passing_through_lines: int;
-     * 
+     *
      * it differs from bad by starting from the error to
      * the synchro point instead of starting from start of
      * function to end of function.
      *)
 
-    mutable problematic_lines: 
+    mutable problematic_lines:
       (string list (* ident in error line *) * int (* line_error *)) list;
 
-  } 
+  }
 
-let default_stat file =  { 
+let default_stat file =  {
     filename = file;
     have_timeout = false;
     correct = 0; bad = 0;
@@ -52,46 +53,46 @@ let default_stat file =  {
     problematic_lines = [];
   }
 
-(* todo: stat per dir ?  give in terms of func_or_decl numbers:   
- * nbfunc_or_decl pbs / nbfunc_or_decl total ?/ 
+(* todo: stat per dir ?  give in terms of func_or_decl numbers:
+ * nbfunc_or_decl pbs / nbfunc_or_decl total ?/
  *
- * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les 
- * valeurs alors on parsera correctement tout le fichier et pourtant y'aura 
- * aucune def  et donc aucune couverture en fait.   
- * ==> TODO evaluer les parties non parsé ? 
+ * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les
+ * valeurs alors on parsera correctement tout le fichier et pourtant y'aura
+ * aucune def  et donc aucune couverture en fait.
+ * ==> TODO evaluer les parties non parsé ?
  *)
 
-let print_parsing_stat_list ?(verbose=false) = fun statxs -> 
+let print_parsing_stat_list ?(verbose=false) = fun statxs ->
   let total = List.length statxs in
-  let perfect = 
-    statxs 
-      +> List.filter (function 
+  let perfect =
+    statxs
+      +> List.filter (function
           {have_timeout = false; bad = 0} -> true | _ -> false)
-      +> List.length 
+      +> List.length
   in
 
   if verbose then begin
   pr "\n\n\n---------------------------------------------------------------";
   pr "pbs with files:";
-  statxs 
-    +> List.filter (function 
-      | {have_timeout = true} -> true 
-      | {bad = n} when n > 0 -> true 
+  statxs
+    +> List.filter (function
+      | {have_timeout = true} -> true
+      | {bad = n} when n > 0 -> true
       | _ -> false)
-    +> List.iter (function 
-        {filename = file; have_timeout = timeout; bad = n} -> 
+    +> List.iter (function
+        {filename = file; have_timeout = timeout; bad = n} ->
           pr (file ^ "  " ^ (if timeout then "TIMEOUT" else i_to_s n));
         );
 
   pr "\n\n\n";
   pr "files with lots of tokens passed/commentized:";
   let threshold_passed = 100 in
-  statxs 
-    +> List.filter (function 
+  statxs
+    +> List.filter (function
       | {commentized = n} when n > threshold_passed -> true
       | _ -> false)
-    +> List.iter (function 
-        {filename = file; commentized = n} -> 
+    +> List.iter (function
+        {filename = file; commentized = n} ->
           pr (file ^ "  " ^ (i_to_s n));
         );
 
@@ -101,14 +102,14 @@ let print_parsing_stat_list ?(verbose=false) = fun statxs ->
   pr (
   (sprintf "NB total files = %d; " total) ^
   (sprintf "perfect = %d; " perfect) ^
-  (sprintf "pbs = %d; "     (statxs +> List.filter (function 
-      {have_timeout = b; bad = n} when n > 0 -> true | _ -> false) 
+  (sprintf "pbs = %d; "     (statxs +> List.filter (function
+      {have_timeout = b; bad = n} when n > 0 -> true | _ -> false)
                                +> List.length)) ^
-  (sprintf "timeout = %d; " (statxs +> List.filter (function 
-      {have_timeout = true; bad = n} -> true | _ -> false) 
+  (sprintf "timeout = %d; " (statxs +> List.filter (function
+      {have_timeout = true; bad = n} -> true | _ -> false)
                                +> List.length)) ^
   (sprintf "=========> %d" ((100 * perfect) / total)) ^ "%"
-                                                          
+
   );
   let good = statxs +> List.fold_left (fun acc {correct = x} -> acc+x) 0 in
   let bad  = statxs +> List.fold_left (fun acc {bad = x} -> acc+x) 0  in
@@ -131,57 +132,57 @@ let print_parsing_stat_list ?(verbose=false) = fun statxs ->
 (*****************************************************************************)
 (* asked/inspired by reviewer of CC'09 *)
 
-let lines_around_error_line ~context (file, line) = 
+let lines_around_error_line ~context (file, line) =
   let arr = Common.cat_array file in
-  
+
   let startl = max 0 (line - context) in
   let endl   = min (Array.length arr) (line + context) in
-  let res = ref [] in 
+  let res = ref [] in
 
-  for i = startl to endl -1 do 
+  for i = startl to endl -1 do
     Common.push2 arr.(i) res
   done;
   List.rev !res
 
 
 
-let print_recurring_problematic_tokens xs = 
+let print_recurring_problematic_tokens xs =
   let h = Hashtbl.create 101 in
-  xs +> List.iter (fun x -> 
-    let file = x.filename in 
-    x.problematic_lines +> List.iter (fun (xs, line_error) -> 
-      xs +> List.iter (fun s -> 
+  xs +> List.iter (fun x ->
+    let file = x.filename in
+    x.problematic_lines +> List.iter (fun (xs, line_error) ->
+      xs +> List.iter (fun s ->
         Common.hupdate_default s
-          (fun (old, example)  -> old + 1, example) 
+          (fun (old, example)  -> old + 1, example)
           (fun() -> 0, (file, line_error)) h;
       )));
   pr2_xxxxxxxxxxxxxxxxx();
   pr2 ("maybe 10 most problematic tokens");
   pr2_xxxxxxxxxxxxxxxxx();
   Common.hash_to_list h
-  +> List.sort (fun (k1,(v1,_)) (k2,(v2,_)) -> compare v2 v1) 
+  +> List.sort (fun (k1,(v1,_)) (k2,(v2,_)) -> compare v2 v1)
   +> Common.take_safe 10
-  +> List.iter (fun (k,(i, (file_ex, line_ex))) -> 
+  +> List.iter (fun (k,(i, (file_ex, line_ex))) ->
     pr2 (spf "%s: present in %d parsing errors" k i);
     pr2 ("example: ");
     let lines = lines_around_error_line ~context:2 (file_ex, line_ex) in
     lines +> List.iter (fun s -> pr2 ("       " ^ s));
-    
+
   );
   pr2_xxxxxxxxxxxxxxxxx();
   ()
 
-  
+
 
 
 (*****************************************************************************)
 (* Stat *)
 (*****************************************************************************)
 
-(* Those variables were written for CC09, to evaluate the need for 
+(* Those variables were written for CC09, to evaluate the need for
  * some of our heuristics and extensions.
- * 
- * coupling: if you add a new var, modify also assoc_stat_number below 
+ *
+ * coupling: if you add a new var, modify also assoc_stat_number below
  *)
 
 let nTypedefInfer = ref 0
@@ -189,8 +190,8 @@ let nTypedefInfer = ref 0
 let nIncludeGrammar = ref 0
 let nIncludeHack = ref 0
 
-let nIteratorGrammar = ref 0 
-let nIteratorHeuristic = ref 0 
+let nIteratorGrammar = ref 0
+let nIteratorHeuristic = ref 0
 
 let nMacroTopDecl = ref 0
 let nMacroStructDecl = ref 0
@@ -213,6 +214,7 @@ let nIfdefExprPassing = ref 0
 let nIfdefPassing = ref 0
 
 let nIncludePassing = ref 0
+let nUndefPassing = ref 0
 let nDefinePassing = ref 0
 
 let nIfdefZero = ref 0
@@ -263,7 +265,7 @@ let nMacroExpand = ref 0
 
 let nNotParsedCorrectly = ref 0
 
-let assoc_stat_number = 
+let assoc_stat_number =
   [
     "nTypedefInfer", nTypedefInfer;
 
@@ -292,6 +294,7 @@ let assoc_stat_number =
 
     "nIncludePassing", nIncludePassing;
     "nDefinePassing", nDefinePassing;
+    "nUndefPassing", nUndefPassing;
 
     "nMacroExpand", nMacroExpand;
     "nMacroHint", nMacroHint;
@@ -338,7 +341,7 @@ let assoc_stat_number =
     "nIteratorGrammar", nIteratorGrammar;
   ]
 
-let print_stat_numbers () = 
-  assoc_stat_number +> List.iter (fun (k, vref) -> 
+let print_stat_numbers () =
+  assoc_stat_number +> List.iter (fun (k, vref) ->
     pr2 (spf "%-30s -> %d" k !vref);
   )