let distrib_max = ref (None : int option)
let mod_distrib = ref false
-
(*****************************************************************************)
(* Profiles *)
(*****************************************************************************)
FC.show_binding_in_out;
FC.show_dependencies;
+ Flag_parsing_cocci.keep_ml_script;
Flag_parsing_cocci.show_iso_failures;
FC.verbose_cocci;
"-version", Arg.Unit (fun () ->
let withpython = if Pycocci.python_support then "with" else "without" in
- pr2 (spf "spatch version %s %s Python support" Config.version withpython);
+ let whichregexp =
+ if !Regexp.pcre_support then "with PCRE support"
+ else "with Str regexp support "
+ in
+ pr2 (spf "spatch version %s %s Python support and %s" Config.version withpython whichregexp);
exit 0;
),
" guess what";
"-date", Arg.Unit (fun () ->
- pr2 "version: $Date: 2011/03/14 21:16:17 $";
+ pr2 "version: $Date$";
raise (Common.UnixExit 0)
),
" guess what";
[
"-show_diff" , Arg.Set FC.show_diff, " ";
"-no_show_diff" , Arg.Clear FC.show_diff, " ";
+ "-force_diff" , Arg.Set FC.force_diff,
+ "show diff even if only spacing changes";
"-show_flow" , Arg.Set FC.show_flow, " ";
(* works in conjunction with -show_ctl_text *)
"-ctl_inline_let",
" drop all back edges derived from looping constructs - unsafe";
"-no_gotos", Arg.Set Flag_parsing_c.no_gotos,
" drop all jumps derived from gotos - unsafe";
+ "-no_saved_typedefs", Arg.Clear Flag_cocci.use_saved_typedefs,
+ " drop all inferred typedefs from one parse of some code to the next";
+
+ "-ocaml_regexps", Arg.Clear Regexp.pcre_support,
+ " use OCaml Str regular expressions for constraints";
"-l1", Arg.Clear Flag_parsing_c.label_strategy_2, " ";
"-ifdef_to_if", Arg.Set FC.ifdef_to_if,
[
"-use_cache", Arg.Set Flag_parsing_c.use_cache,
" use .ast_raw pre-parsed cached C file";
+ "-cache_prefix",
+ Arg.String (function s ->
+ Flag_parsing_c.cache_prefix := Some s;
+ Flag_parsing_c.use_cache := true),
+ " directory of cached ASTs, sets -use_cache";
(* could use Flag_parsing_c.options_pad instead *)
+ "-cache_limit",
+ Arg.Int (function n ->
+ Flag_parsing_c.cache_limit := Some n),
+ " maximum number of cached ASTs, sets -use_cache";
];
raise Impossible (* -help is specified in speclist *)
(* copy paste of Arg.parse. Don't want the default -help msg *)
-let arg_parse2 l f msg =
+let arg_parse2 l f msg argv =
(try
- Arg.parse_argv Sys.argv l f msg;
+ Arg.parse_argv argv l f msg;
with
| Arg.Bad emsg -> (* eprintf "%s" msg; exit 2; *)
if not !ignore_unknown_opt then
else [] in
cpp @ ch
-let main_action xs =
+let rec main_action xs =
+ let (cocci_files,xs) =
+ List.partition (function nm -> Filename.check_suffix nm ".cocci") xs in
+ (match (!cocci_file,cocci_files) with
+ "",[fl] -> cocci_file := fl
+ | _,[] -> ()
+ | _ -> failwith "only one .cocci file allowed");
Iteration.base_file_list := xs;
let rec toploop = function
[] -> raise Impossible
groups +> List.map (function Kbuild.Group xs -> xs)
)
in
-
+
+ (* 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
(cocci_infos,res)) in
let outfiles = List.concat outfiles in
(match Iteration.get_pending_instance() with
- None -> (x,xs,cocci_infos,outfiles)
+ 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
- "Transformation not compatible with iteration. Aborting.";
+ "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();
- 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");
-
+ 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)
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");
- );
- if !compare_with_expected
- then Testing.compare_with_expected outfiles)
-
-
+ 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"))
+
(*****************************************************************************)
(* The coccinelle main entry point *)
(*****************************************************************************)
let main () =
begin
let arglist = Array.to_list Sys.argv in
+ let arglist = Command_line.command_line arglist in
if not (null (Common.inter_set arglist
["-cocci_file";"-sp_file";"-sp";"-test";"-testall";
(* Gc.set {(Gc.get ()) with Gc.stack_limit = 1024 * 1024};*)
(* this call can set up many global flag variables via the cmd line *)
- arg_parse2 (Arg.align all_options) (fun x -> args := x::!args) usage_msg;
+ arg_parse2 (Arg.align all_options) (fun x -> args := x::!args) usage_msg
+ (Array.of_list arglist);
(* julia hack so that one can override directories specified on
* the command line. *)