Release coccinelle-0.2.2-rc2
authorCoccinelle <cocci@diku.dk>
Sun, 3 Oct 2010 12:03:36 +0000 (14:03 +0200)
committerRene Rydhof Hansen <rrh@cs.aau.dk>
Sun, 3 Oct 2010 12:03:36 +0000 (14:03 +0200)
Release Candidate 2 for coccinelle-0.2.2

18 files changed:
changes.txt
cocci.ml
commitmsg
commons/common.ml
docs/manual/main_grammar.pdf
docs/manual/manual.pdf
docs/manual/options.pdf
engine/cocci_vs_c.ml
engine/pretty_print_engine.ml
globals/config.ml.in
main.ml
parsing_c/unparse_c.ml
parsing_c/unparse_cocci.ml
parsing_cocci/get_constants2.ml
parsing_cocci/lexer_cocci.mll
parsing_cocci/lexer_script.mll
parsing_cocci/type_infer.ml
test.ml

index 10b9ddb..78afb2b 100644 (file)
   keywords sush as 'depends on', 'using', 'disable'
 - better treatment of != 0 in isos, communtativity for ==/!= for all
   constants
-- allow adding // comments
+- allow adding // comments and blank lines (even after cocci + code)
 - Add support for multiple -I options
 
 ** Bugfix:
 - correct interaction between virtual rules and included .cocci files
 - improvement in treatment of ! in isos, to avoid duplicating + code
-- improvement intreatment of metavars as isos, to avoid duplicating + code
+- improvement in treatment of metavars as isos, to avoid duplicating + code
   between toplevel and variable instantiation
 - test expression of smpl conditional, etc no longer assumed to have type
   int
 - better handling of . or .. in -dir name
 - allow keywords and metavariable names in identifier constraints (not sure
   keywords is very useful, though)
+- no lubtype on arguments of && and || in SmPL
+- allow unknown as type for array indices in SmPL
+- support matching of static annotation on functions that are both static
+  and inline
+- support ENOTDIR error in Common.lfile_exists, to allow for the case where
+  an include file is in a subdirectory that exists but is an ordinary file,
+  not a directory.
+- better management of unbound position variables that appear in
+  constraints
+- cause python parser to skip over // comments, hoping that // is not
+  meaningful inside python
+- require + on every line of a multiline comment
+- correct caluation of line numbers when there is script code
 
 * 0.2.1
 ** Language:
index 3ab1f4f..59cbe46 100644 (file)
--- a/cocci.ml
+++ b/cocci.ml
@@ -1308,9 +1308,12 @@ let rec apply_cocci_rule r rules_that_have_ever_matched es
                      (new_bindings +>
                       List.map
                         (List.filter
-                           (fun (s,v) ->
-                             List.mem s r.used_after &&
-                             not (List.mem s old_variables)))) in
+                           (function
+                               (* see comment before combine_pos *)
+                               (s,Ast_c.MetaPosValList []) -> false
+                             | (s,v) ->
+                                 List.mem s r.used_after &&
+                                 not (List.mem s old_variables)))) in
                  List.map
                    (function new_binding_to_add ->
                      (List.sort compare
@@ -1391,22 +1394,28 @@ and reassociate_positions free_vars negated_pos_vars envs =
      (List.map (function (non_pos,_) -> List.assoc non_pos extended_relevant)
        splitted_relevant)
 
+(* If the negated posvar is not bound at all, this function will
+nevertheless bind it to [].  If we get rid of these bindings, then the
+matching of the term the position variable with the constraints will fail
+because some variables are unbound.  So we let the binding be [] and then
+we will have to clean these up afterwards.  This should be the only way
+that a position variable can have an empty binding. *)
 and combine_pos negated_pos_vars others =
   List.map
     (function posvar ->
-      (posvar,
-       Ast_c.MetaPosValList
-        (List.sort compare
-           (List.fold_left
-              (function positions ->
-                function other_list ->
-                  try
-                    match List.assoc posvar other_list with
-                      Ast_c.MetaPosValList l1 ->
-                        Common.union_set l1 positions
-                    | _ -> failwith "bad value for a position variable"
-                  with Not_found -> positions)
-              [] others))))
+      let positions =
+       List.sort compare
+         (List.fold_left
+            (function positions ->
+              function other_list ->
+                try
+                  match List.assoc posvar other_list with
+                    Ast_c.MetaPosValList l1 ->
+                      Common.union_set l1 positions
+                  | _ -> failwith "bad value for a position variable"
+                with Not_found -> positions)
+            [] others) in
+      (posvar,Ast_c.MetaPosValList positions))
     negated_pos_vars
 
 and process_a_generated_a_env_a_toplevel2 r env = function
index 7a39b2e..b443914 100644 (file)
--- a/commitmsg
+++ b/commitmsg
@@ -1,3 +1,3 @@
-Release coccinelle-0.2.2-rc1
+Release coccinelle-0.2.2-rc2
 
-Release Candidate 1 for coccinelle-0.2.2
+Release Candidate 2 for coccinelle-0.2.2
index 9308319..5bf1316 100644 (file)
@@ -3238,7 +3238,13 @@ let lfile_exists filename =
     | (Unix.S_REG | Unix.S_LNK) -> true
     | _ -> false
     )
