X-Git-Url: https://git.hcoop.net/bpt/coccinelle.git/blobdiff_plain/174d164065f16d4a54fd565b9cae251e89a5095e..1eddfd5052863e93b723b26a1d1266471882f234:/cocci.ml diff --git a/cocci.ml b/cocci.ml index a43055e..16a4b88 100644 --- a/cocci.ml +++ b/cocci.ml @@ -69,13 +69,14 @@ let _hctl = Hashtbl.create 101 (* --------------------------------------------------------------------- *) let sp_of_file2 file iso = Common.memoized _hparse (file, iso) (fun () -> - let (_,xs,_,_,_,_,_,_) as res = Parse_cocci.process file iso false in + let (_,xs,_,_,_,_,_) as res = Parse_cocci.process file iso false in (match Prepare_ocamlcocci.prepare file xs with None -> () | Some ocaml_script_file -> (* compile file *) Prepare_ocamlcocci.load_file ocaml_script_file; - Prepare_ocamlcocci.clean_file ocaml_script_file); + if not !Common.save_tmp_files + then Prepare_ocamlcocci.clean_file ocaml_script_file); res) let sp_of_file file iso = Common.profile_code "parse cocci" (fun () -> sp_of_file2 file iso) @@ -174,13 +175,15 @@ let fix_sgrep_diffs l = then (match Str.split (Str.regexp " ") s with bef::min::pl::aft -> - (match Str.split (Str.regexp ",") pl with - [n1;n2] -> - let n2 = int_of_string n2 in - (Printf.sprintf "%s %s %s,%d %s" bef min n1 (n2-n) - (String.concat " " aft)) - :: loop1 0 ss - | _ -> failwith "bad + line information") + let (n1,n2) = + match Str.split (Str.regexp ",") pl with + [n1;n2] -> (n1,n2) + | [n1] -> (n1,"1") + | _ -> failwith "bad + line information" in + let n2 = int_of_string n2 in + (Printf.sprintf "%s %s %s,%d %s" bef min n1 (n2-n) + (String.concat " " aft)) + :: loop1 0 ss | _ -> failwith "bad @@ information") else s :: loop1 n ss in let rec loop2 n = function @@ -192,18 +195,21 @@ let fix_sgrep_diffs l = then (match Str.split (Str.regexp " ") s with bef::min::pl::aft -> - (match (Str.split (Str.regexp ",") min, - Str.split (Str.regexp ",") pl) with - ([_;m2],[n1;n2]) -> - let n1 = - int_of_string - (String.sub n1 1 ((String.length n1)-1)) in - let m2 = int_of_string m2 in - let n2 = int_of_string n2 in - (Printf.sprintf "%s %s +%d,%d %s" bef min (n1-n) n2 - (String.concat " " aft)) - :: loop2 (n+(m2-n2)) ss - | _ -> failwith "bad -/+ line information") + let (m2,n1,n2) = + match (Str.split (Str.regexp ",") min, + Str.split (Str.regexp ",") pl) with + ([_;m2],[n1;n2]) -> (m2,n1,n2) + | ([_],[n1;n2]) -> ("1",n1,n2) + | ([_;m2],[n1]) -> (m2,n1,"1") + | ([_],[n1]) -> ("1",n1,"1") + | _ -> failwith "bad -/+ line information" in + let n1 = + int_of_string (String.sub n1 1 ((String.length n1)-1)) in + let m2 = int_of_string m2 in + let n2 = int_of_string n2 in + (Printf.sprintf "%s %s +%d,%d %s" bef min (n1-n) n2 + (String.concat " " aft)) + :: loop2 (n+(m2-n2)) ss | _ -> failwith "bad @@ information") else s :: loop2 n ss in loop2 0 (List.rev (loop1 0 l)) @@ -263,24 +269,26 @@ let show_or_not_diff2 cfile outfile = let diff_line = match List.rev(Str.split (Str.regexp " ") line) with new_file::old_file::cmdrev -> + let old_base_file = drop_prefix old_file in if !Flag.sgrep_mode2 then String.concat " " - (List.rev ("/tmp/nothing" :: old_file :: cmdrev)) + (List.rev + (("/tmp/nothing"^old_base_file) + :: old_file :: cmdrev)) else - let old_base_file = drop_prefix old_file in String.concat " " (List.rev (("b"^old_base_file)::("a"^old_base_file)::cmdrev)) | _ -> failwith "bad command" in let (minus_line,plus_line) = - if !Flag.sgrep_mode2 - then (minus_file,"+++ /tmp/nothing") - else - match (Str.split (Str.regexp "[ \t]") minus_file, - Str.split (Str.regexp "[ \t]") plus_file) with - ("---"::old_file::old_rest,"+++"::new_file::new_rest) -> - let old_base_file = drop_prefix old_file in + match (Str.split (Str.regexp "[ \t]") minus_file, + Str.split (Str.regexp "[ \t]") plus_file) with + ("---"::old_file::old_rest,"+++"::new_file::new_rest) -> + let old_base_file = drop_prefix old_file in + if !Flag.sgrep_mode2 + then (minus_file,"+++ /tmp/nothing"^old_base_file) + else (String.concat " " ("---"::("a"^old_base_file)::old_rest), String.concat " " @@ -511,7 +519,7 @@ let sp_contain_typed_metavar_z toplevel_list_list = let combiner = Visitor_ast.combiner bind option_default mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode - donothing donothing donothing donothing + donothing donothing donothing donothing donothing donothing expression donothing donothing donothing donothing donothing donothing donothing donothing donothing donothing in @@ -568,7 +576,9 @@ let (includes_to_parse: Flag_cocci.I_UNSPECIFIED -> failwith "not possible" | Flag_cocci.I_NO_INCLUDES -> [] | x -> - let all_includes = x =*= Flag_cocci.I_ALL_INCLUDES in + let all_includes = + List.mem x + [Flag_cocci.I_ALL_INCLUDES; Flag_cocci.I_REALLY_ALL_INCLUDES] in xs +> List.map (fun (file, cs) -> let dir = Common.dirname file in @@ -581,15 +591,20 @@ let (includes_to_parse: | Ast_c.Local xs -> let relpath = Common.join "/" xs in let f = Filename.concat dir (relpath) in + if (Sys.file_exists f) then + Some f + else + if !Flag_cocci.relax_include_path (* for our tests, all the files are flat in the current dir *) - if not (Sys.file_exists f) && !Flag_cocci.relax_include_path - then - let attempt2 = Filename.concat dir (Common.last xs) in - if not (Sys.file_exists f) && all_includes then - interpret_include_path relpath - else Some attempt2 - else Some f + let attempt2 = Filename.concat dir (Common.last xs) in + if not (Sys.file_exists attempt2) && all_includes + then + interpret_include_path relpath + else Some attempt2 + else + if all_includes then interpret_include_path relpath + else None | Ast_c.NonLocal xs -> let relpath = Common.join "/" xs in @@ -602,7 +617,7 @@ let (includes_to_parse: ) | _ -> None)) +> List.concat - +> Common.uniq + +> (fun x -> (List.rev (Common.uniq (List.rev x)))) (*uniq keeps last*) let rec interpret_dependencies local global = function Ast_cocci.Dep s -> List.mem s local @@ -754,15 +769,24 @@ type toplevel_c_info = { (* id: int *) } +type rule_info = { + rulename: string; + dependencies: Ast_cocci.dependency; + used_after: Ast_cocci.meta_name list; + ruleid: int; + was_matched: bool ref; +} + type toplevel_cocci_info_script_rule = { - scr_rulename: string; scr_ast_rule: - string * (string * Ast_cocci.meta_name * Ast_cocci.metavar) list * + string * + (Ast_cocci.script_meta_name * Ast_cocci.meta_name * + Ast_cocci.metavar) list * + Ast_cocci.meta_name list (*fresh vars*) * string; language: string; - scr_dependencies: Ast_cocci.dependency; - scr_ruleid: int; script_code: string; + scr_rule_info: rule_info; } type toplevel_cocci_info_cocci_rule = { @@ -771,21 +795,17 @@ type toplevel_cocci_info_cocci_rule = { ast_rule: Ast_cocci.rule; isexp: bool; (* true if + code is an exp, only for Flag.make_hrule *) - rulename: string; - dependencies: Ast_cocci.dependency; (* There are also some hardcoded rule names in parse_cocci.ml: * let reserved_names = ["all";"optional_storage";"optional_qualifier"] *) dropped_isos: string list; free_vars: Ast_cocci.meta_name list; negated_pos_vars: Ast_cocci.meta_name list; - used_after: Ast_cocci.meta_name list; positions: Ast_cocci.meta_name list; - ruleid: int; ruletype: Ast_cocci.ruletype; - was_matched: bool ref; + rule_info: rule_info; } type toplevel_cocci_info = @@ -853,15 +873,13 @@ let python_code = local_python_code ^ "cocci = Cocci()\n" -let make_init name rulenb lang deps code = +let make_init lang code rule_info = let mv = [] in { - scr_rulename = name; - scr_ast_rule = (lang, mv, code); + scr_ast_rule = (lang, mv, [], code); language = lang; - scr_dependencies = deps; - scr_ruleid = rulenb; - script_code = (if lang = "python" then python_code else "") ^code + script_code = (if lang = "python" then python_code else "") ^code; + scr_rule_info = rule_info; } (* --------------------------------------------------------------------- *) @@ -877,6 +895,13 @@ let prepare_cocci ctls free_var_lists negated_pos_lists (fun (((((((((ctl_toplevel_list,metavars),ast),free_var_list), negated_pos_list),ua),fua),fuas),positions_list),rulenb) -> + let build_rule_info rulename deps = + {rulename = rulename; + dependencies = deps; + used_after = (List.hd ua) @ (List.hd fua); + ruleid = rulenb; + was_matched = ref false;} in + let is_script_rule r = match r with Ast_cocci.ScriptRule _ @@ -887,54 +912,45 @@ let prepare_cocci ctls free_var_lists negated_pos_lists then failwith "not handling multiple minirules"; match ast with - Ast_cocci.ScriptRule (name,lang,deps,mv,code) -> + Ast_cocci.ScriptRule (name,lang,deps,mv,script_vars,code) -> let r = - { - scr_rulename = name; - scr_ast_rule = (lang, mv, code); - language = lang; - scr_dependencies = deps; - scr_ruleid = rulenb; - script_code = code; - } + { + scr_ast_rule = (lang, mv, script_vars, code); + language = lang; + script_code = code; + scr_rule_info = build_rule_info name deps; + } in ScriptRuleCocciInfo r | Ast_cocci.InitialScriptRule (name,lang,deps,code) -> - let r = make_init name rulenb lang deps code in + let r = make_init lang code (build_rule_info name deps) in InitialScriptRuleCocciInfo r | Ast_cocci.FinalScriptRule (name,lang,deps,code) -> let mv = [] in let r = - { - scr_rulename = name; - scr_ast_rule = (lang, mv, code); - language = lang; - scr_dependencies = deps; - scr_ruleid = rulenb; - script_code = code; - } + { + scr_ast_rule = (lang, mv, [], code); + language = lang; + script_code = code; + scr_rule_info = build_rule_info name deps; + } in FinalScriptRuleCocciInfo r | Ast_cocci.CocciRule (rulename,(dependencies,dropped_isos,z),restast,isexp,ruletype) -> - CocciRuleCocciInfo ( - { - ctl = List.hd ctl_toplevel_list; - metavars = metavars; - ast_rule = ast; - isexp = List.hd isexp; - rulename = rulename; - dependencies = dependencies; - dropped_isos = dropped_isos; - free_vars = List.hd free_var_list; - negated_pos_vars = List.hd negated_pos_list; - used_after = (List.hd ua) @ (List.hd fua); - positions = List.hd positions_list; - ruleid = rulenb; - ruletype = ruletype; - was_matched = ref false; - }) + CocciRuleCocciInfo ( + { + ctl = List.hd ctl_toplevel_list; + metavars = metavars; + ast_rule = ast; + isexp = List.hd isexp; + dropped_isos = dropped_isos; + free_vars = List.hd free_var_list; + negated_pos_vars = List.hd negated_pos_list; + positions = List.hd positions_list; + ruletype = ruletype; + rule_info = build_rule_info rulename dependencies; + }) ) - (* --------------------------------------------------------------------- *) let build_info_program cprogram env = @@ -1023,63 +1039,75 @@ let rebuild_info_c_and_headers ccs isexp = rebuild_info_program c_or_h.asts c_or_h.full_fname isexp } ) - +let rec prepare_h seen env hpath choose_includes : file_info list = + if not (Common.lfile_exists hpath) + then + begin + pr2 ("TYPE: header " ^ hpath ^ " not found"); + [] + end + else + begin + let h_cs = cprogram_of_file_cached hpath in + let local_includes = + if choose_includes =*= Flag_cocci.I_REALLY_ALL_INCLUDES + then + List.filter + (function x -> not (List.mem x !seen)) + (includes_to_parse [(hpath,h_cs)] choose_includes) + else [] in + seen := local_includes @ !seen; + let others = + List.concat + (List.map (function x -> prepare_h seen env x choose_includes) + local_includes) in + let info_h_cs = build_info_program h_cs !env in + env := + if null info_h_cs + then !env + else last_env_toplevel_c_info info_h_cs; + others@ + [{ + fname = Common.basename hpath; + full_fname = hpath; + asts = info_h_cs; + was_modified_once = ref false; + fpath = hpath; + fkind = Header; + }] + end let prepare_c files choose_includes : file_info list = let cprograms = List.map cprogram_of_file_cached files in let includes = includes_to_parse (zip files cprograms) choose_includes in + let seen = ref includes in (* todo?: may not be good to first have all the headers and then all the c *) - let all = - (includes +> List.map (fun hpath -> Right hpath)) - ++ - ((zip files cprograms) +> - List.map (fun (file, asts) -> Left (file, asts))) - in - let env = ref !TAC.initial_env in - let ccs = all +> Common.map_filter (fun x -> - match x with - | Right hpath -> - if not (Common.lfile_exists hpath) - then begin - pr2 ("TYPE: header " ^ hpath ^ " not found"); - None - end - else - let h_cs = cprogram_of_file_cached hpath in - let info_h_cs = build_info_program h_cs !env in - env := - if null info_h_cs - then !env - else last_env_toplevel_c_info info_h_cs - ; - Some { - fname = Common.basename hpath; - full_fname = hpath; - asts = info_h_cs; - was_modified_once = ref false; - fpath = hpath; - fkind = Header; - } - | Left (file, cprogram) -> - (* todo?: don't update env ? *) + let includes = + includes +> + List.map (function hpath -> prepare_h seen env hpath choose_includes) +> + List.concat in + + let cfiles = + (zip files cprograms) +> + List.map + (function (file, cprogram) -> + (* todo?: don't update env ? *) let cs = build_info_program cprogram !env in (* we do that only for the c, not for the h *) ignore(update_include_rel_pos (cs +> List.map (fun x -> x.ast_c))); - Some { - fname = Common.basename file; - full_fname = file; - asts = cs; - was_modified_once = ref false; - fpath = file; - fkind = Source; - } - ) - in - ccs + { + fname = Common.basename file; + full_fname = file; + asts = cs; + was_modified_once = ref false; + fpath = file; + fkind = Source + }) in + includes @ cfiles (*****************************************************************************) (* Processing the ctls and toplevel C elements *) @@ -1159,33 +1187,55 @@ let contains_binding e (_,(r,m),_) = true with Not_found -> false -let python_application mv ve r = - Pycocci.build_classes (List.map (function (x,y) -> x) ve); - Pycocci.construct_variables mv ve; - let _ = Pycocci.pyrun_simplestring (local_python_code ^r.script_code) in - !Pycocci.inc_match - -let ocaml_application mv ve r = - Run_ocamlcocci.run mv ve r.scr_rulename r.script_code; - !Coccilib.inc_match +let python_application mv ve script_vars r = + let mv = + List.map + (function + ((Some x,None),y,z) -> (x,y,z) + | _ -> + failwith + (Printf.sprintf "unexpected ast metavar in rule %s" + r.scr_rule_info.rulename)) + mv in + try + Pycocci.build_classes (List.map (function (x,y) -> x) ve); + Pycocci.construct_variables mv ve; + Pycocci.construct_script_variables script_vars; + let _ = Pycocci.pyrun_simplestring (local_python_code ^r.script_code) in + if !Pycocci.inc_match + then Some (Pycocci.retrieve_script_variables script_vars) + else None + with Pycocci.Pycocciexception -> + (pr2 ("Failure in " ^ r.scr_rule_info.rulename); + raise Pycocci.Pycocciexception) + +let ocaml_application mv ve script_vars r = + try + let script_vals = + Run_ocamlcocci.run mv ve script_vars + r.scr_rule_info.rulename r.script_code in + if !Coccilib.inc_match + then Some script_vals + else None + with e -> (pr2 ("Failure in " ^ r.scr_rule_info.rulename); raise e) let apply_script_rule r cache newes e rules_that_have_matched rules_that_have_ever_matched script_application = Common.profile_code r.language (fun () -> - show_or_not_scr_rule_name r.scr_ruleid; + show_or_not_scr_rule_name r.scr_rule_info.ruleid; if not(interpret_dependencies rules_that_have_matched - !rules_that_have_ever_matched r.scr_dependencies) + !rules_that_have_ever_matched r.scr_rule_info.dependencies) then begin print_dependencies "dependencies for script not satisfied:" rules_that_have_matched - !rules_that_have_ever_matched r.scr_dependencies; + !rules_that_have_ever_matched r.scr_rule_info.dependencies; show_or_not_binding "in environment" e; (cache, (e, rules_that_have_matched)::newes) end else begin - let (_, mv, _) = r.scr_ast_rule in + let (_, mv, script_vars, _) = r.scr_ast_rule in let ve = (List.map (function (n,v) -> (("virtual",n),Ast_c.MetaIdVal (v,[]))) !Flag.defined_virtual_env) @ e in @@ -1197,43 +1247,70 @@ let apply_script_rule r cache newes e rules_that_have_matched (function ((re,rm),_) -> List.exists (function (_,(r,m),_) -> r =*= re && m =$= rm) mv) e in - if List.mem relevant_bindings cache - then - begin - print_dependencies - "dependencies for script satisfied, but cached:" - rules_that_have_matched - !rules_that_have_ever_matched - r.scr_dependencies; - show_or_not_binding "in" e; - (cache,newes) - end - else + (try + match List.assoc relevant_bindings cache with + None -> (cache,newes) + | Some script_vals -> + print_dependencies + "dependencies for script satisfied, but cached:" + rules_that_have_matched + !rules_that_have_ever_matched + r.scr_rule_info.dependencies; + show_or_not_binding "in" e; + (* env might be bigger than what was cached against, so have to + merge with newes anyway *) + let new_e = (List.combine script_vars script_vals) @ e in + let new_e = + new_e +> + List.filter + (fun (s,v) -> List.mem s r.scr_rule_info.used_after) in + (cache,merge_env [(new_e, rules_that_have_matched)] newes) + with Not_found -> begin print_dependencies "dependencies for script satisfied:" rules_that_have_matched !rules_that_have_ever_matched - r.scr_dependencies; + r.scr_rule_info.dependencies; show_or_not_binding "in" e; - let new_cache = relevant_bindings :: cache in - if script_application mv ve r - then (new_cache, merge_env [(e, rules_that_have_matched)] newes) - else (new_cache, newes) - end + match script_application mv ve script_vars r with + None -> + (* failure means we should drop e, no new bindings *) + (((relevant_bindings,None) :: cache), newes) + | Some script_vals -> + let script_vals = + List.map (function x -> Ast_c.MetaIdVal(x,[])) + script_vals in + let new_e = + (List.combine script_vars script_vals) @ e in + let new_e = + new_e +> + List.filter + (fun (s,v) -> List.mem s r.scr_rule_info.used_after) in + r.scr_rule_info.was_matched := true; + (((relevant_bindings,Some script_vals) :: cache), + merge_env + [(new_e, + r.scr_rule_info.rulename :: rules_that_have_matched)] + newes) + end) | unbound -> (if !Flag_cocci.show_dependencies then let m2c (_,(r,x),_) = r^"."^x in pr2 (Printf.sprintf "script not applied: %s not bound" (String.concat ", " (List.map m2c unbound)))); + let e = + e +> + List.filter + (fun (s,v) -> List.mem s r.scr_rule_info.used_after) in (cache, merge_env [(e, rules_that_have_matched)] newes)) end) 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; - show_or_not_ctl_text r.ctl r.ast_rule r.ruleid; + Common.profile_code r.rule_info.rulename (fun () -> + show_or_not_rule_name r.ast_rule r.rule_info.ruleid; + show_or_not_ctl_text r.ctl r.ast_rule r.rule_info.ruleid; let reorganized_env = reassociate_positions r.free_vars r.negated_pos_vars !es in @@ -1245,17 +1322,20 @@ let rec apply_cocci_rule r rules_that_have_ever_matched es function ((e,rules_that_have_matched),relevant_bindings) -> if not(interpret_dependencies rules_that_have_matched !rules_that_have_ever_matched - r.dependencies) + r.rule_info.dependencies) then begin print_dependencies - ("dependencies for rule "^r.rulename^" not satisfied:") + ("dependencies for rule "^r.rule_info.rulename^ + " not satisfied:") rules_that_have_matched - !rules_that_have_ever_matched r.dependencies; + !rules_that_have_ever_matched r.rule_info.dependencies; show_or_not_binding "in environment" e; (cache, merge_env - [(e +> List.filter (fun (s,v) -> List.mem s r.used_after), + [(e +> + List.filter + (fun (s,v) -> List.mem s r.rule_info.used_after), rules_that_have_matched)] newes) end @@ -1265,10 +1345,11 @@ let rec apply_cocci_rule r rules_that_have_ever_matched es with Not_found -> print_dependencies - ("dependencies for rule "^r.rulename^" satisfied:") + ("dependencies for rule "^r.rule_info.rulename^ + " satisfied:") rules_that_have_matched !rules_that_have_ever_matched - r.dependencies; + r.rule_info.dependencies; show_or_not_binding "in" e; show_or_not_binding "relevant in" relevant_bindings; @@ -1305,7 +1386,9 @@ let rec apply_cocci_rule r rules_that_have_ever_matched es let old_bindings_to_keep = Common.nub - (e +> List.filter (fun (s,v) -> List.mem s r.used_after)) in + (e +> + List.filter + (fun (s,v) -> List.mem s r.rule_info.used_after)) in let new_e = if null new_bindings then @@ -1335,20 +1418,20 @@ let rec apply_cocci_rule r rules_that_have_ever_matched es (* see comment before combine_pos *) (s,Ast_c.MetaPosValList []) -> false | (s,v) -> - List.mem s r.used_after && + List.mem s r.rule_info.used_after && not (List.mem s old_variables)))) in List.map (function new_binding_to_add -> (List.sort compare (Common.union_set old_bindings_to_keep new_binding_to_add), - r.rulename::rules_that_have_matched)) + r.rule_info.rulename::rules_that_have_matched)) new_bindings_to_add in ((relevant_bindings,new_bindings)::cache, merge_env new_e newes)) ([],[]) reorganized_env in (* end iter es *) - if !(r.was_matched) - then Common.push2 r.rulename rules_that_have_ever_matched; + if !(r.rule_info.was_matched) + then Common.push2 r.rule_info.rulename rules_that_have_ever_matched; es := newes; @@ -1446,7 +1529,7 @@ and process_a_generated_a_env_a_toplevel2 r env = function let free_vars = List.filter (function - (rule,_) when rule =$= r.rulename -> false + (rule,_) when rule =$= r.rule_info.rulename -> false | (_,"ARGS") -> false | _ -> true) r.free_vars in @@ -1454,7 +1537,7 @@ and process_a_generated_a_env_a_toplevel2 r env = function let metavars = List.filter (function md -> - let (rl,_) = Ast_cocci.get_meta_name md in rl =$= r.rulename) + let (rl,_) = Ast_cocci.get_meta_name md in rl =$= r.rule_info.rulename) r.metavars in if Common.include_set free_vars env_domain then Unparse_hrule.pp_rule metavars r.ast_rule env cfile.full_fname @@ -1477,7 +1560,7 @@ and process_a_ctl_a_env_a_toplevel2 r e c f = (* !Main point! The call to the engine *) (***************************************) let model_ctl = CCI.model_for_ctl r.dropped_isos (Common.some c.flow) e - in CCI.mysat model_ctl r.ctl (r.used_after, e) + in CCI.mysat model_ctl r.ctl (r.rule_info.used_after, e) ) in if not returned_any_states @@ -1487,9 +1570,10 @@ and process_a_ctl_a_env_a_toplevel2 r e c f = show_or_not_trans_info trans_info; List.iter (show_or_not_binding "out") newbindings; - r.was_matched := true; + r.rule_info.was_matched := true; - if not (null trans_info) + if not (null trans_info) && + not (!Flag.sgrep_mode2 && not !Flag_cocci.show_diff) then begin c.was_modified := true; try @@ -1499,7 +1583,7 @@ and process_a_ctl_a_env_a_toplevel2 r e c f = * trasformation au fichier concerne. *) (* modify ast via side effect *) - ignore(Transformation_c.transform r.rulename r.dropped_isos + ignore(Transformation_c.transform r.rule_info.rulename r.dropped_isos inherited_bindings trans_info (Common.some c.flow)); with Timeout -> raise Timeout | UnixExit i -> raise (UnixExit i) end; @@ -1531,10 +1615,11 @@ let rec bigloop2 rs (ccs: file_info list) = adjust_pp_with_indent (fun () -> Format.force_newline(); - let (l,mv,code) = r.scr_ast_rule in - let deps = r.scr_dependencies in + let (l,mv,script_vars,code) = r.scr_ast_rule in + let nm = r.scr_rule_info.rulename in + let deps = r.scr_rule_info.dependencies in Pretty_print_cocci.unparse - (Ast_cocci.ScriptRule ("",l,deps,mv,code))); + (Ast_cocci.ScriptRule (nm,l,deps,mv,script_vars,code))); end; if !Flag.show_misc then print_endline "RESULT ="; @@ -1561,7 +1646,11 @@ let rec bigloop2 rs (ccs: file_info list) = (cache, newes)) ([],[]) !es in - es := (if newes = [] then init_es else newes); + (if !(r.scr_rule_info.was_matched) + then + Common.push2 r.scr_rule_info.rulename rules_that_have_ever_matched); + + es := newes (*(if newes = [] then init_es else newes)*); | CocciRuleCocciInfo r -> apply_cocci_rule r rules_that_have_ever_matched es ccs); @@ -1596,7 +1685,7 @@ let initial_final_bigloop2 ty rebuild r = adjust_pp_with_indent (fun () -> Format.force_newline(); - Pretty_print_cocci.unparse(rebuild r.scr_ast_rule r.scr_dependencies)); + Pretty_print_cocci.unparse(rebuild r.scr_ast_rule r.scr_rule_info.dependencies)); end; match r.language with @@ -1612,8 +1701,8 @@ let initial_final_bigloop2 ty rebuild r = let _ = apply_script_rule r [] [] [] [] (ref []) ocaml_application in () | _ -> - Printf.printf "Unknown language for initial/final script: %s\n" - r.language + failwith ("Unknown language for initial/final script: "^ + r.language) let initial_final_bigloop a b c = Common.profile_code "initial_final_bigloop" @@ -1638,7 +1727,7 @@ let pre_engine2 (coccifile, isofile) = (* useful opti when use -dir *) let (metavars,astcocci, free_var_lists,negated_pos_lists,used_after_lists, - positions_lists,toks,_) = + positions_lists,(toks,_,_)) = sp_of_file coccifile isofile in let ctls = ctls_of_ast astcocci used_after_lists positions_lists in @@ -1673,12 +1762,12 @@ let pre_engine2 (coccifile, isofile) = then failwith ("double initializer found for "^r.language)); - if interpret_dependencies [] [] r.scr_dependencies + if interpret_dependencies [] [] r.scr_rule_info.dependencies then begin initial_final_bigloop Initial - (fun (x,_,y) -> fun deps -> - Ast_cocci.InitialScriptRule(r.scr_rulename,x,deps,y)) + (fun (x,_,_,y) -> fun deps -> + Ast_cocci.InitialScriptRule(r.scr_rule_info.rulename,x,deps,y)) r; r.language::languages end @@ -1689,15 +1778,20 @@ let pre_engine2 (coccifile, isofile) = let uninitialized_languages = List.filter (fun used -> not (List.mem used initialized_languages)) - used_languages - in - List.iter (fun lgg -> - initial_final_bigloop Initial - (fun (x,_,y) -> fun deps -> - Ast_cocci.InitialScriptRule("",x,deps,y)) - (make_init "" (-1) lgg Ast_cocci.NoDep ""); - ) - uninitialized_languages; + used_languages in + List.iter + (fun lgg -> + let rule_info = + {rulename = ""; + dependencies = Ast_cocci.NoDep; + used_after = []; + ruleid = (-1); + was_matched = ref false;} in + initial_final_bigloop Initial + (fun (x,_,_,y) -> fun deps -> + Ast_cocci.InitialScriptRule("",x,deps,y)) + (make_init lgg "" rule_info)) + uninitialized_languages; (cocci_infos,toks) @@ -1777,8 +1871,8 @@ let post_engine2 (cocci_infos,_) = (if List.mem r.language languages then failwith ("double finalizer found for "^r.language)); initial_final_bigloop Final - (fun (x,_,y) -> fun deps -> - Ast_cocci.FinalScriptRule(r.scr_rulename,x,deps,y)) + (fun (x,_,_,y) -> fun deps -> + Ast_cocci.FinalScriptRule(r.scr_rule_info.rulename,x,deps,y)) r; r.language::languages | _ -> languages)