-(*
- * Copyright 2005-2009, 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.
- *)
-
-
open Common
module CCI = Ctlcocci_integration
+> List.concat
+> Common.uniq
-let rec interpret_dependencies local global virt = function
- Ast_cocci.Dep s ->
- (try List.assoc s virt with Not_found -> List.mem s local)
+let rec interpret_dependencies local global = function
+ Ast_cocci.Dep s -> List.mem s local
| Ast_cocci.AntiDep s ->
(if !Flag_ctl.steps != None
then failwith "steps and ! dependency incompatible");
- (try not(List.assoc s virt) with Not_found -> not (List.mem s local))
- | Ast_cocci.EverDep s ->
- (try List.assoc s virt with Not_found -> List.mem s global)
+ not (List.mem s local)
+ | Ast_cocci.EverDep s -> List.mem s global
| Ast_cocci.NeverDep s ->
(if !Flag_ctl.steps != None
then failwith "steps and ! dependency incompatible");
- (try not(List.assoc s virt) with Not_found -> not (List.mem s global))
+ not (List.mem s global)
| Ast_cocci.AndDep(s1,s2) ->
- (interpret_dependencies local global virt s1) &&
- (interpret_dependencies local global virt s2)
+ (interpret_dependencies local global s1) &&
+ (interpret_dependencies local global s2)
| Ast_cocci.OrDep(s1,s2) ->
- (interpret_dependencies local global virt s1) or
- (interpret_dependencies local global virt s2)
+ (interpret_dependencies local global s1) or
+ (interpret_dependencies local global s2)
| Ast_cocci.NoDep -> true
+ | Ast_cocci.FailDep -> false
-let rec print_dependencies str local global virt dep =
+let rec print_dependencies str local global dep =
if !Flag_cocci.show_dependencies
then
begin
if not (List.mem s !seen)
then
begin
- if try List.assoc s virt with Not_found -> List.mem s local
+ if List.mem s local
then pr2 (s^" satisfied")
else pr2 (s^" not satisfied");
seen := s :: !seen
if not (List.mem s !seen)
then
begin
- if try List.assoc s virt with Not_found -> List.mem s global
+ if List.mem s global
then pr2 (s^" satisfied")
else pr2 (s^" not satisfied");
seen := s :: !seen
| Ast_cocci.OrDep(s1,s2) ->
loop s1;
loop s2
- | Ast_cocci.NoDep -> () in
+ | Ast_cocci.NoDep -> ()
+ | Ast_cocci.FailDep -> pr2 "False not satisfied" in
loop dep
end
| FinalScriptRuleCocciInfo of toplevel_cocci_info_script_rule
| CocciRuleCocciInfo of toplevel_cocci_info_cocci_rule
-type cocci_info = toplevel_cocci_info list * string list list (* tokens *) *
- (string * bool) list (* matched and unmatched virtual rules *)
+type cocci_info = toplevel_cocci_info list * string list list (* tokens *)
type kind_file = Header | Source
type file_info = {
old_e @ (List.rev ext)
let apply_python_rule r cache newes e rules_that_have_matched
- rules_that_have_ever_matched virtual_methods =
+ rules_that_have_ever_matched =
Common.profile_code "python" (fun () ->
show_or_not_scr_rule_name r.scr_ruleid;
if not(interpret_dependencies rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods r.scr_dependencies)
+ !rules_that_have_ever_matched r.scr_dependencies)
then
begin
print_dependencies "dependencies for script not satisfied:"
rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods r.scr_dependencies;
+ !rules_that_have_ever_matched r.scr_dependencies;
show_or_not_binding "in environment" e;
(cache, (e, rules_that_have_matched)::newes)
end
print_dependencies
"dependencies for script satisfied, but cached:"
rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods
+ !rules_that_have_ever_matched
r.scr_dependencies;
show_or_not_binding "in" e;
cache
begin
print_dependencies "dependencies for script satisfied:"
rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods
+ !rules_that_have_ever_matched
r.scr_dependencies;
show_or_not_binding "in" e;
Pycocci.build_classes (List.map (function (x,y) -> x) e);
(cache, merge_env [(e, rules_that_have_matched)] newes))
end)
-let rec apply_cocci_rule r rules_that_have_ever_matched virtual_methods es
+let rec apply_cocci_rule r rules_that_have_ever_matched es
(ccs:file_info list ref) =
Common.profile_code r.rulename (fun () ->
show_or_not_rule_name r.ast_rule r.ruleid;
(function (cache,newes) ->
function ((e,rules_that_have_matched),relevant_bindings) ->
if not(interpret_dependencies rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods
+ !rules_that_have_ever_matched
r.dependencies)
then
begin
print_dependencies
("dependencies for rule "^r.rulename^" not satisfied:")
rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods r.dependencies;
+ !rules_that_have_ever_matched r.dependencies;
show_or_not_binding "in environment" e;
(cache,
merge_env
print_dependencies
("dependencies for rule "^r.rulename^" satisfied:")
rules_that_have_matched
- !rules_that_have_ever_matched virtual_methods
+ !rules_that_have_ever_matched
r.dependencies;
show_or_not_binding "in" e;
show_or_not_binding "relevant in" relevant_bindings;
if !Flag_ctl.partial_match
then
printf
- "Empty list of bindings, I will restart from old env";
+ "Empty list of bindings, I will restart from old env\n";
[(old_bindings_to_keep,rules_that_have_matched)]
end
else
(fun () -> process_a_ctl_a_env_a_toplevel2 a b c f)
-let rec bigloop2 rs virtual_methods (ccs: file_info list) =
- let es = ref [(Ast_c.emptyMetavarsBinding,[])] in
+let rec bigloop2 rs (ccs: file_info list) =
+ let init_es = [(Ast_c.emptyMetavarsBinding,[])] in
+ let es = ref init_es in
let ccs = ref ccs in
let rules_that_have_ever_matched = ref [] in
match r.language with
"python" ->
apply_python_rule r cache newes e rules_that_have_matched
- rules_that_have_ever_matched virtual_methods
+ rules_that_have_ever_matched
| "test" ->
concat_headers_and_c !ccs +> List.iter (fun (c,_) ->
if c.flow <> None
)
([],[]) !es in
- es := newes;
+ es := (if newes = [] then init_es else newes);
| CocciRuleCocciInfo r ->
- apply_cocci_rule r rules_that_have_ever_matched virtual_methods
+ apply_cocci_rule r rules_that_have_ever_matched
es ccs);
if !Flag.sgrep_mode2
"python" ->
(* include_match makes no sense in an initial or final rule, although
er have no way to prevent it *)
- let _ = apply_python_rule r [] [] [] [] (ref []) [] in
+ let _ = apply_python_rule r [] [] [] [] (ref []) in
()
| _ ->
Printf.printf "Unknown language for initial/final script: %s\n"
(* useful opti when use -dir *)
let (metavars,astcocci,free_var_lists,negated_pos_lists,used_after_lists,
- positions_lists,toks,_,virt) =
+ positions_lists,toks,_) =
sp_of_file coccifile isofile in
let ctls = ctls_of_ast astcocci used_after_lists positions_lists in
| _ -> languages)
[] cocci_infos in
- (cocci_infos,toks,virt)
+ (cocci_infos,toks)
let pre_engine a =
Common.profile_code "pre_engine" (fun () -> pre_engine2 a)
-let full_engine2 (cocci_infos,toks,virt) cfiles =
+let full_engine2 (cocci_infos,toks) cfiles =
show_or_not_cfiles cfiles;
if !Flag_cocci.worth_trying_opt && not (worth_trying cfiles toks)
then
begin
- pr2 ("not worth trying:" ^ Common.join " " cfiles);
+ pr2 ("No matches found for " ^ (Common.join " " (Common.union_all toks))
+ ^ "\nSkipping:" ^ (Common.join " " cfiles));
cfiles +> List.map (fun s -> s, None)
end
else
let c_infos = prepare_c cfiles choose_includes in
(* ! the big loop ! *)
- let c_infos' = bigloop cocci_infos virt c_infos in
+ let c_infos' = bigloop cocci_infos c_infos in
if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx ();
if !Flag.show_misc then pr "Finished";
Common.profile_code "full_engine"
(fun () -> let res = full_engine2 a b in (*Gc.print_stat stderr; *)res)
-let post_engine2 (cocci_infos,_,_) =
+let post_engine2 (cocci_infos,_) =
let _ =
List.fold_left
(function languages ->