-  with Unix.Unix_error (Unix.ENOENT, _, _) -> false
+  with
+    Unix.Unix_error (Unix.ENOENT, _, _) -> false
+  | Unix.Unix_error (Unix.ENOTDIR, _, _) -> false
+  | Unix.Unix_error (error, _, fl) ->
+      failwith
+       (Printf.sprintf "unexpected error %s for file %s"
+          (Unix.error_message error) fl)
 
 let is_directory file =
   (Unix.stat file).Unix.st_kind =*= Unix.S_DIR
index 53f8a70..3c125f7 100644 (file)
Binary files a/docs/manual/main_grammar.pdf and b/docs/manual/main_grammar.pdf differ
index 4170648..6813f62 100644 (file)
Binary files a/docs/manual/manual.pdf and b/docs/manual/manual.pdf differ
index c2c5e35..0d1a436 100644 (file)
Binary files a/docs/manual/options.pdf and b/docs/manual/options.pdf differ
index ae3c761..64354e5 100644 (file)
@@ -3059,21 +3059,19 @@ and storage_optional_allminus allminus stoa (stob, iistob) =
   | Some x, ((stobis, inline)) ->
       if equal_storage (term x) stobis
       then
-        match iistob with
-        | [i1] ->
-           tokenf x i1 >>= (fun x i1 ->
-             return (Some x,  ((stobis, inline), [i1]))
-           )
-       (* or if have inline ? have to do a split_storage_inline a la
-        * split_signb_baseb_ii *)
-        | _ -> raise Impossible
+       let rec loop acc = function
+           [] -> fail
+         | i1::iistob ->
+             let try1 =
+               tokenf x i1 >>= (fun x i1 ->
+                 let rebuilt = (List.rev acc) @ i1 :: iistob in
+                 return (Some x,  ((stobis, inline), rebuilt))) in
+             let try2 x = loop (i1::acc) iistob x in (* x for laziness *)
+             try1 >||> try2 in
+       loop [] iistob
       else fail
   )
 
-
-
-
-
 and fullType_optional_allminus allminus tya retb =
   match tya with
   | None ->
index 49a0211..04286bb 100644 (file)
@@ -62,7 +62,8 @@ and pp_binding subst =
   begin
     pp "[";
     Common.print_between (fun () -> pp ";"; Format.print_cut() )
-      (fun ((_,s), kind) -> pp s; pp " --> "; pp_binding_kind kind)
+      (fun ((r,s), kind) ->
+       pp r; pp "."; pp s; pp " --> "; pp_binding_kind kind)
       subst;
     pp "]";
   end
index 769cb48..ca5f236 100644 (file)
@@ -1,4 +1,4 @@
-let version = "0.2.2-rc1"
+let version = "0.2.2-rc2"
 
 let path =
   try (Sys.getenv "COCCINELLE_HOME")
