+(* does side effects on C ast and on Cocci info rule *)
+and process_a_ctl_a_env_a_toplevel2 r e c f =
+ indent_do (fun () ->
+ show_or_not_celem "trying" c.ast_c;
+ Flag.currentfile := Some (f ^ ":" ^get_celem c.ast_c);
+ match (r.ctl,c.ast_c) with
+ ((Asttoctl2.NONDECL ctl,t),Ast_c.Declaration _) -> None
+ | ((Asttoctl2.NONDECL ctl,t), _)
+ | ((Asttoctl2.CODE ctl,t), _) ->
+ let ctl = (ctl,t) in (* ctl and other info *)
+ let (trans_info, returned_any_states, inherited_bindings, newbindings) =
+ Common.save_excursion Flag_ctl.loop_in_src_code (fun () ->
+ Flag_ctl.loop_in_src_code :=
+ !Flag_ctl.loop_in_src_code||c.contain_loop;
+
+ (***************************************)
+ (* !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 ctl (r.rule_info.used_after, e))
+ in
+ if not returned_any_states
+ then None
+ else
+ begin
+ show_or_not_celem "found match in" c.ast_c;
+ show_or_not_trans_info trans_info;
+ List.iter (show_or_not_binding "out") newbindings;
+
+ r.rule_info.was_matched := true;
+
+ if not (null trans_info) &&
+ not (!Flag.sgrep_mode2 && not !Flag_cocci.show_diff)
+ then
+ begin
+ c.was_modified := true;
+ try
+ (* les "more than one var in a decl" et "already tagged token"
+ * font crasher coccinelle. Si on a 5 fichiers, donc on a 5
+ * failed. Le try limite le scope des crashes pendant la
+ * trasformation au fichier concerne. *)
+
+ (* modify ast via side effect *)
+ 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;
+
+ Some (List.map (function x -> x@inherited_bindings) newbindings)
+ end
+ )
+
+and process_a_ctl_a_env_a_toplevel a b c f=
+ Common.profile_code "process_a_ctl_a_env_a_toplevel"
+ (fun () -> process_a_ctl_a_env_a_toplevel2 a b c f)
+
+
+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
+
+ (* looping over the rules *)
+ rs +> List.iter (fun r ->
+ match r with
+ InitialScriptRuleCocciInfo r | FinalScriptRuleCocciInfo r -> ()
+ | ScriptRuleCocciInfo r ->
+ if !Flag_cocci.show_ctl_text then begin
+ Common.pr_xxxxxxxxxxxxxxxxx ();
+ pr ("script: " ^ r.language);
+ Common.pr_xxxxxxxxxxxxxxxxx ();
+
+ adjust_pp_with_indent (fun () ->
+ Format.force_newline();
+ 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 (nm,l,deps,mv,script_vars,code)));
+ end;
+
+ if !Flag.show_misc then print_endline "RESULT =";
+
+ let (_, newes) =
+ List.fold_left
+ (function (cache, newes) ->
+ function (e, rules_that_have_matched) ->
+ match r.language with
+ "python" ->
+ apply_script_rule r cache newes e rules_that_have_matched
+ rules_that_have_ever_matched python_application
+ | "ocaml" ->
+ apply_script_rule r cache newes e rules_that_have_matched
+ rules_that_have_ever_matched ocaml_application
+ | "test" ->
+ concat_headers_and_c !ccs +> List.iter (fun (c,_) ->
+ if c.flow <> None
+ then
+ Printf.printf "Flow: %s\r\nFlow!\r\n%!" c.fullstring);
+ (cache, newes)
+ | _ ->
+ Printf.printf "Unknown language: %s\n" r.language;
+ (cache, newes))
+ ([],[]) !es in
+
+ (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);
+
+ if !Flag.sgrep_mode2
+ then begin
+ (* sgrep can lead to code that is not parsable, but we must
+ * still call rebuild_info_c_and_headers to pretty print the
+ * action (MINUS), so that later the diff will show what was
+ * matched by sgrep. But we don't want the parsing error message
+ * hence the following flag setting. So this code propably
+ * will generate a NotParsedCorrectly for the matched parts
+ * and the very final pretty print and diff will work
+ *)
+ Flag_parsing_c.verbose_parsing := false;
+ ccs := rebuild_info_c_and_headers !ccs false
+ end;
+ !ccs (* return final C asts *)
+
+let bigloop a b =
+ Common.profile_code "bigloop" (fun () -> bigloop2 a b)
+
+type init_final = Initial | Final
+
+let initial_final_bigloop2 ty rebuild r =
+ if !Flag_cocci.show_ctl_text then
+ begin
+ Common.pr_xxxxxxxxxxxxxxxxx ();
+ pr ((match ty with Initial -> "initial" | Final -> "final") ^ ": " ^
+ r.language);
+ Common.pr_xxxxxxxxxxxxxxxxx ();
+
+ adjust_pp_with_indent (fun () ->
+ Format.force_newline();
+ Pretty_print_cocci.unparse(rebuild r.scr_ast_rule r.scr_rule_info.dependencies));
+ end;
+
+ match r.language with
+ "python" ->
+ (* include_match makes no sense in an initial or final rule, although
+ we have no way to prevent it *)
+ let _ = apply_script_rule r [] [] [] [] (ref []) python_application in
+ ()
+ | "ocaml" when ty = Initial -> () (* nothing to do *)
+ | "ocaml" ->
+ (* include_match makes no sense in an initial or final rule, although
+ we have no way to prevent it *)
+ let _ = apply_script_rule r [] [] [] [] (ref []) ocaml_application in
+ ()
+ | _ ->
+ failwith ("Unknown language for initial/final script: "^
+ r.language)
+
+let initial_final_bigloop a b c =
+ Common.profile_code "initial_final_bigloop"
+ (fun () -> initial_final_bigloop2 a b c)