+ (* make cache unique in parallel case *)
+ (match (!distrib_index,!Flag_parsing_c.cache_prefix) with
+ (Some index,Some str) ->
+ Flag_parsing_c.cache_prefix :=
+ Some (Printf.sprintf "%s/d%d" str index)
+ | _ -> ());
+
+ let infiles =
+ match (!distrib_index,!distrib_max) with
+ (None,None) -> infiles
+ | (Some index,Some max) ->
+ (if index >= max
+ then
+ failwith "index starts at 0, and so must be less than max");
+ if !mod_distrib
+ then
+ let rec loop ct = function
+ [] -> []
+ | x::xs ->
+ if (ct mod max) =|= index
+ then x::(loop (ct+1) xs)
+ else loop (ct+1) xs in
+ loop 0 infiles
+ else
+ begin
+ let all_files = List.length infiles in
+ let regions = (all_files + (max - 1)) / max in
+ let this_min = index * regions in
+ let this_max = (index+1) * regions in
+ let rec loop ct = function
+ [] -> []
+ | x::xs ->
+ if this_min <= ct && ct < this_max
+ then x::(loop (ct+1) xs)
+ else loop (ct+1) xs in
+ loop 0 infiles
+ end
+ | _ -> failwith "inconsistent distribution information" in
+
+ let (cocci_infos,outfiles) =
+ Common.profile_code "Main.outfiles computation" (fun () ->
+ let cocci_infos =
+ Cocci.pre_engine (!cocci_file, !Config.std_iso) in
+ let res =
+ infiles +> List.map (fun cfiles ->
+ pr2 ("HANDLING: " ^ (join " " cfiles));
+ (*pr2 (List.hd(Common.cmd_to_list "free -m | grep Mem"));*)
+ flush stderr;
+
+ Common.timeout_function_opt !FC.timeout (fun () ->
+ Common.report_if_take_time 10 (join " " cfiles) (fun () ->
+ try
+ let optfile =
+ if !output_file <> "" && !compat_mode then
+ Some !output_file
+ else
+ None
+ in
+ adjust_stdin cfiles (fun () ->
+ Common.redirect_stdout_opt optfile (fun () ->
+ (* this is the main call *)
+ Cocci.full_engine cocci_infos cfiles
+ ))
+ with
+ | Common.UnixExit x -> raise (Common.UnixExit x)
+ | Pycocci.Pycocciexception ->
+ raise Pycocci.Pycocciexception
+ | e ->
+ if !dir
+ then begin
+ pr2 ("EXN:" ^ Printexc.to_string e);
+ [] (* *)
+ end
+ else raise e))) in
+ (cocci_infos,res)) in
+ let outfiles = List.concat outfiles in
+ (match Iteration.get_pending_instance() with
+ None ->
+ (x,xs,cocci_infos,outfiles)
+ | Some (files,virt_rules,virt_ids) ->
+ if outfiles = [] or outfiles = [] or not !FC.show_diff
+ or !inplace_modif
+ then
+ begin
+ (if !inplace_modif then generate_outfiles outfiles x xs);
+ Flag.defined_virtual_rules := virt_rules;
+ Flag.defined_virtual_env := virt_ids;
+ Common.erase_temp_files();
+ Common.clear_pr2_once();
+ distrib_index := None;
+ distrib_max := None;
+ toploop files
+ end
+ else
+ begin
+ Common.pr2
+ "Out of place transformation not compatible with iteration. Aborting.\n consider using -no_show_diff or -in_place";
+ (x,xs,cocci_infos,outfiles)
+ end) in
+ let (x,xs,cocci_infos,outfiles) = toploop xs in
+
+ Cocci.post_engine cocci_infos;
+ Common.profile_code "Main.result analysis" (fun () ->
+ Ctlcocci_integration.print_bench();
+ generate_outfiles outfiles x xs;
+ if !compare_with_expected
+ then Testing.compare_with_expected outfiles)
+
+and generate_outfiles outfiles x (* front file *) xs (* other files *) =
+ let outfiles = Cocci.check_duplicate_modif outfiles in
+ outfiles +> List.iter (fun (infile, outopt) ->
+ outopt +> Common.do_option (fun outfile ->
+ if !inplace_modif
+ then begin
+ (match !backup_suffix with
+ Some backup_suffix ->
+ Common.command2 ("cp "^infile^" "^infile^backup_suffix)
+ | None -> ());
+ Common.command2 ("cp "^outfile^" "^infile);
+ end;
+
+ if !outplace_modif
+ then Common.command2 ("cp "^outfile^" "^infile^".cocci_res")
+
+ (* potential source of security pb if the /tmp/ file is
+ * a symlink, so simpler to not produce any regular file
+ * (files created by Common.new_temp_file are still ok)
+ * anymore in /tmp.
+ *)
+ (*
+ if !output_file =$= ""
+ then begin
+ let tmpfile = "/tmp/"^Common.basename infile in
+ pr2 (spf "One file modified. Result is here: %s" tmpfile);
+ Common.command2 ("cp "^outfile^" "^tmpfile);
+ end
+ *)
+ ));
+ if !output_file <> "" && not !compat_mode then
+ (match outfiles with
+ | [infile, Some outfile] when infile =$= x && null xs ->
+ Common.command2 ("cp " ^outfile^ " " ^ !output_file)
+ | [infile, None] when infile =$= x && null xs ->
+ Common.command2 ("cp " ^infile^ " " ^ !output_file)
+ | _ ->
+ failwith
+ ("-o can not be applied because there are multiple " ^
+ "modified files"))
+
+let fix_chars s =
+ if (String.length s) > 2 && String.get s 0 = '-'
+ && not (String.get s 1 = '-')
+ then "-"^(String.concat "-" (Str.split (Str.regexp_string "_") s))
+ else s