diff --git a/main.ml b/main.ml
index b96cba4..f088e9f 100644 (file)
--- a/main.ml
+++ b/main.ml
@@ -331,7 +331,7 @@ let short_options = [
     "  guess what";
 
   "-date",   Arg.Unit (fun () ->
-    pr2 "version: $Date: 2010/03/05 21:12:11 $";
+    pr2 "version: $Date: 2010/03/09 08:29:04 $";
     raise (Common.UnixExit 0)
     ),
   "   guess what";
@@ -974,13 +974,19 @@ let main () =
     (* --------------------------------------------------------- *)
     | [x] when !test_mode    ->
        begin
+         let prefix = "tests/" in
          try
-           let prefix = "tests/" in
               FC.include_path := [prefix^"include"];
               Testing.testone prefix x !compare_with_expected
-         with _ ->
-            FC.include_path := ["include"];
-            Testing.testone "" x !compare_with_expected
+         with error ->
+           let testfile = prefix ^ x ^ ".cocci" in
+           if not (Sys.file_exists testfile) then
+             begin
+               FC.include_path := ["include"];
+               Testing.testone "" x !compare_with_expected
+             end
+           else
+             raise error
        end
 
     | []  when !test_all ->
@@ -1043,8 +1049,10 @@ let main_with_better_error_report () =
     try
       main ()
     with
-    | Unix.Unix_error (_, "stat", filename) ->
-        pr2 (spf "ERROR: File %s does not exist" filename);
+    | Unix.Unix_error (e, "stat", filename) ->
+        pr2
+         (spf "ERROR: File %s does not exist: %s"
+            filename (Unix.error_message e));
         raise (UnixExit (-1))
 
 (*****************************************************************************)
index 80a3a80..0cabad4 100644 (file)
@@ -790,6 +790,7 @@ let new_tabbing a =
 
 
 let rec adjust_indentation xs =
+
   let _current_tabbing = ref "" in
   let tabbing_unit = ref None in
 
index cda9814..6b9cb59 100644 (file)
@@ -148,11 +148,14 @@ let mcode fn (s,info,mc,pos) =
                  let str = match str with Ast.Noindent s | Ast.Indent s -> s in
                  print_string str line col; Some line
              | _ ->
+                 force_newline();
+                 (* not super elegant to put side-effecting unindent in a let
+                    expression... *)
                  let str =
                    match str with
                      Ast.Noindent s -> unindent false; s
                    | Ast.Indent s -> s in
-                 force_newline(); print_string str line col; Some line)
+                 print_string str line col; Some line)
          lb comments in
       let line_before = print_comments None info.Ast.strbef in
       (match line_before with
index 2a8f55a..90a0aa3 100644 (file)
@@ -514,10 +514,9 @@ let get_constants rules neg_pos_vars =
                      (build_or dependencies rest_info, in_plus, env, locals))
               | (Ast.InitialScriptRule (_,deps,_),_)
              | (Ast.FinalScriptRule (_,deps,_),_) ->
-                 (match dependencies env deps with
-                   False -> (rest_info, in_plus, env, locals)
-                 | dependencies ->
-                     (build_or dependencies rest_info, in_plus, env, locals))
+                 (* initialize and finalize dependencies are irrelevant to
+                    get_constants *)
+                 (rest_info, in_plus, env, locals)
               | (Ast.CocciRule (nm,(dep,_,_),cur,_,_),neg_pos_vars) ->
                  let (cur_info,cur_plus) =
                    rule_fn cur in_plus ((nm,True)::env)
index 49e4503..a9e1e4a 100644 (file)
@@ -116,6 +116,10 @@ let check_arity_context_linetype s =
   | (D.UNIQUE,_,_) | (D.OPT,_,_) -> ()
   | _ -> lexerr "invalid in a nonempty context: " s
 
+let check_comment s =
+  if not !current_line_started
+  then lexerr "+ expected at the beginning of the line" s
+
 let process_include start finish str =
   (match !current_line_type with
     (D.PLUS,_,_) | (D.PLUSPLUS,_,_) ->
@@ -694,7 +698,7 @@ rule token = parse
   | "/*"
       { start_line true; check_plus_linetype (tok lexbuf);
        (* second argument to TPragma is not quite right, because
-          it represents only the first token of the comemnt, but that
+          it represents only the first token of the comment, but that
           should be good enough *)
        TPragma (Ast.Indent("/*"^(comment lexbuf)),
                 get_current_line_type lexbuf) }
@@ -779,16 +783,23 @@ and string  = parse
   | _ { lexerr "unrecognised symbol: " (tok lexbuf) }
 
 and comment = parse
-  | "*/"     { start_line true; tok lexbuf }
+  | "*/" { let s = tok lexbuf in check_comment s; start_line true; s }
   | ['\n' '\r' '\011' '\012']
-      { reset_line lexbuf; let s = tok lexbuf in s ^ comment lexbuf }
+      { let s = tok lexbuf in
+        (* even blank line should have a + *)
+        check_comment s;
+        reset_line lexbuf; s ^ comment lexbuf }
   | "+" { pass_zero();
          if !current_line_started
          then (start_line true; let s = tok lexbuf in s^(comment lexbuf))
-         else comment lexbuf }
+         else (start_line true; comment lexbuf) }
   (* noteopti: *)
-  | [^ '*'] { start_line true; let s = tok lexbuf in s ^ comment lexbuf }
-  | [ '*']   { start_line true; let s = tok lexbuf in s ^ comment lexbuf }
+  | [^ '*']
+      { let s = tok lexbuf in
+        check_comment s; start_line true; s ^ comment lexbuf }
+  | [ '*']
+      { let s = tok lexbuf in
+        check_comment s; start_line true; s ^ comment lexbuf }
   | _
       { start_line true; let s = tok lexbuf in
         Common.pr2 ("LEXER: unrecognised symbol in comment:"^s);
index 512f905..1cab41c 100644 (file)
@@ -26,16 +26,19 @@ module D = Data
 module Ast = Ast_cocci
 exception Lexical of string
 let tok = Lexing.lexeme
+let inc_line _ = Lexer_cocci.line := !Lexer_cocci.line + 1
 }
 (* ---------------------------------------------------------------------- *)
 (* tokens *)
 
-let myrule = [^'"''@']+
+let myrule = [^'"''@''/''\n''\r''\011''\012']+
 
 rule token = parse
-  | myrule             { TScriptData (tok lexbuf) }
+  | myrule { TScriptData (tok lexbuf) }
+  | ['\n' '\r' '\011' '\012'] { inc_line(); TScriptData (tok lexbuf) }
   | "@@" { TArobArob }
   | "@"  { TArob }
+  | "/"  { TScriptData (tok lexbuf) }
   | "//" [^ '\n']* { token lexbuf } (* skip SmPL comments *)
   | '"'  { TScriptData (Printf.sprintf "\"%s\"" (string lexbuf)) }
   | eof  { EOF }
index 1fc1e1c..04b0ca7 100644 (file)
@@ -189,15 +189,21 @@ let rec propagate_types env =
                    Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; ty in
              (match Ast0.unwrap_mcode op with
                   Ast.Arith(op) -> same_type (ty1, ty2)
+                | Ast.Logical(Ast.AndLog) | Ast.Logical(Ast.OrLog) ->
+                    Some(bool_type)
                 | Ast.Logical(op) ->
                     let ty = lub_type ty1 ty2 in
-                      Ast0.set_type exp1 ty; Ast0.set_type exp2 ty;
-                      Some(bool_type))
+                    Ast0.set_type exp1 ty; Ast0.set_type exp2 ty;
+                    Some(bool_type))
        | Ast0.Paren(lp,exp,rp) -> Ast0.get_type exp
        | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
            (match strip_cv (Ast0.get_type exp2) with
                 None -> Ast0.set_type exp2 (Some(int_type))
               | Some(ty) when is_int_type ty -> ()
+              | Some(Type_cocci.Unknown) ->
+                  (* unknown comes from param types, not sure why this
+                     is not just None... *)
+                  Ast0.set_type exp2 (Some(int_type))
               | Some ty -> err exp2 ty "bad type for an array index");
            (match strip_cv (Ast0.get_type exp1) with
                 None -> None
diff --git a/test.ml b/test.ml
index 02d038d..8ee1f16 100644 (file)
--- a/test.ml
+++ b/test.ml
  *)
 
 
+(*
+ * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
+ * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
+ * This file is part of Coccinelle.
+ *
+ * Coccinelle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, according to version 2 of the License.
+ *
+ * Coccinelle 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The authors reserve the right to distribute this or future versions of
+ * Coccinelle under other licenses.
+ *)
+
+
 (*
  * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
  * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix